From 49615164531f784e9f1a11d981abbac1b6cb874a Mon Sep 17 00:00:00 2001 From: Luc Pionchon Date: Wed, 15 Feb 2006 00:08:11 +0000 Subject: [PATCH] * configure.ac: 0.12.0 Merged hildon-lgpl into hildon-libs (and hildon-fm) * doc/tmpl/hildon-system-sound.sgml: added from hildon-lgpl * doc/tmpl/hildon-appview.sgml: likewise. * doc/tmpl/hildon-color-popup.sgml: likewise. * doc/tmpl/hildon-find-toolbar.sgml: likewise. * doc/tmpl/hildon-app.sgml: likewise. * doc/tmpl/hildon-input-mode-hint.sgml: likewise. * doc/tmpl/hildon-caption.sgml: likewise. * doc/tmpl/hildon-marshalers.sgml: likewise. * doc/tmpl/hildon-add-home-dialog.sgml: likewise. * doc/tmpl/hildon-defines.sgml: likewise. * doc/tmpl/gtk-infoprint.sgml: likewise. * doc/tmpl/hildon-composite-widget.sgml: likewise. * hildon-widgets/gtk-infoprint.[ch]: added from hildon-lgpl * hildon-widgets/hildon-app.[ch]:likewise. * hildon-widgets/hildon-app-private.h:likewise. * hildon-widgets/hildon-appview.[ch]:likewise. * hildon-widgets/hildon-caption.[ch]:likewise. * hildon-widgets/hildon-defines.[ch]:likewise. * hildon-widgets/hildon-find-toolbar.[ch]:likewise. * hildon-widgets/hildon-input-mode-hint.h:likewise. * hildon-widgets/Makefile.am (libhildonwidgets_la_SOURCES): removed hildon-file-details-dialog.[ch] (moved to hildon-fm) added, gtk-infoprint.[ch] hildon-app.[ch] hildon-app-private.h hildon-appview.[ch] hildon-caption.[ch] hildon-defines.[ch] hildon-find-toolbar.[ch] hildon-input-mode-hint.h * hildon-widgets/hildon-get-password-dialog.c: corrected #include path for gtk-infoprint.h and hildon-input-mode-hint.h * po/en_GB.po: merged msgstr from hildon-lgpl * timer/*: added from hildon-lgpl Moved hildon-file-details-dialog from hildon-libs to hildon-fm * hildon-widgets/hildon-file-details-dialog.[ch]: moved to hildon-fm * ut/hildon-widgets_tests.c (test41a): removed test case for hildon_file_details_dialog * doc/hildon-libs.types: likewise. * doc/hildon-libs-docs.xml: likewise. Update build files * hildon-libs.pc.in (Libs): do not requires hildon-lgpl anymore nor hildon-fm * Makefile.am (SUBDIRS): added timer/ * configure.ac: do not depend anymore on hildon-lgpl nor hildon-fm, check for libmb, added Makefile output for timer/ --- ChangeLog | 74 + Makefile.am | 2 +- Makefile.in | 4 +- configure | 126 +- configure.ac | 9 +- debian/changelog | 10 + debian/control | 8 +- debian/hildon-libs-dev.install | 1 + doc/Makefile.in | 2 + doc/hildon-libs-docs.xml | 1 - doc/hildon-libs.types | 2 - doc/tmpl/gtk-infoprint.sgml | 120 ++ doc/tmpl/hildon-add-home-dialog.sgml | 38 + doc/tmpl/hildon-app.sgml | 306 ++++ doc/tmpl/hildon-appview.sgml | 254 +++ doc/tmpl/hildon-caption.sgml | 357 +++++ doc/tmpl/hildon-color-popup.sgml | 38 + doc/tmpl/hildon-composite-widget.sgml | 28 + doc/tmpl/hildon-defines.sgml | 525 +++++++ doc/tmpl/hildon-find-toolbar.sgml | 114 ++ doc/tmpl/hildon-input-mode-hint.sgml | 53 + doc/tmpl/hildon-marshalers.sgml | 18 + hildon-libs.pc.in | 2 +- hildon-widgets/Makefile.am | 34 +- hildon-widgets/Makefile.in | 58 +- hildon-widgets/gtk-infoprint.c | 1120 ++++++++++++++ hildon-widgets/gtk-infoprint.h | 52 + hildon-widgets/hildon-app-private.h | 74 + hildon-widgets/hildon-app.c | 2229 +++++++++++++++++++++++++++ hildon-widgets/hildon-app.h | 152 ++ hildon-widgets/hildon-appview.c | 1480 ++++++++++++++++++ hildon-widgets/hildon-appview.h | 121 ++ hildon-widgets/hildon-caption.c | 1248 +++++++++++++++ hildon-widgets/hildon-caption.h | 131 ++ hildon-widgets/hildon-defines.c | 233 +++ hildon-widgets/hildon-defines.h | 142 ++ hildon-widgets/hildon-file-details-dialog.c | 805 ---------- hildon-widgets/hildon-file-details-dialog.h | 80 - hildon-widgets/hildon-find-toolbar.c | 646 ++++++++ hildon-widgets/hildon-find-toolbar.h | 80 + hildon-widgets/hildon-get-password-dialog.c | 5 +- hildon-widgets/hildon-input-mode-hint.h | 70 + po/Makefile.in | 4 +- po/en_GB.po | 14 + timer/Makefile.am | 8 +- timer/Makefile.in | 20 +- timer/timer.c | 2 +- timer/timer.h | 2 +- ut/Makefile.in | 2 + ut/hildon-widgets_tests.c | 14 - 50 files changed, 9954 insertions(+), 964 deletions(-) create mode 100644 doc/tmpl/gtk-infoprint.sgml create mode 100644 doc/tmpl/hildon-add-home-dialog.sgml create mode 100644 doc/tmpl/hildon-app.sgml create mode 100644 doc/tmpl/hildon-appview.sgml create mode 100644 doc/tmpl/hildon-caption.sgml create mode 100644 doc/tmpl/hildon-color-popup.sgml create mode 100644 doc/tmpl/hildon-composite-widget.sgml create mode 100644 doc/tmpl/hildon-defines.sgml create mode 100644 doc/tmpl/hildon-find-toolbar.sgml create mode 100644 doc/tmpl/hildon-input-mode-hint.sgml create mode 100644 doc/tmpl/hildon-marshalers.sgml create mode 100644 hildon-widgets/gtk-infoprint.c create mode 100644 hildon-widgets/gtk-infoprint.h create mode 100644 hildon-widgets/hildon-app-private.h create mode 100644 hildon-widgets/hildon-app.c create mode 100644 hildon-widgets/hildon-app.h create mode 100644 hildon-widgets/hildon-appview.c create mode 100644 hildon-widgets/hildon-appview.h create mode 100644 hildon-widgets/hildon-caption.c create mode 100644 hildon-widgets/hildon-caption.h create mode 100644 hildon-widgets/hildon-defines.c create mode 100644 hildon-widgets/hildon-defines.h delete mode 100644 hildon-widgets/hildon-file-details-dialog.c delete mode 100644 hildon-widgets/hildon-file-details-dialog.h create mode 100644 hildon-widgets/hildon-find-toolbar.c create mode 100644 hildon-widgets/hildon-find-toolbar.h create mode 100644 hildon-widgets/hildon-input-mode-hint.h diff --git a/ChangeLog b/ChangeLog index 99619aa..247c8d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,77 @@ +2006-02-14 Luc Pionchon + + * configure.ac: 0.12.0 + + Merged hildon-lgpl into hildon-libs (and hildon-fm) + + * doc/tmpl/hildon-system-sound.sgml: added from hildon-lgpl + * doc/tmpl/hildon-appview.sgml: likewise. + * doc/tmpl/hildon-color-popup.sgml: likewise. + * doc/tmpl/hildon-find-toolbar.sgml: likewise. + * doc/tmpl/hildon-app.sgml: likewise. + * doc/tmpl/hildon-input-mode-hint.sgml: likewise. + * doc/tmpl/hildon-caption.sgml: likewise. + * doc/tmpl/hildon-marshalers.sgml: likewise. + * doc/tmpl/hildon-add-home-dialog.sgml: likewise. + * doc/tmpl/hildon-defines.sgml: likewise. + * doc/tmpl/gtk-infoprint.sgml: likewise. + * doc/tmpl/hildon-composite-widget.sgml: likewise. + + * hildon-widgets/gtk-infoprint.[ch]: added from hildon-lgpl + * hildon-widgets/hildon-app.[ch]:likewise. + * hildon-widgets/hildon-app-private.h:likewise. + * hildon-widgets/hildon-appview.[ch]:likewise. + * hildon-widgets/hildon-caption.[ch]:likewise. + * hildon-widgets/hildon-defines.[ch]:likewise. + * hildon-widgets/hildon-find-toolbar.[ch]:likewise. + * hildon-widgets/hildon-input-mode-hint.h:likewise. + + * hildon-widgets/Makefile.am (libhildonwidgets_la_SOURCES): + removed hildon-file-details-dialog.[ch] (moved to hildon-fm) + added, + gtk-infoprint.[ch] + hildon-app.[ch] + hildon-app-private.h + hildon-appview.[ch] + hildon-caption.[ch] + hildon-defines.[ch] + hildon-find-toolbar.[ch] + hildon-input-mode-hint.h + + * hildon-widgets/hildon-get-password-dialog.c: corrected #include + path for gtk-infoprint.h and hildon-input-mode-hint.h + + * po/en_GB.po: merged msgstr from hildon-lgpl + + * timer/*: added from hildon-lgpl + + + + Moved hildon-file-details-dialog from hildon-libs to hildon-fm + + * hildon-widgets/hildon-file-details-dialog.[ch]: moved to + hildon-fm + + * ut/hildon-widgets_tests.c (test41a): removed test case for + hildon_file_details_dialog + + * doc/hildon-libs.types: likewise. + * doc/hildon-libs-docs.xml: likewise. + + + + Update build files + + * hildon-libs.pc.in (Libs): do not requires hildon-lgpl anymore + nor hildon-fm + + * Makefile.am (SUBDIRS): added timer/ + + * configure.ac: do not depend anymore on hildon-lgpl nor + hildon-fm, check for libmb, added Makefile output for timer/ + + + 2006-01-18 Luc Pionchon * configure.ac: 0.10.2 diff --git a/Makefile.am b/Makefile.am index 49ccd06..c3dad42 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = hildon-widgets ut doc +SUBDIRS = hildon-widgets timer ut doc EXTRA_DIST = \ debian/changelog \ debian/control \ diff --git a/Makefile.in b/Makefile.in index 38139e1..86f783e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -94,6 +94,8 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ +LIBMB_CFLAGS = @LIBMB_CFLAGS@ +LIBMB_LIBS = @LIBMB_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -167,7 +169,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -SUBDIRS = hildon-widgets ut doc +SUBDIRS = hildon-widgets timer ut doc EXTRA_DIST = \ debian/changelog \ debian/control \ diff --git a/configure b/configure index 42b105c..34fe6f1 100755 --- a/configure +++ b/configure @@ -463,7 +463,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL PKG_CONFIG OUTO_CFLAGS OUTO_LIBS GTK_CFLAGS GTK_LIBS GTK_VERSION ESD_CFLAGS ESD_LIBS GNOME_VFS_CFLAGS GNOME_VFS_LIBS GCONF_CFLAGS GCONF_LIBS ALL_LINGUAS USE_NLS MSGFMT GMSGFMT XGETTEXT CATALOGS CATOBJEXT DATADIRNAME GMOFILES INSTOBJEXT INTLLIBS PO_IN_DATADIR_TRUE PO_IN_DATADIR_FALSE POFILES POSUB MKINSTALLDIRS GTKDOC ENABLE_GTK_DOC_TRUE ENABLE_GTK_DOC_FALSE DOXYGEN_FOUND HAVE_DOXYGEN_TRUE HAVE_DOXYGEN_FALSE docdir localedir outomoduledir HTML_DIR LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL PKG_CONFIG OUTO_CFLAGS OUTO_LIBS GTK_CFLAGS GTK_LIBS GTK_VERSION ESD_CFLAGS ESD_LIBS GNOME_VFS_CFLAGS GNOME_VFS_LIBS GCONF_CFLAGS GCONF_LIBS LIBMB_CFLAGS LIBMB_LIBS ALL_LINGUAS USE_NLS MSGFMT GMSGFMT XGETTEXT CATALOGS CATOBJEXT DATADIRNAME GMOFILES INSTOBJEXT INTLLIBS PO_IN_DATADIR_TRUE PO_IN_DATADIR_FALSE POFILES POSUB MKINSTALLDIRS GTKDOC ENABLE_GTK_DOC_TRUE ENABLE_GTK_DOC_FALSE DOXYGEN_FOUND HAVE_DOXYGEN_TRUE HAVE_DOXYGEN_FALSE docdir localedir outomoduledir HTML_DIR LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -1773,7 +1773,7 @@ fi # Define the identity of the package. PACKAGE=hildon-libs - VERSION=0.10.2 + VERSION=0.12.0 cat >>confdefs.h <<_ACEOF @@ -19388,23 +19388,23 @@ fi else PKG_CONFIG_MIN_VERSION=0.9.0 if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then - echo "$as_me:$LINENO: checking for hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6" >&5 -echo $ECHO_N "checking for hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6... $ECHO_C" >&6 + echo "$as_me:$LINENO: checking for gtk+-2.0" >&5 +echo $ECHO_N "checking for gtk+-2.0... $ECHO_C" >&6 - if $PKG_CONFIG --exists "hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6" ; then + if $PKG_CONFIG --exists "gtk+-2.0" ; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 succeeded=yes echo "$as_me:$LINENO: checking GTK_CFLAGS" >&5 echo $ECHO_N "checking GTK_CFLAGS... $ECHO_C" >&6 - GTK_CFLAGS=`$PKG_CONFIG --cflags "hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6"` + GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0"` echo "$as_me:$LINENO: result: $GTK_CFLAGS" >&5 echo "${ECHO_T}$GTK_CFLAGS" >&6 echo "$as_me:$LINENO: checking GTK_LIBS" >&5 echo $ECHO_N "checking GTK_LIBS... $ECHO_C" >&6 - GTK_LIBS=`$PKG_CONFIG --libs "hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6"` + GTK_LIBS=`$PKG_CONFIG --libs "gtk+-2.0"` echo "$as_me:$LINENO: result: $GTK_LIBS" >&5 echo "${ECHO_T}$GTK_LIBS" >&6 else @@ -19412,7 +19412,7 @@ echo "${ECHO_T}$GTK_LIBS" >&6 GTK_LIBS="" ## If we have a custom action on failure, don't print errors, but ## do set a variable so people can do so. - GTK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6"` + GTK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "gtk+-2.0"` echo $GTK_PKG_ERRORS fi @@ -19427,8 +19427,8 @@ echo "${ECHO_T}$GTK_LIBS" >&6 if test $succeeded = yes; then : else - { { echo "$as_me:$LINENO: error: Library requirements (hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 -echo "$as_me: error: Library requirements (hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { { echo "$as_me:$LINENO: error: Library requirements (gtk+-2.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (gtk+-2.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} { (exit 1); exit 1; }; } fi @@ -19742,6 +19742,107 @@ echo "$as_me: error: Library requirements (gconf-2.0 >= 2.6) not met; consider a + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for libmb >= 1.3" >&5 +echo $ECHO_N "checking for libmb >= 1.3... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "libmb >= 1.3" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking LIBMB_CFLAGS" >&5 +echo $ECHO_N "checking LIBMB_CFLAGS... $ECHO_C" >&6 + LIBMB_CFLAGS=`$PKG_CONFIG --cflags "libmb >= 1.3"` + echo "$as_me:$LINENO: result: $LIBMB_CFLAGS" >&5 +echo "${ECHO_T}$LIBMB_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking LIBMB_LIBS" >&5 +echo $ECHO_N "checking LIBMB_LIBS... $ECHO_C" >&6 + LIBMB_LIBS=`$PKG_CONFIG --libs "libmb >= 1.3"` + echo "$as_me:$LINENO: result: $LIBMB_LIBS" >&5 +echo "${ECHO_T}$LIBMB_LIBS" >&6 + else + LIBMB_CFLAGS="" + LIBMB_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + LIBMB_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libmb >= 1.3"` + echo $LIBMB_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (libmb >= 1.3) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (libmb >= 1.3) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + + + + ALL_LINGUAS="en_GB" @@ -21468,7 +21569,7 @@ HTML_DIR=${docdir}/html - ac_config_files="$ac_config_files Makefile hildon-widgets/Makefile ut/Makefile po/Makefile po/porules.mk doc/Makefile hildon-libs.pc" + ac_config_files="$ac_config_files Makefile hildon-widgets/Makefile timer/Makefile ut/Makefile po/Makefile po/porules.mk doc/Makefile hildon-libs.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -22042,6 +22143,7 @@ do # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "hildon-widgets/Makefile" ) CONFIG_FILES="$CONFIG_FILES hildon-widgets/Makefile" ;; + "timer/Makefile" ) CONFIG_FILES="$CONFIG_FILES timer/Makefile" ;; "ut/Makefile" ) CONFIG_FILES="$CONFIG_FILES ut/Makefile" ;; "po/Makefile" ) CONFIG_FILES="$CONFIG_FILES po/Makefile" ;; "po/porules.mk" ) CONFIG_FILES="$CONFIG_FILES po/porules.mk" ;; @@ -22209,6 +22311,8 @@ s,@GNOME_VFS_CFLAGS@,$GNOME_VFS_CFLAGS,;t t s,@GNOME_VFS_LIBS@,$GNOME_VFS_LIBS,;t t s,@GCONF_CFLAGS@,$GCONF_CFLAGS,;t t s,@GCONF_LIBS@,$GCONF_LIBS,;t t +s,@LIBMB_CFLAGS@,$LIBMB_CFLAGS,;t t +s,@LIBMB_LIBS@,$LIBMB_LIBS,;t t s,@ALL_LINGUAS@,$ALL_LINGUAS,;t t s,@USE_NLS@,$USE_NLS,;t t s,@MSGFMT@,$MSGFMT,;t t diff --git a/configure.ac b/configure.ac index fdd7758..9813f32 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_INIT(Makefile.am) -AM_INIT_AUTOMAKE(hildon-libs, 0.10.2) +AM_INIT_AUTOMAKE(hildon-libs, 0.12.0) AM_CONFIG_HEADER(config.h) AC_CANONICAL_HOST @@ -21,7 +21,7 @@ CFLAGS="$CFLAGS -std=c99 -Wall -pedantic -Wmissing-prototypes -Wmissing-declarat GTK_VERSION=2.6.4 -PKG_CHECK_MODULES(GTK, hildon-lgpl >= 0.9.1 hildon-fm >= 0.8.6) +PKG_CHECK_MODULES(GTK, gtk+-2.0) AC_SUBST(GTK_LIBS) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_VERSION) @@ -41,6 +41,10 @@ PKG_CHECK_MODULES(GCONF, gconf-2.0 >= 2.6) AC_SUBST(GCONF_CFLAGS) AC_SUBST(GCONF_LIBS) +PKG_CHECK_MODULES(LIBMB, libmb >= 1.3) +AC_SUBST(LIBMB_CFLAGS) +AC_SUBST(LIBMB_LIBS) + ALL_LINGUAS="en_GB" AC_SUBST(ALL_LINGUAS) AM_GLIB_GNU_GETTEXT @@ -111,6 +115,7 @@ AC_SUBST(HTML_DIR) AC_OUTPUT(Makefile \ hildon-widgets/Makefile \ + timer/Makefile \ ut/Makefile \ po/Makefile \ po/porules.mk \ diff --git a/debian/changelog b/debian/changelog index 72aedb9..d9ca300 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +hildon-libs (0.12.0-1) unstable; urgency=low + + * Merge hildon-lgpl into hildon-libs and hildon-fm + * Moved hildon-file-details-dialog.[ch] from hildon-libs to hildon-fm + * debian/control: removed dependency on hildon-lgpl and hildon-fm + * debian/control: added missing dependencies + * debian/hildon-libs-dev.install: added "usr/lib/*.a" + + -- Luc Pionchon Tue, 14 Feb 2006 13:02:06 +0200 + hildon-libs (0.10.2-1) unstable; urgency=low * N#22240 CP: Tapping outside the scroll bar invoke the applet. diff --git a/debian/control b/debian/control index 77925a4..35a1584 100644 --- a/debian/control +++ b/debian/control @@ -2,24 +2,24 @@ Source: hildon-libs Section: x11 Priority: optional Maintainer: Luc Pionchon -Build-Depends: debhelper (>= 4.0.0), pkg-config, hildon-lgpl-dev (>= 0.9.24-1), outo, libosso-gnomevfs2-dev, hildon-fm-dev (>= 0.9.15-1), libgtk2.0-dev (>= 2:2.6.4-1.osso6), osso-esd-dev +Build-Depends: debhelper (>= 4.0.0), pkg-config, outo, libosso-gnomevfs2-dev, libgtk2.0-dev (>= 2:2.6.4-1.osso13), osso-esd-dev, libmatchbox-dev (>= 1.3-2), libxi-dev, libxt-dev, libpng12-dev, libgconf2-dev Standards-Version: 3.6.0 Package: hildon-libs-dev Section: devel Architecture: any -Depends: hildon-libs0 (= ${Source-Version}), libgtk2.0-dev (>= 2:2.6.4-1.osso6), hildon-lgpl-dev (>= 0.9.24-1), hildon-fm-dev (>= 0.9.15-1), libosso-gnomevfs2-dev, osso-esd-dev +Depends: hildon-libs0 (= ${Source-Version}), libgtk2.0-dev (>= 2:2.6.4-1.osso6), libosso-gnomevfs2-dev, osso-esd-dev, libmatchbox-dev, libgconf2-dev Description: Hildon libraries development files Package: hildon-libs0 Section: libs Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, hildon-lgpl0, hildon-fm1, osso-sounds-ui, libosso-gnomevfs2-0, osso-esd, hildon-libs-l10n-3.0-engb | hildon-libs-l10n-3.0-english +Depends: ${shlibs:Depends}, ${misc:Depends}, osso-sounds-ui, libosso-gnomevfs2-0, osso-esd, libgconf2-6, hildon-libs-l10n-3.0-engb | hildon-libs-l10n-3.0-english Description: Hildon libraries Package: hildon-libs0-dbg Section: libs Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, hildon-lgpl0-dbg, hildon-fm1-dbg, osso-sounds-ui, libosso-gnomevfs2-0, osso-esd +Depends: ${shlibs:Depends}, ${misc:Depends}, osso-sounds-ui, libosso-gnomevfs2-0, osso-esd Description: Hildon libraries (with debug info) diff --git a/debian/hildon-libs-dev.install b/debian/hildon-libs-dev.install index f240be8..5660c0d 100644 --- a/debian/hildon-libs-dev.install +++ b/debian/hildon-libs-dev.install @@ -1,4 +1,5 @@ usr/include usr/lib/*.so +usr/lib/*.a usr/lib/*.la usr/lib/pkgconfig diff --git a/doc/Makefile.in b/doc/Makefile.in index 2f7ee0b..8bacabf 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -99,6 +99,8 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ +LIBMB_CFLAGS = @LIBMB_CFLAGS@ +LIBMB_LIBS = @LIBMB_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/doc/hildon-libs-docs.xml b/doc/hildon-libs-docs.xml index 2783201..3395c67 100644 --- a/doc/hildon-libs-docs.xml +++ b/doc/hildon-libs-docs.xml @@ -35,7 +35,6 @@ - diff --git a/doc/hildon-libs.types b/doc/hildon-libs.types index 0409b15..e3b846e 100644 --- a/doc/hildon-libs.types +++ b/doc/hildon-libs.types @@ -24,7 +24,6 @@ #include #include #include -#include #include hildon_color_selector_get_type @@ -43,7 +42,6 @@ hildon_telephone_editor_get_type hildon_time_editor_get_type hildon_time_picker_get_type hildon_weekday_picker_get_type -hildon_file_details_dialog_get_type hildon_file_handling_note_get_type hildon_calendar_popup_get_type diff --git a/doc/tmpl/gtk-infoprint.sgml b/doc/tmpl/gtk-infoprint.sgml new file mode 100644 index 0000000..91a3b71 --- /dev/null +++ b/doc/tmpl/gtk-infoprint.sgml @@ -0,0 +1,120 @@ + +gtk-infoprint + + +A widget which provides methods to show a small amount of information for the user. + + + +A widget which provides methods to show a small amount of information for the user. +There is three different types of infoprints and two different types of banners. +Infoprint options are a normal infoprint with default icon, an infoprint with +a stockicon (determined by developer). Third version provides a similar interface +as a printf function has. + +The banners are used to show a progress of event. The progress can be shown with +a progressbar or with an animation. + + + + + gtk_infoprint( window, "This is a default infoprint" ); + gtk_banner_show_animation( window, "This is an animated banner" ); + + + + + + + + + + + + + + + +@parent: +@text: +@stock_id: + + + + + + + +@parent: +@format: +@Varargs: + + + + + + + + + + + + + + +@parent: +@text: +@stock_id: + + + + + + + +@parent: +@text: + + + + + + + +@parent: +@text: + + + + + + + +@parent: +@text: + + + + + + + +@parent: +@fraction: + + + + + + + +@parent: + + + + + + + + + diff --git a/doc/tmpl/hildon-add-home-dialog.sgml b/doc/tmpl/hildon-add-home-dialog.sgml new file mode 100644 index 0000000..7be4c42 --- /dev/null +++ b/doc/tmpl/hildon-add-home-dialog.sgml @@ -0,0 +1,38 @@ + +HildonAddHomeDialog + + + + + + + + + + + + + + + + + + + + + +@parent: +@name: +@new_name: +@Returns: + + + + + + + +@dialog: +@Returns: + + diff --git a/doc/tmpl/hildon-app.sgml b/doc/tmpl/hildon-app.sgml new file mode 100644 index 0000000..fa9f534 --- /dev/null +++ b/doc/tmpl/hildon-app.sgml @@ -0,0 +1,306 @@ + +HildonApp + + +A base widget to present application. + + + +This is the base for any hildon application. +It controls basic looks and functionality of an application, like a title. + + + + +app = hildon_app_new_with_appview( appview ); + +hildon_app_set_title( app, "This is a hello dude application" ); + + + + + + + + + + + + + + + + + + + + + +@HILDON_ZOOM_SMALL: +@HILDON_ZOOM_MEDIUM: +@HILDON_ZOOM_LARGE: + + + + + + +@Returns: + + + + + + + +@appview: +@Returns: + + + + + + + +@self: +@appview: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@newtitle: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@newzoom: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@istwoparttitle: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@view_ptr: + + + + + + + +@self: +@view_ptr: + + + + + + + +@self: +@view_ptr: + + + + + + + +@self: +@killability: + + + + + + + +@self: +@view_ptr: +@Returns: + + + + + + + +@self: +@view_ptr: +@Param3: +@Returns: + +@view_id: + + + + + + + +@self: +@Param2: + +@view_id: + + + + + + + +@self: +@auto_reg: + + + + + + + +@hildonapp: the object which received the signal. +@arg1: + + + + + + +@hildonapp: the object which received the signal. +@arg1: + + + + + + +@hildonapp: the object which received the signal. +@arg1: + + + + + + +@hildonapp: the object which received the signal. + + + + + + +@hildonapp: the object which received the signal. +@arg1: + + + + + + +@hildonapp: the object which received the signal. + + + + + + +@hildonapp: the object which received the signal. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/tmpl/hildon-appview.sgml b/doc/tmpl/hildon-appview.sgml new file mode 100644 index 0000000..54e1713 --- /dev/null +++ b/doc/tmpl/hildon-appview.sgml @@ -0,0 +1,254 @@ + +HildonAppView + + +A widget which present one view of an application. + + + +A widget which present one view of an application. +Application can have many different views and the appview helps to organize. +It has automatic fullscreen and menu handling. It also helps to handle components +like a toolbar. + + + + +appview = hildon_appview_new( "This is an application view" ); +hildon_appview_set_fullscreen_key_allowed( appview, TRUE ); +hildon_appview_set_toolbar( appview, toolbar ); + +hildon_app_set_appview( appview ); + +hildon_appview_set_fullscreen( appview, TRUE ); + + + + +By default, HildonAppView doesn't toggle fullscreen from the fullscreen +hardware key. This is because there might be applications that are not intended to +have ability to switch to fullscreen mode at all. To enable fullscreen +toggling from fullscreen hardware key, use #hildon_appview_set_fullscreen_key_allowed -function. + + + + + + + + + + + + + + + + + + + + + + + + + +@title: +@Returns: + + + + + + + +@self: +@child: + + + + + + + +@self: +@allow: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@fullscreen: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@toolbar: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@newname: + + + + + + + +@self: +@Returns: + + + + + + + +@self: +@adjustment: + + + + + + + +@self: +@Returns: + + + + + + + +@hildonappview: the object which received the signal. +@arg1: the Gdk key state. + + + + + + +@hildonappview: the object which received the signal. +@arg1: + + + + + + +@hildonappview: the object which received the signal. +@arg1: the Gdk key state. + + + + + + +@hildonappview: the object which received the signal. + + + + + + +@hildonappview: the object which received the signal. + + + + + + +@hildonappview: the object which received the signal. + + + +This is not a valid signal to listen to. Since HildonAppView supports + multi-toolbar, and packing of these toolbars is in the hand of the + programmers. Please access the public member GtkVBox in HildonAppView + to set/get your toolbars. + + + +@hildonappview: the object which received the signal. + + + +This is not a valid signal to listen to. Since HildonAppView supports + multi-toolbar, and showing/hiding of the these toolbars is required from + the programmers. + + + +@hildonappview: the object which received the signal. + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/tmpl/hildon-caption.sgml b/doc/tmpl/hildon-caption.sgml new file mode 100644 index 0000000..6f1ed6e --- /dev/null +++ b/doc/tmpl/hildon-caption.sgml @@ -0,0 +1,357 @@ + +HildonCaption + + + + + + + + + + + + + +##include <hildon-widgets/hildon-caption.h> + +##include <gtk/gtkwidget.h> +##include <gtk/gtkvbox.h> +##include <gtk/gtkhbox.h> +##include <gtk/gtkcombobox.h> +##include <gtk/gtkcomboboxentry.h> +##include <gtk/gtkentry.h> +##include <gtk/gtkscrolledwindow.h> +##include <gtk/gtkimage.h> +##include <gtk/gtkcheckbutton.h> +##include <glib/glist.h> +##include <gtk/gtktogglebutton.h> +##include <gtk/gtklabel.h> + +##include <libintl.h> +##define _(String) gettext(String) + +static void destroy_callback( GtkWidget *widget ); +void _testCaptionControl(GtkWidget *parent, gchar **help); + +gchar *hildon_icons[] = { "hildon-file-open", + "gtk-ok", + "gtk-refresh", + "gtk-remove" +}; + +const int num_icons = sizeof( hildon_icons ) / sizeof( gchar * ); + +static GList *caption_list = NULL; + +static void text_changed_callback( HildonCaption *caption, gpointer user_data ) +{ + hildon_caption_set_label( caption, gtk_entry_get_text( user_data ) ); +} + +static void icon_toggled_callback( HildonCaption *caption, gpointer user_data ) +{ + GtkWidget *phone_image = NULL; + GList *cur = caption_list; + int i = 0; + while ( cur ) + { + if ( !hildon_caption_get_icon_image( HILDON_CAPTION(cur->data) ) ) + { + phone_image = gtk_image_new_from_stock( hildon_icons[i], GTK_ICON_SIZE_SMALL_TOOLBAR ); + } + + hildon_caption_set_icon_image( HILDON_CAPTION( cur->data), phone_image ); + + cur = cur->next; + if ( ++i >= num_icons ) + { + i = 0; + } + + } +} +static void mandatory_toggled_callback( HildonCaption *caption, gpointer user_data ) +{ + GList *cur = caption_list; + int i = 0; + while ( cur ) + { + if ( hildon_caption_is_mandatory( HILDON_CAPTION(cur->data) ) ) + { + hildon_caption_set_status( HILDON_CAPTION(cur->data), HILDON_CAPTION_OPTIONAL ); + } + else + { + hildon_caption_set_status( HILDON_CAPTION(cur->data), HILDON_CAPTION_MANDATORY ); + } + + cur = cur->next; + if ( ++i > num_icons ) + { + i = 0; + } + } +} + +static void destroy_callback( GtkWidget *widget ) +{ + g_print( "Destroying the empty label\n" ); +} + +void _testCaptionControl(GtkWidget *parent, gchar **help) +{ + + GtkWidget *control = NULL; + GtkWidget *caption_control = NULL; + GtkWidget *vbox = gtk_vbox_new( FALSE, 0 ); + GtkWidget *top_vbox = GTK_WIDGET(gtk_vbox_new( FALSE, 0 )); + GtkWidget *hbox = GTK_WIDGET(gtk_hbox_new( FALSE, 0 )); + GtkSizeGroup *group= GTK_SIZE_GROUP( gtk_size_group_new( GTK_SIZE_GROUP_HORIZONTAL ) ); + + GtkWidget *some_image = gtk_image_new_from_file( "../share/themes/commonimages/question.png" ); + + control = gtk_entry_new(); + caption_control = hildon_caption_new( group, _("Man Entry"), control, + NULL, HILDON_CAPTION_MANDATORY); + gtk_box_pack_start( GTK_BOX( top_vbox ), caption_control, FALSE, FALSE, 0 ); + + g_signal_connect( G_OBJECT( control ), "destroy", G_CALLBACK( destroy_callback ), NULL ); + + control = gtk_entry_new(); + caption_control = hildon_caption_new( group, _("O grow"), control, + NULL, HILDON_CAPTION_OPTIONAL); + g_signal_connect_swapped( control, "changed", + G_CALLBACK( text_changed_callback ), caption_control ); + gtk_box_pack_start( GTK_BOX( top_vbox ), caption_control, FALSE, FALSE, 0 ); + + gtk_box_pack_end( GTK_BOX( hbox ), some_image, FALSE, FALSE, 0 ); + gtk_box_pack_end( GTK_BOX( hbox ), top_vbox, TRUE, TRUE, 0 ); + + gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); + + control = gtk_combo_box_entry_new_text(); + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("First Item")); + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("Second Item")); + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("Third Item")); + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("Fourth Item")); + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("Fifth Item")); + caption_control = hildon_caption_new( group, _("M Com"), control, + NULL, HILDON_CAPTION_MANDATORY); + gtk_box_pack_start( GTK_BOX( vbox ), caption_control, FALSE, FALSE, 0 ); + caption_list = g_list_append( caption_list, (gpointer)caption_control ); + + control = gtk_label_new("This text should not be focusable"); + caption_control = hildon_caption_new (group, _("UFLabel"), control, NULL, HILDON_CAPTION_OPTIONAL); + gtk_box_pack_start( GTK_BOX( vbox ), caption_control, FALSE, FALSE, 0 ); + caption_list = g_list_append (caption_list, (gpointer) caption_control ); + + control = gtk_combo_box_new_text(); /* entry */ + + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("Tango")); + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("Mambo")); + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("Merengue")); + gtk_combo_box_append_text(GTK_COMBO_BOX(control), _("Salsa")); + caption_control = hildon_caption_new( group, _("O Option Menu"), control, + NULL, HILDON_CAPTION_MANDATORY); + gtk_box_pack_start( GTK_BOX( vbox ), caption_control, FALSE, FALSE, 0 ); + caption_list = g_list_append( caption_list, (gpointer)caption_control ); + + + control = gtk_check_button_new(); + caption_control = hildon_caption_new( group, _("show icon"), control, + NULL, HILDON_CAPTION_MANDATORY); + g_signal_connect_swapped( control, "toggled", + G_CALLBACK( icon_toggled_callback ), caption_control ); + gtk_box_pack_start( GTK_BOX( vbox ), caption_control, FALSE, FALSE, 0 ); + caption_list = g_list_append( caption_list, (gpointer)caption_control ); + + control = gtk_check_button_new(); + caption_control = hildon_caption_new( group, _("toggle status"), control, + NULL, HILDON_CAPTION_OPTIONAL); + g_signal_connect_swapped( control, "toggled", + G_CALLBACK( mandatory_toggled_callback ), caption_control ); + gtk_box_pack_start( GTK_BOX( vbox ), caption_control, FALSE, FALSE, 0 ); + caption_list = g_list_append( caption_list, (gpointer)caption_control ); + + + gtk_container_add( GTK_CONTAINER( parent ), vbox ); + + gtk_widget_show_all( parent ); + + if (help) + *help = g_strdup (""); + +} + + + + + + + + + + + + + + +@HILDON_CAPTION_OPTIONAL: +@HILDON_CAPTION_MANDATORY: + + + + + + + + + + + + +@group: +@value: +@control: +@icon: +@flag: +@Returns: + + + + + + + +@caption: +@Returns: + + + + + + + +@caption: +@new_group: + + + + + + + +@caption: +@Returns: + + + + + + + +@caption: +@flag: + + + + + + + +@caption: +@Returns: + + + + + + + +@caption: +@icon: + + + + + + + +@caption: +@Returns: + + + + + + + +@caption: +@label: + + + + + + + +@caption: +@Returns: + + + + + + + +@caption: +@Returns: + + + + + + + +@caption: +@control: + + + + + + + +@hildoncaption: the object which received the signal. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/tmpl/hildon-color-popup.sgml b/doc/tmpl/hildon-color-popup.sgml new file mode 100644 index 0000000..6b320f8 --- /dev/null +++ b/doc/tmpl/hildon-color-popup.sgml @@ -0,0 +1,38 @@ + +hildon-color-popup + + + + + + + + + + + + + + + + + + + + + +@parent: +@initial_color: +@popupdata: +@Returns: + + + + + + + +@color: +@popupdata: + + diff --git a/doc/tmpl/hildon-composite-widget.sgml b/doc/tmpl/hildon-composite-widget.sgml new file mode 100644 index 0000000..6e8eb97 --- /dev/null +++ b/doc/tmpl/hildon-composite-widget.sgml @@ -0,0 +1,28 @@ + +hildon-composite-widget + + + + + + + + + + + + + + + + + + + + + +@widget: +@direction: +@Returns: + + diff --git a/doc/tmpl/hildon-defines.sgml b/doc/tmpl/hildon-defines.sgml new file mode 100644 index 0000000..a860eac --- /dev/null +++ b/doc/tmpl/hildon-defines.sgml @@ -0,0 +1,525 @@ + +hildon-defines + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@icon_size_list: +@icon_size_small: +@icon_size_toolbar: +@icon_size_widg: +@icon_size_widg_wizard: +@icon_size_grid: +@icon_size_big_note: +@icon_size_note: +@icon_size_statusbar: +@icon_size_indi_video_player_pre_roll: +@icon_size_indi_key_pad_lock: +@icon_size_indi_copy: +@icon_size_indi_delete: +@icon_size_indi_process: +@icon_size_indi_progressball: +@icon_size_indi_send: +@icon_size_indi_offmode_charging: +@icon_size_indi_tap_and_hold: +@icon_size_indi_send_receive: +@icon_size_indi_wlan_strength: +@image_size_indi_nokia_logo: +@image_size_indi_startup_failed: +@image_size_indi_startup_nokia_logo: +@image_size_indi_nokia_hands: + + + + + + + + + + + + +@iconvar: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@widget: +@logicalfontname: +@Returns: + + + + + + + +@widget: +@rcflags: +@state: +@logicalcolorname: +@Returns: + + diff --git a/doc/tmpl/hildon-find-toolbar.sgml b/doc/tmpl/hildon-find-toolbar.sgml new file mode 100644 index 0000000..9c96ab8 --- /dev/null +++ b/doc/tmpl/hildon-find-toolbar.sgml @@ -0,0 +1,114 @@ + +HildonFindToolbar + + +A special toolbar to be used with HildonAppView. + + + +HildonFindToolbar is a predefined toolbar for text searching purpose. It contains a GtkListStore which +has the text items that the user has searched. But once the application is terminated, or HildonFindToolbar is trashed. Programmer + is responsible for getting the GtkListStore through property "list", if he/she wants to use the information in the future. + And through the same property, programmer is able to set the GtkListStore. Note, once the search button is pressed, string in the + GtkComboxEntry is automatically added to the existing model, unless it is empty. + + + + + + + + + + + + + + + +Create a HildonFindToolbar without any preset GtkListStore. + + +@label: +@Returns: + + + + +Creat a HildonFindToolbar with a preset GtkListStore. + + +@label: +@model: +@column: +@Returns: + + + + +It is emitted everytime the close button is clicked. Note that HildonFindToolbar +does not hide itself. It is programmer's responsibility to hide the HildonFindToolbar + on receiving this signal, or do whatever he thinks is appropreiate. + + +@hildonfindtoolbar: the object which received the signal. + + + +Every time the user presses search button, the search signal is first emitted, + then history-append signal is emitted. The default handler will add + the currect item to the search history list. In case that the programmer + does not want to have the item added to list, for instance, when the search + fails, he must write his own handler and return TRUE. + + + +@hildonfindtoolbar: the object which received the signal. +@Returns: + + + +This signal indicates that the user has reached the maximum allowed character in the + search field. The typical action is to kindly inform the user that he has + reached the limit of search field using info print. + + +@hildonfindtoolbar: the object which received the signal. + + + +It is emitted everytime the search button is clicked, even the GtkComboboxEntry is empty. + + +@hildonfindtoolbar: the object which received the signal. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/tmpl/hildon-input-mode-hint.sgml b/doc/tmpl/hildon-input-mode-hint.sgml new file mode 100644 index 0000000..decc9aa --- /dev/null +++ b/doc/tmpl/hildon-input-mode-hint.sgml @@ -0,0 +1,53 @@ + +hildon-input-mode-hint + + +Wrappers for setting GtkEntry and GtkTextView input modes and autocapitalization. + + + + + + + +g_object_set(G_OBJECT(entry), "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL); + +g_object_set(G_OBJECT(entry), "autocap", FALSE, NULL); + + + + + + + + + + + + + + + +Use this to set the input mode in text widget. Note that this affects +only input methods layout. + + + + + + + + + + +@HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL: +@HILDON_INPUT_MODE_HINT_NUMERIC: +@HILDON_INPUT_MODE_HINT_ALPHA: +@HILDON_INPUT_MODE_HINT_NUMERICSPECIAL: +@HILDON_INPUT_MODE_HINT_ALPHASPECIAL: +@HILDON_INPUT_MODE_HINT_ALPHANUMERIC: +@HILDON_INPUT_MODE_HINT_HEXA: +@HILDON_INPUT_MODE_HINT_HEXASPECIAL: +@HILDON_INPUT_MODE_HINT_TELE: +@HILDON_INPUT_MODE_HINT_TELESPECIAL: + diff --git a/doc/tmpl/hildon-marshalers.sgml b/doc/tmpl/hildon-marshalers.sgml new file mode 100644 index 0000000..acd0a12 --- /dev/null +++ b/doc/tmpl/hildon-marshalers.sgml @@ -0,0 +1,18 @@ + +hildon-marshalers + + + + + + + + + + + + + + + + diff --git a/hildon-libs.pc.in b/hildon-libs.pc.in index 17dcd03..53ffcc9 100644 --- a/hildon-libs.pc.in +++ b/hildon-libs.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: hildon-libs Description: Teema Hildon framework and widget libraries -Requires: hildon-lgpl hildon-fm +Requires: gtk+-2.0 >= @GTK_VERSION@ Version: @VERSION@ Libs: -L${libdir} -lhildonwidgets Cflags: -I${includedir} diff --git a/hildon-widgets/Makefile.am b/hildon-widgets/Makefile.am index 38489a2..2265725 100644 --- a/hildon-widgets/Makefile.am +++ b/hildon-widgets/Makefile.am @@ -1,5 +1,5 @@ INCLUDES = $(GTK_CFLAGS) $(GNOME_VFS_CFLAGS) $(GCONF_CFLAGS) \ - $(ESD_CFLAGS) -DLOCALEDIR=\"$(localedir)\" -I$(srcdir)/.. + $(ESD_CFLAGS) $(LIBMB_CFLAGS) -DLOCALEDIR=\"$(localedir)\" -I$(srcdir)/.. lib_LTLIBRARIES = libhildonwidgets.la @@ -8,7 +8,7 @@ EXTRA_DIST = hildon-marshalers.list libhildonwidgets_la_LDFLAGS = -version-info 5:0:5 libhildonwidgets_la_LIBADD = $(GTK_LIBS) $(GNOME_VFS_LIBS) $(GCONF_LIBS) \ - $(ESD_LIBS) + $(ESD_LIBS) $(LIBMB_LIBS) libhildonwidgets_la_SOURCES = \ hildon-marshalers.c \ @@ -62,8 +62,6 @@ libhildonwidgets_la_SOURCES = \ hildon-font-selection-dialog.h \ hildon-insert-object-dialog.c \ hildon-insert-object-dialog.h \ - hildon-file-details-dialog.c \ - hildon-file-details-dialog.h \ hildon-grid.c \ hildon-grid.h \ hildon-grid-item.c \ @@ -82,7 +80,22 @@ libhildonwidgets_la_SOURCES = \ hildon-color-button.c \ hildon-color-button.h \ hildon-system-sound.c \ - hildon-system-sound.h + hildon-system-sound.h \ + hildon-app.c \ + hildon-defines.c \ + hildon-app.h \ + hildon-defines.h \ + hildon-appview.c \ + hildon-find-toolbar.c \ + gtk-infoprint.c \ + hildon-appview.h \ + hildon-find-toolbar.h \ + gtk-infoprint.h \ + hildon-caption.c \ + hildon-input-mode-hint.h \ + hildon-app-private.h \ + hildon-caption.h + hildon-marshalers.h: hildon-marshalers.list glib-genmarshal --prefix _hildon_marshal --header \ @@ -117,7 +130,6 @@ hildonwidgetsincludeinst_DATA = \ hildon-add-home-dialog.h \ hildon-font-selection-dialog.h \ hildon-insert-object-dialog.h \ - hildon-file-details-dialog.h \ hildon-grid.h \ hildon-grid-item.h \ hildon-file-handling-note.h \ @@ -126,4 +138,12 @@ hildonwidgetsincludeinst_DATA = \ hildon-wizard-dialog.h \ hildon-color-popup.h \ hildon-color-button.h \ - hildon-system-sound.h + hildon-system-sound.h \ + hildon-app.h \ + hildon-defines.h \ + hildon-appview.h \ + hildon-find-toolbar.h \ + gtk-infoprint.h \ + hildon-input-mode-hint.h \ + hildon-app-private.h \ + hildon-caption.h diff --git a/hildon-widgets/Makefile.in b/hildon-widgets/Makefile.in index 7842693..83ab543 100644 --- a/hildon-widgets/Makefile.in +++ b/hildon-widgets/Makefile.in @@ -94,6 +94,8 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ +LIBMB_CFLAGS = @LIBMB_CFLAGS@ +LIBMB_LIBS = @LIBMB_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -168,7 +170,7 @@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ INCLUDES = $(GTK_CFLAGS) $(GNOME_VFS_CFLAGS) $(GCONF_CFLAGS) \ - $(ESD_CFLAGS) -DLOCALEDIR=\"$(localedir)\" -I$(srcdir)/.. + $(ESD_CFLAGS) $(LIBMB_CFLAGS) -DLOCALEDIR=\"$(localedir)\" -I$(srcdir)/.. lib_LTLIBRARIES = libhildonwidgets.la @@ -178,7 +180,7 @@ EXTRA_DIST = hildon-marshalers.list libhildonwidgets_la_LDFLAGS = -version-info 5:0:5 libhildonwidgets_la_LIBADD = $(GTK_LIBS) $(GNOME_VFS_LIBS) $(GCONF_LIBS) \ - $(ESD_LIBS) + $(ESD_LIBS) $(LIBMB_LIBS) libhildonwidgets_la_SOURCES = \ @@ -233,8 +235,6 @@ libhildonwidgets_la_SOURCES = \ hildon-font-selection-dialog.h \ hildon-insert-object-dialog.c \ hildon-insert-object-dialog.h \ - hildon-file-details-dialog.c \ - hildon-file-details-dialog.h \ hildon-grid.c \ hildon-grid.h \ hildon-grid-item.c \ @@ -253,7 +253,21 @@ libhildonwidgets_la_SOURCES = \ hildon-color-button.c \ hildon-color-button.h \ hildon-system-sound.c \ - hildon-system-sound.h + hildon-system-sound.h \ + hildon-app.c \ + hildon-defines.c \ + hildon-app.h \ + hildon-defines.h \ + hildon-appview.c \ + hildon-find-toolbar.c \ + gtk-infoprint.c \ + hildon-appview.h \ + hildon-find-toolbar.h \ + gtk-infoprint.h \ + hildon-caption.c \ + hildon-input-mode-hint.h \ + hildon-app-private.h \ + hildon-caption.h hildonwidgetsincludeinstdir = $(includedir)/hildon-widgets @@ -280,7 +294,6 @@ hildonwidgetsincludeinst_DATA = \ hildon-add-home-dialog.h \ hildon-font-selection-dialog.h \ hildon-insert-object-dialog.h \ - hildon-file-details-dialog.h \ hildon-grid.h \ hildon-grid-item.h \ hildon-file-handling-note.h \ @@ -289,7 +302,15 @@ hildonwidgetsincludeinst_DATA = \ hildon-wizard-dialog.h \ hildon-color-popup.h \ hildon-color-button.h \ - hildon-system-sound.h + hildon-system-sound.h \ + hildon-app.h \ + hildon-defines.h \ + hildon-appview.h \ + hildon-find-toolbar.h \ + gtk-infoprint.h \ + hildon-input-mode-hint.h \ + hildon-app-private.h \ + hildon-caption.h subdir = hildon-widgets ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -311,27 +332,33 @@ am_libhildonwidgets_la_OBJECTS = hildon-marshalers.lo \ hildon-get-password-dialog.lo hildon-set-password-dialog.lo \ hildon-sort-dialog.lo hildon-add-home-dialog.lo \ hildon-font-selection-dialog.lo hildon-insert-object-dialog.lo \ - hildon-file-details-dialog.lo hildon-grid.lo \ - hildon-grid-item.lo hildon-file-handling-note.lo \ + hildon-grid.lo hildon-grid-item.lo hildon-file-handling-note.lo \ hildon-name-password-dialog.lo hildon-scroll-area.lo \ hildon-wizard-dialog.lo hildon-color-popup.lo \ - hildon-color-button.lo hildon-system-sound.lo + hildon-color-button.lo hildon-system-sound.lo hildon-app.lo \ + hildon-defines.lo hildon-appview.lo hildon-find-toolbar.lo \ + gtk-infoprint.lo hildon-caption.lo libhildonwidgets_la_OBJECTS = $(am_libhildonwidgets_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/hildon-add-home-dialog.Plo \ +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gtk-infoprint.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/hildon-add-home-dialog.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/hildon-app.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/hildon-appview.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-calendar-popup.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/hildon-caption.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-color-button.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-color-popup.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-color-selector.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-composite-widget.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-controlbar.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-date-editor.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/hildon-defines.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-dialoghelp.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/hildon-file-details-dialog.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-file-handling-note.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/hildon-find-toolbar.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-font-selection-dialog.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-get-password-dialog.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/hildon-grid-item.Plo \ @@ -415,17 +442,22 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk-infoprint.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-add-home-dialog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-app.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-appview.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-calendar-popup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-caption.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-color-button.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-color-popup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-color-selector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-composite-widget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-controlbar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-date-editor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-defines.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-dialoghelp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-file-details-dialog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-file-handling-note.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-find-toolbar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-font-selection-dialog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-get-password-dialog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hildon-grid-item.Plo@am__quote@ diff --git a/hildon-widgets/gtk-infoprint.c b/hildon-widgets/gtk-infoprint.c new file mode 100644 index 0000000..cad0cdb --- /dev/null +++ b/hildon-widgets/gtk-infoprint.c @@ -0,0 +1,1120 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include "gtk-infoprint.h" +#include "hildon-defines.h" +#include "hildon-app.h" + +#define INFOPRINT_MIN_WIDTH 39 +#define INFOPRINT_MAX_WIDTH 334 +#define BANNER_MIN_WIDTH 35 +#define BANNER_MAX_WIDTH 375 +#define DEFAULT_WIDTH 20 +#define DEFAULT_HEIGHT 28 /* 44-8-8 = 28 */ +#define WINDOW_WIDTH 600 +#define MESSAGE_TIMEOUT 2500 +#define GTK_INFOPRINT_STOCK "gtk-infoprint" +#define GTK_INFOPRINT_ICON_THEME "qgn_note_infoprint" + +#define BANNER_PROGRESSBAR_MIN_WIDTH 83 +#define INFOPRINT_MIN_SIZE 50 +#define INFOPRINT_WINDOW_Y 73 +#define INFOPRINT_WINDOW_FS_Y 20 +#define INFOPRINT_WINDOW_X 15 + + +#define DEFAULT_PROGRESS_ANIMATION "qgn_indi_pball_a" + +static gboolean gtk_infoprint_temporal_wrap_disable_flag = FALSE; + +typedef struct { + GtkWindow *parent; + GtkWidget *window; + gchar *text; + GtkWidget *main_item; + guint timeout; +} InfoprintState; + +enum { + WIN_TYPE = 0, + WIN_TYPE_MESSAGE, + MAX_WIN_MESSAGES +}; + +static GtkWidget *global_banner = NULL; +static GtkWidget *global_infoprint = NULL; + +static GQueue *cbanner_queue = NULL; +static InfoprintState *current_ibanner = NULL; +static InfoprintState *current_pbanner = NULL; +static guint pbanner_refs = 0; + +static gboolean compare_icons(GtkImage *image1, GtkImage *image2); +static void queue_new_cbanner(GtkWindow *parent, + const gchar *text, + GtkWidget *image); +static void gtk_msg_window_init(GtkWindow * parent, GQuark type, + const gchar * text, GtkWidget * main_item); +static gchar *three_lines_truncate(GtkWindow * parent, + const gchar * str, + gint * max_width, gint * resulting_lines); + +static gboolean infoprint_idle_before_timer (GtkWidget *widget, + GdkEventExpose *event, + gpointer data); +static gboolean infoprint_start_timer (gpointer data); + +/* Getters/initializers for needed quarks */ +static GQuark banner_quark(void) +{ + static GQuark quark = 0; + + if (quark == 0) + quark = g_quark_from_static_string("banner"); + + return quark; +} + +static GQuark infoprint_quark(void) +{ + static GQuark quark = 0; + + if (quark == 0) + quark = g_quark_from_static_string("infoprint"); + + return quark; +} + +static GQuark type_quark(void) +{ + static GQuark quark = 0; + + if (quark == 0) + quark = g_quark_from_static_string("Message window type"); + + return quark; +} + +static GQuark label_quark(void) +{ + static GQuark quark = 0; + + if (quark == 0) + quark = g_quark_from_static_string("Message window text"); + + return quark; +} + +static GQuark item_quark(void) +{ + static GQuark quark = 0; + + if (quark == 0) + quark = + g_quark_from_static_string("Message window graphical item"); + + return quark; +} + +static GQuark confirmation_banner_quark(void) +{ + static GQuark quark = 0; + + if (quark == 0) + quark = g_quark_from_static_string("confirmation_banner"); + + return quark; +} + +/* Returns the infoprint/banner linked to the specific window */ +static GtkWindow *gtk_msg_window_get(GtkWindow * parent, GQuark quark) +{ + if (quark == 0) + return NULL; + if (parent == NULL) { + if (quark == banner_quark()) { + return GTK_WINDOW(global_banner); + } + return GTK_WINDOW(global_infoprint); + } + + return GTK_WINDOW(g_object_get_qdata(G_OBJECT(parent), quark)); +} + +/* Returns the given widget from banner type of message window. + This is used when the banner data is updated in later stage. +*/ +static GtkWidget *gtk_banner_get_widget(GtkWindow * parent, + GQuark widget_quark) +{ + GtkWindow *window = gtk_msg_window_get(parent, banner_quark()); + + if (window) + return + GTK_WIDGET(g_object_get_qdata(G_OBJECT(window), widget_quark)); + + return NULL; +} + +/* Timed destroy. Removing this callback is done in other place. */ +static gboolean gtk_msg_window_destroy(gpointer pointer) +{ + g_return_val_if_fail(GTK_IS_WINDOW(pointer), TRUE); + gtk_widget_destroy(GTK_WIDGET(pointer)); + + return FALSE; +} + +static gboolean gtk_msg_window_real_destroy(gpointer pointer) +{ + GObject *parent; + GQuark quark; + + g_return_val_if_fail(GTK_IS_WINDOW(pointer), TRUE); + + parent = G_OBJECT(gtk_window_get_transient_for(GTK_WINDOW(pointer))); + quark = (GQuark) g_object_get_qdata((GObject *) pointer, type_quark()); + + if (quark == infoprint_quark() && current_ibanner) { + gtk_widget_unref(current_ibanner->main_item); + g_free(current_ibanner->text); + g_free(current_ibanner); + current_ibanner = NULL; + } else if (quark == banner_quark() && current_pbanner) { + /* + * If the destroy signal is not emited via gkt_banner_close() + * (for example when the banner is being destroyed with the parent) + * the reference counter will have a value larger than 0 and the + * reference counter should be decremented. + */ + + if (pbanner_refs > 0) + --pbanner_refs; + + gtk_widget_unref(current_pbanner->main_item); + g_free(current_pbanner->text); + g_free(current_pbanner); + current_pbanner = NULL; + } else if (quark == confirmation_banner_quark() && + !g_queue_is_empty(cbanner_queue)) { + InfoprintState *cbanner = g_queue_pop_head(cbanner_queue); + + gtk_widget_unref(cbanner->main_item); + g_free(cbanner->text); + g_free(cbanner); + + if (!g_queue_is_empty(cbanner_queue)) { + cbanner = g_queue_peek_head(cbanner_queue); + gtk_msg_window_init(cbanner->parent, confirmation_banner_quark(), + cbanner->text, cbanner->main_item); + } else { + g_queue_free(cbanner_queue); + cbanner_queue = NULL; + } + } + + if (parent) { + g_object_set_qdata(parent, quark, NULL); + } else { + if (quark == banner_quark()) { + global_banner = NULL; + } else { + global_infoprint = NULL; + } + } + + return FALSE; +} + + +/* Get window ID of top window from _NET_ACTIVE_WINDOW property */ +static Window get_active_window( void ) +{ + unsigned long n; + unsigned long extra; + int format; + int status; + + Atom atom_net_active = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"); + Atom realType; + Window win_result = None; + guchar *data_return = NULL; + + status = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), + atom_net_active, 0L, 16L, + 0, XA_WINDOW, &realType, &format, + &n, &extra, + &data_return); + + if ( status == Success && realType == XA_WINDOW + && format == 32 && n == 1 && data_return != NULL ) + { + win_result = ((Window*) data_return)[0]; + /* g_print("_NET_ACTIVE_WINDOW id %d\n", ((gint *)data_return)[0] );*/ + } + + if ( data_return ) + XFree(data_return); + + return win_result; +} + +/* Checks if a window is in fullscreen state or not */ +static gboolean check_fullscreen_state( Window window ) +{ + unsigned long n; + unsigned long extra; + int format, status, i; + guchar *data_return = NULL; + + Atom realType; + Atom atom_window_state = gdk_x11_get_xatom_by_name ("_NET_WM_STATE"); + Atom atom_fullscreen = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_FULLSCREEN"); + + if ( window == None ) + return FALSE; + + /* in some cases XGetWindowProperty seems to generate BadWindow, + so at the moment this function does not always work perfectly */ + gdk_error_trap_push(); + status = XGetWindowProperty(GDK_DISPLAY(), window, + atom_window_state, 0L, 1000000L, + 0, XA_ATOM, &realType, &format, + &n, &extra, &data_return); + gdk_flush(); + if (gdk_error_trap_pop()) + return FALSE; + + if (status == Success && realType == XA_ATOM && format == 32 && n > 0) + { + for(i=0; i < n; i++) + if ( ((Atom*)data_return)[i] && + ((Atom*)data_return)[i] == atom_fullscreen) + { + if (data_return) XFree(data_return); + return True; + } + } + + if (data_return) + XFree(data_return); + + return False; +} + + +static gboolean +compare_icons(GtkImage *image1, GtkImage *image2) +{ + GtkImageType type = gtk_image_get_storage_type(image1); + gchar *name1, *name2; + const gchar *icon_name1, *icon_name2; + GtkIconSize size1, size2; + + if (gtk_image_get_storage_type(image2) != type) + return FALSE; + + switch (type) { + case GTK_IMAGE_STOCK: + gtk_image_get_stock(image1, &name1, &size1); + gtk_image_get_stock(image2, &name2, &size2); + return ((g_utf8_collate(name1, name2) == 0) && (size1 == size2)); + case GTK_IMAGE_ICON_NAME: + gtk_image_get_icon_name(image1, &icon_name1, &size1); + gtk_image_get_icon_name(image2, &icon_name2, &size2); + return ((g_utf8_collate(icon_name1, icon_name2) == 0) && (size1 == size2)); + case GTK_IMAGE_ANIMATION: + /* there is only one possible animation */ + return TRUE; + default: + /* other types of icons are actually not even supported */ + return FALSE; + } +} + +/* confirmation banners are queued so that all of them will + be shown eventually for the appropriate amount of time */ +static void +queue_new_cbanner(GtkWindow *parent, const gchar *text, GtkWidget *image) +{ + InfoprintState *cbanner; + + if (cbanner_queue == NULL) + cbanner_queue = g_queue_new(); + + /* identical consecutive cbanners are collapsed to just one cbanner */ + if ((cbanner = g_queue_peek_tail(cbanner_queue)) != NULL && + g_utf8_collate(cbanner->text, text) == 0 && + compare_icons(GTK_IMAGE(image), GTK_IMAGE(cbanner->main_item))) { + g_source_remove(cbanner->timeout); + + cbanner->timeout = g_timeout_add(MESSAGE_TIMEOUT, + gtk_msg_window_destroy, + cbanner->window); + g_signal_connect_swapped(cbanner->window, "destroy", + G_CALLBACK(g_source_remove), + GUINT_TO_POINTER(cbanner->timeout)); + gtk_object_sink(GTK_OBJECT(image)); + return; + } + + cbanner = g_new0(InfoprintState, 1); + cbanner->parent = parent; + cbanner->text = g_strdup(text); + cbanner->main_item = image; + gtk_widget_ref(cbanner->main_item); + + g_queue_push_tail(cbanner_queue, cbanner); + + if (g_queue_get_length(cbanner_queue) == 1) + gtk_msg_window_init(parent, confirmation_banner_quark(), text, image); +} + + +/* gtk_msg_window_init + * + * @parent -- The parent window + * @type -- The enumerated type of message window + * @text -- The displayed text + * @item -- The item to be loaded, or NULL if default + * (used only in INFOPRINT_WITH_ICON) + */ +static void +gtk_msg_window_init(GtkWindow * parent, GQuark type, + const gchar * text, GtkWidget * main_item) +{ + GtkWidget *window; + GtkWidget *hbox; + GtkWidget *label; + + gchar *str = NULL; + gint max_width = 0; + + g_return_if_fail((GTK_IS_WINDOW(parent) || parent == NULL)); + + if (type == banner_quark()) + pbanner_refs++; + + /* information banners: just reset the timeout if trying + to recreate the currently visible information banner */ + if (type == infoprint_quark() && current_ibanner) { + + /* caller is trying to recreate current information banner */ + if (g_utf8_collate(current_ibanner->text, text) == 0 && + compare_icons(GTK_IMAGE(main_item), + GTK_IMAGE(current_ibanner->main_item))) { + /* If previous timer has been created, replace it with a new one */ + if (current_ibanner->timeout > 0) { + g_source_remove(current_ibanner->timeout); + current_ibanner->timeout = g_timeout_add(MESSAGE_TIMEOUT, + gtk_msg_window_destroy, + current_ibanner->window); + + g_signal_connect_swapped(current_ibanner->window, "destroy", + G_CALLBACK(g_source_remove), + GUINT_TO_POINTER(current_ibanner->timeout)); + } + gtk_object_sink(GTK_OBJECT(main_item)); + return; + } + + /* If the timer has already been set -> remove it */ + if (current_ibanner->timeout > 0) + g_source_remove(current_ibanner->timeout); + + gtk_msg_window_destroy(current_ibanner->window); + } + + if (type == banner_quark() && current_pbanner) { + if (g_utf8_collate(current_pbanner->text, text) == 0) { + if (GTK_IS_PROGRESS_BAR(main_item) && + GTK_IS_PROGRESS_BAR(current_pbanner->main_item)) { + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(current_pbanner->main_item), 0.0); + gtk_object_sink(GTK_OBJECT(main_item)); + return; + } else if (GTK_IS_IMAGE(main_item) && + GTK_IS_IMAGE(current_pbanner->main_item) && + compare_icons(GTK_IMAGE(main_item), + GTK_IMAGE(current_pbanner->main_item))) { + gtk_object_sink(GTK_OBJECT(main_item)); + return; + } + } + } + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_accept_focus(GTK_WINDOW(window), FALSE); + g_signal_connect(window, "destroy", G_CALLBACK(gtk_msg_window_real_destroy), window); + + hbox = gtk_hbox_new(FALSE, 5); + + if (current_pbanner && type == banner_quark()) { + /* + * The destroy substracts one from the reference counter, + * so adding one to keep the counter working + */ + ++pbanner_refs; + gtk_msg_window_destroy(current_pbanner->window); + } + + if (parent) { + gtk_window_set_transient_for(GTK_WINDOW(window), parent); + gtk_window_set_destroy_with_parent(GTK_WINDOW(window), TRUE); + + g_object_set_qdata(G_OBJECT(parent), type, (gpointer) window); + } else { + if (type == banner_quark()) { + global_banner = window; + } else { + global_infoprint = window; + } + } + + gtk_widget_realize(window); + + if ((type == confirmation_banner_quark()) || (type == banner_quark())) + gtk_infoprint_temporal_wrap_disable_flag = TRUE; + + if (type == banner_quark()) { + max_width = BANNER_MAX_WIDTH; + } else { + max_width = INFOPRINT_MAX_WIDTH; + } + + if (parent == NULL) { + gdk_window_set_transient_for(GDK_WINDOW(window->window), + GDK_WINDOW(gdk_get_default_root_window())); + str = three_lines_truncate(GTK_WINDOW(window), text, &max_width, NULL); + } else { + str = three_lines_truncate(parent, text, &max_width, NULL); + } + + gtk_infoprint_temporal_wrap_disable_flag = FALSE; + + label = gtk_label_new(str); + g_free(str); + + if (max_width < INFOPRINT_MIN_WIDTH) { + gtk_widget_set_size_request(GTK_WIDGET(label), + (max_width < INFOPRINT_MIN_WIDTH) ? + INFOPRINT_MIN_WIDTH : -1, + -1); + } + + if ((type == confirmation_banner_quark()) || (type == banner_quark())) + gtk_widget_set_name(label, "hildon-banner-label"); + + g_object_set_qdata(G_OBJECT(window), type_quark(), (gpointer) type); + g_object_set_qdata(G_OBJECT(window), label_quark(), (gpointer) label); + g_object_set_qdata(G_OBJECT(window), item_quark(), + (gpointer) main_item); + + gtk_container_add(GTK_CONTAINER(window), hbox); + + if (type == banner_quark()) { + gtk_box_pack_start_defaults(GTK_BOX(hbox), label); + if (main_item) { + if (GTK_IS_PROGRESS_BAR(main_item)) { + gtk_widget_set_size_request(GTK_WIDGET(main_item), + BANNER_PROGRESSBAR_MIN_WIDTH, + -1); + } + gtk_box_pack_start_defaults(GTK_BOX(hbox), main_item); + } + } else { + if (main_item) { + GtkAlignment *ali = + GTK_ALIGNMENT(gtk_alignment_new(0, 0, 0, 0)); + gtk_widget_set_size_request(GTK_WIDGET(main_item), + INFOPRINT_MIN_SIZE, + INFOPRINT_MIN_SIZE); + gtk_container_add(GTK_CONTAINER(ali), GTK_WIDGET(main_item)); + gtk_box_pack_start_defaults(GTK_BOX(hbox), GTK_WIDGET(ali)); + } + gtk_box_pack_start_defaults(GTK_BOX(hbox), label); + } + + gtk_window_set_default_size(GTK_WINDOW(window), + DEFAULT_WIDTH, DEFAULT_HEIGHT); + + /* Positioning of the infoprint */ + { + gint y = INFOPRINT_WINDOW_Y; + gint x = gdk_screen_width() + INFOPRINT_WINDOW_X; + + /* Check if the active application is in fullscreen */ + if( check_fullscreen_state(get_active_window()) ) + y = INFOPRINT_WINDOW_FS_Y; + /* this should be fixed to use theme dependant infoprint border size */ + + gtk_window_move(GTK_WINDOW(window), x, y); + } + + gdk_window_set_type_hint(window->window, GDK_WINDOW_TYPE_HINT_MESSAGE); + + gtk_widget_show_all(window); + + if (type == infoprint_quark()) { + current_ibanner = g_new0(InfoprintState, 1); + current_ibanner->parent = parent; + current_ibanner->window = window; + current_ibanner->text = g_strdup(text); + current_ibanner->main_item = main_item; + gtk_widget_ref(current_ibanner->main_item); + } + else if (type == banner_quark()) { + current_pbanner = g_new0(InfoprintState, 1); + current_pbanner->parent = parent; + current_pbanner->window = window; + current_pbanner->text = g_strdup(text); + current_pbanner->main_item = main_item; + gtk_widget_ref(current_pbanner->main_item); + } + + /* If the type is an infoprint we set the timer after the expose-event */ + if (type == infoprint_quark()) { + g_signal_connect_after(window, "expose-event", + G_CALLBACK(infoprint_idle_before_timer), NULL); + } + else if (type == confirmation_banner_quark()) { + InfoprintState *current_cbanner = g_queue_peek_head(cbanner_queue); + + current_cbanner->window = window; + current_cbanner->timeout = g_timeout_add(MESSAGE_TIMEOUT, + gtk_msg_window_destroy, + current_cbanner->window); + g_signal_connect_swapped(window, "destroy", + G_CALLBACK(g_source_remove), + GUINT_TO_POINTER(current_cbanner->timeout)); + } +} + +static gchar *three_lines_truncate(GtkWindow * parent, const gchar * str, + gint * max_width, gint * resulting_lines) +{ + gchar *result = NULL; + PangoLayout *layout; + PangoContext *context; + + if (!str) + return g_strdup(""); + + if (GTK_IS_WIDGET(parent)) { + context = gtk_widget_get_pango_context(GTK_WIDGET(parent)); + } else { + if (gdk_screen_get_default() != NULL) { + context = gdk_pango_context_get_for_screen + (gdk_screen_get_default()); + } else { + g_print("GtkInfoprint : Could not get default screen.\n"); + return NULL; + } + } + + { + gchar *line1 = NULL; + gchar *line2 = NULL; + gchar *line3 = NULL; + + layout = pango_layout_new(context); + pango_layout_set_text(layout, str, -1); + if (gtk_infoprint_temporal_wrap_disable_flag == FALSE) { + pango_layout_set_width(layout, *max_width * PANGO_SCALE); + } else { + pango_layout_set_width(layout, -1); + } + pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); + + if (pango_layout_get_line_count(layout) >= 2) { + PangoLayoutLine *line = pango_layout_get_line(layout, 0); + + if (line != NULL) + line1 = g_strndup(str, line->length); + + line = pango_layout_get_line(layout, 1); + + if (line != NULL) + line2 = g_strndup((gchar *) ((gint) str + line->start_index), + line->length); + + line = pango_layout_get_line(layout, 2); + + if (line != NULL) + line3 = g_strdup((gchar *) ((gint) str + line->start_index)); + + g_object_unref(layout); + layout = pango_layout_new(context); + pango_layout_set_text(layout, line3 ? line3 : "", -1); + + { + gint index = 0; + + if (pango_layout_get_line_count(layout) > 1) { + gchar *templine = NULL; + + line = pango_layout_get_line(layout, 0); + templine = g_strndup(line3, line->length); + g_free(line3); + line3 = g_strconcat(templine, "\342\200\246", NULL); + g_free(templine); + } + + if (pango_layout_xy_to_index(layout, + *max_width * PANGO_SCALE, + 0, &index, NULL) + == TRUE) { + gint ellipsiswidth; + gchar *tempresult; + PangoLayout *ellipsis = pango_layout_new(context); + + pango_layout_set_text(ellipsis, "\342\200\246", -1); + pango_layout_get_size(ellipsis, &ellipsiswidth, NULL); + pango_layout_xy_to_index(layout, + *max_width * PANGO_SCALE - + ellipsiswidth, + 0, &index, NULL); + g_object_unref(G_OBJECT(ellipsis)); + tempresult = g_strndup(line3, index); + g_free(line3); + line3 = g_strconcat(tempresult, "\342\200\246", NULL); + g_free(tempresult); + } + } + + } else + line1 = g_strdup(str); + + { + PangoLayout *templayout = pango_layout_new(context); + + pango_layout_set_text(templayout, line1, -1); + if (pango_layout_get_line_count(templayout) < 3 + && line3 != NULL) { + result = g_strconcat(line1, "\n", line2, "\n", line3, NULL); + } else if (pango_layout_get_line_count(templayout) < 2 + && line2 != NULL) { + result = g_strconcat(line1, "\n", line2, line3, NULL); + } else { + result = g_strconcat(line1, line2, line3, NULL); + } + g_object_unref(templayout); + } + + g_free(line1); + g_free(line2); + g_free(line3); + + g_object_unref(layout); + + if (gtk_infoprint_temporal_wrap_disable_flag == TRUE) { + gint index = 0; + PangoLayout *templayout = pango_layout_new(context); + + pango_layout_set_text(templayout, result, -1); + + if (pango_layout_get_line_count(templayout) >= 2) { + PangoLayoutLine *line = + pango_layout_get_line(templayout, 0); + gchar *templine = g_strndup(result, line->length); + + g_free(result); + result = g_strconcat(templine, "\342\200\246", NULL); + g_free(templine); + pango_layout_set_text(templayout, result, -1); + } + + if (pango_layout_xy_to_index + (templayout, *max_width * PANGO_SCALE, 0, &index, + NULL) == TRUE) { + gint ellipsiswidth; + gchar *tempresult; + PangoLayout *ellipsis = pango_layout_new(context); + + pango_layout_set_text(ellipsis, "\342\200\246", -1); + pango_layout_get_size(ellipsis, &ellipsiswidth, NULL); + pango_layout_xy_to_index(templayout, + *max_width * PANGO_SCALE - + ellipsiswidth, 0, &index, NULL); + g_object_unref(G_OBJECT(ellipsis)); + tempresult = g_strndup(result, index); + g_free(result); + result = g_strconcat(tempresult, "\342\200\246", NULL); + g_free(tempresult); + } + g_object_unref(templayout); + } + } + + { + PangoLayout *templayout = pango_layout_new(context); + + pango_layout_set_text(templayout, result, -1); + pango_layout_get_size(templayout, max_width, NULL); + if (resulting_lines != NULL) + *resulting_lines = pango_layout_get_line_count(templayout); + g_object_unref(templayout); + } + + if (result == NULL) + result = g_strdup(str); + + return result; +} + +/**************************************************/ +/** Public **/ +/**************************************************/ + +/** + * gtk_infoprint: + * @parent: The transient window for the infoprint. + * @text: The text in infoprint + * + * Opens a new infoprint with @text content. + * + * If parent is %NULL, the infoprint is a system infoprint. + * Normally you should use your application window + * or dialog as a transient parent and avoid passing %NULL. + */ +void gtk_infoprint(GtkWindow * parent, const gchar * text) +{ + gtk_infoprint_with_icon_name(parent, text, NULL); +} + +/** + * gtk_infoprint_with_icon_stock: + * @parent: The transient window for the infoprint. + * @text: The text in infoprint + * @stock_id: The stock id of the custom icon + * + * Opens a new infoprint with @text content. + * With this function you can also set a custom icon + * by giving a stock id as last parameter. + * + * If parent is %NULL, the infoprint is a system infoprint. + * Normally you should use your application window + * or dialog as a transient parent and avoid passing %NULL. + */ +void +gtk_infoprint_with_icon_stock(GtkWindow * parent, + const gchar * text, const gchar * stock_id) +{ + GtkWidget *image; + + if (stock_id) { + image = gtk_image_new_from_stock(stock_id, HILDON_ICON_SIZE_NOTE); + } else { + image = gtk_image_new_from_stock(GTK_INFOPRINT_STOCK, + HILDON_ICON_SIZE_NOTE); + } + + gtk_msg_window_init(parent, infoprint_quark(), text, image); +} + +/** + * gtk_infoprint_with_icon_name: + * @parent: The transient window for the infoprint. + * @text: The text in infoprint + * @icon_name: The name of the icon + * + * Opens a new infoprint with @text content. + * With this function you can also set a custom icon + * by giving a icon name as last parameter. + * + * If parent is %NULL, the infoprint is a system infoprint. + * Normally you should use your application window + * or dialog as a transient parent and avoid passing %NULL. + */ +void +gtk_infoprint_with_icon_name(GtkWindow * parent, + const gchar * text, const gchar * icon_name) +{ + GtkWidget *image; + + if (icon_name) { + image = gtk_image_new_from_icon_name(icon_name, HILDON_ICON_SIZE_NOTE); + } else { + image = gtk_image_new_from_icon_name(GTK_INFOPRINT_ICON_THEME, + HILDON_ICON_SIZE_NOTE); + } + + gtk_msg_window_init(parent, infoprint_quark(), text, image); +} + +/** + * gtk_infoprintf: + * @parent: The transient window for the infoprint. + * @format: Format of the text. + * @Varargs: List of parameters. + * + * Opens a new infoprint with @text printf-style formatting + * string and comma-separated list of parameters. + * + * If parent is %NULL, the infoprint is a system infoprint. + * This version of infoprint allow you to make printf-like formatting + * easily. + */ +void gtk_infoprintf(GtkWindow * parent, const gchar * format, ...) +{ + gchar *message; + va_list args; + + va_start(args, format); + message = g_strdup_vprintf(format, args); + va_end(args); + + gtk_infoprint(parent, message); + + g_free(message); +} + +/** + * gtk_infoprint_temporarily_disable_wrap: + * + * Will disable wrapping for the next shown infoprint. This only + * affects next infoprint shown in this application. + */ +void gtk_infoprint_temporarily_disable_wrap(void) +{ + gtk_infoprint_temporal_wrap_disable_flag = TRUE; +} + +/** + * gtk_confirmation_banner: + * @parent: The transient window for the confirmation banner. + * @text: The text in confirmation banner + * @stock_id: The stock id of the custom icon + * + * Opens a new confirmation banner with @text content. + * With this function you can also set a custom icon + * by giving a stock id as last parameter. + * + * If parent is %NULL, the banner is a system banner. + * Normally you should use your application window + * or dialog as a transient parent and avoid passing %NULL. + * + * This function is otherwise similar to + * gtk_infoprint_with_icon_stock except in always restricts + * the text to one line and the font is emphasized. + */ +void +gtk_confirmation_banner(GtkWindow * parent, const gchar * text, + const gchar * stock_id) +{ + GtkWidget *image; + + if (stock_id) { + image = gtk_image_new_from_stock(stock_id, HILDON_ICON_SIZE_NOTE); + } else { + image = gtk_image_new_from_stock(GTK_INFOPRINT_STOCK, + HILDON_ICON_SIZE_NOTE); + } + + queue_new_cbanner(parent, text, image); +} + +/** + * gtk_confirmation_banner_with_icon_name: + * @parent: The transient window for the confirmation banner. + * @text: The text in confirmation banner + * @icon_name: The name of the custom icon in icon theme + * + * Opens a new confirmation banner with @text content. + * With this function you can also set a custom icon + * by giving a icon theme's icon name as last parameter. + * + * If parent is %NULL, the banner is a system banner. + * Normally you should use your application window + * or dialog as a transient parent and avoid passing %NULL. + * + * This function is otherwise similar to + * gtk_infoprint_with_icon_name except in always restricts + * the text to one line and the font is emphasized. + */ +void +gtk_confirmation_banner_with_icon_name(GtkWindow * parent, const gchar * text, + const gchar * icon_name) +{ + GtkWidget *image; + + if (icon_name) { + image = gtk_image_new_from_icon_name(icon_name, HILDON_ICON_SIZE_NOTE); + } else { + image = gtk_image_new_from_stock(GTK_INFOPRINT_STOCK, + HILDON_ICON_SIZE_NOTE); + } + + queue_new_cbanner(parent, text, image); +} + +/** + * gtk_banner_show_animation: + * @parent: #GtkWindow + * @text: #const gchar * + * + * The @text is the text shown in banner. + * Creates a new banner with the animation. + */ +void gtk_banner_show_animation(GtkWindow * parent, const gchar * text) +{ + GtkWidget *item; + GtkIconTheme *theme; + GtkIconInfo *info; + + theme = gtk_icon_theme_get_default(); + + info = gtk_icon_theme_lookup_icon(theme, DEFAULT_PROGRESS_ANIMATION, + HILDON_ICON_SIZE_NOTE, 0); + + if (info) { + const gchar *filename = gtk_icon_info_get_filename(info); + item = gtk_image_new_from_file(filename); + } else { + g_print("icon theme lookup for icon failed!\n"); + item = gtk_image_new(); + } + if (info) + gtk_icon_info_free(info); + + gtk_msg_window_init(parent, banner_quark(), text, item); +} + +/** + * gtk_banner_show_bar + * @parent: #GtkWindow + * @text: #const gchar * + * + * The @text is the text shown in banner. + * Creates a new banner with the progressbar. + */ +void gtk_banner_show_bar(GtkWindow * parent, const gchar * text) +{ + gtk_msg_window_init(parent, banner_quark(), + text, gtk_progress_bar_new()); +} + +/** + * gtk_banner_set_text + * @parent: #GtkWindow + * @text: #const gchar * + * + * The @text is the text shown in banner. + * Sets the banner text. + */ +void gtk_banner_set_text(GtkWindow * parent, const gchar * text) +{ + GtkWidget *item; + + g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL); + + item = gtk_banner_get_widget(parent, label_quark()); + + if (GTK_IS_LABEL(item)) + gtk_label_set_text(GTK_LABEL(item), text); +} + +/** + * gtk_banner_set_fraction: + * @parent: #GtkWindow + * @fraction: #gdouble + * + * The fraction is the completion of progressbar, + * the scale is from 0.0 to 1.0. + * Sets the amount of fraction the progressbar has. + */ +void gtk_banner_set_fraction(GtkWindow * parent, gdouble fraction) +{ + GtkWidget *item; + + g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL); + + item = gtk_banner_get_widget(parent, item_quark()); + + if (GTK_IS_PROGRESS_BAR(item)) + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(item), fraction); +} + +/** + * gtk_banner_close: + * @parent: #GtkWindow + * + * Destroys the banner + */ +void gtk_banner_close(GtkWindow * parent) +{ + g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL); + + if (pbanner_refs > 0) { + --pbanner_refs; + if (pbanner_refs == 0 && current_pbanner) { + gtk_msg_window_destroy(current_pbanner->window); + } + } +} + +/** + * gtk_banner_temporarily_disable_wrap + * + * Will disable wrapping for the next shown banner. This only + * affects next banner shown in this application. + **/ +void gtk_banner_temporarily_disable_wrap(void) +{ + /* The below variable name is intentional. There's no real need for + having two different variables for this functionality. */ + gtk_infoprint_temporal_wrap_disable_flag = TRUE; +} + +/* We want the timer to be launched only after the infoprint is fully drawn. + * As an approximation, we wait for an idle moment before starting + * the timer. This method is not exact, since it does not guarantee that + * the x-server has gotten around to drawing the window. The only way to be + * sure would require syncing with the x-server, but this should be close + * enough. + */ +static gboolean infoprint_idle_before_timer (GtkWidget *widget, + GdkEventExpose *event, + gpointer data) +{ + g_idle_add(infoprint_start_timer, widget); + return FALSE; +} + +/* Start the actual timer for the infoprint */ +static gboolean infoprint_start_timer (gpointer data) +{ + if (GTK_IS_WIDGET (data)) { + current_ibanner->timeout = g_timeout_add(MESSAGE_TIMEOUT, + gtk_msg_window_destroy, + current_ibanner->window); + g_signal_connect_swapped(GTK_WIDGET(data), "destroy", + G_CALLBACK(g_source_remove), + GUINT_TO_POINTER(current_ibanner->timeout)); + } + return FALSE; +} diff --git a/hildon-widgets/gtk-infoprint.h b/hildon-widgets/gtk-infoprint.h new file mode 100644 index 0000000..c76e575 --- /dev/null +++ b/hildon-widgets/gtk-infoprint.h @@ -0,0 +1,52 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __GTK_INFOPRINT_H__ +#define __GTK_INFOPRINT_H__ + +#include + +G_BEGIN_DECLS void gtk_infoprint(GtkWindow * parent, const gchar * text); +void gtk_infoprint_with_icon_stock(GtkWindow * parent, const gchar * text, + const gchar * stock_id); +void gtk_infoprint_with_icon_name(GtkWindow * parent, const gchar * text, + const gchar * icon_name); + +void gtk_infoprintf(GtkWindow * parent, const gchar * format, ...); +void gtk_infoprint_temporarily_disable_wrap(void); + +void gtk_confirmation_banner_with_icon_name(GtkWindow * parent, const gchar * text, + const gchar * icon_name); +void gtk_confirmation_banner(GtkWindow * parent, const gchar * text, + const gchar * stock_id); + +void gtk_banner_show_animation(GtkWindow * parent, const gchar * text); +void gtk_banner_show_bar(GtkWindow * parent, const gchar * text); +void gtk_banner_set_text(GtkWindow * parent, const gchar * text); +void gtk_banner_set_fraction(GtkWindow * parent, gdouble fraction); +void gtk_banner_close(GtkWindow * parent); +void gtk_banner_temporarily_disable_wrap(void); + +G_END_DECLS +#endif /* __GTK_INFOPRINT_H__ */ diff --git a/hildon-widgets/hildon-app-private.h b/hildon-widgets/hildon-app-private.h new file mode 100644 index 0000000..e721a80 --- /dev/null +++ b/hildon-widgets/hildon-app-private.h @@ -0,0 +1,74 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + + +#ifndef HILDON_APP_PRIVATE_H +#define HILDON_APP_PRIVATE_H + +enum { + TOPMOST_STATUS_ACQUIRE, + TOPMOST_STATUS_LOSE, + SWITCH_TO, + IM_CLOSE, + CLIPBOARD_COPY, + CLIPBOARD_CUT, + CLIPBOARD_PASTE, + + HILDON_APP_LAST_SIGNAL +}; + +struct _HildonAppPrivate { + GList *children; + gchar *title; +#ifndef HILDON_DISABLE_DEPRECATED + HildonZoomLevel zoom; +#endif + + /* Used to keep track of menu key press/release */ + gint lastmenuclick; + + gulong curr_view_id; + gulong view_id_counter; + GSList *view_ids; + gboolean scroll_control; + + guint twoparttitle: 1; + guint is_topmost: 1; + gboolean killable; + gboolean autoregistration; + + guint escape_timeout; + guint key_snooper; + + GtkUIManager *uim; + + guint active_menu_id; +}; + +typedef struct { + gpointer view_ptr; + unsigned long view_id; +} view_item; + +#endif /* HILDON_APP_PRIVATE_H */ diff --git a/hildon-widgets/hildon-app.c b/hildon-widgets/hildon-app.c new file mode 100644 index 0000000..14e816a --- /dev/null +++ b/hildon-widgets/hildon-app.c @@ -0,0 +1,2229 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +/* + * @file hildon-app.c + * + * This file implements the HildonApp widget + * + */ + +#include +#include "hildon-app.h" +#include "hildon-app-private.h" +#include "hildon-appview.h" +#include "gtk-infoprint.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define TITLE_DELIMITER " - " + +/* + * 'Magic' values for the titlebar menu area limits + */ +#define MENUAREA_LEFT_LIMIT 80 +#define MENUAREA_RIGHT_LIMIT MENUAREA_LEFT_LIMIT + 307 +#define MENUAREA_TOP_LIMIT 0 +#define MENUAREA_BOTTOM_LIMIT 39 + +#define KILLABLE "CANKILL" + +#define _(String) dgettext(PACKAGE, String) + +#define HILDON_APP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + HILDON_TYPE_APP, HildonAppPrivate)); + +static GtkWindowClass *parent_class; +static guint app_signals[HILDON_APP_LAST_SIGNAL] = { 0 }; + +typedef struct _HildonAppPrivate HildonAppPrivate; + +static void +hildon_app_switch_to_desktop (void); +static gboolean +hildon_app_key_press (GtkWidget *widget, GdkEventKey *keyevent); +static gboolean +hildon_app_key_release (GtkWidget *widget, GdkEventKey *keyevent); +static gboolean +hildon_app_key_snooper (GtkWidget *widget, GdkEventKey *keyevent, HildonApp *app); +static GdkFilterReturn +hildon_app_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data); +static void +hildon_app_construct_title (HildonApp *self); +static void +hildon_app_finalize (GObject *obj_self); +static void +hildon_app_destroy (GtkObject *obj); +static void +hildon_app_init (HildonApp *self); +static void +hildon_app_class_init (HildonAppClass *app_class); +static void +hildon_app_real_topmost_status_acquire (HildonApp *self); +static void +hildon_app_real_topmost_status_lose (HildonApp *self); +static void +hildon_app_real_switch_to (HildonApp *self); +static gboolean +hildon_app_button (GtkWidget *widget, GdkEventButton *event); +static GdkWindow * +find_window (GdkWindow *window, gint by, gint co); +static void +hildon_app_clipboard_copy(HildonApp *self, GtkWidget *widget); +static void +hildon_app_clipboard_cut(HildonApp *self, GtkWidget *widget); +static void +hildon_app_clipboard_paste(HildonApp *self, GtkWidget *widget); +static gboolean hildon_app_escape_timeout(gpointer data); + +static void hildon_app_set_property(GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec); +static void hildon_app_get_property(GObject * object, guint property_id, + GValue * value, GParamSpec * pspec); + +static void hildon_app_add (GtkContainer *container, GtkWidget *child); +static void hildon_app_remove (GtkContainer *container, GtkWidget *child); +static void hildon_app_forall (GtkContainer *container, gboolean include_internals, + GtkCallback callback, gpointer callback_data); + +enum { + PROP_0, + PROP_SCROLL_CONTROL, +#ifndef HILDON_DISABLE_DEPRECATED + PROP_ZOOM, +#endif + PROP_TWO_PART_TITLE, + PROP_APP_TITLE, + PROP_KILLABLE, + PROP_AUTOREGISTRATION, + PROP_APPVIEW, + PROP_UI_MANAGER +}; + +static gpointer find_view(HildonApp *self, unsigned long view_id); + +/** + * hildon_zoom_level_get_type: + * @Returns : GType of #HildonZoomLevel + * + * Initialises, and returns the type of a hildon zoom level + */ +#ifndef HILDON_DISABLE_DEPRECATED +G_CONST_RETURN GType +hildon_zoom_level_get_type (void) +{ + static GType etype = 0; + if (etype == 0) { + static const GEnumValue values[] = { + { HILDON_ZOOM_SMALL, "HILDON_ZOOM_SMALL", "small" }, + { HILDON_ZOOM_MEDIUM, "HILDON_ZOOM_MEDIUM", "medium" }, + { HILDON_ZOOM_LARGE, "HILDON_ZOOM_LARGE", "large" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static ("HildonZoomLevel", values); + } + return etype; +} +#endif + +GType hildon_app_get_type(void) +{ + static GType app_type = 0; + + if (!app_type) + { + static const GTypeInfo app_info = + { + sizeof(HildonAppClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) hildon_app_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(HildonApp), + 0, /* n_preallocs */ + (GInstanceInitFunc) hildon_app_init, + }; + app_type = g_type_register_static(GTK_TYPE_WINDOW, + "HildonApp", &app_info, 0); + } + return app_type; +} + +/* + * Sets or delete a custom property into the XServer, according + * to the boolean value of HildonAppPrivate::killable + */ +static void hildon_app_apply_killable(HildonApp *self) +{ + HildonAppPrivate *priv; + Atom killability_atom = XInternAtom (GDK_DISPLAY(), + "_HILDON_APP_KILLABLE", False); + priv = HILDON_APP_GET_PRIVATE (self); + + g_return_if_fail (HILDON_IS_APP (self) ); + g_assert(GTK_WIDGET_REALIZED(self)); + + if (priv->killable) + { + /* Set the atom to specific value, because perhaps in the future, + there may be other possible values? */ + XChangeProperty(GDK_DISPLAY(), + GDK_WINDOW_XID(GTK_WIDGET(self)->window), + killability_atom, XA_STRING, 8, + PropModeReplace, (unsigned char *)KILLABLE, + strlen(KILLABLE)); + } + else + { + XDeleteProperty(GDK_DISPLAY(), + GDK_WINDOW_XID(GTK_WIDGET(self)->window), + killability_atom); + } +} + +/* + * Updates the _NET_CLIENT_LIST property into the XServer. + * It is the list of the views associated to the HildonApp. + * It will be used by the Task Navigator in order to be able to show a list + * of all the views, and let the user switch and navigate them. + */ +static void hildon_app_apply_client_list(HildonApp *self) +{ + HildonAppPrivate *priv; + Window *win_array; + GSList *list_ptr; + int loopctr = 0; + Atom clientlist; + + g_assert(GTK_WIDGET_REALIZED(self)); + + /* Get the client list handle */ + clientlist = XInternAtom (GDK_DISPLAY(), + "_NET_CLIENT_LIST", False); + + /* Allocate a new array for window IDs */ + priv = HILDON_APP_GET_PRIVATE(self); + win_array = g_new(Window, g_slist_length(priv->view_ids)); + + /* Fill the contents of the window array with current view IDs */ + for (list_ptr = priv->view_ids; list_ptr; list_ptr = list_ptr->next) + { + win_array[loopctr] = + (unsigned long)(((view_item *)(list_ptr->data))->view_id); + loopctr++; + } + + /* Update the details of current view IDs to our X property */ + XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XID(GTK_WIDGET(self)->window), + clientlist, XA_WINDOW, 32, PropModeReplace, + (unsigned char *)win_array, + g_slist_length(priv->view_ids)); + + XFlush(GDK_DISPLAY()); + g_free(win_array); +} + +/* + * Performs the standard gtk realize function. + */ +static void hildon_app_realize(GtkWidget *widget) +{ + HildonApp *self; + HildonAppPrivate *priv; + GdkWindow *window; + Atom *old_atoms, *new_atoms; + gint atom_count; + Display *disp; + + self = HILDON_APP(widget); + priv = HILDON_APP_GET_PRIVATE(self); + + /* + * Of course we need to realize the parent. + * parent_class got already initialised in the hildon_app_init function + */ + GTK_WIDGET_CLASS(parent_class)->realize(widget); + + /* some initialisation code */ + hildon_app_apply_killable(self); + hildon_app_construct_title(self); + hildon_app_apply_client_list(self); + hildon_app_notify_view_changed(self, hildon_app_get_appview(self)); + window = widget->window; + disp = GDK_WINDOW_XDISPLAY(window); + + /* Install a key snooper for the Home button - so that it works everywhere */ + priv->key_snooper = gtk_key_snooper_install + ((GtkKeySnoopFunc) hildon_app_key_snooper, widget); + + /* Enable custom button that is used for menu */ + + /* Get the list of Atoms for the WM_PROTOCOLS property... */ + XGetWMProtocols(disp, GDK_WINDOW_XID(window), &old_atoms, &atom_count); + new_atoms = g_new(Atom, atom_count + 1); + + memcpy(new_atoms, old_atoms, sizeof(Atom) * atom_count); + + /* ... creates a new Atom... */ + new_atoms[atom_count++] = + XInternAtom(disp, "_NET_WM_CONTEXT_CUSTOM", False); + + /* ... and finally update the property within the XServer */ + XSetWMProtocols(disp, GDK_WINDOW_XID(window), new_atoms, atom_count); + + XFree(old_atoms); + g_free(new_atoms); + + /* Add the GDK_SUBSTRUCTURE_MASK (receive events about window configuration + * changes of child windows) to the window. + */ + gdk_window_set_events(window, gdk_window_get_events(window) | GDK_SUBSTRUCTURE_MASK); +} + +/* + * Performs the standard gtk unrealize function. + */ +static void hildon_app_unrealize(GtkWidget *widget) +{ + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(widget); + + if (priv->key_snooper) + { + /* removing the snooper that handles MENU and HOME key presses */ + gtk_key_snooper_remove(priv->key_snooper); + priv->key_snooper = 0; + } + + gdk_window_remove_filter(NULL, hildon_app_event_filter, widget); + GTK_WIDGET_CLASS(parent_class)->unrealize(widget); +} + +/* + * Class initialisation. + */ +static void hildon_app_class_init (HildonAppClass *app_class) +{ + /* get convenience variables */ + GObjectClass *object_class = G_OBJECT_CLASS(app_class); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (app_class); + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS(app_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(app_class); + + /* set the global parent_class here */ + parent_class = g_type_class_peek_parent(app_class); + + g_type_class_add_private(app_class, sizeof(HildonAppPrivate)); + + /* now the object stuff */ + object_class->finalize = hildon_app_finalize; + object_class->set_property = hildon_app_set_property; + object_class->get_property = hildon_app_get_property; + + gtkobject_class->destroy = hildon_app_destroy; + + widget_class->key_press_event = hildon_app_key_press; + widget_class->key_release_event = hildon_app_key_release; + widget_class->button_press_event = hildon_app_button; + widget_class->button_release_event = hildon_app_button; + widget_class->realize = hildon_app_realize; + widget_class->unrealize = hildon_app_unrealize; + + container_class->add = hildon_app_add; + container_class->remove = hildon_app_remove; + container_class->forall = hildon_app_forall; + + app_class->topmost_status_acquire = + hildon_app_real_topmost_status_acquire; + app_class->topmost_status_lose = hildon_app_real_topmost_status_lose; + app_class->switch_to = hildon_app_real_switch_to; + + /* create the signals */ + app_signals[TOPMOST_STATUS_ACQUIRE] = + g_signal_new("topmost_status_acquire", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppClass, + topmost_status_acquire), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + app_signals[TOPMOST_STATUS_LOSE] = + g_signal_new("topmost_status_lose", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppClass, topmost_status_lose), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + app_signals[SWITCH_TO] = + g_signal_new("switch_to", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppClass, switch_to), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); + + app_signals[IM_CLOSE] = + g_signal_new("im_close", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppClass, im_close), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + app_signals[CLIPBOARD_COPY] = + g_signal_new("clipboard_copy", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppClass, clipboard_copy), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); + app_signals[CLIPBOARD_CUT] = + g_signal_new("clipboard_cut", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppClass, clipboard_cut), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); + app_signals[CLIPBOARD_PASTE] = + g_signal_new("clipboard_paste", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppClass, clipboard_paste), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); + + /* properties */ + g_object_class_install_property(object_class, PROP_SCROLL_CONTROL, + g_param_spec_boolean("scroll-control", + "Scroll control", + "Set the scroll control ON/OFF", + TRUE, G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, PROP_TWO_PART_TITLE, + g_param_spec_boolean("two-part-title", + "Two part title", + "Use two part title or not", + FALSE, G_PARAM_READWRITE)); +#ifndef HILDON_DISABLE_DEPRECATED + g_object_class_install_property(object_class, PROP_ZOOM, + g_param_spec_enum ("zoom", + "Zoom level", + "Set the zoom level", + HILDON_TYPE_ZOOM_LEVEL, + HILDON_ZOOM_MEDIUM, + G_PARAM_READWRITE)); +#endif + g_object_class_install_property(object_class, PROP_APP_TITLE, + g_param_spec_string ("app-title", + "Application title", + "Set the application title", + "", + G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, PROP_KILLABLE, + g_param_spec_boolean("killable", + "Killable", + "Whether the application is killable or not", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property(object_class, PROP_AUTOREGISTRATION, + g_param_spec_boolean("autoregistration", + "Autoregistration", + "Whether the application views should be registered automatically", + TRUE, + G_PARAM_READWRITE)); + g_object_class_install_property(object_class, PROP_APPVIEW, + g_param_spec_object("appview", + "Appplication View", + "The currently active application view", + HILDON_TYPE_APPVIEW, + G_PARAM_READWRITE)); + g_object_class_install_property(object_class, PROP_UI_MANAGER, + g_param_spec_object("ui-manager", + "UIManager", + "The associated GtkUIManager for this app", + GTK_TYPE_UI_MANAGER, + G_PARAM_READWRITE)); +} + +/* + * Performs the standard gtk finalize function, freeing allocated + * memory and propagating the finalization to the parent. + */ +static void +hildon_app_finalize (GObject *obj) +{ + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE (obj); + + g_free (priv->title); + + if (G_OBJECT_CLASS(parent_class)->finalize) + G_OBJECT_CLASS(parent_class)->finalize(obj); + + /* This is legacy code, but cannot be removed + without changing functionality */ + gtk_main_quit (); +} + +/* + * This function sets to 0 the GSource id for the escape_timeout + * property. It is called by hildon_app_escape_timeout. We are basically + * using the g_timeout_add (see hildon_app_key_press) to perform just + * one call to hildon_app_escape_timout with a certain delay. Once + * hildon_app_escape_timout is done with its job, we can remove the + * GSource and set priv->escape_timeout to 0. See hildon_app_escape_timeout + * for more information. + */ +static void +hildon_app_remove_timeout(HildonAppPrivate *priv) +{ + if (priv->escape_timeout > 0) + { + g_source_remove (priv->escape_timeout); + priv->escape_timeout = 0; + } +} + +/* + * Frees all the resources and propagates the destroy call to the parent. + */ +static void +hildon_app_destroy (GtkObject *obj) +{ + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE (obj); + + /* Just in case a GDK_Escape key was pressed shortly before the propagation + * of this event, it is safer to remove the timeout that will generate a + * GDK_DELETE key press. We are destroying the app, so we're not interested + * anymore in processing key presses. + */ + hildon_app_remove_timeout(priv); + + if (priv->uim != NULL) + { + g_object_unref (G_OBJECT (priv->uim)); + priv->uim = NULL; + } + + /* Free all the views */ + if (priv->view_ids) + { + g_slist_foreach (priv->view_ids, (GFunc)g_free, NULL); + g_slist_free (priv->view_ids); + priv->view_ids = NULL; + } + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + GTK_OBJECT_CLASS (parent_class)->destroy(obj); +} + +/* + * Overrides gtk_container_forall, calling the callback function for each of + * the children of HildonAppPrivate. + */ +static void hildon_app_forall (GtkContainer *container, gboolean include_internals, + GtkCallback callback, gpointer callback_data) +{ + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE (container); + + g_return_if_fail (callback != NULL); + + /* Note! we only have user added children, no internals */ + g_list_foreach (priv->children, (GFunc)callback, callback_data); +} + +/* + * An accessor to set private properties of HildonAppPrivate. + */ +static void hildon_app_set_property(GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(object); + + switch (property_id) { + case PROP_SCROLL_CONTROL: + priv->scroll_control = g_value_get_boolean(value); + break; +#ifndef HILDON_DISABLE_DEPRECATED + case PROP_ZOOM: + hildon_app_set_zoom( HILDON_APP (object), g_value_get_enum (value) ); + break; +#endif + case PROP_TWO_PART_TITLE: + hildon_app_set_two_part_title( HILDON_APP (object), + g_value_get_boolean (value) ); + break; + case PROP_APP_TITLE: + hildon_app_set_title( HILDON_APP (object), g_value_get_string (value)); + break; + case PROP_KILLABLE: + hildon_app_set_killable( HILDON_APP (object), + g_value_get_boolean (value)); + break; + case PROP_AUTOREGISTRATION: + hildon_app_set_autoregistration( HILDON_APP (object), + g_value_get_boolean (value)); + break; + case PROP_APPVIEW: + hildon_app_set_appview( HILDON_APP (object), + HILDON_APPVIEW (g_value_get_object (value))); + break; + case PROP_UI_MANAGER: + hildon_app_set_ui_manager( HILDON_APP (object), + GTK_UI_MANAGER (g_value_get_object (value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* + * An accessor to get private properties of HildonAppPrivate. + */ +static void hildon_app_get_property(GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(object); + + switch (property_id) { + case PROP_SCROLL_CONTROL: + g_value_set_boolean( value, priv->scroll_control ); + break; +#ifndef HILDON_DISABLE_DEPRECATED + case PROP_ZOOM: + g_value_set_enum( value, priv->zoom); + break; +#endif + case PROP_TWO_PART_TITLE: + g_value_set_boolean( value, priv->twoparttitle); + break; + case PROP_APP_TITLE: + g_value_set_string (value, priv->title); + break; + case PROP_KILLABLE: + g_value_set_boolean (value, priv->killable); + break; + case PROP_AUTOREGISTRATION: + g_value_set_boolean (value, priv->autoregistration); + break; + case PROP_APPVIEW: + g_value_set_object (value, hildon_app_get_appview (HILDON_APP (object))); + break; + case PROP_UI_MANAGER: + g_value_set_object (value, hildon_app_get_ui_manager (HILDON_APP (object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* + * Adds a child widget to HildonApp. + */ +static void hildon_app_add (GtkContainer *container, GtkWidget *child) +{ + HildonApp *app = HILDON_APP (container); + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE (app); + + g_return_if_fail (GTK_IS_WIDGET (child)); + + /* Check if child is already added here */ + if (g_list_find (priv->children, child) != NULL) + return; + + priv->children = g_list_append (priv->children, child); + GTK_BIN (container)->child = child; + gtk_widget_set_parent (child, GTK_WIDGET (app)); + + /* If the default direction (RTL/LTR) is different from the real + default, change it This happens if the locale has been changed + but this appview was orphaned and thus never got to know about + it. "default_direction" could be RTL, but the widget direction + of the view might still be LTR. Thats what we're fixing here. */ + + /* FIXME: This is legacy stuff */ + if (gtk_widget_get_default_direction () != + gtk_widget_get_direction (GTK_WIDGET (child))) + gtk_widget_set_direction (GTK_WIDGET (child), + gtk_widget_get_default_direction ()); + + if (HILDON_IS_APPVIEW (child)) + { + g_signal_connect_swapped (G_OBJECT (child), "title_change", + G_CALLBACK (hildon_app_construct_title), app); + if (priv->autoregistration) + hildon_app_register_view (app, child); + } +} + +/* + * Removes a child widget from HildonApp. + */ +static void hildon_app_remove (GtkContainer *container, GtkWidget *child) +{ + HildonAppPrivate *priv; + GtkBin *bin; + HildonApp *app; + + g_return_if_fail (GTK_WIDGET (child)); + + priv = HILDON_APP_GET_PRIVATE (container); + bin = GTK_BIN (container); + app = HILDON_APP (bin); + + /* Make sure that child is found in the list */ + if (g_list_find (priv->children, child) == NULL) + return; + + priv->children = g_list_remove (priv->children, child); + + if (HILDON_IS_APPVIEW (child)) + { + /* XXX: This is a compilation workaround for gcc > 3.3, since glib-2 API is buggy. + * see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */ +#ifdef __GNUC__ + __extension__ +#endif + + g_signal_handlers_disconnect_by_func (G_OBJECT (child), + (gpointer)hildon_app_construct_title, app); + + if (priv->autoregistration) + hildon_app_unregister_view (app, HILDON_APPVIEW (child)); + } + + /* If that was our visible child, we need to recalculate size. + We could chain up to parent as well... */ + gtk_widget_unparent (child); + + if (bin->child == child) + { + bin->child = NULL; + gtk_widget_queue_resize (GTK_WIDGET (bin)); + } +} + + +/* - FIXME - This is an estimate, when ever some border is changed too much + This will break down.*/ +#define RIGHT_BORDER 31 + +/* + * This function is called in case of a GDK_ESCAPE key press. It does nothing + * but map such key press to a newly created GTK_DELETE key press, which is + * then sent to the GTK main loop. In the hildon_app_key_release function, + * though, the hildon_app_remove_timeout is called if the GDK_Escape key is + * released. This means that it's necessary to hold the GDK_Escape key for all + * the time interval specified in the hildon_app_key_pressed function, in + * order to get this funcion called. + * It returns FALSE in order to get called only once. + */ +static gboolean +hildon_app_escape_timeout(gpointer data) +{ + HildonAppPrivate *priv; + GdkEvent *event; + + g_assert(GTK_WIDGET_REALIZED(data)); + + priv = HILDON_APP_GET_PRIVATE(data); + + /* Send fake event, simulation a situation that user + pressed 'x' from the corner */ + event = gdk_event_new(GDK_DELETE); + ((GdkEventAny *)event)->window = GTK_WIDGET(data)->window; + gtk_main_do_event(event); + gdk_event_free(event); + + priv->escape_timeout = 0; + + return FALSE; +} + +/* + * Looks for the visible window to whom the point of coordinates (co,by) + * belongs. Search recursively all the children of the window. + * + * This functionality is only needed for scrollbar remote control. + */ +static GdkWindow *find_window (GdkWindow *window, gint by, gint co) +{ + GdkWindow *child; + GList *children = gdk_window_peek_children (window); + + /* If the window has no children, then the coordinates must match it */ + if (!children) + return window; + + if (!(child = (GdkWindow *)children->data)) + return window; + + do + { + /* It makes sense to process a child window only if it's visible and it's + * capable to get the GDK_BUTTON_PRESS_MASK event. */ + if (gdk_window_is_visible (child) && + gdk_window_get_events (child) & GDK_BUTTON_PRESS_MASK) + { + gint x, width, y, height; + + gdk_window_get_geometry (child, &x, &y, &width, &height, NULL); + /* This checks that the the point of coordinates (co,by) is in the rectangle + * made by (x,y,x+width,y+height). If so, then we spotted which child of the + * original window is in the point (co,by). We can now recursively search + * its own children. + */ + if (x < co && x + width > co && y < by && y + height > by) + return find_window (child, by, co); + } + + /* If the window has no more children, then it's the one we're looking for */ + if (!(children = g_list_next (children))) + return window; + + } while ( (child = children->data)); + + return NULL; +} + +/* + * This is the callback function that gets called in case of a button press + * event. Such event has got x and y coordinates, so we will need to realize + * which child-window the event has to be addressed to. + * + * This functionality is used for right-hand side scrollbar remotecontrol. + */ +static gboolean +hildon_app_button (GtkWidget *widget, GdkEventButton *event) +{ + HildonAppPrivate *priv; + priv = HILDON_APP_GET_PRIVATE (widget); + g_assert(GTK_WIDGET_REALIZED(widget)); + + /* If the press event comes to certain area at right side + of the window, modify the coordinates and send a new fake event */ + if (priv->scroll_control && + (event->x > widget->allocation.width - RIGHT_BORDER)) + { + GdkWindow *window = NULL; + gint co = widget->allocation.width - RIGHT_BORDER; + + /* We now need to know in which window the _modified_ coordinates are */ + if ((window = find_window (widget->window, event->y, co))) + { + GdkEventButton nevent; + + if (window == widget->window) + return FALSE; + + /* Build a new event and associate the proper window to it */ + nevent = *event; + nevent.x = 8; + nevent.window = window; + g_object_ref (nevent.window); + gtk_main_do_event ((GdkEvent*)&nevent); + } + } + return FALSE; +} + +/* + * Performs the initialisation of the widget. + */ +static void +hildon_app_init (HildonApp *self) +{ + HildonAppPrivate *priv; + + /* Earlier textdomain was bound here. That was a dirty hack */ + priv = HILDON_APP_GET_PRIVATE(self); + + /* init private */ + priv->title = g_strdup(""); +#ifndef HILDON_DISABLE_DEPRECATED + priv->zoom = HILDON_ZOOM_MEDIUM; +#endif + priv->twoparttitle = FALSE; + priv->lastmenuclick = 0; + priv->is_topmost = FALSE; + priv->curr_view_id = 0; + priv->view_id_counter = 1; + priv->view_ids = NULL; + priv->killable = FALSE; + priv->autoregistration = TRUE; + priv->scroll_control = TRUE; + priv->uim = NULL; + priv->active_menu_id = 0; + + /* grab the events here since HildonApp isn't necessarily ever shown */ + gdk_window_set_events(gdk_get_default_root_window(), + gdk_window_get_events(gdk_get_default_root_window()) | + GDK_PROPERTY_CHANGE_MASK); + + /* For some reason, the titlebar menu has problems with the grab + (bugzilla bug 1527). This is part of somewhat ugly fix for it to + get it to work until a more satisfactory solution is found */ + gdk_window_add_filter(NULL, hildon_app_event_filter, self); + + /* Forced geometry (720x420 min/max) was removed for following reasons: + - If window was not realized when widgets with subwindows were + added, those child windows were placed incorrectly (this happens + *only* when forced geometry is at least equal to available size). + This is some kind of gtk weirdness, but removing this step + from HildonApp is much easier than figuring out gtk problem. + - matchbox-window-manager still maximizes the window, no matter + what kind of geometry hints we set. + */ + gtk_widget_set_events (GTK_WIDGET(self), GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK); +} + +/*public functions */ + +/** + * hildon_app_new: + * + * Creates a new #HildonApp + * + * Return value: Pointer to a new @HildonApp structure. + **/ +GtkWidget * +hildon_app_new (void) +{ + return GTK_WIDGET(g_object_new(HILDON_TYPE_APP, NULL)); +} + +/** + * hildon_app_new_with_appview: + * @appview : A @HildonAppView + * + * Creates an app, and sets it's initial appview. + * + * Return value: Pointer to a new @HildonApp structure. + **/ +GtkWidget * +hildon_app_new_with_appview (HildonAppView *appview) +{ + GtkWidget *app; + + g_return_val_if_fail (HILDON_IS_APPVIEW (appview), NULL); + + app = hildon_app_new (); + + hildon_app_set_appview(HILDON_APP(app), appview); + + return app; +} + +/** + * hildon_app_get_appview: + * @self : A @HildonApp + * + * Gets the currently shown appview. + * + * Return value: The currently shown appview in this HildonApp. + * If no appview is currently set for this HildonApp, + * returns NULL. + **/ +HildonAppView * +hildon_app_get_appview (HildonApp *self) +{ + GtkBin *bin; + + g_return_val_if_fail (HILDON_IS_APP (self), NULL); + bin = GTK_BIN (self); + if (HILDON_IS_APPVIEW (bin->child)) + { + return HILDON_APPVIEW (bin->child); + } + + return NULL; +} + +/** + * hildon_app_set_appview: + * @self : A @HildonApp + * @appview : A @HildonAppView. + * + * Sets (switches to) appview. + */ +void +hildon_app_set_appview (HildonApp *app, HildonAppView *view) +{ + HildonAppPrivate *priv; + GtkBin *bin; + GtkWidget *widget; /*(view to be set)*/ + gchar *menu_ui; + + g_return_if_fail (HILDON_IS_APP (app)); + g_return_if_fail (HILDON_IS_APPVIEW (view)); + + bin = GTK_BIN (app); + priv = HILDON_APP_GET_PRIVATE (app); + widget = GTK_WIDGET (view); + + if (widget == bin->child) + return; + + /* Make old appview dissapear */ + if (bin->child) + { + gtk_widget_hide (bin->child); + g_signal_emit_by_name (bin->child, "switched_from", NULL); + + if (priv->active_menu_id > 0) + { + if (priv->uim != NULL) + { + gtk_ui_manager_remove_ui (priv->uim, + priv->active_menu_id); + } + priv->active_menu_id = 0; + } + + bin->child = NULL; + } + + /* Ensure that new view is in our child list */ + if (!g_list_find (priv->children, widget)) + gtk_container_add (GTK_CONTAINER (app), widget); + + bin->child = widget; + + gtk_widget_show (widget); + + /* UI manager support, merge menu for activated view */ + g_object_get (G_OBJECT (view), + "menu-ui", &menu_ui, + NULL); + + if (menu_ui && priv->uim) + { + + priv->active_menu_id = + gtk_ui_manager_add_ui_from_string (priv->uim, menu_ui, -1, NULL); + + gtk_ui_manager_ensure_update (priv->uim); + + } + + g_free (menu_ui); + + g_signal_emit_by_name (widget, "switched_to", NULL); + + /* Inform task navigator about changed view */ + hildon_app_notify_view_changed (app, view); + + /* Update title to show currently activated view */ + hildon_app_construct_title (app); + gtk_widget_child_focus (widget, GTK_DIR_TAB_FORWARD); +} + +/** + * hildon_app_set_title: + * @self : A @HildonApp + * @newtitle : The new title assigned to the application. + * + * Sets title of the application. + **/ +void +hildon_app_set_title (HildonApp *self, const gchar *newtitle) +{ + HildonAppPrivate *priv; + gchar *oldstr; + + g_return_if_fail(HILDON_IS_APP(self)); + + priv = HILDON_APP_GET_PRIVATE(self); + oldstr = priv->title; + + if (newtitle) + { + priv->title = g_strdup(newtitle); + g_strstrip(priv->title); + } + else + priv->title = g_strdup(""); + + if (oldstr) + g_free(oldstr); + + hildon_app_construct_title(self); +} + +/** + * hildon_app_get_title: + * @self : A @HildonApp + * + * Gets the title of the application. + * + * Return value: The title currently assigned to the application. This + * value is not to be freed or modified by the calling application. + **/ +const gchar * +hildon_app_get_title (HildonApp *self) +{ + HildonAppPrivate *priv; + + g_return_val_if_fail (HILDON_IS_APP(self), NULL); + priv = HILDON_APP_GET_PRIVATE(self); + return priv->title; +} + +#ifndef HILDON_DISABLE_DEPRECATED + +/** + * hildon_app_set_zoom: + * @self : A @HildonApp + * @newzoom: The zoom level of type @HildonZoomLevel to be assigned to an + * application. + * + * Sets the zoom level. Warning! This function is deprecated and + * should not be used. It's lecacy stuff from ancient specs. + **/ +void +hildon_app_set_zoom (HildonApp *self, HildonZoomLevel newzoom) +{ + HildonAppPrivate *priv; + + g_return_if_fail(HILDON_IS_APP(self)); + + priv = HILDON_APP_GET_PRIVATE(self); + + if (newzoom != priv->zoom) + { + if (newzoom < HILDON_ZOOM_SMALL) + { + newzoom = HILDON_ZOOM_SMALL; + gtk_infoprint(GTK_WINDOW(self), _("ckct_ib_min_zoom_level_reached")); + } + else if (newzoom > HILDON_ZOOM_LARGE) { + newzoom = HILDON_ZOOM_LARGE; + gtk_infoprint(GTK_WINDOW(self), _("ckct_ib_max_zoom_level_reached")); + } + priv->zoom = newzoom; + } +} + +/** + * hildon_app_get_zoom: + * @self : A @HildonApp + * + * Gets the zoom level. Warning! This function is deprecated and + * should not be used. It's lecacy stuff from ancient specifications. + * + * Return value: Returns the zoom level of the Hildon application. The + * returned zoom level is of type @HildonZoomLevel. + **/ +HildonZoomLevel +hildon_app_get_zoom (HildonApp *self) +{ + HildonAppPrivate *priv; + + g_return_val_if_fail(HILDON_IS_APP(self), HILDON_ZOOM_MEDIUM); + priv = HILDON_APP_GET_PRIVATE(self); + return priv->zoom; +} + +/** + * hildon_app_get_default_font: + * @self : A @HildonApp + * + * Gets default font. Warning! This function is deprecated and should + * not be used. It's legacy stuff from ancient version of specification. + * + * Return value: Pointer to PangoFontDescription for the default, + * normal size font. + **/ +PangoFontDescription * +hildon_app_get_default_font (HildonApp *self) +{ + PangoFontDescription *font_desc = NULL; + GtkStyle *fontstyle = NULL; + + g_return_val_if_fail(HILDON_IS_APP(self), NULL); + + fontstyle = + gtk_rc_get_style_by_paths (gtk_widget_get_settings + (GTK_WIDGET(self)), NULL, NULL, + gtk_widget_get_type()); + + if (!fontstyle) + { + g_print("WARNING : default font not found. " + "Defaulting to swissa 19\n"); + font_desc = pango_font_description_from_string("swissa 19"); + + } + else + font_desc = pango_font_description_copy(fontstyle->font_desc); + + return font_desc; +} + +/** + * hildon_app_get_zoom_font: + * @self : A @HildonApp + * + * Gets the description of the default font. Warning! This function + * is deprecated and should not be used. It's legacy stuff from + * ancient specs. + * + * Return value: Pointer to PangoFontDescription for the default, + * normal size font. + **/ +PangoFontDescription * +hildon_app_get_zoom_font (HildonApp *self) +{ + HildonAppPrivate *priv; + PangoFontDescription *font_desc = NULL; + gchar *style_name = 0; + GtkStyle *fontstyle = NULL; + + g_return_val_if_fail(HILDON_IS_APP(self), NULL); + + priv = HILDON_APP_GET_PRIVATE(self); + if (priv->zoom == HILDON_ZOOM_SMALL) + style_name = g_strdup("hildon-zoom-small"); + else if (priv->zoom == HILDON_ZOOM_MEDIUM) + style_name = g_strdup("hildon-zoom-medium"); + else if (priv->zoom == HILDON_ZOOM_LARGE) + style_name = g_strdup("hildon-zoom-large"); + else + { + g_warning("Invalid Zoom Value\n"); + style_name = g_strdup(""); + } + + fontstyle = + gtk_rc_get_style_by_paths (gtk_widget_get_settings + (GTK_WIDGET(self)), style_name, NULL, + G_TYPE_NONE); + g_free (style_name); + + if (!fontstyle) + { + g_print("WARNING : theme specific zoomed font not found. " + "Defaulting to preset zoom-specific fonts\n"); + if (priv->zoom == HILDON_ZOOM_SMALL) + font_desc = pango_font_description_from_string("swissa 16"); + else if (priv->zoom == HILDON_ZOOM_MEDIUM) + font_desc = pango_font_description_from_string("swissa 19"); + else if (priv->zoom == HILDON_ZOOM_LARGE) + font_desc = pango_font_description_from_string("swissa 23"); + } + else + font_desc = pango_font_description_copy(fontstyle->font_desc); + + return font_desc; +} + +#endif /* disable deprecated */ + +/** + * hildon_app_set_two_part_title: + * @self : A @HildonApp + * @istwoparttitle : A gboolean indicating wheter to activate + * a title that has both the application title and application + * view title separated by a triangle. + * + * Sets the two part title. + */ +void +hildon_app_set_two_part_title (HildonApp *self, gboolean istwoparttitle) +{ + HildonAppPrivate *priv; + g_return_if_fail(HILDON_IS_APP(self)); + priv = HILDON_APP_GET_PRIVATE(self); + + if (istwoparttitle != priv->twoparttitle) + { + priv->twoparttitle = istwoparttitle; + hildon_app_construct_title(self); + } +} + +/** + * hildon_app_get_two_part_title: + * @self : A @HildonApp + * + * Gets the 'twopart' represention of the title inside #HildonApp. + * + * Return value: A boolean indicating wheter title shown has both + * application, and application view title separated by a triangle. + **/ +gboolean +hildon_app_get_two_part_title (HildonApp *self) +{ + HildonAppPrivate *priv; + + g_return_val_if_fail(HILDON_IS_APP(self), FALSE); + priv = HILDON_APP_GET_PRIVATE(self); + return priv->twoparttitle; +} + + +/* private functions */ + + +/* + * Generates and sends an event of type _NET_SHOWING_DESKTOP to the XServer, + * which will be then caught by the window Manager. + */ +static void +hildon_app_switch_to_desktop (void) +{ + + XEvent ev; + Atom showing_desktop = XInternAtom(GDK_DISPLAY(), + "_NET_SHOWING_DESKTOP", False); + memset(&ev, 0, sizeof(ev)); + ev.xclient.type = ClientMessage; + gdk_error_trap_push(); + ev.xclient.window = GDK_ROOT_WINDOW(); + ev.xclient.message_type = showing_desktop; + ev.xclient.format = 32; + ev.xclient.data.l[0] = 1; + gdk_error_trap_push(); + XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False, + SubstructureRedirectMask, &ev); + gdk_error_trap_pop(); +} + +/* + * Handles the key press of the Escape, Increase and Decrease keys. Other keys + * are treaed by the parent GkWidgetClass. + */ +static gboolean +hildon_app_key_press (GtkWidget *widget, GdkEventKey *keyevent) +{ + HildonApp *app = HILDON_APP (widget); + HildonAppView *appview; + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(app); + + if (HILDON_IS_APPVIEW(GTK_BIN (app)->child)) + { + appview = HILDON_APPVIEW (GTK_BIN (app)->child); + } + else + { + return FALSE; + } + + if (keyevent->keyval == GDK_Escape && priv->escape_timeout == 0) + { + /* Call hildon_app_escape_timeout every 1500ms until it returns FALSE + * and store the relative GSource id. Since hildon_app_escape_timeout + * can only return FALSE, the call will occurr only once. + */ + priv->escape_timeout = g_timeout_add(1500, hildon_app_escape_timeout, app); + } + + /* FIXME: Handling +/- keys here is not usefull. Applications + can equally easily handle the keypress themselves. */ + else if (HILDON_KEYEVENT_IS_INCREASE_KEY (keyevent)) + { + _hildon_appview_increase_button_state_changed (appview, + keyevent->type); + } + else if (HILDON_KEYEVENT_IS_DECREASE_KEY (keyevent)) + { + _hildon_appview_decrease_button_state_changed (appview, + keyevent->type); + } + + /* Activate default bindings and let the widget with focus to handle key */ + return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, keyevent); +} + +/* + * Handles the key release event for the Escape, Toolbar and Fullscreen keys. + */ +static gboolean +hildon_app_key_release (GtkWidget *widget, GdkEventKey *keyevent) +{ + HildonApp *app = HILDON_APP (widget); + HildonAppView *appview; + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(app); + + if (HILDON_IS_APPVIEW(GTK_BIN (app)->child)) + { + appview = HILDON_APPVIEW (GTK_BIN (app)->child); + } + else + { + return FALSE; + } + + if (keyevent->keyval == GDK_Escape) + { + /* + * This will prevent the hildon_app_escape_timeout from being called. + * See hildon_app_escape_timeout and hildon_app_remove_timeout for more. + */ + hildon_app_remove_timeout(priv); + } + else if (HILDON_KEYEVENT_IS_TOOLBAR_KEY (keyevent)) + { + /* FIXME: Unexpected parameter 0 */ + g_signal_emit_by_name(G_OBJECT(appview), + "toolbar-toggle-request", 0); + } + else if (HILDON_KEYEVENT_IS_FULLSCREEN_KEY (keyevent)) + { + /* FIXME: Why not to use a similar pattern as above + "fullscreen-toggle-request" ? */ + if (hildon_appview_get_fullscreen_key_allowed (appview)) + { + hildon_appview_set_fullscreen (appview, + !(hildon_appview_get_fullscreen (appview))); + } + } + + /* FIXME: Should the event be marked as handled if any of the three + above cases took an action */ + + /* Activate default bindings and let the widget with focus to handle key */ + return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, keyevent); +} + +/* + * Handles the MENU and HOME key presses. + */ +static gboolean +hildon_app_key_snooper (GtkWidget *widget, GdkEventKey *keyevent, HildonApp *app) +{ + /* FIXME: Using normal keypress handler would be better choise. All + keyevents come to window anyway, so we would get the same + keys in that way as well, but we wouldn't need to struggle + with grabs (modal dialogs etc). */ + + /* Menu key handling is done here */ + if ( HILDON_KEYEVENT_IS_MENU_KEY (keyevent) ) { + HildonAppView *appview; + HildonAppPrivate *priv; + GtkWidget *toplevel; + + /* Don't act on modal dialogs */ + toplevel = gtk_widget_get_toplevel (widget); + if (GTK_IS_DIALOG (toplevel) + && gtk_window_get_modal (GTK_WINDOW (toplevel))) + { + return TRUE; + } + + appview = HILDON_APPVIEW (GTK_BIN(app)->child); + priv = HILDON_APP_GET_PRIVATE(app); + + if ( keyevent->type == GDK_KEY_PRESS ) { + /* Toggle menu on press, avoid key repeat */ + if ( priv->lastmenuclick == 0 ){ + _hildon_appview_toggle_menu(appview, + gtk_get_current_event_time()); + + priv->lastmenuclick = 1; + } + } else if ( keyevent->type == GDK_KEY_RELEASE ) { + /* We got release, so next press is really a new press, + not a repeat */ + if ( priv->lastmenuclick == 1 ) { + priv->lastmenuclick = 0; + } + + } else { + /* Unknown key event */ + return FALSE; + } + + /* don't stop the key event so that it reaches GTK where it + closes all existing menus that might be open */ + return FALSE; + } + + /* Home key handling is done here. */ + if ((keyevent->type == GDK_KEY_RELEASE) && + HILDON_KEYEVENT_IS_HOME_KEY (keyevent)) + { + hildon_app_switch_to_desktop(); + + return TRUE; + } + + return FALSE; +} + +/* + * Returns the message_type of the Atom registered with a certain name. + */ +static int +xclient_message_type_check(XClientMessageEvent *cm, const gchar *name) +{ + return cm->message_type == XInternAtom(GDK_DISPLAY(), name, FALSE); +} + +/* + * Returns the GtkWidget associated to a certain Window. + */ +static GtkWidget * +hildon_app_xwindow_lookup_widget(Window xwindow) +{ + GdkWindow *window; + gpointer widget; + + window = gdk_xid_table_lookup(xwindow); + if (window == NULL) + return NULL; + + gdk_window_get_user_data(window, &widget); + return widget; +} + +/* + * Let's search a actual main window using tranciency hints. + * Note that there can be several levels of menus/dialogs above + * the actual main window. + */ +static Window get_active_main_window(Window window) +{ + Window parent_window; + gint limit = 0; + + gdk_error_trap_push (); + + while (XGetTransientForHint(GDK_DISPLAY(), window, &parent_window)) + { + /* The limit > TRANSIENCY_MAXITER ensures that we can't be stuck + here forever if we have circular transiencies for some reason. + Use of _MB_CURRENT_APP_WINDOW might be more elegant... */ + + if (!parent_window || parent_window == GDK_ROOT_WINDOW() || + parent_window == window || limit > TRANSIENCY_MAXITER) + { + break; + } + + limit++; + window = parent_window; + } + + gdk_flush (); + + if (gdk_error_trap_pop ()) + return 0; + + return window; +} + +/* + * Filters every GDK event first. + */ +static GdkFilterReturn +hildon_app_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) +{ + gint x,y; + HildonApp *app = data; + HildonAppPrivate *priv; + HildonAppView *appview = NULL; + + XAnyEvent *eventti = xevent; + + if (HILDON_IS_APPVIEW (GTK_BIN (app)->child)) + { + appview = HILDON_APPVIEW (GTK_BIN (app)->child); + } + + g_return_val_if_fail (app, GDK_FILTER_CONTINUE); + g_return_val_if_fail (HILDON_IS_APP(app), GDK_FILTER_CONTINUE); + + priv = HILDON_APP_GET_PRIVATE(app); + if (eventti->type == ClientMessage) + { + XClientMessageEvent *cm = xevent; + + /* Check if a message indicating a click on titlebar has been + received. Don't open it if mouse is grabbed (eg. modal dialog + was just opened). + _MB_GRAB_TRANSFER is emitted by MatchBox, and signals that a button + has just been released. */ + if (xclient_message_type_check(cm, "_MB_GRAB_TRANSFER") && + HILDON_IS_APPVIEW(appview) && + gtk_grab_get_current() == NULL && + !_hildon_appview_menu_visible(appview)) + { + _hildon_appview_toggle_menu(appview, cm->data.l[0]); + return GDK_FILTER_REMOVE; + } + /* IM_CLOSE is input method specific hack that is really questionable */ + else if (xclient_message_type_check(cm, "_HILDON_IM_CLOSE")) + { + g_signal_emit_by_name(app, "im_close", NULL); + return GDK_FILTER_REMOVE; + } + /* Task user changed the view through task navigator? */ + else if (xclient_message_type_check(cm, "_NET_ACTIVE_WINDOW")) + { + unsigned long view_id = cm->window; + gpointer view_ptr = find_view(app, view_id); + + /* When getting a _NET_ACTIVE_WINDOW signal from the WM we need + * to bring the application to the front */ + if (!priv->is_topmost) + g_signal_emit_by_name (G_OBJECT(app), "topmost_status_acquire"); + + if (HILDON_IS_APPVIEW(view_ptr)) + /* Sets the current view to the "window" that the _NET_ACTIVE_WINDOW + * specified */ + hildon_app_set_appview(app, (HILDON_APPVIEW(view_ptr))); + else + /* there was no view, so we have to switch to an actual application */ + g_signal_emit_by_name (G_OBJECT(app), "switch_to", view_ptr); + + /* FIXME: This is a hack. This was once just gtk_window_present, but + was changed into this at some day!! */ + if (GTK_WIDGET(app)->window) + { + mb_util_window_activate(GDK_DISPLAY(), + GDK_WINDOW_XID(GTK_WIDGET(app)->window)); + } + } + /* FIXME: IM hack */ + else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_COPY")) + { + Window xwindow = cm->data.l[0]; + GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow); + + g_signal_emit_by_name (G_OBJECT(app), "clipboard_copy", widget); + } + /* FIXME: IM hack */ + else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_CUT")) + { + Window xwindow = cm->data.l[0]; + GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow); + + g_signal_emit_by_name (G_OBJECT(app), "clipboard_cut", widget); + } + /* FIXME: IM hack */ + else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_PASTE")) + { + Window xwindow = cm->data.l[0]; + GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow); + + g_signal_emit_by_name (G_OBJECT(app), "clipboard_paste", widget); + } + } + + if (eventti->type == ButtonPress) + { + + /* FIXME: This is mysterious bugfix related to problems to open the + application menu (bugzilla N#3204) */ + XButtonEvent *bev = (XButtonEvent *)xevent; + + if (HILDON_IS_APPVIEW(appview) && + _hildon_appview_menu_visible(appview) && + !hildon_appview_get_fullscreen(appview)) + { + x = bev->x_root; + y = bev->y_root; + if ( (x >= MENUAREA_LEFT_LIMIT) && (x <= MENUAREA_RIGHT_LIMIT) && + (y >= MENUAREA_TOP_LIMIT) && (y <= MENUAREA_BOTTOM_LIMIT)) + { + _hildon_appview_toggle_menu(appview, bev->time); + return GDK_FILTER_CONTINUE; + } + } + } + + /* FIXME: as above */ + if (eventti->type == ButtonRelease) + { + if (HILDON_IS_APPVIEW(appview) && + _hildon_appview_menu_visible(appview) && + !hildon_appview_get_fullscreen(appview)) + { + XButtonEvent *bev = (XButtonEvent *)xevent; + x = bev->x_root; + y = bev->y_root; + if ( (x >= MENUAREA_LEFT_LIMIT) && (x < MENUAREA_RIGHT_LIMIT) && + (y >= MENUAREA_TOP_LIMIT) && (y <= MENUAREA_BOTTOM_LIMIT)) + { + return GDK_FILTER_REMOVE; + } + } + return GDK_FILTER_CONTINUE; + } + + /* Application stacking order changed */ + if (eventti->type == PropertyNotify) + { + Atom active_app_atom = + XInternAtom (GDK_DISPLAY(), "_MB_CURRENT_APP_WINDOW", False); + XPropertyEvent *prop = xevent; + + if ((prop->atom == active_app_atom) + && (prop->window == GDK_ROOT_WINDOW())) + { + Atom realtype; + int format; + int status; + unsigned long n; + unsigned long extra; + Window my_window; + union + { + Window *win; + unsigned char *char_pointer; + } win; + + win.win = NULL; + + status = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), + active_app_atom, 0L, 16L, + 0, XA_WINDOW, &realtype, &format, + &n, &extra, &win.char_pointer); + if (!(status == Success && realtype == XA_WINDOW && format == 32 + && n == 1 && win.win != NULL)) + { + if (win.win != NULL) + XFree(win.char_pointer); + return GDK_FILTER_CONTINUE; + } + + my_window = GDK_WINDOW_XID(GTK_WIDGET(app)->window); + + /* Are we the topmost one? */ + if (win.win[0] == my_window || + get_active_main_window(win.win[0]) == my_window) + { + if (!priv->is_topmost) + g_signal_emit_by_name (G_OBJECT(app), + "topmost_status_acquire"); + } + else if (priv->is_topmost) + { + GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(app)); + + /* FIXME: IM hack, IM-module should do this in response to + topmost_status_lose (emission hook?) */ + if (GTK_IS_ENTRY(focus)) + gtk_im_context_focus_out(GTK_ENTRY(focus)->im_context); + if (GTK_IS_TEXT_VIEW(focus)) + gtk_im_context_focus_out(GTK_TEXT_VIEW(focus)->im_context); + + g_signal_emit_by_name (app, "topmost_status_lose"); + } + + if (win.win != NULL) + XFree(win.char_pointer); + } + } + + return GDK_FILTER_CONTINUE; + } + +/* + * Sets the GTK Window title to the application's title, or + * combined appview/app title, if two part title is asked. + */ +static void +hildon_app_construct_title (HildonApp *self) +{ + g_return_if_fail (HILDON_IS_APP (self)); + + if (GTK_WIDGET_REALIZED(self)) + { + HildonAppPrivate *priv; + GdkAtom subname; + gchar *concatenated_title = NULL; + HildonAppView *appview; + + priv = HILDON_APP_GET_PRIVATE (self); + appview = hildon_app_get_appview(self); + + /* FIXME: The subname property is legacy stuff no longer supported by + Matchbox. However, it is still set for the convenience of + the Task Navigator. */ + subname = gdk_atom_intern("_MB_WIN_SUB_NAME", FALSE); + + if (!appview || !hildon_app_get_two_part_title(self) || + g_utf8_strlen(hildon_appview_get_title(appview), -1) < 1 ) + { + /* Set an invisible dummy value if there is no appview title */ + gdk_property_change (GTK_WIDGET(self)->window, subname, + gdk_atom_intern ("UTF8_STRING", FALSE), + 8, GDK_PROP_MODE_REPLACE, (guchar *) " \0", 1); + gtk_window_set_title (GTK_WINDOW(self), priv->title); + } + else + { + gdk_property_change (GTK_WIDGET(self)->window, subname, + gdk_atom_intern ("UTF8_STRING", FALSE), + 8, GDK_PROP_MODE_REPLACE, + (guchar *)hildon_appview_get_title(appview), + strlen(hildon_appview_get_title (appview))); + concatenated_title = g_strjoin(TITLE_DELIMITER, priv->title, + hildon_appview_get_title(appview), NULL); + if (concatenated_title != NULL) + { + gtk_window_set_title (GTK_WINDOW(self), concatenated_title); + g_free(concatenated_title); + } + else + { + /* FIXME: This section is never executed */ + gtk_window_set_title(GTK_WINDOW(self), priv->title); + } + } + } +} + +/* + * Callback function to the topmost_status_acquire signal emitted by + * hildon_app_event_filter function. See it for more details. + */ +void +hildon_app_real_topmost_status_acquire (HildonApp *self) +{ + HildonAppPrivate *priv; + g_return_if_fail (HILDON_IS_APP (self)); + priv = HILDON_APP_GET_PRIVATE (self); + + /* FIXME: What is the logic not to update topmost status now? */ + if (!GTK_BIN (self)->child) + return; + + priv->is_topmost = TRUE; +} + +/* + * Callback function to the topmost_status_lose signal emitted by + * hildon_app_event_filter function. See it for more details. + */ +void +hildon_app_real_topmost_status_lose (HildonApp *self) +{ + HildonAppPrivate *priv; + g_return_if_fail (HILDON_IS_APP (self)); + priv = HILDON_APP_GET_PRIVATE (self); + + /* FIXME: What is the logic not to update topmost status now? */ + if (!GTK_BIN (self)->child) + return; + + priv->is_topmost = FALSE; +} + +void +hildon_app_real_switch_to (HildonApp *self) +{ + g_return_if_fail (HILDON_IS_APP (self)); + /* Do we have to do anything here? */ +} + + +/** + * hildon_app_set_autoregistration + * @self : a @HildonApp + * @auto_reg : Whether the (app)view autoregistration should be active + * + * Controls the autoregistration/unregistration of (app)views. + **/ + +void hildon_app_set_autoregistration(HildonApp *self, gboolean auto_reg) +{ + HildonAppPrivate *priv; + g_return_if_fail (HILDON_IS_APP (self)); + + priv = HILDON_APP_GET_PRIVATE (self); + priv->autoregistration = auto_reg; +} + + +/** + * hildon_app_register_view: + * @self : a @HildonApp + * @view_ptr : Pointer to the view instance to be registered + * + * Registers a new view. For appviews, this can be done automatically + * if autoregistration is set. + */ + +void hildon_app_register_view(HildonApp *self, gpointer view_ptr) +{ + HildonAppPrivate *priv; + view_item *view_item_inst; + + g_return_if_fail (HILDON_IS_APP (self) || view_ptr != NULL); + + priv = HILDON_APP_GET_PRIVATE (self); + + if (hildon_app_find_view_id(self, view_ptr) == 0) + { + /* The pointer to the view was unique, so add it to the list */ + view_item_inst = g_malloc(sizeof(view_item)); + view_item_inst->view_id = priv->view_id_counter; + view_item_inst->view_ptr = view_ptr; + + priv->view_id_counter++; + + priv->view_ids = + g_slist_append(priv->view_ids, view_item_inst); + + /* Update the list of views */ + if (GTK_WIDGET_REALIZED(self)) + hildon_app_apply_client_list(self); + } +} + + +/** + * hildon_app_register_view_with_id: + * @self : a @HildonApp + * @view_ptr : Pointer to the view instance to be registered + * @view_id : The ID of the view + * + * Registers a new view. Allows the application to specify any ID. + * + * Return value: TRUE if the view registration succeeded, FALSE otherwise. + * The probable cause of failure is that view with that ID + * already existed. + */ + +gboolean hildon_app_register_view_with_id(HildonApp *self, + gpointer view_ptr, + unsigned long view_id) +{ + view_item *view_item_inst; + HildonAppPrivate *priv; + GSList *list_ptr = NULL; + + g_return_val_if_fail (HILDON_IS_APP (self), FALSE); + g_return_val_if_fail (view_ptr, FALSE); + + priv = HILDON_APP_GET_PRIVATE (self); + + list_ptr = g_slist_nth(priv->view_ids, 0); + + /* Check that the view is not already registered */ + while (list_ptr) + { + if ( (gpointer)((view_item *)list_ptr->data)->view_ptr == view_ptr + && (unsigned long)((view_item *)list_ptr->data)->view_id == view_id) + { + return FALSE; + } + list_ptr = list_ptr->next; + } + + /* The pointer to the view was unique, so add it to the list */ + view_item_inst = g_malloc(sizeof(view_item)); + view_item_inst->view_id = view_id; + view_item_inst->view_ptr = view_ptr; + + priv->view_ids = + g_slist_append(priv->view_ids, view_item_inst); + + priv->view_id_counter++; + + /* Finally, update the _NET_CLIENT_LIST property */ + if (GTK_WIDGET_REALIZED(self)) + hildon_app_apply_client_list(self); + + return TRUE; +} + +/** + * hildon_app_unregister_view: + * @self : A @HildonApp + * @view_ptr : Pointer to the view instance to be unregistered + * + * Unregisters a view from HildonApp. Done usually when a view is + * destroyed. For appviews, this is can be automatically + * if autoregistration is set. + */ + + +void hildon_app_unregister_view(HildonApp *self, gpointer view_ptr) +{ + HildonAppPrivate *priv; + GSList *list_ptr = NULL; + + /* FIXME: could this and the following function be combined some way? */ + g_return_if_fail (HILDON_IS_APP (self) || view_ptr != NULL); + + priv = HILDON_APP_GET_PRIVATE (self); + + /* Search the view from the list */ + list_ptr = priv->view_ids; + + while (list_ptr) + { + if ( (gpointer)((view_item *)list_ptr->data)->view_ptr == view_ptr) + { + /* Found the view, kick it off */ + g_free (list_ptr->data); + priv->view_ids = g_slist_delete_link(priv->view_ids, list_ptr); + break; + } + list_ptr = list_ptr->next; + } + + if (GTK_WIDGET_REALIZED(self)) + hildon_app_apply_client_list(self); +} + + +/** + * hildon_app_unregister_view_with_id: + * @self : A @HildonApp + * @view_id : The ID of the view that should be unregistered + * + * Unregisters a view with specified ID, if it exists. + */ +void hildon_app_unregister_view_with_id(HildonApp *self, + unsigned long view_id) +{ + HildonAppPrivate *priv; + GSList *list_ptr = NULL; + + g_return_if_fail (HILDON_IS_APP (self)); + + priv = HILDON_APP_GET_PRIVATE (self); + + /* Search the view from the list */ + list_ptr = priv->view_ids; /*g_slist_nth(priv->view_ids, 0);*/ + + while (list_ptr) + { + if ( (unsigned long)((view_item *)list_ptr->data)->view_id == view_id) + { + /* Found view with given id, kick it off */ + g_free (list_ptr->data); + priv->view_ids = g_slist_delete_link(priv->view_ids, list_ptr); + break; + } + list_ptr = list_ptr->next; + } + + /* Update client list to reflect new situation. If we are not + realized, then nobody knows about us anyway... */ + if (GTK_WIDGET_REALIZED(self)) + hildon_app_apply_client_list(self); +} + + +/** + * hildon_app_notify_view_changed: + * @self : A @HildonApp + * @view_ptr : Pointer to the view that is switched to + * + * Updates the X property that contains the currently active view + */ + +void hildon_app_notify_view_changed(HildonApp *self, gpointer view_ptr) +{ + /* FIXME: This precondition should use && instead of || */ + g_return_if_fail (HILDON_IS_APP (self) || view_ptr != NULL); + + /* We need GdkWindow before we can send X messages */ + if (GTK_WIDGET_REALIZED(self)) + { + gulong id = hildon_app_find_view_id(self, view_ptr); + Atom active_view = XInternAtom (GDK_DISPLAY(), + "_NET_ACTIVE_WINDOW", False); + + if (id) { + /* Set _NET_ACTIVE_WINDOW for our own toplevel to contain view id */ + XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XID(GTK_WIDGET(self)->window), + active_view, XA_WINDOW, 32, PropModeReplace, + (unsigned char *)&id, 1); + XFlush(GDK_DISPLAY()); + } + } +} + + +/** + * hildon_app_find_view_id: + * @self : a @HildonApp + * @view_ptr : Pointer to the view whose ID we want to acquire + * + * Return value: The ID of the view, or 0 if not found. + * + * Allows mapping of view pointer to its view ID. If NULL is passed + * as the view pointer, returns the ID of the current view. + */ +unsigned long hildon_app_find_view_id(HildonApp *self, gpointer view_ptr) +{ + HildonAppPrivate *priv; + GSList *iter; + + priv = HILDON_APP_GET_PRIVATE (self); + + /* FIXME: It probably should be a precondition that view_ptr + is given. Check preconditions with g_return_val_if_fail. */ + if (!view_ptr) + view_ptr = GTK_BIN (self)->child; + if (!view_ptr) + return 0; + + /* Iterate through list and search for given view pointer */ + for (iter = priv->view_ids; iter; iter = iter->next) + { + if ( (gpointer)((view_item *)iter->data)->view_ptr == view_ptr) + return (unsigned long)((view_item *)iter->data)->view_id; + } + + return 0; +} + +/** + * hildon_app_set_killable: + * @self : A @HildonApp + * @killability : Truth value indicating whether the app can be killed + * + * Updates information about whether the application can be killed or not by + * Task Navigator (i.e. whether its statesave is up to date) + */ +void hildon_app_set_killable(HildonApp *self, gboolean killability) +{ + HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE (self); + g_return_if_fail (HILDON_IS_APP (self) ); + + if (killability != priv->killable) + { + priv->killable = killability; + + /* If we have a window, then we can actually set this + property. Otherwise we wait until we are realized */ + if (GTK_WIDGET_REALIZED(self)) + hildon_app_apply_killable(self); + } +} + + +/** + * hildon_app_set_ui_manager: + * @self : #HildonApp + * @uim : #GtkUIManager to be set + * + * Sets the #GtkUIManager assigned to the #HildonApp. + * If @uim is NULL, unsets the current ui manager. + * The @HildonApp holds a reference to the ui manager until + * the @HildonApp is destroyed or unset. + **/ +void hildon_app_set_ui_manager(HildonApp *self, GtkUIManager *uim) +{ + HildonAppPrivate *priv; + + g_return_if_fail(self && HILDON_IS_APP(self)); + + priv = HILDON_APP_GET_PRIVATE (self); + + /* Release old ui-manager object if such exists */ + if (priv->uim != NULL) + { + g_object_unref (G_OBJECT (priv->uim)); + } + + priv->uim = uim; + + /* If we got new ui-manager (it's perfectly valid not + to give one), acquire reference to it */ + if (priv->uim != NULL) + { + g_object_ref (G_OBJECT (uim)); + } + + g_object_notify (G_OBJECT(self), "ui-manager"); +} + +/** + * hildon_app_get_ui_manager: + * @self : #HildonApp + * + * Gets the #GtkUIManager assigned to the #HildonApp. + * + * Return value: The #GtkUIManager assigned to this application + * or null if no manager is assigned. + **/ +GtkUIManager *hildon_app_get_ui_manager(HildonApp *self) +{ + HildonAppPrivate *priv; + + g_return_val_if_fail(self && HILDON_IS_APP(self), NULL); + + priv = HILDON_APP_GET_PRIVATE (self); + + return (priv->uim); +} + +/* + * Search for a view with the given id within HildonApp. + * Returns a pointer to the found view. NULL in case of insuccess. + */ +static gpointer find_view(HildonApp *self, unsigned long view_id) +{ + HildonAppPrivate *priv; + GSList *iter; + + priv = HILDON_APP_GET_PRIVATE (self); + + /* Iterate through the list of view ids and search given id */ + for (iter = priv->view_ids; iter; iter = iter->next) + { + if ( (unsigned long)((view_item *)iter->data)->view_id == view_id) + return (gpointer)((view_item *)iter->data)->view_ptr; + } + + return NULL; +} diff --git a/hildon-widgets/hildon-app.h b/hildon-widgets/hildon-app.h new file mode 100644 index 0000000..c8365d7 --- /dev/null +++ b/hildon-widgets/hildon-app.h @@ -0,0 +1,152 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __HILDON_APP_H__ +#define __HILDON_APP_H__ + +#include +#include +#include "hildon-appview.h" + +G_BEGIN_DECLS +/** + * HildonApp: + * + * Contains only private data not to be touched by outsiders. + */ +typedef struct _HildonApp HildonApp; +typedef struct _HildonAppClass HildonAppClass; + +#define HILDON_TYPE_APP ( hildon_app_get_type() ) + +#define HILDON_APP(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_APP, \ + HildonApp)) + +#define HILDON_APP_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \ + HILDON_TYPE_APP, HildonAppClass)) + +#define HILDON_IS_APP(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_APP)) + +#define HILDON_IS_APP_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \ + HILDON_TYPE_APP)) + + +struct _HildonApp { + GtkWindow parent; +}; + +struct _HildonAppClass { + GtkWindowClass parent_class; + void (*topmost_status_acquire) (HildonApp *self); + void (*topmost_status_lose) (HildonApp *self); + void (*switch_to) (HildonApp *self); + void (*im_close) (HildonApp *self); + void (*clipboard_copy) (HildonApp *self, GtkWidget *widget); + void (*clipboard_cut) (HildonApp *self, GtkWidget *widget); + void (*clipboard_paste) (HildonApp *self, GtkWidget *widget); +}; + +#ifndef HILDON_DISABLE_DEPRECATED +/* Make these values >0 so that we can detect when someone sets SMALL-1 + * zoom level (enum seems to be unsigned int) + */ + +/** + * HildonZoomLevel: + * @HILDON_ZOOM_SMALL: Smallest font. + * @HILDON_ZOOM_MEDIUM: Middle size font. + * @HILDON_ZOOM_LARGE: Largest font. + * + * The Hildon zoom levels. Small meaning small font. Large meaning + * large font. These font are specified in the gtkrc files. + * This enum is deprecated and should not be used. It's just + * lecagy stuff from ancient specs. + */ +typedef enum { + HILDON_ZOOM_SMALL = 1, + HILDON_ZOOM_MEDIUM = 2, + HILDON_ZOOM_LARGE = 3 +} HildonZoomLevel; + +#define HILDON_TYPE_ZOOM_LEVEL (hildon_zoom_level_get_type ()) + +G_CONST_RETURN GType hildon_zoom_level_get_type (void); +#endif /* deprecated */ + +/* You should use the correct ones from hildon-defines.h */ +#define HILDON_MENU_KEY GDK_F4 +#define HILDON_HOME_KEY GDK_F5 +#define HILDON_TOOLBAR_KEY GDK_T +#define HILDON_FULLSCREEN_KEY GDK_F6 +#define HILDON_INCREASE_KEY GDK_F7 +#define HILDON_DECREASE_KEY GDK_F8 +#define HILDON_TOOLBAR_MODIFIERS (GDK_SHIFT_MASK | GDK_CONTROL_MASK) + +#define HILDON_KEYEVENT_IS_MENU_KEY(keyevent) (keyevent->keyval == HILDON_MENU_KEY) +#define HILDON_KEYEVENT_IS_HOME_KEY(keyevent) (keyevent->keyval == HILDON_HOME_KEY) +#define HILDON_KEYEVENT_IS_TOOLBAR_KEY(keyevent) ((keyevent->keyval == HILDON_TOOLBAR_KEY) && \ + (keyevent->state == HILDON_TOOLBAR_MODIFIERS)) +#define HILDON_KEYEVENT_IS_FULLSCREEN_KEY(keyevent) (keyevent->keyval == HILDON_FULLSCREEN_KEY) +#define HILDON_KEYEVENT_IS_INCREASE_KEY(keyevent) (keyevent->keyval == HILDON_INCREASE_KEY) +#define HILDON_KEYEVENT_IS_DECREASE_KEY(keyevent) (keyevent->keyval == HILDON_DECREASE_KEY) + +#define TRANSIENCY_MAXITER 50 + +GType hildon_app_get_type(void); +GtkWidget *hildon_app_new(void); +GtkWidget *hildon_app_new_with_appview(HildonAppView * appview); +void hildon_app_set_appview(HildonApp * self, HildonAppView * appview); +HildonAppView *hildon_app_get_appview(HildonApp * self); +void hildon_app_set_title(HildonApp * self, const gchar * newtitle); +const gchar *hildon_app_get_title(HildonApp * self); + +#ifndef HILDON_DISABLE_DEPRECATED +void hildon_app_set_zoom(HildonApp * self, HildonZoomLevel newzoom); +HildonZoomLevel hildon_app_get_zoom(HildonApp * self); +PangoFontDescription *hildon_app_get_default_font(HildonApp * self); +PangoFontDescription *hildon_app_get_zoom_font(HildonApp * self); +#endif + +void hildon_app_set_two_part_title(HildonApp * self, + gboolean istwoparttitle); +gboolean hildon_app_get_two_part_title(HildonApp * self); + +void hildon_app_set_autoregistration(HildonApp *self, gboolean auto_reg); +void hildon_app_register_view(HildonApp *self, gpointer view_ptr); +gboolean hildon_app_register_view_with_id(HildonApp *self, + gpointer view_ptr, + unsigned long view_id); +void hildon_app_unregister_view(HildonApp *self, gpointer view_ptr); +void hildon_app_unregister_view_with_id(HildonApp *self, + unsigned long view_id); +unsigned long hildon_app_find_view_id(HildonApp *self, gpointer view_ptr); +void hildon_app_notify_view_changed(HildonApp *self, gpointer view_ptr); + +void hildon_app_set_killable(HildonApp *self, gboolean killability); + +void hildon_app_set_ui_manager(HildonApp *self, GtkUIManager *uim); +GtkUIManager *hildon_app_get_ui_manager(HildonApp *self); + +G_END_DECLS +#endif /* HILDON_APP_H */ diff --git a/hildon-widgets/hildon-appview.c b/hildon-widgets/hildon-appview.c new file mode 100644 index 0000000..c288a7a --- /dev/null +++ b/hildon-widgets/hildon-appview.c @@ -0,0 +1,1480 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + + +#include +#include +#include +#include +#include "hildon-app.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#include +#define _(String) gettext(String) + +enum { + PROP_0, + PROP_CONNECTED_ADJUSTMENT, + PROP_FULLSCREEN_KEY_ALLOWED, + PROP_FULLSCREEN, + PROP_TITLE, + PROP_MENU_UI +}; + +/*The size of screen*/ +#define WINDOW_HEIGHT 480 +#define WINDOW_WIDTH 800 + +#define NAVIGATOR_HEIGHT WINDOW_HEIGHT + +#define APPVIEW_HEIGHT 396 +#define APPVIEW_WIDTH 672 + +#define TOOLBAR_HEIGHT 40 +#define TOOLBAR_UP 9 +#define TOOLBAR_DOWN 9 +#define TOOLBAR_MIDDLE 10 +#define TOOLBAR_RIGHT 24 +#define TOOLBAR_LEFT 24 +#define TOOLBAR_WIDTH APPVIEW_WIDTH + +#define WORKAREA_ATOM "_NET_WORKAREA" + +/* Non atom defines */ +#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ +#define _NET_WM_STATE_ADD 1 /* add/set property */ + +/*Margins + * These margins are set to be 5pixels smaller than in the specs + * Inner things are allocation that extra space + * */ +/* +#define MARGIN_TOOLBAR_TOP 2 +#define MARGIN_TOOLBAR_BOTTOM 6 +#define MARGIN_TOOLBAR_LEFT 22 +#define MARGIN_TOOLBAR_RIGHT 23 +*/ +#define MARGIN_APPVIEW_TOP 0 +#define MARGIN_APPVIEW_BOTTOM 24 +#define MARGIN_APPVIEW_LEFT 24 +#define MARGIN_APPVIEW_RIGHT 24 + + +#define HILDON_APPVIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\ + HILDON_TYPE_APPVIEW, HildonAppViewPrivate)) + +/*Progressbar*/ +#define DEFAULT_WIDTH 20 +#define DEFAULT_HEIGHT 28 +#define BANNER_WIDTH DEFAULT_WIDTH +#define BANNER_HEIGHT DEFAULT_HEIGHT + +static GtkBinClass *parent_class; + +static void hildon_appview_init(HildonAppView * self); +static void hildon_appview_class_init(HildonAppViewClass * appview_class); + +static void hildon_appview_menupopupfunc(GtkMenu *menu, gint *x, gint *y, + gboolean *push_in, + GtkWidget *widget); +static void hildon_appview_menupopupfuncfull(GtkMenu *menu, gint *x, gint *y, + gboolean *push_in, + GtkWidget *widget); +static gboolean hildon_appview_expose(GtkWidget * widget, + GdkEventExpose * event); +static void hildon_appview_forall(GtkContainer * container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); +static void hildon_appview_show_all(GtkWidget *widget); + +static void hildon_appview_size_allocate(GtkWidget * widget, + GtkAllocation * allocation); +static void hildon_appview_size_request(GtkWidget * widget, + GtkRequisition * requisition); +static void hildon_appview_finalize(GObject * obj_self); +static void hildon_appview_set_property(GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec); +static void hildon_appview_get_property(GObject * object, guint property_id, + GValue * value, GParamSpec * pspec); +static void hildon_appview_destroy(GtkObject *obj); +static void hildon_appview_real_fullscreen_state_change(HildonAppView * + self, + gboolean + fullscreen); +static void hildon_appview_switched_to(HildonAppView * self); +static void get_client_area(GtkWidget * widget, + GtkAllocation * allocation); + +typedef void (*HildonAppViewSignal) (HildonAppView *, gint, gpointer); + +/* signals */ +enum { + TOOLBAR_CHANGED, + TOOLBAR_TOGGLE_REQUEST, + FULLSCREEN_STATE_CHANGE, + TITLE_CHANGE, + SWITCHED_TO, + SWITCHED_FROM, + INCREASE_BUTTON_EVENT, + DECREASE_BUTTON_EVENT, + HILDON_APPVIEW_LAST_SIGNAL +}; + +static guint appview_signals[HILDON_APPVIEW_LAST_SIGNAL] = { 0 }; + +enum { + WIN_TYPE = 0, + WIN_TYPE_MESSAGE, + MAX_WIN_MESSAGES +}; + +struct _HildonAppViewPrivate { + GtkWidget *menu; + gchar *title; + + GtkAllocation allocation; + + guint fullscreen : 1; + guint fullscreenshortcutallowed : 1; + /* For future expansion. We might use the below variables for disabling keyrepeat + * if we need it someday. */ + guint increase_button_pressed_down : 1; + guint decrease_button_pressed_down : 1; + gint visible_toolbars; + GtkAdjustment * connected_adjustment; + + gchar *menu_ui; +}; + +/* FIXME: Extremely old Legacy code. I wonder why we need + a custom marshaller in the first place. */ +static void hildon_appview_signal_marshal(GClosure * closure, + GValue * return_value, + guint n_param_values, + const GValue * param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + register HildonAppViewSignal callback; + register GCClosure *cc = (GCClosure *) closure; + register gpointer data1, data2; + + g_return_if_fail(n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA(closure)) { + data1 = closure->data; + data2 = g_value_peek_pointer(param_values + 0); + } else { + data1 = g_value_peek_pointer(param_values + 0); + data2 = closure->data; + } + + callback = + /* This is a compilation workaround for gcc > 3.3 since glib is buggy */ + /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */ + +#ifdef __GNUC__ + __extension__ +#endif + (HildonAppViewSignal) (marshal_data != + NULL ? marshal_data : cc->callback); + + callback((HildonAppView *) data1, + (gint) g_value_get_int(param_values + 1), data2); +} + +GType hildon_appview_get_type(void) +{ + static GType appview_type = 0; + + if (!appview_type) { + static const GTypeInfo appview_info = { + sizeof(HildonAppViewClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) hildon_appview_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(HildonAppView), + 0, /* n_preallocs */ + (GInstanceInitFunc) hildon_appview_init, + }; + appview_type = g_type_register_static(GTK_TYPE_BIN, + "HildonAppView", + &appview_info, 0); + } + return appview_type; +} + +/* + * Class initialisation. + */ +static void hildon_appview_class_init(HildonAppViewClass * appview_class) +{ + /* Get convenience variables */ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(appview_class); + GObjectClass *object_class = G_OBJECT_CLASS(appview_class); + GtkContainerClass *container_class = + GTK_CONTAINER_CLASS(appview_class); + + /* Set the global parent_class here */ + parent_class = g_type_class_peek_parent(appview_class); + + object_class->set_property = hildon_appview_set_property; + object_class->get_property = hildon_appview_get_property; + + /* Set the widgets virtual functions */ + widget_class->size_allocate = hildon_appview_size_allocate; + widget_class->size_request = hildon_appview_size_request; + widget_class->expose_event = hildon_appview_expose; + widget_class->show_all = hildon_appview_show_all; + /* widget_class->realize = hildon_appview_realize; */ + + /* now the object stuff */ + object_class->finalize = hildon_appview_finalize; + + /* To the container */ + container_class->forall = hildon_appview_forall; + + /* gtkobject stuff*/ + GTK_OBJECT_CLASS(appview_class)->destroy = hildon_appview_destroy; + + /* And own virtual functions */ + appview_class->fullscreen_state_change = + hildon_appview_real_fullscreen_state_change; + appview_class->switched_to = hildon_appview_switched_to; + + g_type_class_add_private(appview_class, + sizeof(struct _HildonAppViewPrivate)); + + /* New signals */ + appview_signals[TOOLBAR_CHANGED] = + g_signal_new("toolbar-changed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppViewClass, toolbar_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + appview_signals[TOOLBAR_TOGGLE_REQUEST] = + g_signal_new("toolbar-toggle-request", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppViewClass, + toolbar_toggle_request), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + appview_signals[FULLSCREEN_STATE_CHANGE] = + g_signal_new("fullscreen_state_change", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppViewClass, + fullscreen_state_change), NULL, NULL, + hildon_appview_signal_marshal, G_TYPE_NONE, 1, + G_TYPE_INT); + + appview_signals[TITLE_CHANGE] = + g_signal_new("title_change", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppViewClass, title_change), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + appview_signals[SWITCHED_TO] = + g_signal_new("switched_to", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppViewClass, switched_to), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + appview_signals[SWITCHED_FROM] = + g_signal_new("switched_from", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppViewClass, switched_from), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + appview_signals[INCREASE_BUTTON_EVENT] = + g_signal_new("increase_button_event", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppViewClass, increase_button_event), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, + G_TYPE_UINT); + + appview_signals[DECREASE_BUTTON_EVENT] = + g_signal_new("decrease_button_event", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(HildonAppViewClass, decrease_button_event), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, + G_TYPE_UINT); + + /* New properties */ + g_object_class_install_property(object_class, PROP_CONNECTED_ADJUSTMENT, + g_param_spec_object("connected-adjustment", + "Connected GtkAdjustment", + "The GtkAdjustment. The increase and decrease hardware buttons are mapped to this.", + GTK_TYPE_ADJUSTMENT, + G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, PROP_FULLSCREEN_KEY_ALLOWED, + g_param_spec_boolean("fullscreen-key-allowed", + "Fullscreen key allowed", + "Whether the fullscreen key is allowed or not", + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, PROP_FULLSCREEN, + g_param_spec_boolean("fullscreen", + "Fullscreen", + "Whether the appview should be fullscreen or not", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property(object_class, PROP_TITLE, + g_param_spec_string("title", + "Title", + "Appview title", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property(object_class, PROP_MENU_UI, + g_param_spec_string("menu-ui", + "Menu UI string", + "UI string for application view menu", + NULL, + G_PARAM_READWRITE)); + widget_class = (GtkWidgetClass*) appview_class; +} + +/* + * Performs the initialisation of the widget. + */ +static void hildon_appview_init(HildonAppView * self) +{ + HildonAppViewPrivate *priv = self->priv = + HILDON_APPVIEW_GET_PRIVATE(self); + + /* the vbox is used to handle both the view's main body and how many + * toolbars as the user wants */ + + /* FIXME: Where does this constant 10 come from */ + self->vbox = gtk_vbox_new(TRUE, 10); + gtk_widget_set_parent(self->vbox, GTK_WIDGET(self)); + priv->menu = NULL; + priv->visible_toolbars = 0; + + priv->title = g_strdup(""); + + priv->fullscreen = FALSE; + priv->fullscreenshortcutallowed = FALSE; + priv->increase_button_pressed_down = FALSE; + priv->decrease_button_pressed_down = FALSE; + + priv->connected_adjustment = NULL; +} + +/* + * Performs the standard gtk finalize function, freeing allocated + * memory and propagating the finalization to the parent. + */ +static void hildon_appview_finalize(GObject * obj_self) +{ + HildonAppView *self; + g_return_if_fail(HILDON_APPVIEW(obj_self)); + self = HILDON_APPVIEW(obj_self); + + if (self->priv->menu_ui) + g_free (self->priv->menu_ui); + + if (self->priv->connected_adjustment != NULL) + g_object_remove_weak_pointer (G_OBJECT (self->priv->connected_adjustment), + (gpointer) &self->priv->connected_adjustment); + + if (G_OBJECT_CLASS(parent_class)->finalize) + G_OBJECT_CLASS(parent_class)->finalize(obj_self); + + g_free(self->priv->title); +} + +/* + * An accessor to set private properties of HildonAppView. + */ +static void hildon_appview_set_property(GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + HildonAppView *appview = HILDON_APPVIEW (object); + + switch (property_id) { + case PROP_CONNECTED_ADJUSTMENT: + hildon_appview_set_connected_adjustment (appview, g_value_get_object (value)); + break; + + case PROP_FULLSCREEN_KEY_ALLOWED: + hildon_appview_set_fullscreen_key_allowed (appview, g_value_get_boolean (value)); + break; + + case PROP_FULLSCREEN: + hildon_appview_set_fullscreen (appview, g_value_get_boolean (value)); + break; + + case PROP_TITLE: + hildon_appview_set_title (appview, g_value_get_string (value)); + break; + + case PROP_MENU_UI: + hildon_appview_set_menu_ui (appview, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* + * An accessor to get private properties of HildonAppView. + */ +static void hildon_appview_get_property(GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + HildonAppViewPrivate *priv = HILDON_APPVIEW_GET_PRIVATE(object); + + switch (property_id) { + case PROP_CONNECTED_ADJUSTMENT: + g_value_set_object (value, priv->connected_adjustment); + break; + + case PROP_FULLSCREEN_KEY_ALLOWED: + g_value_set_boolean (value, priv->fullscreenshortcutallowed); + break; + + case PROP_FULLSCREEN: + g_value_set_boolean (value, priv->fullscreen); + break; + + case PROP_TITLE: + g_value_set_string (value, priv->title); + break; + + case PROP_MENU_UI: + g_value_set_string (value, priv->menu_ui); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* + * Used when the HildonAppView is exposed, this function gets a GtkBoxChild + * as first argument, and a pointer to a gint as second argument. If such + * GtkBoxChild is visible, the function increments the gint. It is used + * in a loop, to compute the number of visible toolbars. + */ +static void visible_toolbar(gpointer data, gpointer user_data) +{ + if(GTK_WIDGET_VISIBLE(((GtkBoxChild *)data)->widget)) + (*((gint *)user_data))++; +} + +/* + * Used in the paint_toolbar function to discover how many toolbars are + * above the find toolbar. It's called in a loop that iterates through + * all the children of the GtkVBox of the HildonAppView. + */ +static void find_findtoolbar_index(gpointer data, gpointer user_data) +{ + gint *pass_bundle = (gint *)user_data; + + if(((GtkBoxChild *)data)->widget->allocation.y < pass_bundle[0] + && GTK_WIDGET_VISIBLE(((GtkBoxChild *)data)->widget)) + pass_bundle[1]++; +} + +/* + * Used in the paint_toolbar function, it's get a GtkBoxChild as first argument + * and a pointer to a GtkWidget as the second one, which will be addressed to + * the find toolbar widget, if it is contained in the given GtkBoxChild. + */ +static void find_findtoolbar(gpointer data, gpointer user_data) +{ + if(HILDON_IS_FIND_TOOLBAR(((GtkBoxChild *)data)->widget) + && GTK_WIDGET_VISIBLE(((GtkBoxChild *)data)->widget)) + (*((GtkWidget **)user_data)) = ((GtkBoxChild *)data)->widget; +} + +/* + * Paints all the toolbar children of the GtkVBox of the HildonAppView. + */ +static void paint_toolbar(GtkWidget *widget, GtkBox *box, + GdkEventExpose * event, + gboolean fullscreen) +{ + gint toolbar_num = 0; + gint ftb_index = 0; + gint count; + GtkWidget *findtoolbar = NULL; + gchar toolbar_mode[40]; + + /* Iterate through all the children of the vbox of the HildonAppView. + * The visible_toolbar function increments toolbar_num if the toolbar + * is visible. After this loop, toobar_num will contain the number + * of the visible toolbars. */ + g_list_foreach(box->children, visible_toolbar, + (gpointer) &toolbar_num); + if(toolbar_num <= 0) + return; + + /* Loop through all the children of the GtkVBox of the HildonAppView. + * The find_findtoolbar function will assign a pointer to the find toolbar + * to "findtoolbar" argument. If the findtoolbar is not found, i.e. it + * isn't in the GtkVBox, then the "findtoolbar" argument will stay NULL */ + g_list_foreach(box->children, find_findtoolbar, + (gpointer) &findtoolbar); + if(findtoolbar != NULL){ + gint pass_bundle[2];/* an array for convient data passing + the first member contains the y allocation + of the find toolbar, and the second allocation + contains the index(how many toolbars are above + find toolbar) */ + pass_bundle[0] = findtoolbar->allocation.y; + pass_bundle[1] = ftb_index; + + /* computes how many toolbars are above the find toolbar, and the value is + * stored in pass_bundle[1] */ + g_list_foreach(box->children, find_findtoolbar_index, + (gpointer) pass_bundle); + ftb_index = pass_bundle[1]; + } + /*upper border*/ + sprintf(toolbar_mode, "toolbar%sframe-top", + fullscreen ? "-fullscreen-" : "-"); + gtk_paint_box(widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, widget, toolbar_mode, + widget->allocation.x, + GTK_WIDGET(box)->allocation.y -TOOLBAR_UP, + widget->allocation.width, TOOLBAR_UP); + + /*top most toolbar painting*/ + if(findtoolbar != NULL && ftb_index == 0 ) + { + sprintf(toolbar_mode, "findtoolbar%s", + fullscreen ? "-fullscreen" : ""); + + gtk_paint_box(widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, widget, toolbar_mode, + widget->allocation.x, + GTK_WIDGET(box)->allocation.y, + widget->allocation.width, + TOOLBAR_HEIGHT); + }else{ + sprintf(toolbar_mode, "toolbar%s", + fullscreen ? "-fullscreen" : ""); + gtk_paint_box(widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, widget, toolbar_mode, + widget->allocation.x, + GTK_WIDGET(box)->allocation.y, + widget->allocation.width, + TOOLBAR_HEIGHT); + } + /*multi toolbar painting*/ + for(count = 0; count < toolbar_num - 1; count++) + { + sprintf(toolbar_mode, "toolbar%sframe-middle", + fullscreen ? "-fullscreen-" : "-"); + + gtk_paint_box(widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, widget, toolbar_mode, + widget->allocation.x, + GTK_WIDGET(box)->allocation.y + + (1 + count) * TOOLBAR_HEIGHT + + count * TOOLBAR_MIDDLE, + widget->allocation.width, + TOOLBAR_MIDDLE); + + if(findtoolbar != NULL && count + 1 == ftb_index){ + sprintf(toolbar_mode, "findtoolbar%s", + fullscreen ? "-fullscreen" : ""); + + gtk_paint_box(widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, widget, toolbar_mode, + widget->allocation.x, + GTK_WIDGET(box)->allocation.y + + (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE), + widget->allocation.width, + TOOLBAR_HEIGHT); + }else{ + sprintf(toolbar_mode, "toolbar%s", + fullscreen ? "-fullscreen" : ""); + + gtk_paint_box(widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, widget, toolbar_mode, + widget->allocation.x, + GTK_WIDGET(box)->allocation.y + + (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE), + widget->allocation.width, + TOOLBAR_HEIGHT); + } + } + sprintf(toolbar_mode, "toolbar%sframe-bottom", + fullscreen ? "-fullscreen-" : "-"); + + gtk_paint_box(widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, widget, toolbar_mode, + widget->allocation.x, + GTK_WIDGET(box)->allocation.y + + GTK_WIDGET(box)->allocation.height, + widget->allocation.width, TOOLBAR_DOWN); +} + +/* + * Callback function to an expose event. + */ +static gboolean hildon_appview_expose(GtkWidget * widget, + GdkEventExpose * event) +{ + gint toolbar_num = 0; + GtkBox *box = GTK_BOX(HILDON_APPVIEW(widget)->vbox); + + if(GTK_WIDGET_VISIBLE(box) && box->children != NULL) + { + HildonAppViewPrivate *priv = HILDON_APPVIEW_GET_PRIVATE(widget); + + /* Iterate through all the children of the vbox of the HildonAppView. + * The visible_toolbar function increments toolbar_num if the toolbar + * is visible. After this loop, toobar_num will contain the number + * of the visible toolbars. */ + g_list_foreach(box->children, visible_toolbar, + (gpointer) &toolbar_num); + + if( priv->visible_toolbars != toolbar_num) + { + /* If the code reaches this block, it means that a toolbar as been added + * or removed since last time the view was drawn. Let's then compute the + * new height of the toolbars areas */ + gint y_pos = 0; + /* the height difference */ + gint change = (priv->visible_toolbars - toolbar_num) * + (TOOLBAR_HEIGHT+TOOLBAR_MIDDLE+TOOLBAR_UP); + if( change < 0 ) + change = TOOLBAR_MIDDLE + TOOLBAR_UP; + /* the new y-coordinate for the toolbars area */ + y_pos = HILDON_APPVIEW(widget)->vbox->allocation.y - change; + + gtk_widget_queue_draw_area(widget, 0, y_pos, widget->allocation.width, + change + HILDON_APPVIEW(widget)->vbox->allocation.height + + TOOLBAR_DOWN); + priv->visible_toolbars = toolbar_num; + } + } + + + if (HILDON_APPVIEW(widget)->priv->fullscreen) + { + if (toolbar_num > 0) + paint_toolbar(widget, box, event, TRUE); + } + else + { + gint appview_height_decrement = 0; + if (toolbar_num > 0) + { + appview_height_decrement = toolbar_num * TOOLBAR_HEIGHT + + (toolbar_num - 1) * TOOLBAR_MIDDLE + + TOOLBAR_UP + TOOLBAR_DOWN; + + paint_toolbar(widget, box, event, FALSE); + } + else + { + appview_height_decrement = MARGIN_APPVIEW_BOTTOM; + + gtk_paint_box(widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, widget, "bottom-border", + widget->allocation.x, + widget->allocation.y + + (widget->allocation.height - MARGIN_APPVIEW_BOTTOM), + widget->allocation.width, MARGIN_APPVIEW_BOTTOM); + } + gtk_paint_box( widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, + widget, "left-border", widget->allocation.x, + widget->allocation.y, MARGIN_APPVIEW_LEFT, + widget->allocation.height - appview_height_decrement ); + gtk_paint_box( widget->style, widget->window, + GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT, + &event->area, + widget, "right-border", + (widget->allocation.x + + widget->allocation.width) - + MARGIN_APPVIEW_RIGHT, widget->allocation.y, + MARGIN_APPVIEW_RIGHT, + widget->allocation.height - appview_height_decrement ); + } + + GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event); + + return FALSE; + +} + +/* + * Responds to the usual size_request signal. + */ +static void hildon_appview_size_request(GtkWidget * widget, + GtkRequisition * requisition) +{ + HildonAppViewPrivate *priv = HILDON_APPVIEW(widget)->priv; + GtkWidget *child = GTK_BIN(widget)->child; + + /* forward the size_request to the eventual child of the main container */ + if (child) + gtk_widget_size_request(child, requisition); + + /* forward the size_request to the eventual vbox (which may contain + * toolbars) */ + if (HILDON_APPVIEW(widget)->vbox != NULL) + gtk_widget_size_request(HILDON_APPVIEW(widget)->vbox, requisition); + + /* express the size_request for the view */ + if (priv->fullscreen) { + requisition->height = WINDOW_HEIGHT; + requisition->width = WINDOW_WIDTH; + } else { + requisition->height = APPVIEW_HEIGHT; + requisition->width = APPVIEW_WIDTH; + } +} + +/* + * Computes size and position for the children of the view. + */ +static void hildon_appview_size_allocate(GtkWidget * widget, + GtkAllocation * allocation) +{ + GtkAllocation box_allocation; + GtkAllocation alloc = *allocation; + gint border_width = GTK_CONTAINER(widget)->border_width; + GtkBin *bin = GTK_BIN(widget); + GtkBox *box = GTK_BOX(HILDON_APPVIEW(widget)->vbox); + gboolean at_least_one_visible_toolbar = FALSE; + + if(!GTK_IS_WIDGET(bin->child)) return; + + widget->allocation = *allocation; + + if (bin->child != NULL && GTK_IS_WIDGET(bin->child)) { + if (HILDON_APPVIEW(widget)->priv->fullscreen) { + alloc.x += border_width; + alloc.y += border_width; + alloc.width -= (border_width * 2); + alloc.height -= (border_width * 2); + } else { + alloc.x += border_width + MARGIN_APPVIEW_LEFT; + alloc.y += border_width + MARGIN_APPVIEW_TOP; + alloc.width -= (border_width * 2) + (MARGIN_APPVIEW_LEFT + + MARGIN_APPVIEW_RIGHT); + alloc.height -= (border_width * 2) + MARGIN_APPVIEW_TOP; + } + } + + if (box->children != NULL) { + gint length = 0; + gint box_height = 0; + /* Iterate through all the children of the vbox of the HildonAppView. + * The visible_toolbar function increments toolbar_num if the toolbar + * is visible. After this loop, toobar_num will contain the number + * of the visible toolbars. */ + g_list_foreach(box->children, visible_toolbar, + (gpointer) &length); + if(length > 0){ + box_height = length * TOOLBAR_HEIGHT + + (length - 1) * TOOLBAR_MIDDLE; + + if(bin->child != NULL) { + alloc.height = alloc.height - box_height - TOOLBAR_UP + - TOOLBAR_DOWN; + at_least_one_visible_toolbar = TRUE; + } + + box_allocation.y = allocation->height - box_height - TOOLBAR_DOWN; + box_allocation.height = box_height; + box_allocation.x = allocation->x + TOOLBAR_LEFT; + box_allocation.width = allocation->width - TOOLBAR_LEFT - + TOOLBAR_RIGHT; + gtk_widget_size_allocate(GTK_WIDGET(box), &box_allocation); + } + } + + /* The bottom skin graphics is visible only when there are no toolbars */ + if ((HILDON_APPVIEW(widget)->priv->fullscreen == FALSE) && + (at_least_one_visible_toolbar == FALSE)) + alloc.height -= MARGIN_APPVIEW_BOTTOM; + + gtk_widget_size_allocate(GTK_WIDGET(bin->child), &alloc); +} + +/* + * Overrides gtk_container_forall, calling the callback function for each of + * the children of HildonAppPrivate. + */ +static void hildon_appview_forall(GtkContainer * container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + HildonAppView *self = HILDON_APPVIEW(container); + + g_return_if_fail(callback != NULL); + + GTK_CONTAINER_CLASS(parent_class)->forall(container, include_internals, + callback, callback_data); + if(include_internals && self->vbox != NULL) + (* callback)(GTK_WIDGET(self->vbox), callback_data); +} + +/** + * Shows all the widgets in the container. + */ +static void hildon_appview_show_all(GtkWidget *widget) +{ + HildonAppView *self = HILDON_APPVIEW(widget); + + /* Toolbar items */ + gtk_widget_show_all(self->vbox); + + /* Parent handless stuff inside appview */ + GTK_WIDGET_CLASS(parent_class)->show_all(widget); +} + +/* + * Frees all the resources and propagates the destroy call to the parent. + */ +static void hildon_appview_destroy(GtkObject *obj) +{ + HildonAppView *self = HILDON_APPVIEW(obj); + + if(self->vbox != NULL){ + gtk_widget_unparent(self->vbox); + self->vbox = NULL; + } + + GTK_OBJECT_CLASS(parent_class)->destroy(obj); +} + +/*******************/ +/* Signals */ +/*******************/ + +/* +static void hildon_appview_toolbar_toggle_request( HildonAppView *self ) +{ + +} +*/ + +/*Signal - When is changed to this appview, this is called*/ +static void hildon_appview_switched_to(HildonAppView * self) +{ + GtkWidget *parent; + + g_return_if_fail(self && HILDON_IS_APPVIEW(self)); + + parent = gtk_widget_get_parent(GTK_WIDGET(self)); + hildon_appview_set_fullscreen( self, self->priv->fullscreen ); +} + +/*Signal - When the fullscreen state is changed, this is called*/ +static void hildon_appview_real_fullscreen_state_change(HildonAppView * + self, + gboolean + fullscreen) +{ + HildonAppViewPrivate *priv; + g_return_if_fail(self && HILDON_IS_APPVIEW(self)); + priv = self->priv; + + /* Ensure that state is really changed */ + if( priv->fullscreen == fullscreen ) + return; + + if( fullscreen ) + gtk_window_fullscreen( GTK_WINDOW( + gtk_widget_get_parent(GTK_WIDGET(self))) ); + else + gtk_window_unfullscreen( GTK_WINDOW( + gtk_widget_get_parent(GTK_WIDGET(self))) ); + + priv->fullscreen = fullscreen; +} + +/*******************/ +/* General */ +/*******************/ + + +/* + * queries a window for the root window coordinates and size of its + * client area (i.e. minus the title borders etc.) + */ +static void get_client_area(GtkWidget * widget, GtkAllocation * allocation) +{ + GdkWindow *window = widget->window; + + if (window) + gdk_window_get_origin(window, &allocation->x, &allocation->y); + else + memset( allocation, 0, sizeof(GtkAllocation) ); +} + +/*The menu popuping needs a menu popup-function*/ +static void hildon_appview_menupopupfunc( GtkMenu *menu, gint *x, gint *y, + gboolean *push_in, GtkWidget *widget ) +{ + GtkAllocation client_area = { 0, 0, 0, 0 }; + + get_client_area( GTK_WIDGET(widget), &client_area ); + + gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x, + "vertical-offset", y, NULL); + + *x += client_area.x; + *y += client_area.y; + +} + +/* Similar to above, but used in fullscreen mode */ +static void hildon_appview_menupopupfuncfull( GtkMenu *menu, gint *x, gint *y, + gboolean *push_in, + GtkWidget *widget ) +{ + gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x, + "vertical-offset", y, NULL); + + *x = MAX (0, *x); + *y = MAX (0, *y); +} + +/*******************/ +/*public functions*/ +/*******************/ + + +/** + * hildon_appview_new: + * @title: The application view title of the new @HildonAppView. + * + * Use this function to create a new application view. + * + * Return value: A @HildonAppView. + **/ +GtkWidget *hildon_appview_new(const gchar * title) +{ + HildonAppView *newappview = g_object_new(HILDON_TYPE_APPVIEW, NULL); + + hildon_appview_set_title(newappview, title); + return GTK_WIDGET(newappview); +} + +/** + * hildon_appview_add_with_scrollbar + * @self : A @HildonAppView + * @child : A @GtkWidget + * + * Adds the @child to the @self(HildonAppView) and creates a scrollbar + * to it. Similar as adding first a @GtkScrolledWindow and then the + * @child to it. + */ +void hildon_appview_add_with_scrollbar(HildonAppView * self, + GtkWidget * child) +{ + GtkScrolledWindow *scrolledw; + + g_return_if_fail(HILDON_IS_APPVIEW(self)); + g_return_if_fail(GTK_IS_WIDGET(child)); + g_return_if_fail(child->parent == NULL); + + scrolledw = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL)); + gtk_scrolled_window_set_policy(scrolledw, GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(scrolledw, GTK_SHADOW_NONE); + + /* FIXME: child doesn't need to be a viewport in order it can + be packed into scrolled window. It just needs to support + setting adjustments. */ + if (GTK_IS_VIEWPORT(child)) + gtk_container_add(GTK_CONTAINER(scrolledw), child); + else + { + if( GTK_IS_CONTAINER(child) ) + gtk_container_set_focus_vadjustment( GTK_CONTAINER(child), + gtk_scrolled_window_get_vadjustment(scrolledw) ); + gtk_scrolled_window_add_with_viewport(scrolledw, child); + } + + gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(scrolledw)); +} + +/** + * hildon_appview_get_title: + * @self : A @HildonAppView + * + * Gets the title of given #HildonAppView. + * + * Return value: The title of the application view. + **/ +const gchar *hildon_appview_get_title(HildonAppView * self) +{ + g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), ""); + return self->priv->title; +} + +/** + * hildon_appview_set_title: + * @self : A @HildonAppView + * @newname : The new title of the application view. + * + * Sets an title of an application view. The title is visible only if + * twoparttitle is enabled on the @HildonApp + * + **/ +void hildon_appview_set_title(HildonAppView * self, const gchar * newname) +{ + gchar *oldtitle; + + g_return_if_fail(self && HILDON_IS_APPVIEW(self)); + oldtitle = self->priv->title; + + if (newname != NULL) + self->priv->title = g_strdup(newname); + else + self->priv->title = g_strdup(""); + + g_free(oldtitle); + g_signal_emit_by_name(G_OBJECT(self), "title_change"); +} + +/** + * hildon_appview_set_toolbar: + * @self: A #HildonAppView + * @toolbar: A #GtkToolbar + * + * Sets the #GtkToolbar to given #HildonAppView. This is, however, not a recommned way to + * set your toolbars. When you have multi toolbars, calling this function more than once will just + * replace the bottom most toolbar. There is a #GtkVBox in #HildonAppView's public structure, the programmer + * is responsible to pack his toolbars in the #GtkVBox, and #HildonAppView will take care of put them at the + * right place. + * + **/ +#ifndef HILDON_DISABLE_DEPRECATED +void hildon_appview_set_toolbar(HildonAppView * self, GtkToolbar * toolbar) +{ + GtkBox *box = GTK_BOX(HILDON_APPVIEW(self)->vbox); + g_return_if_fail(self && HILDON_IS_APPVIEW(self)); + if(toolbar != NULL)/*for failure checking*/ + g_return_if_fail(GTK_IS_TOOLBAR(toolbar)); + + /*if it is NULL, it unsets the last one, + * if it is not null, it unsets the last one anyway*/ + if(box->children != NULL){ + GtkWidget *last_widget; + + last_widget = ((GtkBoxChild *)g_list_last + (box->children)->data)->widget; + gtk_container_remove(GTK_CONTAINER(box), + last_widget); + } + + gtk_box_pack_end(box, GTK_WIDGET(toolbar), TRUE, TRUE, 0); + gtk_widget_queue_resize(GTK_WIDGET(self)); + /*deprecated signal*/ + g_signal_emit_by_name(G_OBJECT(self), "toolbar-changed"); +} +#endif +/** + * hildon_appview_get_toolbar: + * @self: A #HildonAppView + * + * This function will only + * return the last widget that has been packed into the #GtkVBox in the public structure. Note + * this does not, however, mean that it is the bottom most toolbar. + * + * Return value: The #GtkToolbar assigned to this application view. + **/ +#ifndef HILDON_DISABLE_DEPRECATED +GtkToolbar *hildon_appview_get_toolbar(HildonAppView * self) +{ + GtkBox *box = GTK_BOX(HILDON_APPVIEW(self)->vbox); + g_return_val_if_fail(self != NULL && HILDON_IS_APPVIEW(self), FALSE); + if(box != NULL && box->children != NULL) + return GTK_TOOLBAR(((GtkBoxChild*) + g_list_last(box->children)->data)->widget); + else + return NULL; +} +#endif +/** + * hildon_appview_set_fullscreen: + * @self: A @HildonAppView + * @fullscreen: The new state of fullscreen mode. TRUE means fullscreen + * will be set. FALSE the opposite. + * + * Set the fullscreen state of given #HildonAppView class. + **/ +void hildon_appview_set_fullscreen(HildonAppView * self, + gboolean fullscreen) +{ + g_return_if_fail(self && HILDON_IS_APPVIEW(self)); + g_signal_emit_by_name(G_OBJECT(self), "fullscreen_state_change", + fullscreen); +} + +/** + * hildon_appview_get_fullscreen: + * @self: A @HildonAppView + * + * Gets the current state of fullscreen mode. + * + * Return value: The current state of fullscreen mode. + **/ +gboolean hildon_appview_get_fullscreen(HildonAppView * self) +{ + g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), FALSE); + return self->priv->fullscreen; +} + +/** + * hildon_appview_get_fullscreen_key_allowed: + * @self: A @HildonAppView + * + * Check if fullscreening with a shortcut is allowed for given + * #HildonAppView. + * + * Return value: Wheter it's possible to swith fullscreen on/off with + * a shortcut key. + **/ +gboolean hildon_appview_get_fullscreen_key_allowed(HildonAppView * self) +{ + g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), FALSE); + return self->priv->fullscreenshortcutallowed; +} + +/** + * hildon_appview_set_fullscreen_key_allowed: + * @self: A @HildonAppView + * @allow: Wheter it's possible to swith fullscreen on/off with + * a shortcut key. + * + * Sets given #HildonAppView whether to allow toggling fullscreen mode + * with a shortcut key. + **/ +void hildon_appview_set_fullscreen_key_allowed(HildonAppView * self, + gboolean allow) +{ + g_return_if_fail(self && HILDON_IS_APPVIEW(self)); + self->priv->fullscreenshortcutallowed = allow; +} + +/** + * hildon_appview_get_menu: + * @self : #HildonAppView + * + * Gets the #GtMenu assigned to the #HildonAppview. + * + * Return value: The #GtkMenu assigned to this application view. + **/ +GtkMenu *hildon_appview_get_menu(HildonAppView * self) +{ + g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), NULL); + + if (self->priv->menu == NULL) { + /* Create hildonlike menu */ + + GtkUIManager *uim; + GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (self)); + + /* Try to get appview menu from ui manager */ + if (parent && HILDON_IS_APP (parent)) + { + uim = hildon_app_get_ui_manager (HILDON_APP (parent)); + if (uim) + { + self->priv->menu = + gtk_ui_manager_get_widget (uim, "/HildonApp"); + } + } + + + if (self->priv->menu == NULL) + { + /* Fall back to oldskool menus */ + self->priv->menu = GTK_WIDGET (g_object_new (GTK_TYPE_MENU, NULL)); + } + + gtk_widget_set_name(GTK_WIDGET(self->priv->menu), + "menu_force_with_corners"); + gtk_widget_show_all (self->priv->menu); + } + + return GTK_MENU(self->priv->menu); +} + +/** + * _hildon_appview_toggle_menu: + * @self : A @HildonAppView + * @button_event_time : + * + * This function should be only called from @HildonApp. + * Should be renamed to popup menu. Just the first parameter is used. + */ +void _hildon_appview_toggle_menu(HildonAppView * self, + Time button_event_time) +{ + GList *children; + + g_return_if_fail(self && HILDON_IS_APPVIEW(self)); + + if (!self->priv->menu) + return; + + if (GTK_WIDGET_VISIBLE(self->priv->menu)) { + gtk_menu_popdown(GTK_MENU(self->priv->menu)); + gtk_menu_shell_deactivate(GTK_MENU_SHELL(self->priv->menu)); + return; + } + + /* Avoid opening an empty menu */ + children = gtk_container_get_children( + GTK_CONTAINER(hildon_appview_get_menu(self))); + if (children != NULL) { + GtkWidget *menu; + + g_list_free(children); + menu = GTK_WIDGET(hildon_appview_get_menu(self)); + if (self->priv->fullscreen) { + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, + (GtkMenuPositionFunc) + hildon_appview_menupopupfuncfull, + self, 0, button_event_time); + } else { + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, + (GtkMenuPositionFunc) + hildon_appview_menupopupfunc, + self, 0, button_event_time); + } + gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), TRUE); + } + +} + +/** + * _hildon_appview_menu_visible + * @self : A @HildonAppView + * + * Checks whether the titlebar menu is currently visible + * Return value : TRUE if the menu is visible, FALSE if not. + */ + +gboolean _hildon_appview_menu_visible(HildonAppView * self) +{ + g_return_val_if_fail (HILDON_IS_APPVIEW (self), FALSE); + + return GTK_WIDGET_VISIBLE(GTK_WIDGET(hildon_appview_get_menu(self))); +} + +/** + * hildon_appview_set_connected_adjustment + * @self : A @HildonAppView + * @adjustment : A new #GtkAdjustment set to reach to increase + * / decrease hardware keys or NULL to unset. + * + * Sets a #GtkAdjustment which will change when increase/decrease buttons + * are pressed. + **/ +void hildon_appview_set_connected_adjustment (HildonAppView * self, + GtkAdjustment * adjustment) +{ + g_return_if_fail (HILDON_IS_APPVIEW (self)); + + /* Disconnect old adjustment */ + if (self->priv->connected_adjustment != NULL) + g_object_remove_weak_pointer (G_OBJECT (self->priv->connected_adjustment), + (gpointer) &self->priv->connected_adjustment); + + /* Start using the new one */ + self->priv->connected_adjustment = adjustment; + if (self->priv->connected_adjustment != NULL) + g_object_add_weak_pointer (G_OBJECT (self->priv->connected_adjustment), + (gpointer) &self->priv->connected_adjustment); +} + +/** + * hildon_appview_get_connected_adjustment + * @self : A @HildonAppView + * + * Retrieves the @GtkAdjustment which is connected to this application view + * and is changed with increase / decrease hardware buttons. + * + * Return value: Currently connectd #GtkAdjustment assigned to this + * application view or NULL if it's not set. + **/ +GtkAdjustment * hildon_appview_get_connected_adjustment (HildonAppView * self) +{ + g_return_val_if_fail (HILDON_IS_APPVIEW (self), NULL); + + return self->priv->connected_adjustment; +} + + +/** + * hildon_appview_set_menu_ui + * @self : A @HildonAppView + * @ui_string : A @GtkUIManager ui description string + * + * Sets the ui description (xml) from which the UIManager creates menus + * (see @GtkUIManager for details on how to use it) + **/ +void hildon_appview_set_menu_ui(HildonAppView *self, const gchar *ui_string) +{ + g_return_if_fail (HILDON_IS_APPVIEW (self)); + + if (ui_string) + { + if (self->priv->menu_ui) + g_free (self->priv->menu_ui); + + self->priv->menu_ui = g_strdup (ui_string); + + /* FIXME: We should update the menu here, preferrably by a + * hildon_app_ensure_menu_update() which re-installs the menu ui + * and calls gtk_ui_manager_ensure_update() + */ + } + else + { + /* Reset the UI */ + if (self->priv->menu_ui) + { + g_free (self->priv->menu_ui); + self->priv->menu_ui = NULL; + } + } + + g_object_notify (G_OBJECT(self), "menu-ui"); +} + +/** + * hildon_appview_get_menu_ui + * @self : A @HildonAppView + * + * Sets the ui description (xml) from which the UIManager creates menus + * (see @GtkUIManager for details on how to use it) + * + * Return value: Currently set ui description + * + **/ +const gchar *hildon_appview_get_menu_ui(HildonAppView *self) +{ + g_return_val_if_fail (HILDON_IS_APPVIEW (self), NULL); + + return (self->priv->menu_ui); + +} + +/* Called when '+' hardkey is pressed/released */ +void _hildon_appview_increase_button_state_changed (HildonAppView * self, + guint newkeytype) +{ + self->priv->increase_button_pressed_down = newkeytype; + + /* Transform '+' press into adjustment update (usually scrollbar move) */ + if ((self->priv->connected_adjustment != NULL) && (newkeytype == GDK_KEY_PRESS)) + { + gfloat clampedvalue = CLAMP (gtk_adjustment_get_value (self->priv->connected_adjustment) + self->priv->connected_adjustment->step_increment, + self->priv->connected_adjustment->lower, + self->priv->connected_adjustment->upper - self->priv->connected_adjustment->page_size); + gtk_adjustment_set_value (self->priv->connected_adjustment, clampedvalue); + } + + g_signal_emit (G_OBJECT (self), appview_signals[INCREASE_BUTTON_EVENT], 0, newkeytype); +} + +/* Called when '-' hardkey is pressed/released */ +void _hildon_appview_decrease_button_state_changed (HildonAppView * self, + guint newkeytype) +{ + self->priv->decrease_button_pressed_down = newkeytype; + + /* Transform '-' press into adjustment update (usually scrollbar move) */ + if ((self->priv->connected_adjustment != NULL) && (newkeytype == GDK_KEY_PRESS)) + { + gfloat clampedvalue = CLAMP (gtk_adjustment_get_value (self->priv->connected_adjustment) - self->priv->connected_adjustment->step_increment, + self->priv->connected_adjustment->lower, + self->priv->connected_adjustment->upper - self->priv->connected_adjustment->page_size); + gtk_adjustment_set_value (self->priv->connected_adjustment, clampedvalue); + } + + g_signal_emit (G_OBJECT (self), appview_signals[DECREASE_BUTTON_EVENT], 0, newkeytype); +} diff --git a/hildon-widgets/hildon-appview.h b/hildon-widgets/hildon-appview.h new file mode 100644 index 0000000..79c7c7d --- /dev/null +++ b/hildon-widgets/hildon-appview.h @@ -0,0 +1,121 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + + +#ifndef HILDON_APPVIEW_H +#define HILDON_APPVIEW_H + +#include +#include +#include +#include +#include +#include + + +G_BEGIN_DECLS +#define HILDON_TYPE_APPVIEW ( hildon_appview_get_type() ) +#define HILDON_APPVIEW(obj) \ + (GTK_CHECK_CAST (obj, HILDON_TYPE_APPVIEW, HildonAppView)) +#define HILDON_APPVIEW_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass),\ + HILDON_TYPE_APPVIEW, HildonAppViewClass)) +#define HILDON_IS_APPVIEW(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_APPVIEW)) +#define HILDON_IS_APPVIEW_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_APPVIEW)) +typedef struct _HildonAppView HildonAppView; +typedef struct _HildonAppViewClass HildonAppViewClass; + +/** + * HildonAppViewPrivate: + * + * This structure contains just internal data. It should not + * be accessed directly. + */ +typedef struct _HildonAppViewPrivate HildonAppViewPrivate; + +struct _HildonAppView { + GtkBin parent; + + /*public*/ + GtkWidget *vbox; + + /*private*/ + HildonAppViewPrivate *priv; +}; + +struct _HildonAppViewClass { + GtkBinClass parent_class; + void (*toolbar_changed) (HildonAppView * self); + void (*toolbar_toggle_request) (HildonAppView * self); + void (*fullscreen_state_change) (HildonAppView * self, + gboolean is_fullscreen); + void (*title_change) (HildonAppView * self); + void (*switched_to) (HildonAppView * self); + void (*switched_from) (HildonAppView * self); + void (*increase_button_event) (HildonAppView * self, + guint newkeytype); + void (*decrease_button_event) (HildonAppView * self, + guint newkeytype); +}; + + +GType hildon_appview_get_type(void); +GtkWidget *hildon_appview_new(const gchar * title); +void hildon_appview_add_with_scrollbar(HildonAppView * self, + GtkWidget * child); +void hildon_appview_set_fullscreen_key_allowed(HildonAppView * self, + gboolean allow); +gboolean hildon_appview_get_fullscreen_key_allowed(HildonAppView * self); + +gboolean hildon_appview_get_fullscreen(HildonAppView * self); +void hildon_appview_set_fullscreen(HildonAppView * self, + gboolean fullscreen); +GtkMenu *hildon_appview_get_menu(HildonAppView * self); +#ifndef HILDON_DISABLE_DEPRECATED +void hildon_appview_set_toolbar(HildonAppView * self, + GtkToolbar * toolbar); +GtkToolbar *hildon_appview_get_toolbar(HildonAppView * self); +#endif +void hildon_appview_set_title(HildonAppView * self, const gchar * newname); +const gchar *hildon_appview_get_title(HildonAppView * self); + +void _hildon_appview_toggle_menu(HildonAppView * self, + Time button_event_time); +gboolean _hildon_appview_menu_visible(HildonAppView * self); + +void hildon_appview_set_connected_adjustment (HildonAppView * self, + GtkAdjustment * adjustment); +GtkAdjustment * hildon_appview_get_connected_adjustment (HildonAppView * self); + +void _hildon_appview_increase_button_state_changed (HildonAppView * self, + guint newkeytype); +void _hildon_appview_decrease_button_state_changed (HildonAppView * self, + guint newkeytype); + +void hildon_appview_set_menu_ui(HildonAppView *self, const gchar *ui_string); +const gchar *hildon_appview_get_menu_ui(HildonAppView *self); + +G_END_DECLS +#endif /* HILDON_APPVIEW_H */ diff --git a/hildon-widgets/hildon-caption.c b/hildon-widgets/hildon-caption.c new file mode 100644 index 0000000..0fd3e94 --- /dev/null +++ b/hildon-widgets/hildon-caption.c @@ -0,0 +1,1248 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hildon-caption.h" +#include "hildon-defines.h" + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#define _(String) dgettext(PACKAGE, String) + +#define HILDON_CAPTION_MANDATORY_ICON "qgn_list_gene_mandat_field" +#define HILDON_CAPTION_SPACING 6 + +#define HILDON_CAPTION_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + HILDON_TYPE_CAPTION, HildonCaptionPrivate)); + +/*our parent class*/ +static GtkEventBox *parent_class = NULL; + +typedef struct _HildonCaptionPrivate HildonCaptionPrivate; + +enum +{ + PROP_NONE, + PROP_LABEL, + PROP_ICON, + PROP_STATUS, + PROP_SEPARATOR, + PROP_SIZE_GROUP +}; + +enum +{ + CHILD_PROP_NONE, + CHILD_PROP_EXPAND +}; + +static void hildon_caption_class_init( HildonCaptionClass *caption_class ); +static void hildon_caption_init( HildonCaption *caption ); +static void hildon_caption_size_request( GtkWidget *widget, + GtkRequisition *requisition ); +static void hildon_caption_size_allocate( GtkWidget *widget, + GtkAllocation *allocation ); +static void hildon_caption_forall( GtkContainer *container, + gboolean include_internals, + GtkCallback callback, gpointer data ); +static void hildon_caption_hierarchy_changed( GtkWidget *widget, + GtkWidget *previous_toplevel); +static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget, + GtkWidget *caption ); +static void hildon_caption_activate( GtkWidget *widget ); + +static void hildon_caption_set_property( GObject *object, guint param_id, + const GValue *value, GParamSpec *pspec ); +static void hildon_caption_get_property( GObject *object, guint param_id, + GValue *value, GParamSpec *pspec ); +static gboolean hildon_caption_expose( GtkWidget *widget, + GdkEventExpose *event ); +static void hildon_caption_destroy( GtkObject *self ); +static gboolean hildon_caption_button_press( GtkWidget *widget, GdkEventButton *event ); +static void +hildon_caption_set_focus_child( GtkContainer *container, GtkWidget *child ); + +static void +hildon_caption_set_label_text( HildonCaptionPrivate *priv ); + +static void hildon_caption_set_child_property (GtkContainer *container, + GtkWidget *child, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void hildon_caption_get_child_property (GtkContainer *container, + GtkWidget *child, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void get_first_focusable_child ( GtkWidget *widget, gpointer data ); + +struct _HildonCaptionPrivate +{ + GtkWidget *caption_area; + GtkWidget *mandatory_icon; + GtkWidget *label; + GtkWidget *icon; + GtkWidget *icon_align; /* Arbitrary icon widgets do not support alignment */ + GtkSizeGroup *group; + gchar *text; + gchar *separator; + guint is_focused : 1; + guint activate_block : 1; + guint expand : 1; + HildonCaptionStatus status; +}; + +/* Register optional/manatory type enumeration */ +G_CONST_RETURN GType +hildon_caption_status_get_type (void) +{ + static GType etype = 0; + if (etype == 0) { + static const GEnumValue values[] = { + { HILDON_CAPTION_OPTIONAL, "HILDON_CAPTION_OPTIONAL", "optional" }, + { HILDON_CAPTION_MANDATORY, "HILDON_CAPTION_MANDATORY", "mandatory" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static ("HildonCaptionStatus", values); + } + return etype; +} + +/** + * hildon_caption_get_type: + * @Returns : GType of #HildonCaption. + * + * Initialises, and returns the type of a hildon caption. + */ +G_CONST_RETURN GType hildon_caption_get_type( void ) +{ + static GType caption_type = 0; + + if (!caption_type) + { + static const GTypeInfo caption_info = { + sizeof(HildonCaptionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) hildon_caption_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(HildonCaption), + 0, /* n_preallocs */ + (GInstanceInitFunc) hildon_caption_init, + }; + caption_type = g_type_register_static( GTK_TYPE_EVENT_BOX, + "HildonCaption", &caption_info, 0 ); + } + return caption_type; +} + +/* + * Initialises the caption class. + */ +static void hildon_caption_class_init( HildonCaptionClass *caption_class ) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(caption_class); + GObjectClass *gobject_class = G_OBJECT_CLASS(caption_class); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS(caption_class); + + parent_class = g_type_class_peek_parent( caption_class ); + + g_type_class_add_private( caption_class, sizeof(HildonCaptionPrivate) ); + + /* Override virtual functions */ + gobject_class->get_property = hildon_caption_get_property; + gobject_class->set_property = hildon_caption_set_property; + caption_class->activate = hildon_caption_activate; + GTK_OBJECT_CLASS(caption_class)->destroy = hildon_caption_destroy; + container_class->forall = hildon_caption_forall; + container_class->set_focus_child = hildon_caption_set_focus_child; + container_class->set_child_property = hildon_caption_set_child_property; + container_class->get_child_property = hildon_caption_get_child_property; + widget_class->expose_event = hildon_caption_expose; + widget_class->hierarchy_changed = hildon_caption_hierarchy_changed; + widget_class->size_request = hildon_caption_size_request; + widget_class->size_allocate = hildon_caption_size_allocate; + widget_class->button_press_event = hildon_caption_button_press; + + /* Create new signals and properties */ + widget_class->activate_signal = g_signal_new( "activate", + G_OBJECT_CLASS_TYPE( + gobject_class), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_ACTION, + G_STRUCT_OFFSET( HildonCaptionClass, + activate), NULL, NULL, + gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * HildonCaption:label: + * + * Caption label. + */ + g_object_class_install_property( gobject_class, PROP_LABEL, + g_param_spec_string("label", + "Current label", "Caption label", + NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) ); + + /** + * HildonCaption:icon: + * + * The icon shown on the caption area. + */ + g_object_class_install_property( gobject_class, PROP_ICON, + g_param_spec_object("icon", + "Current icon", + "The icon shown on the caption area", + GTK_TYPE_WIDGET, G_PARAM_READABLE | + G_PARAM_WRITABLE) ); + /** + * HildonCaption:status: + * + * Mandatory or optional status. + */ + g_object_class_install_property( gobject_class, PROP_STATUS, + g_param_spec_enum("status", + "Current status", + "Mandatory or optional status", + HILDON_TYPE_CAPTION_STATUS, + HILDON_CAPTION_OPTIONAL, + G_PARAM_READABLE | G_PARAM_WRITABLE) ); + /** + * HildonCaption:size_group: + * + * Current size group the caption is in. + */ + g_object_class_install_property( gobject_class, PROP_SIZE_GROUP, + g_param_spec_object("size_group", + "Current size group", + "Current size group the caption is in", + GTK_TYPE_SIZE_GROUP, G_PARAM_READABLE | + G_PARAM_WRITABLE) ); + + /** + * HildonCaption:separator: + * + * The current separator. + */ + g_object_class_install_property( gobject_class, PROP_SEPARATOR, + g_param_spec_string("separator", + "Current separator", "Current separator", + _("Ecdg_ti_caption_separator"), + G_PARAM_READABLE | G_PARAM_WRITABLE) ); + + /* Create child properties. These are related to + child <-> parent relationship, not to either of objects itself */ + gtk_container_class_install_child_property (container_class, + CHILD_PROP_EXPAND, + g_param_spec_boolean ("expand", + "Same as GtkBox expand.", + "Same as GtkBox expand. Wheter the child should be expanded or not.", + FALSE, + G_PARAM_READWRITE)); +} + +/* Destroy can be called multiple times, remember to set pointers to NULL */ +static void hildon_caption_destroy( GtkObject *self ) +{ + HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(self); + + /* Free our internal child */ + if( priv->caption_area ) + { + gtk_widget_unparent( priv->caption_area ); + priv->caption_area = NULL; + } + + /* Free user provided strings */ + if( priv->text ) + { + g_free( priv->text ); + priv->text = NULL; + } + if( priv->separator ) + { + g_free( priv->separator ); + priv->separator = NULL; + } + + /* Parent classes destroy takes care of user packed contents */ + if( GTK_OBJECT_CLASS(parent_class)->destroy ) + GTK_OBJECT_CLASS(parent_class)->destroy( self ); +} + +/* Parent, eventbox will run allocate also for the child which may be + * owning a window too. This window is then moved and resized and we do not + * want to do that -> It causes flickering. + * And just because we also want to + */ +static gboolean hildon_caption_expose( GtkWidget *widget, + GdkEventExpose *event ) +{ + HildonCaptionPrivate *priv = NULL; + GtkRequisition req; + GtkAllocation alloc; + gfloat align; + + g_return_val_if_fail( HILDON_IS_CAPTION(widget), TRUE ); + priv = HILDON_CAPTION_GET_PRIVATE(widget); + + if( !GTK_WIDGET_DRAWABLE(widget) ) + return FALSE; + + GTK_WIDGET_CLASS(parent_class)->expose_event( widget, event ); + + /* If our child control is focused, we draw nice looking focus + graphics for the caption */ + if ( priv->is_focused ) + { + /* Determine focus box dimensions */ + gtk_widget_get_child_requisition( priv->caption_area, &req ); + align = hildon_caption_get_label_alignment(HILDON_CAPTION(widget)); + + alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING; + alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height); + alloc.x = priv->caption_area->allocation.x; + alloc.y = priv->caption_area->allocation.y + + MAX(((priv->caption_area->allocation.height - alloc.height) * align), 0); + + /* Paint the focus box */ + gtk_paint_box( widget->style, widget->window, GTK_STATE_ACTIVE, + GTK_SHADOW_OUT, NULL, widget, "selection", + alloc.x, alloc.y, alloc.width, alloc.height ); + + /* Paint caption contents on top of the focus box */ + GTK_WIDGET_GET_CLASS(priv->caption_area)->expose_event( + priv->caption_area, event); + } + + return FALSE; +} + +static void hildon_caption_set_property( GObject *object, guint param_id, + const GValue *value, + GParamSpec *pspec ) +{ + HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object); + + switch( param_id ) + { + case PROP_LABEL: + + /* FIXME: This property setter is badly written. + * It does strange if (value) + * it calls queue_resize without reason? */ + if( priv->text ) + { + g_free( priv->text ); + priv->text = NULL; + } + + /* Update label */ + if( value ) + { + priv->text = g_strdup( g_value_get_string(value) ); + hildon_caption_set_label_text( priv ); + } + gtk_widget_queue_resize( GTK_WIDGET(object) ); + break; + + case PROP_ICON: + /* Remove old icon */ + if( priv->icon ) + gtk_container_remove( GTK_CONTAINER(priv->icon_align), priv->icon ); + + /* Pack and display new icon */ + priv->icon = g_value_get_object( value ); + if( priv->icon ) + { + gtk_container_add(GTK_CONTAINER(priv->icon_align), priv->icon); + gtk_widget_show_all( priv->caption_area ); + } + break; + + case PROP_STATUS: + priv->status = g_value_get_enum( value ); + + /* For mandatory fields we display a special icon */ + if( priv->status == HILDON_CAPTION_MANDATORY ) + { + if( !priv->mandatory_icon ) + { + gfloat align; + + /* Create mandatory icon */ + priv->mandatory_icon = gtk_image_new_from_icon_name( + HILDON_CAPTION_MANDATORY_ICON, + HILDON_ICON_SIZE_NOTE ); + + align = hildon_caption_get_label_alignment(HILDON_CAPTION(object)); + g_object_set(priv->mandatory_icon, "yalign", align, NULL); + + /* Pack and show mandatory icon */ + if( priv->mandatory_icon ) + { + gtk_box_pack_end( GTK_BOX(priv->caption_area), + priv->mandatory_icon, FALSE, FALSE, 0 ); + gtk_widget_show_all( priv->caption_area ); + } + } + } + else + { + if( priv->mandatory_icon ) + { + /* Remove mandatory icon */ + gtk_container_remove( GTK_CONTAINER(priv->caption_area), + priv->mandatory_icon ); + priv->mandatory_icon = NULL; + + /* FIXME: calls queue_draw without reason? */ + gtk_widget_queue_draw( GTK_WIDGET(object) ); + } + } + break; + + case PROP_SIZE_GROUP: + /* Detach from previous size group */ + if( priv->group ) + gtk_size_group_remove_widget( priv->group, priv->caption_area ); + + priv->group = g_value_get_object( value ); + + /* Attach to new size group */ + if( priv->group ) + gtk_size_group_add_widget( priv->group, priv->caption_area ); + gtk_widget_queue_draw( GTK_WIDGET(object) ); + break; + + case PROP_SEPARATOR: + + /* Free old separator */ + if( priv->separator ) + { + g_free( priv->separator ); + priv->separator = NULL; + } + + /* FIXME: Value cannot be NULL */ + if( value ) + { + priv->separator = g_strdup( g_value_get_string(value) ); + hildon_caption_set_label_text( priv ); + } + + /* FIXME: Do we really need to explicitly call this? */ + gtk_widget_queue_resize( GTK_WIDGET(object) ); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + break; + } +} + +static void hildon_caption_get_property( GObject *object, guint param_id, + GValue *value, GParamSpec *pspec ) +{ + HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object); + + switch (param_id) + { + case PROP_LABEL: + g_value_set_string( value, priv->text ); + break; + case PROP_ICON: + g_value_set_object( value, priv->icon ); + break; + case PROP_STATUS: + g_value_set_enum( value, priv->status ); + break; + case PROP_SIZE_GROUP: + g_value_set_object( value, priv->group ); + break; + case PROP_SEPARATOR: + g_value_set_string( value, priv->separator ); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + break; + } +} + +static void hildon_caption_set_child_property( GtkContainer *container, + GtkWidget *child, + guint property_id, + const GValue *value, + GParamSpec *pspec ) +{ + switch (property_id) + { + case CHILD_PROP_EXPAND: + hildon_caption_set_child_expand( HILDON_CAPTION(container), + g_value_get_boolean(value) ); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec); + break; + } +} + +static void hildon_caption_get_child_property( GtkContainer *container, + GtkWidget *child, + guint property_id, + GValue *value, + GParamSpec *pspec ) +{ + switch (property_id) + { + case CHILD_PROP_EXPAND: + g_value_set_boolean( value, hildon_caption_get_child_expand( + HILDON_CAPTION(container)) ); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec); + break; + } +} + +/* We want to activate out child control on button press */ +static gboolean hildon_caption_button_press( GtkWidget *widget, + GdkEventButton *event ) +{ + HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(widget); + + /* If child can take focus, we simply grab focus to it */ + if (GTK_WIDGET_CAN_FOCUS(GTK_BIN(widget)->child) && + GTK_WIDGET_IS_SENSITIVE(GTK_BIN(widget)->child)) + { + priv->is_focused = TRUE; + gtk_widget_grab_focus( GTK_BIN(widget)->child ); + } + /* Containers usually do not accept focus, but can contain focusable widgets */ + else if ( GTK_IS_CONTAINER(GTK_BIN(widget)->child) ) + { + GtkWidget *cwid= NULL; + + /* go through the children of the container for the first focusable children */ + /* FIXME: Can we somehow avoid this unintuitive looping. Something like + gtk_widget_child_focus ?? */ + gtk_container_forall (GTK_CONTAINER(GTK_BIN(widget)->child), (GtkCallback) get_first_focusable_child, &cwid ); + if (cwid) + { + priv->is_focused = TRUE; + gtk_widget_grab_focus( GTK_WIDGET(cwid) ); + } + } + + return FALSE; +} + +static void get_first_focusable_child ( GtkWidget *widget, gpointer data ) +{ + GtkWidget **child = (GtkWidget**)data; + + /* if a first child has already been found then do nothing */ + if (*child) return; + + if (GTK_WIDGET_CAN_FOCUS (widget) && + GTK_WIDGET_IS_SENSITIVE (widget)) + *child = widget; + else if (GTK_IS_CONTAINER(widget)) /* if the child is a container itself then go through them also /including/ internals */ + { + gtk_container_forall (GTK_CONTAINER(widget), get_first_focusable_child, child); + } +} + +static void hildon_caption_init( HildonCaption *caption ) +{ + HildonCaptionPrivate *priv = NULL; + g_return_if_fail( HILDON_IS_CAPTION(caption) ); + + /* Initialize startup state */ + priv = HILDON_CAPTION_GET_PRIVATE(caption); + priv->status = HILDON_CAPTION_OPTIONAL; + priv->icon = NULL; + priv->group = NULL; + priv->is_focused = FALSE; + + priv->separator = g_strdup(_("Ecdg_ti_caption_separator")); + + /* FIXME: We probably should use gtk_widget_set_composite_name as well */ + gtk_widget_push_composite_child(); + + /* Create caption text */ + priv->caption_area = gtk_hbox_new( FALSE, HILDON_CAPTION_SPACING ); + priv->label = gtk_label_new( NULL ); + priv->icon_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f); + + /* We want to receive button presses for child widget activation */ + gtk_event_box_set_above_child( GTK_EVENT_BOX(caption), FALSE ); + gtk_widget_add_events( GTK_WIDGET(caption), GDK_BUTTON_PRESS_MASK ); + + /* Pack text label caption layout */ + gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->icon_align, FALSE, FALSE, 0); + gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->label, FALSE, FALSE, 0 ); + gtk_widget_set_parent( priv->caption_area, GTK_WIDGET(caption) ); + + gtk_widget_pop_composite_child(); + + gtk_widget_show_all( priv->caption_area ); +} + +static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget, + GtkWidget *caption ) +{ + GtkWidget *win = GTK_WIDGET(window); + GtkWidget *tmp = widget; + HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption); + + /* Try to find caption among the ancestors of widget */ + /* FIXME: gtk_widget_get_ancestor */ + while( GTK_IS_WIDGET(tmp) && win != tmp ) + { + if( tmp == caption ) + { + /* Caption found, so it is now considered focused */ + priv->is_focused = TRUE; + gtk_widget_queue_draw( caption ); + return; + } + tmp = gtk_widget_get_parent( tmp ); + } + + if( priv->is_focused == TRUE ) + { + /* Caption wasn't found, so cannot focus */ + priv->is_focused = FALSE; + gtk_widget_queue_draw( caption ); + } +} + +/* FIXME: Is this function really needed at all? */ +static void +hildon_caption_set_focus_child( GtkContainer *container, GtkWidget *child ) +{ + GtkWidget *parent = gtk_widget_get_parent( GTK_WIDGET(container) ); + + GTK_CONTAINER_CLASS(parent_class)->set_focus_child( container, child ); + + if( parent && child != container->focus_child ) + gtk_container_set_focus_child( GTK_CONTAINER(parent), + GTK_WIDGET(container) ); +} + +/* We need to connect/disconnect signal handlers to toplevel window + in which we reside. Ww want to update connected signals if our + parent changes */ +static void hildon_caption_hierarchy_changed( GtkWidget *widget, + GtkWidget *previous_toplevel) +{ + GtkWidget *current_ancestor; + HildonCaptionPrivate *priv; + + g_return_if_fail( HILDON_IS_CAPTION(widget) ); + priv = HILDON_CAPTION_GET_PRIVATE(widget); + + if( GTK_WIDGET_CLASS(parent_class)->hierarchy_changed ) + GTK_WIDGET_CLASS(parent_class)->hierarchy_changed( widget, + previous_toplevel ); + + /* If we already were inside a window, remove old handler */ + if (previous_toplevel) { + /* This is a compilation workaround for gcc > 3.3 since glib is buggy */ + /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */ +#ifdef __GNUC__ + __extension__ +#endif + g_signal_handlers_disconnect_by_func + (previous_toplevel, (gpointer) hildon_caption_set_focus, widget); + } + current_ancestor = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); + + /* Install new handler for focus movement */ + if (current_ancestor) + g_signal_connect( current_ancestor, "set-focus", + G_CALLBACK(hildon_caption_set_focus), widget ); +} + +static void hildon_caption_size_request( GtkWidget *widget, + GtkRequisition *requisition ) +{ + GtkRequisition req; + HildonCaptionPrivate *priv = NULL; + g_return_if_fail( HILDON_IS_CAPTION(widget) ); + priv = HILDON_CAPTION_GET_PRIVATE(widget); + + /* Use the same size requisition for the main box of the caption */ + gtk_widget_size_request( priv->caption_area, &req ); + + if( GTK_WIDGET_CLASS(parent_class)->size_request ) + GTK_WIDGET_CLASS(parent_class)->size_request( widget, requisition ); + + /* Perform some useless calculations so that we can ignore the results <3 */ + requisition->width += req.width + HILDON_CAPTION_SPACING * 3; + + if( (req.height + (2 * widget->style->ythickness)) > requisition->height ) + requisition->height = req.height + (2 * widget->style->ythickness); +} + +/* We use HILDON_CAPTION_SPACING to make it look a bit nicer */ +static void hildon_caption_size_allocate( GtkWidget *widget, + GtkAllocation *allocation ) +{ + GtkAllocation allocA; + GtkAllocation allocB; + GtkRequisition req; + GtkWidget *child = NULL; + HildonCaptionPrivate *priv = NULL; + g_return_if_fail( HILDON_IS_CAPTION(widget) ); + priv = HILDON_CAPTION_GET_PRIVATE(widget); + + /* Position the caption to its allocated location */ + if( GTK_WIDGET_REALIZED(widget) ) + gdk_window_move_resize (widget->window, + allocation->x + GTK_CONTAINER (widget)->border_width, + allocation->y + GTK_CONTAINER (widget)->border_width, + MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0), + MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0)); + + child = GTK_BIN(widget)->child; + + widget->allocation = *allocation; + gtk_widget_get_child_requisition( priv->caption_area, &req ); + + allocA.height = allocB.height = allocation->height; + allocA.width = allocB.width = allocation->width; + allocA.x = allocB.x = allocB.y = allocA.y = 0; + + /* Center the captioned widget */ + if( allocA.width > req.width + HILDON_CAPTION_SPACING ) + { + allocA.x += req.width + HILDON_CAPTION_SPACING * 2; + allocB.width = req.width; + } + + /* Leave room for the other drawable parts of the caption control */ + allocA.width -= req.width + HILDON_CAPTION_SPACING * 2; + + /* Give the child at least its minimum requisition, unless it is expandable */ + if( !priv->expand && child && GTK_WIDGET_VISIBLE(child) ) + { + GtkRequisition child_req; + gtk_widget_get_child_requisition( child, &child_req ); + allocA.width = MIN( allocA.width, child_req.width ); + allocA.height = MIN( allocA.height, child_req.height ); + } + + /* Ensure there are no negative dimensions */ + if( allocA.width < 0 ) + { + allocB.width = req.width + allocA.width; + allocA.width = 0; + allocB.width = MAX (allocB.width, 0); + } + + allocA.height = MAX (allocA.height, 0); + allocB.height = MAX (allocB.height, 0); + + if (child && GTK_WIDGET_VISIBLE(child) ) + gtk_widget_size_allocate( child, &allocA ); + gtk_widget_size_allocate( priv->caption_area, &allocB ); +} + +static void hildon_caption_forall( GtkContainer *container, + gboolean include_internals, + GtkCallback callback, gpointer data ) +{ + HildonCaptionPrivate *priv = NULL; + g_return_if_fail( HILDON_IS_CAPTION(container) ); + priv = HILDON_CAPTION_GET_PRIVATE(container); + + /* Execute callback for the child widgets */ + if( GTK_CONTAINER_CLASS(parent_class)->forall ) + GTK_CONTAINER_CLASS(parent_class)->forall( container, include_internals, + callback, data ); + + if( include_internals ) + /* Execute callback for the parent box as well */ + (*callback)( priv->caption_area, data ); +} + + +/** + * hildon_caption_set_sizegroup: + * @caption : A #HildonCaption + * @new_group : A #GtkSizeGroup + * + * Sets a #GtkSizeGroup of a given captioned control. + * + * Deprecated: Use g_object_set, property "size_group". + */ +#ifndef HILDON_DISABLE_DEPRECATED +void hildon_caption_set_sizegroup( const HildonCaption *self, + GtkSizeGroup *group ) +{ + g_object_set( G_OBJECT(self), "size_group", group, NULL ); +} +#endif +/** + * hildon_caption_get_sizegroup: + * @caption : A #HildonCaption + * @Returns : A #GtkSizeGroup + * + * Query given captioned control for the #GtkSizeGroup assigned to it. + * + * Deprecated: Use g_object_get, property "size_group". + */ +#ifndef HILDON_DISABLE_DEPRECATED +GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *self ) +{ + HildonCaptionPrivate *priv; + g_return_val_if_fail( HILDON_IS_CAPTION (self), NULL ); + priv = HILDON_CAPTION_GET_PRIVATE(self); + return priv->group; +} +#endif +/** + * hildon_caption_new: + * @group : a #GtkSizeGroup for controlling the size of related captions. + * Can be NULL. + * @value : the caption text to accompany the text entry. The widget makes + * a copy of this text. + * @control : the control that is to be captioned + * @icon : an icon to accompany the label - can be NULL in which case no + * icon is displayed + * @flag : indicates whether this captioned control is mandatory or + * optional. + * @returns : A #GtkWidget pointer of Caption + * + * Creates a new instance of hildon_caption widget, with a specific + * control and image. + * Note: Clicking on a focused caption will trigger the activate signal. + * The default behaviour for the caption's activate signal is to call + * gtk_widget_activate on it's control. + */ +GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value, + GtkWidget *control, GtkWidget *icon, + HildonCaptionStatus flag) +{ + GtkWidget *widget; + g_return_val_if_fail( GTK_IS_WIDGET(control), NULL ); + + widget = g_object_new( HILDON_TYPE_CAPTION, "label", value, + "size_group", group, "icon", icon, "status", flag, + NULL ); + + /* Pack the captioned widget */ + hildon_caption_set_child_expand( HILDON_CAPTION(widget), TRUE ); + gtk_container_add( GTK_CONTAINER(widget), control ); + + + return widget; +} + +/** + * hildon_caption_is_mandatory: + * @caption : A #HildonCaption + * @returns : is this captioned control a mandatory one? + * + * Query #HildonCaption whether this captioned control is a mandatory one. + * + */ + +gboolean hildon_caption_is_mandatory( const HildonCaption *caption ) +{ + HildonCaptionPrivate *priv; + g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE ); + priv = HILDON_CAPTION_GET_PRIVATE(caption); + + return priv->status == HILDON_CAPTION_MANDATORY; +} + +/** + * hildon_caption_set_status: + * @caption : A #HildonCaption + * @flag : one of the values from #HildonCaptionStatus + * + * Sets #HildonCaption status. + * + + */ + +void hildon_caption_set_status( HildonCaption *caption, + HildonCaptionStatus flag ) +{ + g_object_set( G_OBJECT(caption), "status", flag, NULL ); +} + +/** + * hildon_caption_get_status: + * @caption : A #HildonCaption + * @returns : one of the values from #HildonCaptionStatus + * + * Gets #HildonCaption status. + * + */ + +HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption ) +{ + HildonCaptionPrivate *priv; + g_return_val_if_fail( HILDON_IS_CAPTION(caption), HILDON_CAPTION_OPTIONAL ); + priv = HILDON_CAPTION_GET_PRIVATE(caption); + + return priv->status; +} + +/** + * hildon_caption_set_icon_image: + * @caption : A #HildonCaption + * @icon : the #GtkImage to use as the icon. + * calls gtk_widget_show on the icon if !GTK_WIDGET_VISIBLE(icon) + * + * Sets the icon to be used by this hildon_caption widget. + * + */ + +void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon ) +{ + g_object_set( G_OBJECT(caption), "icon", icon, NULL ); +} + +/** + * hildon_caption_get_icon_image: + * @caption : A #HildonCaption + * @returns : the #GtkImage that is being used as the icon by the + * hildon_caption, or NULL if no icon is in use. + * + * Gets icon of #HildonCaption + * + */ + +GtkWidget *hildon_caption_get_icon_image( const HildonCaption *caption ) +{ + HildonCaptionPrivate *priv; + g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL ); + priv = HILDON_CAPTION_GET_PRIVATE(caption); + + return priv->icon; +} + +/** + * hildon_caption_set_label: + * @caption : A #HildonCaption + * @label : the text to use + * + * Sets the label text that appears before the control. + * Separator character is added to the end of the label string. By default + * the separator is ":". + * + */ + +void hildon_caption_set_label( HildonCaption *caption, const gchar *label ) +{ + g_object_set( G_OBJECT(caption), "label", label, NULL ); +} + +/** + * hildon_caption_get_label: + * @caption : A #HildonCaption + * @returns : the text currently being used as the label of the caption + * control. The string is owned by the label and the caller should never free or + * modify this value. + * + * Gets label of #HildonCaption + * + */ + +gchar *hildon_caption_get_label( const HildonCaption *caption ) +{ + HildonCaptionPrivate *priv; + g_return_val_if_fail(HILDON_IS_CAPTION(caption), ""); + priv = HILDON_CAPTION_GET_PRIVATE(caption); + + return (gchar*)gtk_label_get_text(GTK_LABEL(GTK_LABEL(priv->label))); +} + +/** + * hildon_caption_set_separator: + * @caption : A #HildonCaption + * @separator : the separator to use + * + * Sets the separator character that appears after the label. + * The default seaparator character is ":" + * separately. + * + + */ + +void hildon_caption_set_separator( HildonCaption *caption, + const gchar *separator ) +{ + g_object_set( G_OBJECT(caption), "separator", separator, NULL ); +} + +/** + * hildon_caption_get_separator: + * @caption : A #HildonCaption + * @returns : the text currently being used as the separator of the caption + * control. The string is owned by the caption control and the caller should + * never free or modify this value. + * + * Gets separator string of #HildonCaption + * + */ + +gchar *hildon_caption_get_separator( const HildonCaption *caption ) +{ + HildonCaptionPrivate *priv; + g_return_val_if_fail(HILDON_IS_CAPTION(caption), ""); + priv = HILDON_CAPTION_GET_PRIVATE(caption); + + return priv->separator; +} + + +/** + * hildon_caption_get_control: + * @caption : A #HildonCaption + * @returns : A #GtkWidget + * + * Gets caption's control. + * + * Deprecated: use gtk_bin_get_child instead + */ +#ifndef HILDON_DISABLE_DEPRECATED +GtkWidget *hildon_caption_get_control( const HildonCaption *caption ) +{ + g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL ); + return GTK_BIN(caption)->child; +} +#endif +/*activates the child control + *We have this signal so that if needed an application can + *know when we've been activated (useful for captions with + *multiple children + */ +static void hildon_caption_activate( GtkWidget *widget ) +{ + HildonCaptionPrivate *priv; + GtkWidget *child = GTK_BIN(widget)->child; + priv = HILDON_CAPTION_GET_PRIVATE(widget); + + /* FIXME: This seems to be related to some functionality + that is already removed? */ + if( priv->activate_block ) + { + priv->is_focused = FALSE; + return; + } + + if( child ) + { + priv->activate_block = TRUE; + gtk_widget_grab_focus( child ); + } +} + +/** + * hildon_caption_set_child_expand: + * @caption : A #HildonCaption + * @expand : gboolean to determine is the child expandable + * + * Sets child expandability. + */ +void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand ) +{ + HildonCaptionPrivate *priv = NULL; + GtkWidget *child = NULL; + g_return_if_fail( HILDON_IS_CAPTION(caption) ); + + priv = HILDON_CAPTION_GET_PRIVATE(caption); + + /* Did the setting really change? */ + if( priv->expand == expand ) + return; + + priv->expand = expand; + child = GTK_BIN(caption)->child; + + /* We do not have a child, nothing to do */ + if( !GTK_IS_WIDGET(child) ) + return; + + if( GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (caption) ) + gtk_widget_queue_resize( child ); + + gtk_widget_child_notify( child, "expand" ); +} + +/** + * hildon_caption_get_child_expand: + * @caption : A #HildonCaption + * @returns : Wheter the child is expandable or not. + * + * Gets childs expandability. + */ +gboolean hildon_caption_get_child_expand( HildonCaption *caption ) +{ + HildonCaptionPrivate *priv = NULL; + g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE ); + priv = HILDON_CAPTION_GET_PRIVATE(caption); + return priv->expand; +} + +/** + * hildon_caption_set_control: + * @caption : A #HildonCaption + * @control : The control to use. Control should not be NULL. + * + * Sets the control of the caption. + * The old control will be destroyed, unless the caller has added a + * reference to it. + * Function unparents the old control (if there is one) and adds the new + * control. + * + * Deprecated: Use gtk_container_add. + */ +#ifndef HILDON_DISABLE_DEPRECATED +void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control ) +{ + GtkWidget *child = NULL; + g_return_if_fail( HILDON_IS_CAPTION(caption) ); + child = GTK_BIN(caption)->child; + + if( child ) + gtk_container_remove( GTK_CONTAINER(caption), child ); + + if( control ) + { + gtk_container_add( GTK_CONTAINER(caption), control ); + child = control; + } + else + child = NULL; +} +#endif + +static void +hildon_caption_set_label_text( HildonCaptionPrivate *priv ) +{ + gchar *tmp = NULL; + g_return_if_fail ( priv != NULL ); + + if ( priv->text ) + { + if( priv->separator ) + { + /* Don't duplicate the separator, if the string already contains one */ + /* FIXME: The separator was taken from translations originally, it's not + safe to assume that to be a certain constant. */ + if( !strcmp( priv->separator, ":" ) && + priv->text [strlen ( priv->text ) - 1] == ':') + { + gtk_label_set_text( GTK_LABEL( priv->label ), priv->text ); + } + else + { + /* Append separator and set text */ + tmp = g_strconcat( priv->text, priv->separator, NULL ); + gtk_label_set_text( GTK_LABEL( priv->label ), tmp ); + g_free( tmp ); + } + } + else + { + gtk_label_set_text( GTK_LABEL( priv->label ), priv->text ); + } + } + else + { + /* Clear the label */ + gtk_label_set_text( GTK_LABEL( priv->label ), "" ); + } + +} + +/** + * hildon_caption_set_label_alignment: + * @caption: a #HildonCaption widget. + * @alignment: new vertical alignment. + * + * Sets the vertical alignment to be used for the + * text part of the caption. Applications need to + * align the child control themselves. + */ +void hildon_caption_set_label_alignment(HildonCaption *caption, + gfloat alignment) +{ + HildonCaptionPrivate *priv; + + g_return_if_fail(HILDON_IS_CAPTION(caption)); + + priv = HILDON_CAPTION_GET_PRIVATE(caption); + g_object_set(priv->label, "yalign", alignment, NULL); + g_object_set(priv->icon_align, "yalign", alignment, NULL); + + if (priv->mandatory_icon) + g_object_set(priv->mandatory_icon, "yalign", alignment, NULL); +} + +/** + * hildon_caption_get_label_alignment: + * @caption: a #HildonCaption widget. + * + * Gets current vertical alignment for the text part. + * + * Returns: vertical alignment. + */ +gfloat hildon_caption_get_label_alignment(HildonCaption *caption) +{ + HildonCaptionPrivate *priv; + gfloat result; + + g_return_val_if_fail( HILDON_IS_CAPTION(caption), 0); + priv = HILDON_CAPTION_GET_PRIVATE(caption); + g_object_get(priv->label, "yalign", &result, NULL); + + return result; +} diff --git a/hildon-widgets/hildon-caption.h b/hildon-widgets/hildon-caption.h new file mode 100644 index 0000000..b0669bf --- /dev/null +++ b/hildon-widgets/hildon-caption.h @@ -0,0 +1,131 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __HILDON_CAPTION_H__ +#define __HILDON_CAPTION_H__ + +#include +#include +#include +#include + +G_BEGIN_DECLS + + +#define HILDON_TYPE_CAPTION ( hildon_caption_get_type() ) +#define HILDON_CAPTION(obj) \ + (GTK_CHECK_CAST (obj, HILDON_TYPE_CAPTION, HildonCaption)) +#define HILDON_CAPTION_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass),\ + HILDON_TYPE_CAPTION, HildonCaptionClass)) +#define HILDON_IS_CAPTION(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_CAPTION)) +#define HILDON_IS_CAPTION_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_CAPTION)) + + +/** + * HildonCaptionStatus: + * @HILDON_CAPTION_OPTIONAL: Optional. + * @HILDON_CAPTION_MANDATORY: Mandatory. + * + * Keys to set the #HildonCaption to be optional or mandatory. + */ +typedef enum { + HILDON_CAPTION_OPTIONAL = 0, + HILDON_CAPTION_MANDATORY +} HildonCaptionStatus; + +#define HILDON_TYPE_CAPTION_STATUS (hildon_caption_status_get_type ()) + +G_CONST_RETURN GType hildon_caption_status_get_type (void); + +/** + * HildonCaption: + * + * Contains only private data. + */ +typedef struct _HildonCaption HildonCaption; +typedef struct _HildonCaptionClass HildonCaptionClass; + + +struct _HildonCaption +{ + GtkEventBox event_box; +}; + + +struct _HildonCaptionClass +{ + GtkEventBoxClass parent_class; + void (*activate) (GtkWidget *widget); +}; + + +G_CONST_RETURN GType hildon_caption_get_type( void ); + +GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value, + GtkWidget *control, GtkWidget *icon, + HildonCaptionStatus flag ); +#ifndef HILDON_DISABLE_DEPRECATED +GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *caption ); + +void hildon_caption_set_sizegroup( const HildonCaption *caption, + GtkSizeGroup *new_group ); +#endif + +gboolean hildon_caption_is_mandatory( const HildonCaption *caption ); + +void hildon_caption_set_status( HildonCaption *caption, + HildonCaptionStatus flag ); + +HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption ); + +void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon ); + +GtkWidget *hildon_caption_get_icon_image(const HildonCaption *caption); + +void hildon_caption_set_label( HildonCaption *caption, const gchar *label ); + +gchar *hildon_caption_get_label( const HildonCaption *caption ); + +void hildon_caption_set_separator( HildonCaption *caption, + const gchar *separator ); + +gchar *hildon_caption_get_separator( const HildonCaption *caption ); + +void hildon_caption_set_label_alignment(HildonCaption *caption, + gfloat alignment); +gfloat hildon_caption_get_label_alignment(HildonCaption *caption); + +#ifndef HILDON_DISABLE_DEPRECATED +GtkWidget *hildon_caption_get_control( const HildonCaption *caption ); + +void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control ); +#endif + +void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand ); +gboolean hildon_caption_get_child_expand( HildonCaption *caption ); + +G_END_DECLS +#endif /* __HILDON_CAPTION_H__ */ diff --git a/hildon-widgets/hildon-defines.c b/hildon-widgets/hildon-defines.c new file mode 100644 index 0000000..11285e0 --- /dev/null +++ b/hildon-widgets/hildon-defines.c @@ -0,0 +1,233 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include "hildon-defines.h" + +HildonIconSizes *hildoniconsizes = NULL; /* FIXME: could be const */ +HildonIconSizes hildoninternaliconsizes; /* FIXME: should be static */ + +/** + * hildon_icon_sizes_init: + * + * Initializes the icon sizes. This is automatically + * called when the icon sizes have not been initialized + * and one is requested. + **/ +void hildon_icon_sizes_init (void) +{ + if (hildoniconsizes != NULL) + return; + + hildoniconsizes = &hildoninternaliconsizes; + + hildoniconsizes->icon_size_list = gtk_icon_size_register ("hildon_icon_size_list", 64, 64); + hildoniconsizes->icon_size_small = gtk_icon_size_register ("*icon_size_small", 26, 26); + hildoniconsizes->icon_size_toolbar = gtk_icon_size_register ("icon_size_toolbar", 26, 26); + hildoniconsizes->icon_size_widg = gtk_icon_size_register ("icon_size_widg", 26, 26); + hildoniconsizes->icon_size_widg_wizard = gtk_icon_size_register ("icon_size_widg_wizard", 50, 50); + hildoniconsizes->icon_size_grid = gtk_icon_size_register ("icon_size_grid", 64, 64); + hildoniconsizes->icon_size_big_note = gtk_icon_size_register ("icon_size_big_note", 50, 50); + hildoniconsizes->icon_size_note = gtk_icon_size_register ("icon_size_note", 26, 26); + hildoniconsizes->icon_size_statusbar = gtk_icon_size_register ("icon_size_statusbar", 40, 40); + hildoniconsizes->icon_size_indi_video_player_pre_roll = gtk_icon_size_register ("icon_size_indi_video_player_pre_roll", 64, 64); + hildoniconsizes->icon_size_indi_key_pad_lock = gtk_icon_size_register ("icon_size_indi_key_pad_lock", 50, 50); + hildoniconsizes->icon_size_indi_copy = gtk_icon_size_register ("icon_size_indi_copy", 64, 64); + hildoniconsizes->icon_size_indi_delete = gtk_icon_size_register ("icon_size_indi_delete", 64, 64); + hildoniconsizes->icon_size_indi_process = gtk_icon_size_register ("icon_size_indi_process", 64, 64); + hildoniconsizes->icon_size_indi_progressball = gtk_icon_size_register ("icon_size_indi_progressball", 64, 64); + hildoniconsizes->icon_size_indi_send = gtk_icon_size_register ("icon_size_indi_send", 64, 64); + hildoniconsizes->icon_size_indi_offmode_charging = gtk_icon_size_register ("icon_size_indi_offmode_charging", 50, 50); + hildoniconsizes->icon_size_indi_tap_and_hold = gtk_icon_size_register ("icon_size_indi_tap_and_hold", 34, 34); + hildoniconsizes->icon_size_indi_send_receive = gtk_icon_size_register ("icon_size_indi_send_receive", 64, 64); + hildoniconsizes->icon_size_indi_wlan_strength = gtk_icon_size_register ("icon_size_indi_wlan_strength", 64, 64); + + hildoniconsizes->image_size_indi_nokia_logo = gtk_icon_size_register ("image_size_indi_nokia_logo", 64, 64); + hildoniconsizes->image_size_indi_startup_failed = gtk_icon_size_register ("image_size_indi_startup_failed", 64, 64); + hildoniconsizes->image_size_indi_startup_nokia_logo = gtk_icon_size_register ("image_size_indi_startup_nokia_logo", 64, 64); + hildoniconsizes->image_size_indi_nokia_hands = gtk_icon_size_register ("image_size_indi_nokia_hands", 64, 64); +} + +typedef struct _HildonLogicalData HildonLogicalData; + +struct _HildonLogicalData +{ + GtkRcFlags rcflags; + GtkStateType state; + gchar *logicalcolorstring; + gchar *logicalfontstring; +}; + + +static void hildon_change_style_recursive_from_ld (GtkWidget *widget, GtkStyle *prev_style, HildonLogicalData *ld) +{ + /* Change the style for child widgets */ + if (GTK_IS_CONTAINER (widget)) + gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) (hildon_change_style_recursive_from_ld), ld); + + /* gtk_widget_modify_*() emit "style_set" signals, so if we got here from + "style_set" signal, we need to block this function from being called + again or we get into inifinite loop. + + Compiling with gcc > 3.3 and -pedantic won't allow conversion between + function and object pointers. GLib API however requires an object pointer + for a function, so we have to work around this. See + see http://bugzilla.gnome.org/show_bug.cgi?id=310175 + + FIXME: Use G_GNUC_EXTENSION instead of our own ifdef + */ +#ifdef __GNUC__ + __extension__ +#endif + g_signal_handlers_block_matched (G_OBJECT (widget), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC, + g_signal_lookup ("style_set", G_TYPE_FROM_INSTANCE (widget)), + 0, NULL, + (gpointer) hildon_change_style_recursive_from_ld, + NULL); + + if (ld->logicalcolorstring != NULL) + { + /* Changing logical color */ + GdkColor color; + if (gtk_style_lookup_logical_color (widget->style, ld->logicalcolorstring, &color) == TRUE) + switch (ld->rcflags) + { + case GTK_RC_FG: + gtk_widget_modify_fg (widget, ld->state, &color); + break; + case GTK_RC_BG: + gtk_widget_modify_bg (widget, ld->state, &color); + break; + case GTK_RC_TEXT: + gtk_widget_modify_text (widget, ld->state, &color); + break; + case GTK_RC_BASE: + gtk_widget_modify_base (widget, ld->state, &color); + break; + } + } + + if (ld->logicalfontstring != NULL) + { + /* Changing logical font */ + GtkStyle *fontstyle = gtk_rc_get_style_by_paths (gtk_settings_get_default (), ld->logicalfontstring, NULL, G_TYPE_NONE); + if (fontstyle != NULL) + { + PangoFontDescription *fontdesc = fontstyle->font_desc; + + if (fontdesc != NULL) + gtk_widget_modify_font (widget, fontdesc); + } + } + + + /* Compilation workaround for gcc > 3.3 + -pedantic again */ +#ifdef __GNUC__ + __extension__ +#endif + g_signal_handlers_unblock_matched (G_OBJECT (widget), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC, + g_signal_lookup ("style_set", G_TYPE_FROM_INSTANCE (widget)), + 0, NULL, + (gpointer) hildon_change_style_recursive_from_ld, + NULL); +} + +/** + * hildon_gtk_widget_set_logical_font: + * @widget : A @GtkWidget to assign this logical font for. + * @logicalfontname : A gchar* with the logical font name to assign to the widget with an "osso-" -prefix. + * + * This function assigns a defined logical font to the @widget and all its child widgets. + * It also connects to the "style_set" signal which will retrieve & assign the new font for the given logical name each time the theme is changed. + * The returned signal id can be used to disconnect the signal. + * + * Return value : The signal id that is triggered every time theme is changed. 0 if font set failed. + **/ +gulong hildon_gtk_widget_set_logical_font (GtkWidget *widget, gchar *logicalfontname) +{ + HildonLogicalData *ld; + gulong signum = 0; + + g_return_val_if_fail (GTK_IS_WIDGET (widget), 0); + g_return_val_if_fail (logicalfontname != NULL, 0); + + ld = g_malloc (sizeof (HildonLogicalData)); + + ld->rcflags = 0; + ld->state = 0; + ld->logicalcolorstring = NULL; + ld->logicalfontstring = logicalfontname; /* FIXME: g_strdup() */ + + /* Change the font now */ + hildon_change_style_recursive_from_ld (widget, NULL, ld); + + /* Connect to "style_set" so that the font gets changed whenever theme + changes. FIXME: if this function is called multiple times, the old signal + handler should be disconnected */ + signum = g_signal_connect_data (G_OBJECT (widget), "style_set", G_CALLBACK (hildon_change_style_recursive_from_ld), ld, (GClosureNotify) g_free, 0); + + return signum; +} + +/** + * hildon_gtk_widget_set_logical_color: + * @widget : A @GtkWidget to assign this logical font for. + * @rcflags : @GtkRcFlags enumeration defining whether to assign to FG, BG, TEXT or BASE style. + * @state : @GtkStateType indicating to which state to assign the logical color + * @logicalcolorname : A gchar* with the logical font name to assign to the widget. + * + * This function assigns a defined logical color to the @widget and all it's child widgets. + * It also connects to the "style_set" signal which will retrieve & assign the new color for the given logical name each time the theme is changed. + * The returned signal id can be used to disconnect the signal. + * + * Example : If the style you want to modify is bg[NORMAL] then set rcflags to GTK_RC_BG and state to GTK_STATE_NORMAL. + * + * Return value : The signal id that is triggered every time theme is changed. 0 if color set failed. + **/ +gulong hildon_gtk_widget_set_logical_color (GtkWidget *widget, GtkRcFlags rcflags, + GtkStateType state, gchar *logicalcolorname) +{ + HildonLogicalData *ld; + gulong signum = 0; + + g_return_val_if_fail (GTK_IS_WIDGET (widget), 0); + g_return_val_if_fail (logicalcolorname != NULL, 0); + + ld = g_malloc (sizeof (HildonLogicalData)); + + ld->rcflags = rcflags; + ld->state = state; + ld->logicalcolorstring = logicalcolorname; /* FIXME: g_strdup() */ + ld->logicalfontstring = NULL; + + /* Change the colors now */ + hildon_change_style_recursive_from_ld (widget, NULL, ld); + + /* Connect to "style_set" so that the colors gets changed whenever theme + changes. FIXME: if this function is called multiple times, the old signal + handler should be disconnected */ + signum = g_signal_connect_data (G_OBJECT (widget), "style_set", G_CALLBACK (hildon_change_style_recursive_from_ld), ld, (GClosureNotify) g_free, 0); + + return signum; +} diff --git a/hildon-widgets/hildon-defines.h b/hildon-widgets/hildon-defines.h new file mode 100644 index 0000000..db424ab --- /dev/null +++ b/hildon-widgets/hildon-defines.h @@ -0,0 +1,142 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __HILDON_DEFINES_H__ +#define __HILDON_DEFINES_H__ + +#include +#include "hildon-appview.h" + +G_BEGIN_DECLS + +void hildon_icon_sizes_init (void); + +typedef struct _HildonIconSizes HildonIconSizes; + +struct _HildonIconSizes +{ + GtkIconSize icon_size_list; + GtkIconSize icon_size_small; + GtkIconSize icon_size_toolbar; + GtkIconSize icon_size_widg; + GtkIconSize icon_size_widg_wizard; + GtkIconSize icon_size_grid; + GtkIconSize icon_size_big_note; + GtkIconSize icon_size_note; + GtkIconSize icon_size_statusbar; + GtkIconSize icon_size_indi_video_player_pre_roll; + GtkIconSize icon_size_indi_key_pad_lock; + GtkIconSize icon_size_indi_copy; + GtkIconSize icon_size_indi_delete; + GtkIconSize icon_size_indi_process; + GtkIconSize icon_size_indi_progressball; + GtkIconSize icon_size_indi_send; + GtkIconSize icon_size_indi_offmode_charging; + GtkIconSize icon_size_indi_tap_and_hold; + GtkIconSize icon_size_indi_send_receive; + GtkIconSize icon_size_indi_wlan_strength; + GtkIconSize image_size_indi_nokia_logo; + GtkIconSize image_size_indi_startup_failed; + GtkIconSize image_size_indi_startup_nokia_logo; + GtkIconSize image_size_indi_nokia_hands; +}; + +extern HildonIconSizes *hildoniconsizes; + +#define HILDON_ICON_SIZE_CHECK_AND_GET(iconvar) (!hildoniconsizes ? hildon_icon_sizes_init (), hildoniconsizes->iconvar : hildoniconsizes->iconvar) + +#define HILDON_ICON_SIZE_LIST HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_list) +#define HILDON_ICON_SIZE_SMALL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_small) +#define HILDON_ICON_SIZE_TOOLBAR HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_toolbar) +#define HILDON_ICON_SIZE_WIDG HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_widg) +#define HILDON_ICON_SIZE_WIDG_WIZARD HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_widg_wizard) +#define HILDON_ICON_SIZE_GRID HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_grid) +#define HILDON_ICON_SIZE_BIG_NOTE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_big_note) +#define HILDON_ICON_SIZE_NOTE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_note) +#define HILDON_ICON_SIZE_STATUSBAR HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_statusbar) +#define HILDON_ICON_SIZE_INDI_VIDEO_PLAYER_PRE_ROLL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_video_player_pre_roll) +#define HILDON_ICON_SIZE_INDI_COPY HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_copy) +#define HILDON_ICON_SIZE_INDI_DELETE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_delete) +#define HILDON_ICON_SIZE_INDI_PROCESS HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_process) +#define HILDON_ICON_SIZE_INDI_PROGRESSBALL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_progressball) +#define HILDON_ICON_SIZE_INDI_SEND HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_send) +#define HILDON_ICON_SIZE_INDI_OFFMODE_CHARGING HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_offmode) +#define HILDON_ICON_SIZE_INDI_TAP_AND_HOLD HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_tap_and_hold) +#define HILDON_ICON_SIZE_INDI_SEND_RECEIVE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_send_receive) +#define HILDON_ICON_SIZE_INDI_WLAN_STRENGTH HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_wlan_strength) + +#define HILDON_IMAGE_SIZE_INDI_NOKIA_LOGO HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_nokia_logo) +#define HILDON_IMAGE_SIZE_INDI_STARTUP_FAILED HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_startup_nokia_failed) +#define HILDON_IMAGE_SIZE_INDI_STARTUP_NOKIA_LOGO HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_startup_nokia_logo) +#define HILDON_IMAGE_SIZE_INDI_NOKIA_HAND HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_nokia_hands) + +#define HILDON_ICON_PIXEL_SIZE_LIST 64 +#define HILDON_ICON_PIXEL_SIZE_SMALL 26 +#define HILDON_ICON_PIXEL_SIZE_TOOLBAR 26 +#define HILDON_ICON_PIXEL_SIZE_WIDG 26 +#define HILDON_ICON_PIXEL_SIZE_WIDG_WIZARD 50 +#define HILDON_ICON_PIXEL_SIZE_GRID 64 +#define HILDON_ICON_PIXEL_SIZE_BIG_NOTE 50 +#define HILDON_ICON_PIXEL_SIZE_NOTE 26 +#define HILDON_ICON_PIXEL_SIZE_STATUSBAR 40 +#define HILDON_ICON_PIXEL_SIZE_INDI_VIDEO_PLAYER_PRE_ROLL 64 +#define HILDON_ICON_PIXEL_SIZE_INDI_KEY_PAD_LOCK 50 +#define HILDON_ICON_PIXEL_SIZE_INDI_COPY 64 +#define HILDON_ICON_PIXEL_SIZE_INDI_DELETE 64 +#define HILDON_ICON_PIXEL_SIZE_INDI_PROCESS 64 +#define HILDON_ICON_PIXEL_SIZE_INDI_PROGRESSBALL 64 +#define HILDON_ICON_PIXEL_SIZE_INDI_SEND 64 +#define HILDON_ICON_PIXEL_SIZE_INDI_OFFMODE_CHARGING 50 +#define HILDON_ICON_PIXEL_SIZE_INDI_TAP_AND_HOLD 34 +#define HILDON_ICON_PIXEL_SIZE_INDI_SEND_RECEIVE 64 +#define HILDON_ICON_PIXEL_SIZE_INDI_WLAN_STRENGTH 64 + +#define HILDON_IMAGE_PIXEL_SIZE_INDI_NOKIA_LOGO 64 +#define HILDON_IMAGE_PIXEL_SIZE_INDI_STARTUP_FAILED 64 +#define HILDON_IMAGE_PIXEL_SIZE_INDI_STARTUP_NOKIA_LOGO 64 +#define HILDON_IMAGE_PIXEL_SIZE_INDI_NOKIA_HANDS 64 + +#define HILDON_MARGIN_HALF 3 +#define HILDON_MARGIN_DEFAULT 6 +#define HILDON_MARGIN_DOUBLE 12 +#define HILDON_MARGIN_TRIPLE 18 + +#define HILDON_HARDKEY_UP GDK_Up +#define HILDON_HARDKEY_LEFT GKD_Left +#define HILDON_HARDKEY_RIGHT GDK_Right +#define HILDON_HARDKEY_DOWN GDK_Down +#define HILDON_HARDKEY_SELECT GDK_Return +#define HILDON_HARDKEY_MENU GDK_F4 +#define HILDON_HARDKEY_HOME GDK_F5 +#define HILDON_HARDKEY_ESC GDK_Escape +#define HILDON_HARDKEY_FULLSCREEN GDK_F6 +#define HILDON_HARDKEY_INCREASE GDK_F7 +#define HILDON_HARDKEY_DECREASE GDK_F8 + +gulong hildon_gtk_widget_set_logical_font (GtkWidget *widget, gchar *logicalfontname); +gulong hildon_gtk_widget_set_logical_color (GtkWidget *widget, GtkRcFlags rcflags, + GtkStateType state, gchar *logicalcolorname); + +G_END_DECLS +#endif /* HILDON_DEFINES_H */ diff --git a/hildon-widgets/hildon-file-details-dialog.c b/hildon-widgets/hildon-file-details-dialog.c deleted file mode 100644 index d46c052..0000000 --- a/hildon-widgets/hildon-file-details-dialog.c +++ /dev/null @@ -1,805 +0,0 @@ -/* - * This file is part of hildon-libs - * - * Copyright (C) 2005 Nokia Corporation. - * - * Contact: Luc Pionchon - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -/* @file hildon-file-details-dialog.c - * - * This file contains API for Hildon File Details dialog. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "hildon-file-details-dialog.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -#define _(String) dgettext(PACKAGE, String) - -enum -{ - PROP_SHOW_TABS = 1, - PROP_ADDITIONAL_TAB, - PROP_ADDITIONAL_TAB_LABEL, - PROP_MODEL -}; - -struct _HildonFileDetailsDialogPrivate { - GtkNotebook *notebook; - - GtkWidget *file_location, *file_name; - GtkWidget *file_type, *file_size; - GtkWidget *file_date, *file_time; - GtkWidget *file_readonly, *file_device; - GtkWidget *file_location_image, *file_device_image; - GtkWidget *ok_button; - - GtkTreeRowReference *active_file; - gboolean checkbox_original_state; - gulong toggle_handler; - gulong delete_handler; - - /* Properties */ - HildonFileSystemModel *model; - GtkWidget *tab_label; -}; - -static void -hildon_file_details_dialog_class_init(HildonFileDetailsDialogClass * - klass); -static void hildon_file_details_dialog_init(HildonFileDetailsDialog * - filedetailsdialog); -static void hildon_file_details_dialog_finalize(GObject * object); - -static void -hildon_file_details_dialog_set_property( GObject *object, guint param_id, - const GValue *value, - GParamSpec *pspec ); -static void -hildon_file_details_dialog_get_property( GObject *object, guint param_id, - GValue *value, GParamSpec *pspec ); -static void -hildon_file_details_dialog_response(GtkDialog *dialog, gint response_id); - -static GtkDialogClass *file_details_dialog_parent_class = NULL; - -GType hildon_file_details_dialog_get_type(void) -{ - static GType file_details_dialog_type = 0; - - if (!file_details_dialog_type) { - static const GTypeInfo file_details_dialog_info = { - sizeof(HildonFileDetailsDialogClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) hildon_file_details_dialog_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(HildonFileDetailsDialog), - 0, /* n_preallocs */ - (GInstanceInitFunc) hildon_file_details_dialog_init, - }; - - file_details_dialog_type = - g_type_register_static(GTK_TYPE_DIALOG, - "HildonFileDetailsDialog", - &file_details_dialog_info, - 0); - } - - return file_details_dialog_type; -} - -static gboolean write_access(const gchar *uri) -{ - GnomeVFSFileInfo *info; - gboolean result = FALSE; - - /* Get information about file */ - info = gnome_vfs_file_info_new (); - if (gnome_vfs_get_file_info(uri, info, - GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS) == GNOME_VFS_OK) - - /* Detect that the file is writable or not */ - result = ((info->permissions & GNOME_VFS_PERM_ACCESS_WRITABLE) - == GNOME_VFS_PERM_ACCESS_WRITABLE); - - gnome_vfs_file_info_unref(info); - return result; -} - -/* When model deletes a file, we check if our reference is still valid. - If not, we emit response, which usually closes the dialog */ -static void check_validity(GtkTreeModel *model, - GtkTreePath *path, gpointer data) -{ - GtkTreeRowReference *ref; - - g_return_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(data)); - - ref = HILDON_FILE_DETAILS_DIALOG(data)->priv->active_file; - - if (ref && !gtk_tree_row_reference_valid(ref)) - gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_NONE); -} - -static void change_state(HildonFileDetailsDialog *self, gboolean readonly) -{ - GtkTreeIter iter; - - g_return_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(self)); - - /* We fail to get the iterator in cases when the reference is - invalidated, for example when the file is removed. */ - if (hildon_file_details_dialog_get_file_iter(self, &iter)) - { - gchar *uri; - GnomeVFSFileInfo *info; - GnomeVFSResult result; - - /* Get the value of cells referenced by a tree_modle */ - gtk_tree_model_get(GTK_TREE_MODEL(self->priv->model), &iter, - HILDON_FILE_SYSTEM_MODEL_COLUMN_URI, &uri, -1); - - info = gnome_vfs_file_info_new(); - result = gnome_vfs_get_file_info(uri, info, - GNOME_VFS_FILE_INFO_DEFAULT); - - /* Change the file information */ - if (result == GNOME_VFS_OK) - { - if (readonly) - info->permissions &= ~(S_IWUSR | S_IWGRP | S_IWOTH); - else - info->permissions |= (S_IWUSR | S_IWGRP); - - result = gnome_vfs_set_file_info(uri, info, - GNOME_VFS_SET_FILE_INFO_PERMISSIONS); - } - - if (result != GNOME_VFS_OK) - gtk_infoprint(GTK_WINDOW(self), gnome_vfs_result_to_string(result)); - - gnome_vfs_file_info_unref(info); - g_free(uri); - } -} - -/* Cancel changes if read-only is changed */ -static void -hildon_file_details_dialog_response(GtkDialog *dialog, gint response_id) -{ - if (response_id == GTK_RESPONSE_CANCEL) - { - HildonFileDetailsDialog *self; - gboolean state; - - self = HILDON_FILE_DETAILS_DIALOG(dialog); - state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(self->priv->file_readonly)); - - if (state != self->priv->checkbox_original_state) - change_state(self, self->priv->checkbox_original_state); - } -} - -static void -hildon_file_details_dialog_read_only_toggled(GtkWidget *widget, gpointer data) -{ - change_state(HILDON_FILE_DETAILS_DIALOG(data), - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); -} - -static void -hildon_file_details_dialog_map(GtkWidget *widget) -{ - HildonFileDetailsDialogPrivate *priv; - - priv = HILDON_FILE_DETAILS_DIALOG(widget)->priv; - - /* Map the GtkWidget */ - GTK_WIDGET_CLASS(file_details_dialog_parent_class)->map(widget); - - /* Set the first page as default and - * make the GtkNotebook focusable if it shows tabs */ - if (gtk_notebook_get_show_tabs(priv->notebook)) - { - gtk_notebook_set_current_page(priv->notebook, 0); - gtk_widget_grab_focus(GTK_WIDGET(priv->notebook)); - } - else - /* Otherwise make one GtkButton in the dialog - * sensitive with the keyboard event */ - gtk_widget_grab_focus(priv->ok_button); -} - -static void -hildon_file_details_dialog_class_init(HildonFileDetailsDialogClass * klass) -{ - GObjectClass *gobject_class; - - file_details_dialog_parent_class = g_type_class_peek_parent(klass); - gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = hildon_file_details_dialog_finalize; - gobject_class->get_property = hildon_file_details_dialog_get_property; - gobject_class->set_property = hildon_file_details_dialog_set_property; - GTK_WIDGET_CLASS(klass)->map = hildon_file_details_dialog_map; - GTK_DIALOG_CLASS(klass)->response = hildon_file_details_dialog_response; - - g_type_class_add_private(klass, sizeof(HildonFileDetailsDialogPrivate)); - - /** - * HildonFileDetailsDialog:additional_tab: - * - * This is a place for an additional tab. - */ - g_object_class_install_property( gobject_class, PROP_ADDITIONAL_TAB, - g_param_spec_object("additional-tab", - "Additional tab", - "Tab to show additinal information", - GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - /** - * HildonFileDetailsDialog:show_tabs: - * - * Do we want to show the tab labels. - */ - g_object_class_install_property( gobject_class, PROP_SHOW_TABS, - g_param_spec_boolean("show-tabs", - "Show tab labels", - "Do we want to show the tab label.", - FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - /** - * HildonFileDetailsDialog:additional_tab_label: - * - * - */ - g_object_class_install_property( gobject_class, PROP_ADDITIONAL_TAB_LABEL, - g_param_spec_string("additional-tab-label", - "Additional tab label", - "Label to the additional tab", - NULL, G_PARAM_READWRITE)); - - g_object_class_install_property( gobject_class, PROP_MODEL, - g_param_spec_object("model", "Model", - "HildonFileSystemModel to use when fetching information", - HILDON_TYPE_FILE_SYSTEM_MODEL, G_PARAM_READWRITE)); -} - -static void -hildon_file_details_dialog_init(HildonFileDetailsDialog *self) -{ - GtkWidget *caption_location, *caption_name, *caption_type; - GtkWidget *caption_date, *caption_size, *caption_time; - GtkWidget *caption_read, *caption_device; - GtkWidget *hbox_location, *hbox_device; - GtkWidget *vbox; - GtkWidget *scroll; - GtkSizeGroup *group; - GdkGeometry geometry; - - HildonFileDetailsDialogPrivate *priv; - - /* Initialize the private property */ - self->priv = priv = - G_TYPE_INSTANCE_GET_PRIVATE(self, \ - HILDON_TYPE_FILE_DETAILS_DIALOG, HildonFileDetailsDialogPrivate); - - priv->notebook = GTK_NOTEBOOK(gtk_notebook_new()); - scroll = gtk_scrolled_window_new(NULL, NULL); - vbox = gtk_vbox_new(FALSE, 0); - group = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); - - priv->tab_label = gtk_label_new(_("sfil_ti_notebook_file")); - g_object_ref(priv->tab_label); - gtk_object_sink(GTK_OBJECT(priv->tab_label)); - gtk_widget_show(priv->tab_label); - - priv->file_device = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL); - priv->file_location = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL); - priv->file_name = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL); - priv->file_type = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL); - priv->file_size = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL); - priv->file_date = g_object_new(GTK_TYPE_LABEL,"xalign", 0.0f, NULL); - priv->file_time = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL); - priv->file_readonly = gtk_check_button_new(); - - hbox_location = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT); - hbox_device = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT); - - priv->file_location_image = gtk_image_new(); - priv->file_device_image = gtk_image_new(); - - gtk_box_pack_start(GTK_BOX(hbox_location), priv->file_location_image, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(hbox_location), priv->file_location, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(hbox_device), priv->file_device_image, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(hbox_device), priv->file_device, TRUE, TRUE, 0); - - /* Create captions for the dialog */ - caption_name = hildon_caption_new(group, _("ckdg_fi_properties_name_prompt"), - priv->file_name, NULL, HILDON_CAPTION_OPTIONAL); - caption_type = hildon_caption_new(group, _("ckdg_fi_properties_type_prompt"), - priv->file_type, NULL, HILDON_CAPTION_OPTIONAL); - caption_location = hildon_caption_new(group, _("sfil_fi_properties_location_prompt"), - hbox_location, NULL, HILDON_CAPTION_OPTIONAL); - caption_device = hildon_caption_new(group, _("sfil_fi_properties_device_prompt"), - hbox_device, NULL, HILDON_CAPTION_OPTIONAL); - caption_date = hildon_caption_new(group, _("ckdg_fi_properties_date_prompt"), - priv->file_date, NULL, HILDON_CAPTION_OPTIONAL); - caption_time = hildon_caption_new(group, _("ckdg_fi_properties_time_prompt"), - priv->file_time, NULL, HILDON_CAPTION_OPTIONAL); - caption_size = hildon_caption_new(group, _("ckdg_fi_properties_size_prompt"), - priv->file_size, NULL, HILDON_CAPTION_OPTIONAL); - caption_read = hildon_caption_new(group, _("ckdg_fi_properties_read_only"), - priv->file_readonly, NULL, HILDON_CAPTION_OPTIONAL); - - hildon_caption_set_separator(HILDON_CAPTION(caption_name), ""); - hildon_caption_set_separator(HILDON_CAPTION(caption_type), ""); - hildon_caption_set_separator(HILDON_CAPTION(caption_location), ""); - hildon_caption_set_separator(HILDON_CAPTION(caption_device), ""); - hildon_caption_set_separator(HILDON_CAPTION(caption_date), ""); - hildon_caption_set_separator(HILDON_CAPTION(caption_time), ""); - hildon_caption_set_separator(HILDON_CAPTION(caption_size), ""); - hildon_caption_set_separator(HILDON_CAPTION(caption_read), ""); - - g_object_unref(group); - - /* Pack captions to the dialog */ - gtk_box_pack_start(GTK_BOX(vbox), caption_name, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox), caption_type, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox), caption_location, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox), caption_device, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox), caption_date, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox), caption_time, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox), caption_size, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox), caption_read, FALSE, TRUE, 0); - - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), vbox); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_container_set_border_width(GTK_CONTAINER(scroll), - HILDON_MARGIN_DEFAULT); - /* Both scrolled window and viewport have separate shadows... */ - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), - GTK_SHADOW_NONE); - gtk_viewport_set_shadow_type( - GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(scroll))), - GTK_SHADOW_NONE); - - gtk_container_set_focus_vadjustment(GTK_CONTAINER(vbox), - gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scroll))); - - /* Populate dialog */ - gtk_notebook_append_page(priv->notebook, scroll, - gtk_label_new(_("sfil_ti_notebook_common"))); - - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(self)->vbox), - GTK_WIDGET(priv->notebook), TRUE, TRUE, 0); - - /* From widget specs, generic dialog size */ - geometry.min_width = 133; - geometry.max_width = 602; - /* Scrolled windows do not ask space for whole contents in size_request. - So, we must force the dialog to have larger than minimum size */ - geometry.min_height = 240 + (2 * HILDON_MARGIN_DEFAULT); - geometry.max_height = 240 + (2 * HILDON_MARGIN_DEFAULT); - - gtk_window_set_geometry_hints(GTK_WINDOW(self), - GTK_WIDGET(priv->notebook), &geometry, - GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE); - - gtk_widget_show_all(GTK_WIDGET(priv->notebook)); - - priv->ok_button = gtk_dialog_add_button(GTK_DIALOG(self), - _("sfil_bd_filetype_details_dialog_ok"), - GTK_RESPONSE_OK); - gtk_dialog_add_button(GTK_DIALOG(self), - _("sfil_bd_filetype_details_dialog_cancel"), - GTK_RESPONSE_CANCEL); - - priv->toggle_handler = g_signal_connect(priv->file_readonly, "toggled", - G_CALLBACK(hildon_file_details_dialog_read_only_toggled), - self); -} - -static void -hildon_file_details_dialog_set_property( GObject *object, guint param_id, - const GValue *value, - GParamSpec *pspec ) -{ - HildonFileDetailsDialogPrivate *priv; - GtkNotebook *notebook; - GtkLabel *label; - - priv = HILDON_FILE_DETAILS_DIALOG(object)->priv; - notebook = priv->notebook; - label = GTK_LABEL(priv->tab_label); - - switch( param_id ) - { - case PROP_SHOW_TABS: - { - gtk_notebook_set_show_tabs(notebook, g_value_get_boolean(value)); - gtk_notebook_set_show_border(notebook, g_value_get_boolean(value)); - break; - } - case PROP_ADDITIONAL_TAB: - { - GtkWidget *widget = g_value_get_object(value); - GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL); - - if (gtk_notebook_get_n_pages(notebook) == 2) - gtk_notebook_remove_page(notebook, 1); - - if (widget == NULL) - { - widget = g_object_new(GTK_TYPE_LABEL, - "label", _("sfil_ia_filetype_no_details"), "yalign", 0.0f, NULL); - gtk_widget_show(widget); - } - - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), widget); - gtk_viewport_set_shadow_type(GTK_VIEWPORT(GTK_BIN(sw)->child), - GTK_SHADOW_NONE); - gtk_widget_show_all(sw); - gtk_notebook_append_page(notebook, sw, priv->tab_label); - gtk_notebook_set_current_page(notebook, 0); - break; - } - case PROP_ADDITIONAL_TAB_LABEL: - gtk_label_set_text(label, g_value_get_string(value)); - break; - case PROP_MODEL: - { - HildonFileSystemModel *new_model = g_value_get_object(value); - if (new_model != priv->model) - { - if (G_IS_OBJECT(priv->model)) - { - g_signal_handler_disconnect(priv->model, priv->delete_handler); - g_object_unref(priv->model); - priv->delete_handler = 0; - } - priv->model = new_model; - if (new_model) - { - g_object_ref(new_model); - priv->delete_handler = g_signal_connect(priv->model, "row-deleted", - G_CALLBACK(check_validity), object); - } - } - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); - break; - } -} - -static void -hildon_file_details_dialog_get_property( GObject *object, guint param_id, - GValue *value, GParamSpec *pspec ) -{ - HildonFileDetailsDialogPrivate *priv; - - priv = HILDON_FILE_DETAILS_DIALOG(object)->priv; - - switch (param_id) - { - case PROP_SHOW_TABS: - g_value_set_boolean(value, gtk_notebook_get_show_tabs(priv->notebook)); - break; - case PROP_ADDITIONAL_TAB: - g_assert(gtk_notebook_get_n_pages(priv->notebook) == 2); - g_value_set_object(value, gtk_notebook_get_nth_page(priv->notebook, 1)); - break; - case PROP_ADDITIONAL_TAB_LABEL: - g_value_set_string(value, gtk_label_get_text(GTK_LABEL(priv->tab_label))); - break; - case PROP_MODEL: - g_value_set_object(value, priv->model); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); - break; - } -} - -static void hildon_file_details_dialog_finalize(GObject * object) -{ - HildonFileDetailsDialogPrivate *priv; - - g_return_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(object)); - - priv = HILDON_FILE_DETAILS_DIALOG(object)->priv; - if (G_IS_OBJECT(priv->model)) - { - g_signal_handler_disconnect(priv->model, priv->delete_handler); - g_object_unref(priv->model); - } - if (G_IS_OBJECT(priv->tab_label)) - g_object_unref(priv->tab_label); - if (priv->active_file) - gtk_tree_row_reference_free(priv->active_file); - - G_OBJECT_CLASS(file_details_dialog_parent_class)->finalize(object); -} - -/*******************/ -/* Public functions */ -/*******************/ - -/** - * hildon_file_details_dialog_new: - * @parent: the parent window. - * @filename: the filename. - * - * Creates a new #hildon_file_details_dialog AND new underlying - * HildonFileSystemModel. Be carefull with #filename - * parameter: You don't get any notification if something fails. - * THIS FUNCTION IS DEPRICATED AND PROVIDED ONLY FOR - * BACKWARDS COMPABILITY. - * - * Returns: a new #HildonFileDetailsDialog. - */ -#ifndef HILDON_DISABLE_DEPRECATED -GtkWidget *hildon_file_details_dialog_new(GtkWindow * parent, - const gchar * filename) -{ - HildonFileDetailsDialog *dialog; - HildonFileSystemModel *model; - GtkTreeIter iter; - - model = g_object_new(HILDON_TYPE_FILE_SYSTEM_MODEL, NULL); - - dialog = - g_object_new(HILDON_TYPE_FILE_DETAILS_DIALOG, - "has-separator", FALSE, "title", _("sfil_ti_file_details"), - "model", model, NULL); - - if (filename && filename[0] && - hildon_file_system_model_load_local_path(dialog->priv->model, filename, &iter)) - hildon_file_details_dialog_set_file_iter(dialog, &iter); - - if (parent) - gtk_window_set_transient_for(GTK_WINDOW(dialog), parent); - - return GTK_WIDGET(dialog); -} -#endif -/** - * hildon_file_details_dialog_new_with_model: - * @parent: the parent window. - * @model: a #HildonFileSystemModel object used to fetch data. - * - * This is the preferred way to create #HildonFileDetailsDialog. - * You can use a shared model structure to save loading times - * (because you probably already have one at your disposal). - * - * Returns: a new #HildonFileDetailsDialog. - */ -GtkWidget *hildon_file_details_dialog_new_with_model(GtkWindow *parent, - HildonFileSystemModel *model) -{ - GtkWidget *dialog; - - dialog = g_object_new(HILDON_TYPE_FILE_DETAILS_DIALOG, - "has-separator", FALSE, "title", _("sfil_ti_file_details"), - "model", model, NULL); - - if (parent) - gtk_window_set_transient_for(GTK_WINDOW(dialog), parent); - - return dialog; -} - -/** - * hildon_file_details_dialog_set_file_iter: - * @self: a #HildonFileDetailsDialog. - * @iter: a #GtkTreeIter pointing to desired file. - * - * Sets the dialog to display information about a file defined by - * given iterator. - */ -void hildon_file_details_dialog_set_file_iter(HildonFileDetailsDialog *self, GtkTreeIter *iter) -{ - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter temp_iter, parent_iter; - gchar *name, *mime, *uri; - const gchar *fmt; - gint64 time_stamp, size; - gchar buffer[256]; - struct tm *time_struct; - time_t time_val; - gint type; - gboolean location_readonly = TRUE; - - g_return_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(self)); - - model = GTK_TREE_MODEL(self->priv->model); - - /* Save iterator to priv struct as row reference */ - gtk_tree_row_reference_free(self->priv->active_file); - path = gtk_tree_model_get_path(model, iter); - self->priv->active_file = gtk_tree_row_reference_new(model, path); - gtk_tree_path_free(path); - - /* Setup the view */ - gtk_tree_model_get(model, iter, - HILDON_FILE_SYSTEM_MODEL_COLUMN_DISPLAY_NAME, &name, - HILDON_FILE_SYSTEM_MODEL_COLUMN_MIME_TYPE, &mime, - HILDON_FILE_SYSTEM_MODEL_COLUMN_URI, &uri, - HILDON_FILE_SYSTEM_MODEL_COLUMN_FILE_SIZE, &size, - HILDON_FILE_SYSTEM_MODEL_COLUMN_FILE_TIME, &time_stamp, - -1); - - g_object_set(self->priv->file_name, "label", name, NULL); - g_object_set(self->priv->file_type, "label", _(mime), NULL); - - if (size < 1024) - g_snprintf(buffer, sizeof(buffer), - _("ckdg_va_properties_size_bytes"), (gint) size); - else - g_snprintf(buffer, sizeof(buffer), - _("ckdg_va_properties_size_kb"), (gint) size / 1024); - - g_object_set(self->priv->file_size, "label", buffer, NULL); - - /* Too bad. We cannot use GDate function, because it doesn't handle - time, just dates */ - time_val = (time_t) time_stamp; - time_struct = localtime(&time_val); - - /* There are no more logical names for these. We are allowed - to hardcode */ - strftime(buffer, sizeof(buffer), "%X", time_struct); - g_object_set(self->priv->file_time, "label", buffer, NULL); - - /* If format is passed directly to strftime, gcc complains about - that some locales use only 2 digit year numbers. Using - a temporary disable this warning (from strftime man page) */ - fmt = "%x"; - strftime(buffer, sizeof(buffer), fmt, time_struct); - g_object_set(self->priv->file_date, "label", buffer, NULL); - - /* Parent information */ - if (gtk_tree_model_iter_parent(model, &parent_iter, iter)) - { - gchar *location_name, *parent_path; - GdkPixbuf *location_icon; - - gtk_tree_model_get(model, &parent_iter, - HILDON_FILE_SYSTEM_MODEL_COLUMN_DISPLAY_NAME, &location_name, - HILDON_FILE_SYSTEM_MODEL_COLUMN_URI, &parent_path, - HILDON_FILE_SYSTEM_MODEL_COLUMN_ICON, &location_icon, -1); - - if (parent_path) - location_readonly = !write_access(parent_path); - - gtk_label_set_text(GTK_LABEL(self->priv->file_location), location_name); - gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv->file_location_image), - location_icon); - - if (G_IS_OBJECT(location_icon)) - g_object_unref(location_icon); - g_free(location_name); - - /* Go upwards in model until we find a device node */ - while (TRUE) - { - gtk_tree_model_get(model, &parent_iter, - HILDON_FILE_SYSTEM_MODEL_COLUMN_TYPE, &type, -1); - - if (type >= HILDON_FILE_SYSTEM_MODEL_MMC) - break; - - if (gtk_tree_model_iter_parent(model, &temp_iter, &parent_iter)) - parent_iter = temp_iter; - else - break; - } - - gtk_tree_model_get(model, &parent_iter, - HILDON_FILE_SYSTEM_MODEL_COLUMN_DISPLAY_NAME, &location_name, - HILDON_FILE_SYSTEM_MODEL_COLUMN_ICON, &location_icon, - -1); - - gtk_label_set_text(GTK_LABEL(self->priv->file_device), location_name); - gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv->file_device_image), - location_icon); - - if (G_IS_OBJECT(location_icon)) - g_object_unref(location_icon); - g_free(location_name); - g_free(parent_path); - } - else - { /* We really should not come here */ - gtk_label_set_text(GTK_LABEL(self->priv->file_location), ""); - gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv->file_location_image), NULL); - gtk_label_set_text(GTK_LABEL(self->priv->file_device), ""); - gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv->file_device_image), NULL); - } - - /* We do not want initial setting to cause any action */ - g_signal_handler_block(self->priv->file_readonly, self->priv->toggle_handler); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->priv->file_readonly), - location_readonly || !write_access(uri)); - gtk_widget_set_sensitive(self->priv->file_readonly, !location_readonly); - - self->priv->checkbox_original_state = gtk_toggle_button_get_active( - GTK_TOGGLE_BUTTON(self->priv->file_readonly)); - - g_signal_handler_unblock(self->priv->file_readonly, self->priv->toggle_handler); - - g_free(uri); - g_free(name); - g_free(mime); -} - -/** - * hildon_file_details_dialog_get_file_iter: - * @self: a #HildonFileDetailsDialog. - * @iter: a #GtkTreeIter to be filled. - * - * Gets an iterator pointing to displayed file. - * - * Returns: %TRUE, if dialog is displaying some information. - */ -gboolean -hildon_file_details_dialog_get_file_iter(HildonFileDetailsDialog *self, GtkTreeIter *iter) -{ - GtkTreePath *path; - gboolean result; - - g_return_val_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(self), FALSE); - - if (!self->priv->active_file) - return FALSE; - path = gtk_tree_row_reference_get_path(self->priv->active_file); - if (!path) - return FALSE; - - result = gtk_tree_model_get_iter(GTK_TREE_MODEL(self->priv->model), iter, path); - gtk_tree_path_free(path); - - return result; -} diff --git a/hildon-widgets/hildon-file-details-dialog.h b/hildon-widgets/hildon-file-details-dialog.h deleted file mode 100644 index ba5d16c..0000000 --- a/hildon-widgets/hildon-file-details-dialog.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of hildon-libs - * - * Copyright (C) 2005 Nokia Corporation. - * - * Contact: Luc Pionchon - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __HILDON_FILE_DETAILS_DIALOG_H__ -#define __HILDON_FILE_DETAILS_DIALOG_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define HILDON_TYPE_FILE_DETAILS_DIALOG \ - (hildon_file_details_dialog_get_type ()) -#define HILDON_FILE_DETAILS_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_FILE_DETAILS_DIALOG,\ - HildonFileDetailsDialog)) -#define HILDON_FILE_DETAILS_DIALOG_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), HILDON_TYPE_FILE_DETAILS_DIALOG,\ - HildonFileDetailsDialogClass)) -#define HILDON_IS_FILE_DETAILS_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_FILE_DETAILS_DIALOG)) -#define HILDON_IS_FILE_DETAILS_DIALOG_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_FILE_DETAILS_DIALOG)) -#define HILDON_FILE_DETAILS_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), HILDON_TYPE_FILE_DETAILS_DIALOG,\ - HildonFileDetailsDialogClass)) - -typedef struct _HildonFileDetailsDialog HildonFileDetailsDialog; -typedef struct _HildonFileDetailsDialogPrivate HildonFileDetailsDialogPrivate; -typedef struct _HildonFileDetailsDialogClass HildonFileDetailsDialogClass; - -struct _HildonFileDetailsDialog { - GtkDialog parent; - HildonFileDetailsDialogPrivate *priv; -}; - -struct _HildonFileDetailsDialogClass { - GtkDialogClass parent_class; -}; - -GType hildon_file_details_dialog_get_type(void) G_GNUC_CONST; - -/* Depricated constructor... */ -#ifndef HILDON_DISABLE_DEPRECATED -GtkWidget *hildon_file_details_dialog_new(GtkWindow * parent, - const gchar * filename); -#endif - -/* New API inspired by GtkComboBox */ -GtkWidget *hildon_file_details_dialog_new_with_model(GtkWindow *parent, - HildonFileSystemModel *model); - -void hildon_file_details_dialog_set_file_iter(HildonFileDetailsDialog *self, GtkTreeIter *iter); -gboolean hildon_file_details_dialog_get_file_iter(HildonFileDetailsDialog *self, GtkTreeIter *iter); - -G_END_DECLS - -#endif /* __HILDON_FILEDETAILS_H__ */ diff --git a/hildon-widgets/hildon-find-toolbar.c b/hildon-widgets/hildon-find-toolbar.c new file mode 100644 index 0000000..0a040a8 --- /dev/null +++ b/hildon-widgets/hildon-find-toolbar.c @@ -0,0 +1,646 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "hildon-find-toolbar.h" +#include "hildon-defines.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#define _(String) dgettext(PACKAGE, String) + +/*same define as gtkentry.c as entry will further handle this*/ +#define MAX_SIZE G_MAXUSHORT +#define FIND_LABEL_XPADDING 6 +#define FIND_LABEL_YPADDING 0 + +enum +{ + SEARCH = 0, + CLOSE, + INVALID_INPUT, + HISTORY_APPEND, + + LAST_SIGNAL +}; + +enum +{ + PROP_LABEL = 1, + PROP_PREFIX, + PROP_LIST, + PROP_COLUMN, + PROP_MAX, + PROP_HISTORY_LIMIT +}; + +struct _HildonFindToolbarPrivate +{ + GtkWidget* label; + GtkWidget* entry_combo_box; + GtkToolItem* find_button; + GtkToolItem* separator; + GtkToolItem* close_button; + + gint history_limit; +}; +static guint HildonFindToolbar_signal[LAST_SIGNAL] = {0}; + +G_DEFINE_TYPE(HildonFindToolbar, \ + hildon_find_toolbar, GTK_TYPE_TOOLBAR) + +static gboolean +hildon_find_toolbar_filter(GtkTreeModel *model, + GtkTreeIter *iter, + gpointer self) +{ + GtkTreePath *path; + gint *indices; + gint n; + gint limit; + + g_object_get(G_OBJECT(self), "history_limit", &limit, NULL); + path = gtk_tree_model_get_path(model, iter); + indices = gtk_tree_path_get_indices (path); + + /* List store has only one level. If this row's index number is larger + than history_limit, we want to filter it. */ + n = indices[0]; + gtk_tree_path_free(path); + + if(n < limit) + return TRUE; + else + return FALSE; +} + +static void +hildon_find_toolbar_apply_filter(HildonFindToolbar *self, + GtkListStore *list, + gboolean set_column) +{ + GtkTreeModel *filter; + gint c_n = 0; + HildonFindToolbarPrivate *priv = self->priv; + + /* Create a filter for the given list store. Its only purpose is to hide + the oldest entries so only "history_limit" entries are visible. */ + filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(list), NULL); + + /* FIXME: next two lines are useless */ + if(gtk_combo_box_get_model(GTK_COMBO_BOX(priv->entry_combo_box)) != NULL) + g_object_get(G_OBJECT(self), "column", &c_n, NULL); + + gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter), + hildon_find_toolbar_filter, + (gpointer) self, NULL); + gtk_combo_box_set_model(GTK_COMBO_BOX(priv->entry_combo_box), filter); + + /* ComboBox keeps the only needed reference to the filter */ + g_object_unref(filter); + + /* If "column" property hasn't been set yet and we have set_column=TRUE, + set the column to 0. This is done when we're creating the list store + internally. */ + if ( gtk_combo_box_entry_get_text_column( + GTK_COMBO_BOX_ENTRY(priv->entry_combo_box)) == -1 && set_column) + gtk_combo_box_entry_set_text_column( + GTK_COMBO_BOX_ENTRY(priv->entry_combo_box), c_n); +} + +static void +hildon_find_toolbar_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + const gchar *string; + gint c_n; + HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(object)->priv; + + switch (prop_id) + { + case PROP_LABEL: + string = gtk_label_get_text(GTK_LABEL(priv->label)); + g_value_set_string(value, string); + break; + case PROP_PREFIX: + string = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child + (GTK_BIN(priv->entry_combo_box)))); + g_value_set_string(value, string); + break; + case PROP_LIST: + g_value_set_object(value, + (gpointer) gtk_tree_model_filter_get_model( + GTK_TREE_MODEL_FILTER(gtk_combo_box_get_model( + GTK_COMBO_BOX(priv->entry_combo_box))))); + break; + case PROP_COLUMN: + c_n = gtk_combo_box_entry_get_text_column( + GTK_COMBO_BOX_ENTRY(priv->entry_combo_box)); + g_value_set_int(value, c_n); + break; + case PROP_MAX: + g_value_set_int(value, gtk_entry_get_max_length(GTK_ENTRY(gtk_bin_get_child + (GTK_BIN(priv->entry_combo_box))))); + break; + case PROP_HISTORY_LIMIT: + g_value_set_int(value, priv->history_limit); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +hildon_find_toolbar_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + const gchar *string; + GtkTreeModel *model; + HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(object)->priv; + + switch (prop_id) + { + case PROP_LABEL: + string = g_value_get_string(value); + gtk_label_set_text(GTK_LABEL(priv->label), string); + break; + case PROP_PREFIX: + string = g_value_get_string(value); + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child + (GTK_BIN(priv->entry_combo_box))), + string); + break; + case PROP_LIST: + hildon_find_toolbar_apply_filter(HILDON_FIND_TOOLBAR(object), + GTK_LIST_STORE(g_value_get_object(value)), + FALSE); + break; + case PROP_COLUMN: + gtk_combo_box_entry_set_text_column ( + GTK_COMBO_BOX_ENTRY(priv->entry_combo_box), g_value_get_int(value)); + break; + case PROP_MAX: + gtk_entry_set_max_length(GTK_ENTRY(gtk_bin_get_child + (GTK_BIN(priv->entry_combo_box))), + g_value_get_int(value)); + break; + case PROP_HISTORY_LIMIT: + priv->history_limit = g_value_get_int(value); + model = gtk_combo_box_get_model(GTK_COMBO_BOX(priv->entry_combo_box)); + if(model != NULL) + { + /*FIXME refilter function doesnt update the status of the combobox + * pop up arrowi, which will cause crash, recall apply filter + * solves the problem*/ + + /*gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(model));*/ + + /* FIXME: don't call with set_column=TRUE since it sets column to 0. + We can't know that it's correct. */ + hildon_find_toolbar_apply_filter(HILDON_FIND_TOOLBAR(object),GTK_LIST_STORE( + gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model))), + TRUE); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +hildon_find_toolbar_history_append(HildonFindToolbar *self, + gpointer data) +{ + gchar *string; + gchar *old_string; + gboolean occupy; + gint c_n = 0; + GtkListStore *list = NULL; + GtkTreeIter iter; + gboolean self_create = FALSE; + HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(self)->priv; + + g_object_get(G_OBJECT(self), "prefix", &string, NULL); + + if(strcmp(string, "") != 0) + { + GtkTreeModel *model = NULL; + + /* If list store is set, get it */ + if(gtk_combo_box_get_model(GTK_COMBO_BOX(priv->entry_combo_box)) != NULL) + { + list = GTK_LIST_STORE(gtk_tree_model_filter_get_model( + GTK_TREE_MODEL_FILTER(gtk_combo_box_get_model( + GTK_COMBO_BOX(priv->entry_combo_box))))); + model = GTK_TREE_MODEL (list); + } + if(list == NULL) + { + /* No list store set. Create our own. */ + list = gtk_list_store_new(1, G_TYPE_STRING); + self_create = TRUE; + } + else + g_object_get(G_OBJECT(self), "column", &c_n, NULL); + + + /* Latest string is always the first one in list. */ + /* Remove item if too many, remove also duplicates. */ + if (model) + { + occupy = gtk_tree_model_get_iter_first(model, &iter); + + while(occupy) + { + gtk_tree_model_get (model, &iter, c_n, &old_string, -1); + if(old_string != NULL && strcmp(string, old_string) == 0) + { + /* Found it, remove. */ + occupy = FALSE; + gtk_list_store_remove (list, &iter); + } + else + occupy = gtk_tree_model_iter_next(model, &iter); + } + + /* If we have more than history_limit amount of items + * in the list, remove one. */ + if(gtk_tree_model_iter_n_children(model, NULL) >= priv->history_limit) + { + gtk_tree_model_get_iter_first(model, &iter); + gtk_list_store_remove(list, &iter); + } + } + + /* Column number is -1 if "column" property hasn't been set but + "list" property is. */ + if(c_n >= 0) + {/* Add the string to first in list */ + gtk_list_store_append(list, &iter); + gtk_list_store_set(list, &iter, c_n, string, -1); + if(self_create) + { + /* Add the created list to ComboBoxEntry */ + hildon_find_toolbar_apply_filter(self, list, TRUE); + /* ComboBoxEntry keeps the only needed reference to this list */ + g_object_unref(list); + } + else + /* Refilter to get the oldest entry hidden from history */ + gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER( + gtk_combo_box_get_model(GTK_COMBO_BOX(priv->entry_combo_box)))); + } + } + g_free(string); + + return TRUE; +} + +static void +hildon_find_toolbar_emit_search(GtkButton *button, gpointer self) +{ + gboolean rb; + + /* Clicked search button. Perform search and add search prefix to history */ + g_signal_emit_by_name(self, "search", NULL); + g_signal_emit_by_name(self, "history_append", &rb, NULL); +} + +static void +hildon_find_toolbar_emit_close(GtkButton *button, gpointer self) +{ + /* Clicked close button */ + g_signal_emit_by_name(self, "close", NULL); +} + +static void +hildon_find_toolbar_emit_invalid_input(GtkEntry *entry, + GtkInvalidInputType type, + gpointer self) +{ + if(type == GTK_INVALID_INPUT_MAX_CHARS_REACHED) + g_signal_emit_by_name(self, "invalid_input", NULL); +} + +static gboolean +hildon_find_toolbar_entry_key_press (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data) +{ + GtkWidget *find_toolbar = GTK_WIDGET(user_data); + + /* on enter we emit search and history_append signals and keep + * focus by returning true */ + if (event->keyval == GDK_KP_Enter) + { + gboolean rb; + g_signal_emit_by_name(find_toolbar, "search", NULL); + g_signal_emit_by_name(find_toolbar, "history_append", &rb, NULL); + + return TRUE; + } + + return FALSE; +} + +static void +hildon_find_toolbar_class_init(HildonFindToolbarClass *klass) +{ + GObjectClass *object_class; + + g_type_class_add_private(klass, sizeof(HildonFindToolbarPrivate)); + + object_class = G_OBJECT_CLASS(klass); + + object_class->get_property = hildon_find_toolbar_get_property; + object_class->set_property = hildon_find_toolbar_set_property; + + klass->history_append = hildon_find_toolbar_history_append; + + g_object_class_install_property(object_class, PROP_LABEL, + g_param_spec_string("label", + "Label", "Displayed name for" + " find-toolbar", + _("Ecdg_ti_find_toolbar_label"), + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property(object_class, PROP_PREFIX, + g_param_spec_string("prefix", + "Prefix", "Search string", NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, PROP_LIST, + g_param_spec_object("list", + "List"," GtkListStore model where " + "history list is kept", + GTK_TYPE_LIST_STORE, + G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, PROP_COLUMN, + g_param_spec_int("column", + "Column", "Column number in GtkListStore " + "where history list strings are kept", + 0, G_MAXINT, + 0, G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, PROP_MAX, + g_param_spec_int("max_characters", + "Maximum number of characters", + "Maximum number of characters " + "in search string", + 0, MAX_SIZE, + 0, G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property(object_class, PROP_HISTORY_LIMIT, + g_param_spec_int("history_limit", + "Maximum number of history items", + "Maximum number of history items " + "in search combobox", + 0, G_MAXINT, + 5, G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + /** + * HildonFindToolbar::search: + * @toolbar: the toolbar which received the signal + * + * Gets emitted when the find button is pressed. + */ + HildonFindToolbar_signal[SEARCH] = + g_signal_new( + "search", HILDON_TYPE_FIND_TOOLBAR, + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET + (HildonFindToolbarClass, search), + NULL, NULL, gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * HildonFindToolbar::close: + * @toolbar: the toolbar which received the signal + * + * Gets emitted when the close button is pressed. + */ + HildonFindToolbar_signal[CLOSE] = + g_signal_new( + "close", HILDON_TYPE_FIND_TOOLBAR, + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET + (HildonFindToolbarClass, close), + NULL, NULL, gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * HildonFindToolbar::invalid-input: + * @toolbar: the toolbar which received the signal + * + * Gets emitted when the maximum search prefix length is reached and + * user tries to type more. + */ + HildonFindToolbar_signal[INVALID_INPUT] = + g_signal_new( + "invalid_input", HILDON_TYPE_FIND_TOOLBAR, + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET + (HildonFindToolbarClass, invalid_input), + NULL, NULL, gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * HildonFindToolbar::history-append: + * @toolbar: the toolbar which received the signal + * + * Gets emitted when the current search prefix should be added to history. + */ + HildonFindToolbar_signal[HISTORY_APPEND] = + g_signal_new( + "history_append", HILDON_TYPE_FIND_TOOLBAR, + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET + (HildonFindToolbarClass, history_append), + g_signal_accumulator_true_handled, NULL, + gtk_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, 0); +} + +static void +hildon_find_toolbar_init(HildonFindToolbar *self) +{ + GtkToolItem *label_container; + GtkToolItem *entry_combo_box_container; + + self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, \ + HILDON_TYPE_FIND_TOOLBAR, + HildonFindToolbarPrivate); + + /* Create the label */ + self->priv->label = gtk_label_new(_("Ecdg_ti_find_toolbar_label")); + + gtk_misc_set_padding (GTK_MISC(self->priv->label), FIND_LABEL_XPADDING, + FIND_LABEL_YPADDING); + + label_container = gtk_tool_item_new(); + gtk_container_add(GTK_CONTAINER(label_container), + self->priv->label); + gtk_widget_show_all(GTK_WIDGET(label_container)); + gtk_toolbar_insert (GTK_TOOLBAR(self), label_container, -1); + + /* ComboBoxEntry for search prefix string / history list */ + self->priv->entry_combo_box = gtk_combo_box_entry_new(); + g_signal_connect(G_OBJECT(gtk_bin_get_child( + GTK_BIN(self->priv->entry_combo_box))), + "invalid_input", + G_CALLBACK(hildon_find_toolbar_emit_invalid_input), + (gpointer) self); + entry_combo_box_container = gtk_tool_item_new(); + gtk_tool_item_set_expand(entry_combo_box_container, TRUE); + gtk_container_add(GTK_CONTAINER(entry_combo_box_container), + self->priv->entry_combo_box); + gtk_widget_show_all(GTK_WIDGET(entry_combo_box_container)); + gtk_toolbar_insert (GTK_TOOLBAR(self), entry_combo_box_container, -1); + g_signal_connect(GTK_BIN (self->priv->entry_combo_box)->child, + "key-press-event", + G_CALLBACK(hildon_find_toolbar_entry_key_press), + (gpointer) self); + + /* Find button */ + self->priv->find_button = gtk_tool_button_new ( + gtk_image_new_from_icon_name ("qgn_toolb_browser_gobutton", + HILDON_ICON_SIZE_TOOLBAR), + "Find"); + g_signal_connect(G_OBJECT(self->priv->find_button), "clicked", + G_CALLBACK(hildon_find_toolbar_emit_search), + (gpointer) self); + gtk_widget_show_all(GTK_WIDGET(self->priv->find_button)); + gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->find_button, -1); + if ( GTK_WIDGET_CAN_FOCUS( GTK_BIN(self->priv->find_button)->child) ) + GTK_WIDGET_UNSET_FLAGS( + GTK_BIN(self->priv->find_button)->child, GTK_CAN_FOCUS); + + /* Separator */ + self->priv->separator = gtk_separator_tool_item_new(); + gtk_widget_show(GTK_WIDGET(self->priv->separator)); + gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->separator, -1); + + /* Close button */ + self->priv->close_button = gtk_tool_button_new ( + gtk_image_new_from_icon_name ("qgn_toolb_gene_close", + HILDON_ICON_SIZE_TOOLBAR), + "Close"); + g_signal_connect(G_OBJECT(self->priv->close_button), "clicked", + G_CALLBACK(hildon_find_toolbar_emit_close), + (gpointer) self); + gtk_widget_show_all(GTK_WIDGET(self->priv->close_button)); + gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->close_button, -1); + if ( GTK_WIDGET_CAN_FOCUS( GTK_BIN(self->priv->close_button)->child) ) + GTK_WIDGET_UNSET_FLAGS( + GTK_BIN(self->priv->close_button)->child, GTK_CAN_FOCUS); +} + +/*Public functions*/ + +/** + * hildon_find_toolbar_new: + * @label: label for the find_toolbar, NULL to set the label to + * default "Find". + * + * Returns a new HildonFindToolbar. + * + **/ + +GtkWidget * +hildon_find_toolbar_new(gchar *label) +{ + GtkWidget *findtoolbar; + + findtoolbar = GTK_WIDGET(g_object_new(HILDON_TYPE_FIND_TOOLBAR, NULL)); + if(label != NULL) + g_object_set(G_OBJECT(findtoolbar), "label", label, NULL); + + return findtoolbar; +} + +/** + * hildon_find_toolbar_new_with_model + * @label: label for the find_toolbar, NULL to set the label to + * default "Find". + * @model: A @GtkListStore. + * @column: Indicating which column the search histry list will + * retreive string from. + * + * Returns a new HildonFindToolbar, with a model. + * + **/ +GtkWidget * +hildon_find_toolbar_new_with_model(gchar *label, + GtkListStore *model, + gint column) +{ + GtkWidget *findtoolbar; + + findtoolbar = hildon_find_toolbar_new(label); + g_object_set(G_OBJECT(findtoolbar), "list", model, + "column", column, NULL); + + return findtoolbar; +} + +/** + * hildon_find_toolbar_highlight_entry + * @HildonFindToolbar: Find Toolbar whose entry is to be highlighted. + * @get_focus: if user passes TRUE to this value, then the text in + * the entry will not only get highlighted, but also get focused. + * + * */ +void +hildon_find_toolbar_highlight_entry(HildonFindToolbar *ftb, + gboolean get_focus) +{ + GtkWidget *entry = NULL; + + if(!HILDON_IS_FIND_TOOLBAR(ftb)) + return; + + entry = gtk_bin_get_child(GTK_BIN(ftb->priv->entry_combo_box)); + + gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1); + + if(get_focus) + gtk_widget_grab_focus(entry); +} diff --git a/hildon-widgets/hildon-find-toolbar.h b/hildon-widgets/hildon-find-toolbar.h new file mode 100644 index 0000000..5f87110 --- /dev/null +++ b/hildon-widgets/hildon-find-toolbar.h @@ -0,0 +1,80 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __HILDON_FIND_TOOLBAR_H__ +#define __HILDON_FIND_TOOLBAR_H__ + +#include +#include + +G_BEGIN_DECLS + +#define HILDON_TYPE_FIND_TOOLBAR (hildon_find_toolbar_get_type()) +#define HILDON_FIND_TOOLBAR(object) \ + (G_TYPE_CHECK_INSTANCE_CAST((object), HILDON_TYPE_FIND_TOOLBAR, \ + HildonFindToolbar)) +#define HILDON_FIND_TOOLBARClass(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), HILDON_TYPE_FIND_TOOLBAR, \ + HildonFindToolbarClass)) +#define HILDON_IS_FIND_TOOLBAR(object) \ + (G_TYPE_CHECK_INSTANCE_TYPE((object), HILDON_TYPE_FIND_TOOLBAR)) +#define HILDON_IS_FIND_TOOLBAR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), HILDON_TYPE_FIND_TOOLBAR)) +#define HILDON_FIND_TOOLBAR_GET_CLASS(object) \ + (G_TYPE_INSTANCE_GET_CLASS((object), HILDON_TYPE_FIND_TOOLBAR, \ + HildonFindToolbarClass)) + +typedef struct _HildonFindToolbar HildonFindToolbar; +typedef struct _HildonFindToolbarClass HildonFindToolbarClass; +typedef struct _HildonFindToolbarPrivate HildonFindToolbarPrivate; + +struct _HildonFindToolbar +{ + GtkToolbar parent; + + HildonFindToolbarPrivate *priv; +}; + +struct _HildonFindToolbarClass +{ + GtkToolbarClass parent_class; + + void (*search) (HildonFindToolbar *toolbar, gpointer data); + void (*close) (HildonFindToolbar *toolbar, gpointer data); + void (*invalid_input) (HildonFindToolbar *toolbar, gpointer data); + gboolean (*history_append) (HildonFindToolbar *tooblar, gpointer data); +}; + +GType hildon_find_toolbar_get_type (void); +GtkWidget* hildon_find_toolbar_new (gchar *label); +GtkWidget* hildon_find_toolbar_new_with_model (gchar *label, + GtkListStore* + model, + gint column); +void hildon_find_toolbar_highlight_entry (HildonFindToolbar *ftb, + gboolean get_focus); + +G_END_DECLS + +#endif diff --git a/hildon-widgets/hildon-get-password-dialog.c b/hildon-widgets/hildon-get-password-dialog.c index 394abdd..20a6fb2 100644 --- a/hildon-widgets/hildon-get-password-dialog.c +++ b/hildon-widgets/hildon-get-password-dialog.c @@ -32,9 +32,8 @@ #include -/* FIXME: These two includes are broken */ -#include -#include +#include "gtk-infoprint.h" +#include "hildon-input-mode-hint.h" #include #include diff --git a/hildon-widgets/hildon-input-mode-hint.h b/hildon-widgets/hildon-input-mode-hint.h new file mode 100644 index 0000000..33f9186 --- /dev/null +++ b/hildon-widgets/hildon-input-mode-hint.h @@ -0,0 +1,70 @@ +/* + * This file is part of hildon-libs + * + * Copyright (C) 2005 Nokia Corporation. + * + * Contact: Luc Pionchon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __HILDON_INPUT_MODE_HINT_H__ +#define __HILDON_INPUT_MODE_HINT_H__ + +G_BEGIN_DECLS + +/* Hildon wrapper for setting the input mode in a GtkEntry + * Usage: g_object_set(G_OBJECT(entry), HILDON_INPUT_MODE_HINT, HILDON_INPUT_MODE_HINT_HEXA, NULL); + */ +#define HILDON_INPUT_MODE_HINT "input-mode" + +/* Hildon wrapper for setting the autocapitalization in text widgets. + * Usage: g_object_set(G_OBJECT(entry), HILDON_AUTOCAP, FALSE, NULL); + */ +#define HILDON_AUTOCAP "autocap" + +/** + * HildonInputModeHint: + * @HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL: accept all characters. + * @HILDON_INPUT_MODE_HINT_NUMERIC: accept only NUMERIC characters. + * @HILDON_INPUT_MODE_HINT_ALPHA: accept only ALPHA characters + * @HILDON_INPUT_MODE_HINT_NUMERICSPECIAL: accept only NUMERIC and SPECIAL + * @HILDON_INPUT_MODE_HINT_ALPHASPECIAL: accept only ALPHA and SPECIAL + * @HILDON_INPUT_MODE_HINT_ALPHANUMERIC: accept only ALPHA and NUMERIC + * @HILDON_INPUT_MODE_HINT_HEXA: accept only HEXA + * @HILDON_INPUT_MODE_HINT_HEXASPECIAL: accept only HEXA and SPECIAL + * @HILDON_INPUT_MODE_HINT_TELE: accept only TELEPHONE + * @HILDON_INPUT_MODE_HINT_TELESPECIAL: accept only TELEPHONE and SPECIAL + * + * Keys to set the mode in a GtkEntry widget into ALPHANUMERIC or NUMERIC mode. Note that this is only a hint; it only shows VKB with specified layout. Use it by calling 'g_object_set(G_OBJECT(entry), "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL);'. + */ +typedef enum { + HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL = 0, + HILDON_INPUT_MODE_HINT_NUMERIC, + HILDON_INPUT_MODE_HINT_ALPHA, + HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, + HILDON_INPUT_MODE_HINT_ALPHASPECIAL, + HILDON_INPUT_MODE_HINT_ALPHANUMERIC, + HILDON_INPUT_MODE_HINT_HEXA, + HILDON_INPUT_MODE_HINT_HEXASPECIAL, + HILDON_INPUT_MODE_HINT_TELE, + HILDON_INPUT_MODE_HINT_TELESPECIAL + +} HildonInputModeHint; + +G_END_DECLS +#endif /* HILDON_INPUT_MODE_HINT_H */ diff --git a/po/Makefile.in b/po/Makefile.in index 43f5987..08ca523 100644 --- a/po/Makefile.in +++ b/po/Makefile.in @@ -94,6 +94,8 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ +LIBMB_CFLAGS = @LIBMB_CFLAGS@ +LIBMB_LIBS = @LIBMB_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -174,7 +176,7 @@ EXTRA_DIST = $(foreach po,$(languages),$(po).po) POTFILES.in README \ debian/compat \ debian/control \ debian/rules \ - debian/hildon-libs-l10n-engb.install \ + debian/hildon-libs-l10n-engb.install subdir = po ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 diff --git a/po/en_GB.po b/po/en_GB.po index fb60710..c1751ba 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -530,3 +530,17 @@ msgstr "No items" # determines the first day of the week (0 for Sunday, 1 for Monday etc.) msgid "week_start" msgstr "0" + +#: ../hildon-widgets/hildon-app.c:650 +msgid "ckct_ib_min_zoom_level_reached" +msgstr "Maximum zoom level reached" + +#: ../hildon-widgets/hildon-app.c:654 +msgid "ckct_ib_max_zoom_level_reached" +msgstr "Minimum zoom level reached" + +msgid "Ecdg_ti_find_toolbar_label" +msgstr "Find" + +msgid "Ecdg_ti_caption_separator" +msgstr ":" diff --git a/timer/Makefile.am b/timer/Makefile.am index 0e33f52..5205a7d 100644 --- a/timer/Makefile.am +++ b/timer/Makefile.am @@ -5,9 +5,7 @@ lib_LIBRARIES = libtimer.a EXTRA_DIST = -libtimer_a_SOURCES = \ - timer.h timer.c - +libtimer_a_SOURCES = timer.h timer.c + timerincludeinstdir=$(includedir)/hildon-lgpl/timer -timerincludeinst_DATA = \ - timer.h +timerincludeinst_DATA = timer.h diff --git a/timer/Makefile.in b/timer/Makefile.in index 5e0ed35..7d228be 100644 --- a/timer/Makefile.in +++ b/timer/Makefile.in @@ -64,6 +64,7 @@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DOXYGEN_FOUND = @DOXYGEN_FOUND@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -71,6 +72,8 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_GTK_DOC_FALSE = @ENABLE_GTK_DOC_FALSE@ ENABLE_GTK_DOC_TRUE = @ENABLE_GTK_DOC_TRUE@ +ESD_CFLAGS = @ESD_CFLAGS@ +ESD_LIBS = @ESD_LIBS@ EXEEXT = @EXEEXT@ F77 = @F77@ FFLAGS = @FFLAGS@ @@ -78,10 +81,14 @@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ +GNOME_VFS_CFLAGS = @GNOME_VFS_CFLAGS@ +GNOME_VFS_LIBS = @GNOME_VFS_LIBS@ GTKDOC = @GTKDOC@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ GTK_VERSION = @GTK_VERSION@ +HAVE_DOXYGEN_FALSE = @HAVE_DOXYGEN_FALSE@ +HAVE_DOXYGEN_TRUE = @HAVE_DOXYGEN_TRUE@ HTML_DIR = @HTML_DIR@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -122,11 +129,6 @@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ -X_CFLAGS = @X_CFLAGS@ -X_DIR = @X_DIR@ -X_EXTRA_LIBS = @X_EXTRA_LIBS@ -X_LIBS = @X_LIBS@ -X_PRE_LIBS = @X_PRE_LIBS@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ @@ -175,14 +177,10 @@ lib_LIBRARIES = libtimer.a EXTRA_DIST = -libtimer_a_SOURCES = \ - timer.h timer.c - +libtimer_a_SOURCES = timer.h timer.c timerincludeinstdir = $(includedir)/hildon-lgpl/timer -timerincludeinst_DATA = \ - timer.h - +timerincludeinst_DATA = timer.h subdir = timer ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs diff --git a/timer/timer.c b/timer/timer.c index 01c9f94..994b3ce 100644 --- a/timer/timer.c +++ b/timer/timer.c @@ -1,5 +1,5 @@ /* - * This file is part of hildon-lgpl + * This file is part of hildon-libs * * Copyright (C) 2005 Nokia Corporation. * diff --git a/timer/timer.h b/timer/timer.h index e2e89a6..b171540 100644 --- a/timer/timer.h +++ b/timer/timer.h @@ -1,5 +1,5 @@ /* - * This file is part of hildon-lgpl + * This file is part of hildon-libs * * Copyright (C) 2005 Nokia Corporation. * diff --git a/ut/Makefile.in b/ut/Makefile.in index eeadab2..76b01e4 100644 --- a/ut/Makefile.in +++ b/ut/Makefile.in @@ -94,6 +94,8 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ LDFLAGS = -module -avoid-version +LIBMB_CFLAGS = @LIBMB_CFLAGS@ +LIBMB_LIBS = @LIBMB_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ diff --git a/ut/hildon-widgets_tests.c b/ut/hildon-widgets_tests.c index 8406cb4..71aa561 100644 --- a/ut/hildon-widgets_tests.c +++ b/ut/hildon-widgets_tests.c @@ -50,7 +50,6 @@ #include #include #include -#include #include /* Icon which must exist (HildonGridItem). */ @@ -2909,16 +2908,6 @@ int test39b() return 1; } -#ifndef HILDON_DISABLE_DEPRECATED -int test41a() -{ - GtkWidget *fdialog; - - fdialog = hildon_file_details_dialog_new (NULL, "this is probably very very long filename"); - assert (HILDON_FILE_DETAILS_DIALOG (fdialog)); - return 1; -} -#endif testcase tcases[] = { {*test1a, "hildon_controlbar_new", EXPECT_OK}, @@ -3135,9 +3124,6 @@ testcase tcases[] = {*test37b, "gtk_banner_temporarily_disable_wrap", EXPECT_OK}, {*test39a, "namepassword dialog get_name", EXPECT_OK}, {*test39b, "namepassword dialog get_password", EXPECT_OK}, -#ifndef HILDON_DISABLE_DEPRECATED - {*test41a, "hildon_file_details_dialog_new", EXPECT_OK}, -#endif /* {*test38a, "gtk_confirmation_banner (sometext)", EXPECT_OK}, {*test38a, "gtk_confirmation_banner (NULL)", EXPECT_OK},*/ -- 1.7.9.5