+2006-02-14 Luc Pionchon <luc.pionchon@nokia.com>
+
+ * 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 <luc.pionchon@nokia.com>
* configure.ac: 0.10.2
-SUBDIRS = hildon-widgets ut doc
+SUBDIRS = hildon-widgets timer ut doc
EXTRA_DIST = \
debian/changelog \
debian/control \
INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
LDFLAGS = @LDFLAGS@
+LIBMB_CFLAGS = @LIBMB_CFLAGS@
+LIBMB_LIBS = @LIBMB_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
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 \
# include <unistd.h>
#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.
# Define the identity of the package.
PACKAGE=hildon-libs
- VERSION=0.10.2
+ VERSION=0.12.0
cat >>confdefs.h <<_ACEOF
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
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
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
+
+ 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"
- 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
# 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" ;;
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
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
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)
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
AC_OUTPUT(Makefile \
hildon-widgets/Makefile \
+ timer/Makefile \
ut/Makefile \
po/Makefile \
po/porules.mk \
+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 <luc.pionchon@nokia.com> 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.
Section: x11
Priority: optional
Maintainer: Luc Pionchon <luc.pionchon@nokia.com>
-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)
usr/include
usr/lib/*.so
+usr/lib/*.a
usr/lib/*.la
usr/lib/pkgconfig
INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
LDFLAGS = @LDFLAGS@
+LIBMB_CFLAGS = @LIBMB_CFLAGS@
+LIBMB_LIBS = @LIBMB_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
<xi:include href="xml/hildon-volumebar.xml"/>
<xi:include href="xml/hildon-vvolumebar.xml"/>
<xi:include href="xml/hildon-weekday-picker.xml"/>
- <xi:include href="xml/hildon-file-details-dialog.xml"/>
<xi:include href="xml/hildon-file-handling-note.xml"/>
<xi:include href="xml/hildon-grid-item.xml"/>
<xi:include href="xml/hildon-grid.xml"/>
#include <hildon-widgets/hildon-time-editor.h>
#include <hildon-widgets/hildon-time-picker.h>
#include <hildon-widgets/hildon-weekday-picker.h>
-#include <hildon-widgets/hildon-file-details-dialog.h>
#include <hildon-widgets/hildon-file-handling-note.h>
hildon_color_selector_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
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+gtk-infoprint
+
+<!-- ##### SECTION Short_Description ##### -->
+A widget which provides methods to show a small amount of information for the user.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+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.
+
+<informalexample>
+<programlisting>
+
+ gtk_infoprint( window, "This is a default infoprint" );
+ gtk_banner_show_animation( window, "This is an animated banner" );
+
+</programlisting>
+</informalexample>
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION gtk_infoprint_with_icon_stock ##### -->
+<para>
+
+</para>
+
+@parent:
+@text:
+@stock_id:
+
+
+<!-- ##### FUNCTION gtk_infoprintf ##### -->
+<para>
+
+</para>
+
+@parent:
+@format:
+@Varargs:
+
+
+<!-- ##### FUNCTION gtk_infoprint_temporarily_disable_wrap ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION gtk_confirmation_banner ##### -->
+<para>
+
+</para>
+
+@parent:
+@text:
+@stock_id:
+
+
+<!-- ##### FUNCTION gtk_banner_show_animation ##### -->
+<para>
+
+</para>
+
+@parent:
+@text:
+
+
+<!-- ##### FUNCTION gtk_banner_show_bar ##### -->
+<para>
+
+</para>
+
+@parent:
+@text:
+
+
+<!-- ##### FUNCTION gtk_banner_set_text ##### -->
+<para>
+
+</para>
+
+@parent:
+@text:
+
+
+<!-- ##### FUNCTION gtk_banner_set_fraction ##### -->
+<para>
+
+</para>
+
+@parent:
+@fraction:
+
+
+<!-- ##### FUNCTION gtk_banner_close ##### -->
+<para>
+
+</para>
+
+@parent:
+
+
+<!-- ##### FUNCTION gtk_banner_temporarily_disable_wrap ##### -->
+<para>
+
+</para>
+
+
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+HildonAddHomeDialog
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION hildon_add_home_dialog_new ##### -->
+<para>
+
+</para>
+
+@parent:
+@name:
+@new_name:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_add_home_dialog_get_name ##### -->
+<para>
+
+</para>
+
+@dialog:
+@Returns:
+
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+HildonApp
+
+<!-- ##### SECTION Short_Description ##### -->
+A base widget to present application.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+This is the base for any hildon application.
+It controls basic looks and functionality of an application, like a title.
+
+<informalexample>
+<programlisting>
+
+app = hildon_app_new_with_appview( appview );
+
+hildon_app_set_title( app, "This is a hello dude application" );
+
+</programlisting>
+</informalexample>
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### STRUCT HildonApp ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ENUM HildonZoomLevel ##### -->
+<para>
+
+</para>
+
+@HILDON_ZOOM_SMALL:
+@HILDON_ZOOM_MEDIUM:
+@HILDON_ZOOM_LARGE:
+
+<!-- ##### FUNCTION hildon_app_new ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_new_with_appview ##### -->
+<para>
+
+</para>
+
+@appview:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_set_appview ##### -->
+<para>
+
+</para>
+
+@self:
+@appview:
+
+
+<!-- ##### FUNCTION hildon_app_get_appview ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_set_title ##### -->
+<para>
+
+</para>
+
+@self:
+@newtitle:
+
+
+<!-- ##### FUNCTION hildon_app_get_title ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_set_zoom ##### -->
+<para>
+
+</para>
+
+@self:
+@newzoom:
+
+
+<!-- ##### FUNCTION hildon_app_get_zoom ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_get_default_font ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_get_zoom_font ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_set_two_part_title ##### -->
+<para>
+
+</para>
+
+@self:
+@istwoparttitle:
+
+
+<!-- ##### FUNCTION hildon_app_get_two_part_title ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_unregister_view ##### -->
+<para>
+
+</para>
+
+@self:
+@view_ptr:
+
+
+<!-- ##### FUNCTION hildon_app_register_view ##### -->
+<para>
+
+</para>
+
+@self:
+@view_ptr:
+
+
+<!-- ##### FUNCTION hildon_app_notify_view_changed ##### -->
+<para>
+
+</para>
+
+@self:
+@view_ptr:
+
+
+<!-- ##### FUNCTION hildon_app_set_killable ##### -->
+<para>
+
+</para>
+
+@self:
+@killability:
+
+
+<!-- ##### FUNCTION hildon_app_find_view_id ##### -->
+<para>
+
+</para>
+
+@self:
+@view_ptr:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_app_register_view_with_id ##### -->
+<para>
+
+</para>
+
+@self:
+@view_ptr:
+@Param3:
+@Returns:
+<!-- # Unused Parameters # -->
+@view_id:
+
+
+<!-- ##### FUNCTION hildon_app_unregister_view_with_id ##### -->
+<para>
+
+</para>
+
+@self:
+@Param2:
+<!-- # Unused Parameters # -->
+@view_id:
+
+
+<!-- ##### FUNCTION hildon_app_set_autoregistration ##### -->
+<para>
+
+</para>
+
+@self:
+@auto_reg:
+
+
+<!-- ##### SIGNAL HildonApp::clipboard-copy ##### -->
+<para>
+
+</para>
+
+@hildonapp: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL HildonApp::clipboard-cut ##### -->
+<para>
+
+</para>
+
+@hildonapp: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL HildonApp::clipboard-paste ##### -->
+<para>
+
+</para>
+
+@hildonapp: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL HildonApp::im-close ##### -->
+<para>
+
+</para>
+
+@hildonapp: the object which received the signal.
+
+<!-- ##### SIGNAL HildonApp::switch-to ##### -->
+<para>
+
+</para>
+
+@hildonapp: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL HildonApp::topmost-status-acquire ##### -->
+<para>
+
+</para>
+
+@hildonapp: the object which received the signal.
+
+<!-- ##### SIGNAL HildonApp::topmost-status-lose ##### -->
+<para>
+
+</para>
+
+@hildonapp: the object which received the signal.
+
+<!-- ##### ARG HildonApp:app-title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonApp:killable ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonApp:scroll-control ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonApp:two-part-title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonApp:zoom ##### -->
+<para>
+
+</para>
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+HildonAppView
+
+<!-- ##### SECTION Short_Description ##### -->
+A widget which present one view of an application.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+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.
+
+<informalexample>
+<programlisting>
+
+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 );
+
+</programlisting>
+</informalexample>
+
+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.
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### STRUCT HildonAppViewPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT HildonAppView ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION hildon_appview_new ##### -->
+<para>
+
+</para>
+
+@title:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_appview_add_with_scrollbar ##### -->
+<para>
+
+</para>
+
+@self:
+@child:
+
+
+<!-- ##### FUNCTION hildon_appview_set_fullscreen_key_allowed ##### -->
+<para>
+
+</para>
+
+@self:
+@allow:
+
+
+<!-- ##### FUNCTION hildon_appview_get_fullscreen_key_allowed ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_appview_get_fullscreen ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_appview_set_fullscreen ##### -->
+<para>
+
+</para>
+
+@self:
+@fullscreen:
+
+
+<!-- ##### FUNCTION hildon_appview_get_menu ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_appview_set_toolbar ##### -->
+<para>
+
+</para>
+
+@self:
+@toolbar:
+
+
+<!-- ##### FUNCTION hildon_appview_get_toolbar ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_appview_set_title ##### -->
+<para>
+
+</para>
+
+@self:
+@newname:
+
+
+<!-- ##### FUNCTION hildon_appview_get_title ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_appview_set_connected_adjustment ##### -->
+<para>
+
+</para>
+
+@self:
+@adjustment:
+
+
+<!-- ##### FUNCTION hildon_appview_get_connected_adjustment ##### -->
+<para>
+
+</para>
+
+@self:
+@Returns:
+
+
+<!-- ##### SIGNAL HildonAppView::decrease-button-event ##### -->
+<para>
+
+</para>
+
+@hildonappview: the object which received the signal.
+@arg1: the Gdk key state.
+
+<!-- ##### SIGNAL HildonAppView::fullscreen-state-change ##### -->
+<para>
+
+</para>
+
+@hildonappview: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL HildonAppView::increase-button-event ##### -->
+<para>
+
+</para>
+
+@hildonappview: the object which received the signal.
+@arg1: the Gdk key state.
+
+<!-- ##### SIGNAL HildonAppView::switched-from ##### -->
+<para>
+
+</para>
+
+@hildonappview: the object which received the signal.
+
+<!-- ##### SIGNAL HildonAppView::switched-to ##### -->
+<para>
+
+</para>
+
+@hildonappview: the object which received the signal.
+
+<!-- ##### SIGNAL HildonAppView::title-change ##### -->
+<para>
+
+</para>
+
+@hildonappview: the object which received the signal.
+
+<!-- ##### SIGNAL HildonAppView::toolbar-changed ##### -->
+<para>
+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.
+
+</para>
+
+@hildonappview: the object which received the signal.
+
+<!-- ##### SIGNAL HildonAppView::toolbar-toggle-request ##### -->
+<para>
+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.
+
+</para>
+
+@hildonappview: the object which received the signal.
+
+<!-- ##### ARG HildonAppView:connected-adjustment ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonAppView:fullscreen ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonAppView:fullscreen-key-allowed ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonAppView:title ##### -->
+<para>
+
+</para>
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+HildonCaption
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<para>
+<informalexample>
+<programlisting>
+<!-- hildon-tests/wt/hildon-widgets-combo/testcaptioncontrol.c -->
+##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 ("");
+
+}
+</programlisting>
+</informalexample>
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### ENUM HildonCaptionStatus ##### -->
+<para>
+
+</para>
+
+@HILDON_CAPTION_OPTIONAL:
+@HILDON_CAPTION_MANDATORY:
+
+<!-- ##### STRUCT HildonCaption ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION hildon_caption_new ##### -->
+<para>
+
+</para>
+
+@group:
+@value:
+@control:
+@icon:
+@flag:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_caption_get_sizegroup ##### -->
+<para>
+
+</para>
+
+@caption:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_caption_set_sizegroup ##### -->
+<para>
+
+</para>
+
+@caption:
+@new_group:
+
+
+<!-- ##### FUNCTION hildon_caption_is_mandatory ##### -->
+<para>
+
+</para>
+
+@caption:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_caption_set_status ##### -->
+<para>
+
+</para>
+
+@caption:
+@flag:
+
+
+<!-- ##### FUNCTION hildon_caption_get_status ##### -->
+<para>
+
+</para>
+
+@caption:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_caption_set_icon_image ##### -->
+<para>
+
+</para>
+
+@caption:
+@icon:
+
+
+<!-- ##### FUNCTION hildon_caption_get_icon_image ##### -->
+<para>
+
+</para>
+
+@caption:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_caption_set_label ##### -->
+<para>
+
+</para>
+
+@caption:
+@label:
+
+
+<!-- ##### FUNCTION hildon_caption_get_label ##### -->
+<para>
+
+</para>
+
+@caption:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_caption_get_control ##### -->
+<para>
+
+</para>
+
+@caption:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_caption_set_control ##### -->
+<para>
+
+</para>
+
+@caption:
+@control:
+
+
+<!-- ##### SIGNAL HildonCaption::activate ##### -->
+<para>
+
+</para>
+
+@hildoncaption: the object which received the signal.
+
+<!-- ##### ARG HildonCaption:icon ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonCaption:label ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonCaption:separator ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonCaption:size-group ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonCaption:status ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonCaption:expand ##### -->
+<para>
+
+</para>
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+hildon-color-popup
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION hildon_color_popup_new ##### -->
+<para>
+
+</para>
+
+@parent:
+@initial_color:
+@popupdata:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_color_popup_set_color_from_sliders ##### -->
+<para>
+
+</para>
+
+@color:
+@popupdata:
+
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+hildon-composite-widget
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION hildon_composite_widget_focus ##### -->
+<para>
+
+</para>
+
+@widget:
+@direction:
+@Returns:
+
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+hildon-defines
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION hildon_icon_sizes_init ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### STRUCT HildonIconSizes ##### -->
+<para>
+
+</para>
+
+@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:
+
+<!-- ##### VARIABLE hildoniconsizes ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_CHECK_AND_GET ##### -->
+<para>
+
+</para>
+
+@iconvar:
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_LIST ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_SMALL ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_TOOLBAR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_WIDG ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_WIDG_WIZARD ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_GRID ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_BIG_NOTE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_NOTE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_STATUSBAR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_VIDEO_PLAYER_PRE_ROLL ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_COPY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_DELETE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_PROCESS ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_PROGRESSBALL ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_SEND ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_OFFMODE_CHARGING ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_TAP_AND_HOLD ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_SEND_RECEIVE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_SIZE_INDI_WLAN_STRENGTH ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_IMAGE_SIZE_INDI_NOKIA_LOGO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_IMAGE_SIZE_INDI_STARTUP_FAILED ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_IMAGE_SIZE_INDI_STARTUP_NOKIA_LOGO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_IMAGE_SIZE_INDI_NOKIA_HAND ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_LIST ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_SMALL ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_TOOLBAR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_WIDG ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_WIDG_WIZARD ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_GRID ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_BIG_NOTE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_NOTE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_STATUSBAR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_VIDEO_PLAYER_PRE_ROLL ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_KEY_PAD_LOCK ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_COPY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_DELETE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_PROCESS ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_PROGRESSBALL ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_SEND ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_OFFMODE_CHARGING ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_TAP_AND_HOLD ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_SEND_RECEIVE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_ICON_PIXEL_SIZE_INDI_WLAN_STRENGTH ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_IMAGE_PIXEL_SIZE_INDI_NOKIA_LOGO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_IMAGE_PIXEL_SIZE_INDI_STARTUP_FAILED ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_IMAGE_PIXEL_SIZE_INDI_STARTUP_NOKIA_LOGO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_IMAGE_PIXEL_SIZE_INDI_NOKIA_HANDS ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_MARGIN_HALF ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_MARGIN_DEFAULT ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_MARGIN_DOUBLE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_MARGIN_TRIPLE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_UP ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_LEFT ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_RIGHT ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_DOWN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_SELECT ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_MENU ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_HOME ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_ESC ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_FULLSCREEN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_INCREASE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO HILDON_HARDKEY_DECREASE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION hildon_gtk_widget_set_logical_font ##### -->
+<para>
+
+</para>
+
+@widget:
+@logicalfontname:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_gtk_widget_set_logical_color ##### -->
+<para>
+
+</para>
+
+@widget:
+@rcflags:
+@state:
+@logicalcolorname:
+@Returns:
+
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+HildonFindToolbar
+
+<!-- ##### SECTION Short_Description ##### -->
+A special toolbar to be used with HildonAppView.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+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.
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### STRUCT HildonFindToolbar ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION hildon_find_toolbar_new ##### -->
+<para>
+Create a HildonFindToolbar without any preset GtkListStore.
+</para>
+
+@label:
+@Returns:
+
+
+<!-- ##### FUNCTION hildon_find_toolbar_new_with_model ##### -->
+<para>
+Creat a HildonFindToolbar with a preset GtkListStore.
+</para>
+
+@label:
+@model:
+@column:
+@Returns:
+
+
+<!-- ##### SIGNAL HildonFindToolbar::close ##### -->
+<para>
+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.
+</para>
+
+@hildonfindtoolbar: the object which received the signal.
+
+<!-- ##### SIGNAL HildonFindToolbar::history-append ##### -->
+<para>
+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.
+
+</para>
+
+@hildonfindtoolbar: the object which received the signal.
+@Returns:
+
+<!-- ##### SIGNAL HildonFindToolbar::invalid-input ##### -->
+<para>
+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.
+</para>
+
+@hildonfindtoolbar: the object which received the signal.
+
+<!-- ##### SIGNAL HildonFindToolbar::search ##### -->
+<para>
+It is emitted everytime the search button is clicked, even the GtkComboboxEntry is empty.
+</para>
+
+@hildonfindtoolbar: the object which received the signal.
+
+<!-- ##### ARG HildonFindToolbar:column ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonFindToolbar:history-limit ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonFindToolbar:label ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonFindToolbar:list ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonFindToolbar:max-characters ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG HildonFindToolbar:prefix ##### -->
+<para>
+
+</para>
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+hildon-input-mode-hint
+
+<!-- ##### SECTION Short_Description ##### -->
+Wrappers for setting GtkEntry and GtkTextView input modes and autocapitalization.
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+<informalexample>
+<programlisting>
+
+g_object_set(G_OBJECT(entry), "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
+
+g_object_set(G_OBJECT(entry), "autocap", FALSE, NULL);
+
+
+</programlisting>
+</informalexample>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### MACRO HILDON_INPUT_MODE_HINT ##### -->
+<para>
+
+Use this to set the input mode in text widget. Note that this affects
+only input methods layout.
+
+</para>
+
+
+
+<!-- ##### ENUM HildonInputModeHint ##### -->
+<para>
+
+</para>
+
+@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:
+
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+hildon-marshalers
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
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}
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
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 \
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 \
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 \
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 \
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
INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
LDFLAGS = @LDFLAGS@
+LIBMB_CFLAGS = @LIBMB_CFLAGS@
+LIBMB_LIBS = @LIBMB_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
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
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-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 \
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
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 \
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
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 \
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@
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#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;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gtk/gtkwindow.h>
+
+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__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gdk/gdk.h>
+#include "hildon-app.h"
+#include "hildon-app-private.h"
+#include "hildon-appview.h"
+#include "gtk-infoprint.h"
+
+#include <gdk/gdkevents.h>
+#include <gdk/gdkkeysyms.h>
+#include <X11/Xatom.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkeditable.h>
+#include <gtk/gtktextview.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkuimanager.h>
+#include <gtk/gtkactiongroup.h>
+#include <gtk/gtkdialog.h>
+
+#include <libintl.h>
+#include <string.h>
+
+#include <libmb/mbutil.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#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;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gtk/gtkwindow.h>
+#include <gtk/gtkuimanager.h>
+#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 */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <memory.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include "hildon-app.h"
+#include <hildon-appview.h>
+#include <hildon-find-toolbar.h>
+
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkimcontext.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkcheckmenuitem.h>
+#include <gtk/gtkmenushell.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkprogressbar.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkiconfactory.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdk.h>
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+
+#include <libintl.h>
+#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);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkbin.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtktoolbar.h>
+#include <gdk/gdkx.h>
+
+
+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 */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkcombo.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkcomboboxentry.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkmarshal.h>
+#include <gtk/gtkalignment.h>
+#include <stdio.h>
+#include <string.h>
+#include "hildon-caption.h"
+#include "hildon-defines.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <libintl.h>
+#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;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkeventbox.h>
+#include <gtk/gtksizegroup.h>
+
+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__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gtk/gtk.h>
+#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;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gtk/gtkwindow.h>
+#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 */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005 Nokia Corporation.
- *
- * Contact: Luc Pionchon <luc.pionchon@nokia.com>
- *
- * 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 <gtk/gtkcheckbutton.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtknotebook.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkscrolledwindow.h>
-#include <time.h>
-#include <libintl.h>
-#include <libgnomevfs/gnome-vfs.h>
-
-#include <hildon-widgets/hildon-caption.h>
-#include <hildon-widgets/hildon-file-system-model.h>
-#include <hildon-widgets/gtk-infoprint.h>
-#include <hildon-widgets/hildon-defines.h>
-#include "hildon-file-details-dialog.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#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;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005 Nokia Corporation.
- *
- * Contact: Luc Pionchon <luc.pionchon@nokia.com>
- *
- * 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 <gtk/gtkdialog.h>
-#include <gtk/gtktreemodel.h>
-#include <hildon-widgets/hildon-file-system-model.h>
-
-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__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gdk/gdkkeysyms.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtktoolbutton.h>
+#include <gtk/gtktoolitem.h>
+#include <gtk/gtkcomboboxentry.h>
+#include <gtk/gtkseparatortoolitem.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <libintl.h>
+#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);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 <gtk/gtktoolbar.h>
+#include <gtk/gtkliststore.h>
+
+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
#include <gtk/gtk.h>
-/* FIXME: These two includes are broken */
-#include <hildon-lgpl/hildon-widgets/gtk-infoprint.h>
-#include <hildon-lgpl/hildon-widgets/hildon-input-mode-hint.h>
+#include "gtk-infoprint.h"
+#include "hildon-input-mode-hint.h"
#include <hildon-widgets/hildon-caption.h>
#include <hildon-widgets/hildon-get-password-dialog.h>
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005 Nokia Corporation.
+ *
+ * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ *
+ * 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 */
INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
LDFLAGS = @LDFLAGS@
+LIBMB_CFLAGS = @LIBMB_CFLAGS@
+LIBMB_LIBS = @LIBMB_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
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
# 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 ":"
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
DATADIRNAME = @DATADIRNAME@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DOXYGEN_FOUND = @DOXYGEN_FOUND@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
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@
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@
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@
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
/*
- * This file is part of hildon-lgpl
+ * This file is part of hildon-libs
*
* Copyright (C) 2005 Nokia Corporation.
*
/*
- * This file is part of hildon-lgpl
+ * This file is part of hildon-libs
*
* Copyright (C) 2005 Nokia Corporation.
*
INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
LDFLAGS = -module -avoid-version
+LIBMB_CFLAGS = @LIBMB_CFLAGS@
+LIBMB_LIBS = @LIBMB_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
#include <hildon-widgets/hildon-grid.h>
#include <hildon-widgets/hildon-time-editor.h>
#include <hildon-widgets/hildon-name-password-dialog.h>
-#include <hildon-widgets/hildon-file-details-dialog.h>
#include <outo.h>
/* Icon which must exist (HildonGridItem). */
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},
{*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},*/