diff --git a/Makefile.am b/Makefile.am index 28f1d33..310f590 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,7 @@ ## Process this file with automake to produce Makefile.in ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} -SUBDIRS = xed pixmaps po data plugin-loaders plugins docs help - -if ENABLE_TESTS - SUBDIRS += tests -endif +SUBDIRS = xed pixmaps po data plugins docs help distuninstallcheck_listfiles = find . -type f -print @@ -55,7 +51,7 @@ MAINTAINERCLEANFILES = \ m4/lt~obsolete.m4 \ `find "$(srcdir)" -type f -name Makefile.in -print` -DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --disable-tests +DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc dist-hook: @if test -d "$(srcdir)/.git"; \ diff --git a/autogen.sh b/autogen.sh index 6769318..56ea79f 100755 --- a/autogen.sh +++ b/autogen.sh @@ -24,7 +24,6 @@ which yelp-build || { } REQUIRED_AUTOMAKE_VERSION=1.9 -REQUIRED_MACROS=python.m4 GNOME_DATADIR="$gnome_datadir" USE_COMMON_DOC_BUILD=yes diff --git a/configure.ac b/configure.ac index e37126a..29e9783 100644 --- a/configure.ac +++ b/configure.ac @@ -49,12 +49,6 @@ dnl toolbar style for GSettings schemas TOOLBAR_STYLE="XED_TOOLBAR_SYSTEM" AC_SUBST(TOOLBAR_STYLE) -# GLib min/max required versions -AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_36], - [Warn on use of APIs added after GLib 2.36]) -AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_36], - [Warn on use of APIs deprecated before GLib 2.36]) - dnl =============================================================== dnl Expanded dirs dnl =============================================================== @@ -151,12 +145,14 @@ dnl ================================================================ PKG_CHECK_MODULES(GMODULE,gmodule-2.0,[GMODULE_ADD="gmodule-2.0"],[GMODULE_ADD=""]) PKG_CHECK_MODULES(XED, [ libxml-2.0 >= 2.5.0 - glib-2.0 >= 2.36.0 + glib-2.0 >= 2.40.0 $GMODULE_ADD gthread-2.0 >= 2.13.0 - gio-2.0 >= 2.26.0 - gtk+-3.0 >= 3.10.0 - gtksourceview-3.0 >= 2.9.7 + gio-2.0 >= 2.40.0 + gtk+-3.0 >= 3.14.0 + gtksourceview-3.0 >= 3.14.3 + libpeas-1.0 >= 1.12.0 + libpeas-gtk-1.0 >= 1.12.0 ]) PKG_CHECK_MODULES(X11, [x11]) @@ -167,10 +163,15 @@ XED_LIBS="$XED_LIBS $X11_LIBS" AC_SUBST(XED_CFLAGS) AC_SUBST(XED_LIBS) -PKG_CHECK_MODULES(EGG_SMCLIENT, [sm >= 1.0.0]) +# Introspection +GOBJECT_INTROSPECTION_CHECK([0.9.3]) -AC_SUBST(EGG_SMCLIENT_CFLAGS) -AC_SUBST(EGG_SMCLIENT_LIBS) +if test "$found_introspection" = "yes"; then + enable_introspection=yes + AC_DEFINE([ENABLE_INTROSPECTION], [1], [Define to enable GObject Introspection]) +else + enable_introspection=no +fi dnl ================================================================ dnl GSettings related settings @@ -178,126 +179,10 @@ dnl ================================================================ GLIB_GSETTINGS -dnl ================================================================ -dnl Python -dnl ================================================================ - -AC_MSG_CHECKING([whether Python support is requested]) -AC_ARG_ENABLE([python], - AS_HELP_STRING([--enable-python],[Enable python support]), - [enable_python=$enableval have_python=$enableval], - [enable_python=autodetect have_python=yes]) -AC_MSG_RESULT([$enable_python]) - -if test "x$have_python" != "xno"; then - AM_PATH_PYTHON([2.5],[],[no]) - if test "x$PYTHON" = "x:"; then - have_python=no - fi -fi - -if test "x$have_python" != "xno"; then - AM_CHECK_PYTHON_HEADERS([],[have_python=no]) -fi - -if test "x$have_python" != "xno"; then - PY_EXEC_PREFIX=`$PYTHON -c 'import sys ; print sys.exec_prefix'` - PYTHON_LIBS="-lpython$PYTHON_VERSION" - - PY_PREFIX=`$PYTHON -c 'import sys ; print sys.prefix'` - PYTHON_LIB_LOC="-L$libdir/python$PYTHON_VERSION/config" - PYTHON_CFLAGS="-I$PY_PREFIX/include/python$PYTHON_VERSION" - PYTHON_MAKEFILE="$libdir/python$PYTHON_VERSION/config/Makefile" - PYTHON_BASEMODLIBS=`sed -n -e 's/^BASEMODLIBS=\(.*\)/\1/p' $PYTHON_MAKEFILE` - PYTHON_OTHER_LIBS=`sed -n -e 's/^LIBS=\(.*\)/\1/p' $PYTHON_MAKEFILE` - PYTHON_EXTRA_LIBS="$PYTHON_BASEMODLIBS $PYTHON_OTHER_LIBS" - - AC_SUBST([PYTHON_LIBS]) - AC_SUBST([PYTHON_LIB_LOC]) - AC_SUBST([PYTHON_CFLAGS]) - AC_SUBST([PYTHON_EXTRA_LIBS]) -fi - -if test "x$have_python" != "xyes"; then - if test "x$enable_python" = "xyes"; then - AC_MSG_ERROR([Python not found]) - elif test "x$enable_python" = "xautodetect"; then - enable_python=no - AC_MSG_WARN([Python not found, disabling python support]) - fi -fi - -if test "x$have_python" != "xno"; then - PYGOBJECT_REQUIRED=2.15.4 - PYGTK_REQUIRED=2.12.0 - PYGTKSOURCEVIEW_REQUIRED=2.9.2 - - PKG_CHECK_MODULES([PYGTK], [ - pygobject-2.0 >= $PYGOBJECT_REQUIRED - pygtk-2.0 >= $PYGTK_REQUIRED - pygtksourceview-2.0 >= $PYGTKSOURCEVIEW_REQUIRED], - [], - [ - have_python=no - if test "x$enable_python" = "xyes"; then - AC_MSG_ERROR([$PYGTK_PKG_ERRORS]) - elif test "x$enable_python" = "xautodetect"; then - enable_python=no - AC_MSG_WARN([$PYGTK_PKG_ERRORS]) - AC_MSG_WARN([Disabling python support]) - fi - ]) -fi - -if test "x$have_python" != "xno"; then - AC_MSG_CHECKING([for pygtk defs]) - PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0` - AC_MSG_RESULT([$PYGTK_DEFSDIR]) - - AC_MSG_CHECKING([for pygobject defs]) - PYGOBJECT_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygobject-2.0` - AC_MSG_RESULT([$PYGOBJECT_DEFSDIR]) - - AC_MSG_CHECKING([for pygtk codegen]) - PYGTK_CODEGEN="$PYTHON `$PKG_CONFIG --variable=codegendir pygtk-2.0`/codegen.py" - AC_MSG_RESULT([$PYGTK_CODEGEN]) - - AC_MSG_CHECKING([for pygtk h2def]) - PYGTK_H2DEF="$PYTHON `$PKG_CONFIG --variable=codegendir pygtk-2.0`/h2def.py" - AC_MSG_RESULT([$PYGTK_H2DEF]) - - AC_SUBST([PYGTK_DEFSDIR]) - AC_SUBST([PYGOBJECT_DEFSDIR]) - AC_SUBST([PYGTK_CODEGEN]) - AC_SUBST([PYGTK_H2DEF]) - - dnl Check for -fno-strict-aliasing - FLAGS="-fno-strict-aliasing" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $FLAGS" - AC_MSG_CHECKING([whether [$]CC understands $FLAGS]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[compiler_has_option=yes],[compiler_has_option=no]) - CFLAGS="$save_CFLAGS" - AC_MSG_RESULT($compiler_has_option) - if test $compiler_has_option = yes; then - NO_STRICT_ALIASING_CFLAGS="$FLAGS" - fi - AC_SUBST([NO_STRICT_ALIASING_CFLAGS]) -fi - -if test "x$have_python" != "xno" -a "x$enable_python" != "xno"; then - enable_python=yes - AC_DEFINE([ENABLE_PYTHON],[1],[Define to compile with python support]) -fi - -AM_CONDITIONAL([ENABLE_PYTHON],[test "x$enable_python" = "xyes"]) - -dnl This allows the bug-report script to know whether python has been enabled -AC_SUBST(enable_python) - dnl ================================================================ dnl Misc dnl ================================================================ +AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources) AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal) AC_PATH_PROG(GLIB_MKENUMS, glib-mkenums) @@ -318,18 +203,9 @@ if test "x$enable_deprecations" = "xyes"; then AC_SUBST(DISABLE_DEPRECATED_CFLAGS) fi -AC_ARG_ENABLE([tests], - AS_HELP_STRING([--enable-tests], [Enable the tests]), - [enable_tests=$enableval], - [enable_tests=yes]) - -AM_CONDITIONAL(ENABLE_TESTS, test x$enable_tests = xyes) - PLUGIN_LIBTOOL_FLAGS="-module -avoid-version" -LOADER_LIBTOOL_FLAGS="-module -avoid-version" AC_SUBST(PLUGIN_LIBTOOL_FLAGS) -AC_SUBST(LOADER_LIBTOOL_FLAGS) XED_PLUGINS_DATA_DIR="$datadir/xed/plugins" AC_SUBST(XED_PLUGINS_DATA_DIR) @@ -348,17 +224,10 @@ data/org.x.editor.gschema.xml data/Makefile docs/Makefile docs/reference/Makefile -xed/dialogs/Makefile -xed/smclient/Makefile xed/Makefile help/Makefile pixmaps/Makefile -plugin-loaders/Makefile -plugin-loaders/c/Makefile -plugin-loaders/python/Makefile -plugin-loaders/python/bindings/Makefile plugins/Makefile -plugins/changecase/Makefile plugins/docinfo/Makefile plugins/filebrowser/Makefile plugins/filebrowser/org.x.editor.plugins.filebrowser.gschema.xml @@ -371,7 +240,6 @@ plugins/time/Makefile plugins/time/org.x.editor.plugins.time.gschema.xml plugins/trailsave/Makefile po/Makefile.in -tests/Makefile ]) AC_OUTPUT @@ -381,9 +249,8 @@ echo " Configuration: Source code location: ${srcdir} - Compiler: ${CC} - Python Plugins Support: $enable_python + Compiler: ${CC} Spell Plugin enabled: $enable_enchant Gvfs metadata enabled: $enable_gvfs_metadata - Tests enabled: $enable_tests + GObject Introspection: ${enable_introspection} " diff --git a/data/Makefile.am b/data/Makefile.am index 067ad8f..c234c15 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -4,13 +4,22 @@ desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) @INTLTOOL_DESKTOP_RULE@ @INTLTOOL_XML_RULE@ + appdatadir = $(datadir)/appdata appdata_in_files = xed.appdata.xml.in appdata_DATA = $(appdata_in_files:.xml.in=.xml) gsettings_SCHEMAS = org.x.editor.gschema.xml + @GSETTINGS_RULES@ +servicedir = $(datadir)/dbus-1/services +service_in_files = org.x.editor.service.in +service_DATA = $(service_in_files:.service.in=.service) + +$(service_DATA): $(service_in_files) Makefile + @sed -e "s|\@bindir\@|$(bindir)|" $<> $@ + man_MANS = xed.1 pkgconfigdir = $(libdir)/pkgconfig @@ -22,12 +31,14 @@ bugreport_SCRIPTS = xed-bugreport.sh EXTRA_DIST = \ $(appdata_in_files) \ $(desktop_in_files) \ + $(service_in_files) \ $(man_MANS) \ xed.pc.in \ xed-bugreport.sh.in CLEANFILES = \ $(desktop_DATA) \ + $(service_DATA) \ $(gsettings_SCHEMAS) \ $(pkgconfig_DATA) \ $(appdata_DATA) diff --git a/data/org.x.editor.gschema.xml.in b/data/org.x.editor.gschema.xml.in index 8dc46c9..371ebf4 100644 --- a/data/org.x.editor.gschema.xml.in +++ b/data/org.x.editor.gschema.xml.in @@ -1,195 +1,342 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true Use Default Font Whether to use the system's default fixed width font for editing text instead of a font specific to xed. If this option is turned off, then the font named in the "Editor Font" option will be used instead of the system font. + 'Monospace 12' Editor Font A custom font that will be used for the editing area. This will only take effect if the "Use Default Font" option is turned off. - + + + false + Prefer Dark Theme + Whether xed should prefer the dark variation of the current Gtk theme if available. + + + 'tango' Style Scheme The ID of a GtkSourceView Style Scheme used to color the text. + false Create Backup Copies Whether xed should create backup copies for the files it saves. You can set the backup file extension with the "Backup Copy Extension" option. + false Autosave Whether xed should automatically save modified files after a time interval. You can set the time interval with the "Autosave Interval" option. - + + 10 Autosave Interval Number of minutes after which xed will automatically save modified files. This will only take effect if the "Autosave" option is turned on. + [ 'dav', 'davs', 'ftp', 'sftp', 'smb', 'ssh' ] Writable VFS schemes List of VFS schemes xed supports in write mode. The 'file' scheme is writable by default. + 2000 Maximum Number of Undo Actions Maximum number of actions that xed will be able to undo or redo. Use "-1" for unlimited number of actions. - - 'GTK_WRAP_WORD' + + + 'word' Line Wrapping Mode - Specifies how to wrap long lines in the editing area. Use "GTK_WRAP_NONE" for no wrapping, "GTK_WRAP_WORD" for wrapping at word boundaries, and "GTK_WRAP_CHAR" for wrapping at individual character boundaries. Note that the values are case-sensitive, so make sure they appear exactly as mentioned here. + Specifies how to wrap long lines in the editing area. Use "none" for no wrapping, "word" for wrapping at word boundaries, and "char" for wrapping at individual character boundaries. Note that the values are case-sensitive, so make sure they appear exactly as mentioned here. - + + 4 Tab Size Specifies the number of spaces that should be displayed instead of Tab characters. + true Insert spaces Whether xed should insert spaces instead of tabs. + false Automatic indent Whether xed should enable automatic indentation. + false Display Line Numbers Whether xed should display line numbers in the editing area. + false Highlight Current Line Whether xed should highlight the current line. + false Highlight Matching Bracket Whether xed should highlight the bracket matching the selected one. + false Display Right Margin Whether xed should display the right margin in the editing area. - + + 120 Right Margin Position Specifies the position of the right margin. - + + 'after' Smart Home End - Specifies how the cursor moves when the HOME and END keys are pressed. Use "DISABLED" to always move at the start/end of the line, "AFTER" to move to the start/end of the line the first time the keys are pressed and to the start/end of the text ignoring whitespaces the second time the keys are pressed, "BEFORE" to move to the start/end of the text before moving to the start/end of the line and "ALWAYS" to always move to the start/end of the text instead of the start/end of the line. + Specifies how the cursor moves when the HOME and END keys are pressed. Use "disabled" to always move at the start/end of the line, "after" to move to the start/end of the line the first time the keys are pressed and to the start/end of the text ignoring whitespaces the second time the keys are pressed, "before" to move to the start/end of the text before moving to the start/end of the line and "always" to always move to the start/end of the text instead of the start/end of the line. + true Restore Previous Cursor Position Whether xed should restore the previous cursor position when a file is loaded. - + + true Enable Search Highlighting Whether xed should highlight all the occurrences of the searched text. - + + true Enable Syntax Highlighting Whether xed should enable syntax highlighting. + + + true + Ensure Trailing Newline + Whether gedit will ensure that documents always end with a trailing newline. + + + + + + true Toolbar is Visible Whether the toolbar should be visible in editing windows. + true Status Bar is Visible Whether the status bar at the bottom of editing windows should be visible. - + + false Side Pane is Visible Whether the side pane at the left of editing windows should be visible. + false Bottom Panel is Visible Whether the bottom panel at the bottom of editing windows should be visible. - + + + true + Allow changing active tabs by scrolling + Whether you can change active tabs by scrolling. + + + 5 Maximum Recent Files Specifies the maximum number of recently opened files that will be displayed in the "Recent Files" submenu. + + + + + true Print Syntax Highlighting Whether xed should print syntax highlighting when printing documents. + true Print Header Whether xed should include a document header when printing documents. - - 'GTK_WRAP_WORD' + + + 'word' Printing Line Wrapping Mode - Specifies how to wrap long lines for printing. Use "GTK_WRAP_NONE" for no wrapping, "GTK_WRAP_WORD" for wrapping at word boundaries, and "GTK_WRAP_CHAR" for wrapping at individual character boundaries. Note that the values are case-sensitive, so make sure they appear exactly as mentioned here. + Specifies how to wrap long lines for printing. Use "none" for no wrapping, "word" for wrapping at word boundaries, and "char" for wrapping at individual character boundaries. Note that the values are case-sensitive, so make sure they appear exactly as mentioned here. - + + 0 Print Line Numbers If this value is 0, then no line numbers will be inserted when printing a document. Otherwise, xed will print line numbers every such number of lines. + 'Monospace 9' Body Font for Printing Specifies the font to use for a document's body when printing documents. + 'Sans 11' Header Font for Printing Specifies the font to use for page headers when printing a document. This will only take effect if the "Print Header" option is turned on. + 'Sans 8' Line Number Font for Printing Specifies the font to use for line numbers when printing. This will only take effect if the "Print Line Numbers" option is non-zero. - + + + + + + [ 'UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16' ] Automatically Detected Encodings Sorted list of encodings used by xed for automatically detecting the encoding of a file. "CURRENT" represents the current locale encoding. Only recognized encodings are used. - + + [ 'ISO-8859-15' ] Encodings shown in menu List of encodings shown in the Character Encoding menu in open/save file selector. Only recognized encodings are used. + + + + + + + + + + + + + 0 + + + + (650,500) + + + + 200 + + + + 0 + + + + 140 + + + + 0 + + + + + + + + 0 + + + + + + [] History for "search for" entries List of entries in "search for" textbox. + [] History for "replace with" entries List of entries in "replace with" textbox. + + + + + [ 'docinfo', 'modelines', 'filebrowser', 'spell', 'time' ] Active plugins List of active plugins. It contains the "Location" of the active plugins. See the .xed-plugin file for obtaining the "Location" of a given plugin. + + diff --git a/data/org.x.editor.service.in b/data/org.x.editor.service.in new file mode 100644 index 0000000..53b59e5 --- /dev/null +++ b/data/org.x.editor.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.x.editor +Exec=@bindir@/xed \ No newline at end of file diff --git a/data/xed-bugreport.sh.in b/data/xed-bugreport.sh.in index fcaed9f..6d6bf0c 100644 --- a/data/xed-bugreport.sh.in +++ b/data/xed-bugreport.sh.in @@ -1,10 +1,6 @@ #!/bin/sh -ENABLE_PYTHON=@enable_python@ - -PKG_CONFIG_MODULES="glib-2.0 gtk+-2.0 gtksourceview-2.0 \ - pygobject-2.0 pygtk-2.0 \ - pygtksourceview-2.0 enchant iso-codes" +PKG_CONFIG_MODULES="glib-2.0 gtk+-3.0 gtksourceview-3.0 enchant iso-codes" echo_padded () { @@ -53,21 +49,3 @@ else echo " pkg-config unavailable" fi echo - -echo "Python module versions:" -if test "$ENABLE_PYTHON" = "yes" -then - echo_padded "python" - python -V 2>&1 | cut -c8- - - echo_padded "pygtk" - python -c "import gtk, sys; \ - sys.stdout.write('%d.%d.%d ' % gtk.pygtk_version); \ - sys.stdout.write('(GTK+ %d.%d.%d)' % gtk.gtk_version)" \ - 2>/dev/null - echo -else - echo " Python support was not enabled at compile time." -fi -echo - diff --git a/data/xed.pc.in b/data/xed.pc.in index 80ab0a3..68685d0 100644 --- a/data/xed.pc.in +++ b/data/xed.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/xed/plugins Name: xed Description: xed -Requires: gtksourceview-@GTK_API_VERSION@ +Requires: gtksourceview-3.0 libpeas-1.0 libpeas-gtk-1.0 Version: @VERSION@ Cflags: -I${includedir}/xed Libs: -L${libdir} diff --git a/debian/control b/debian/control index 7ebdb41..d0ad9e8 100644 --- a/debian/control +++ b/debian/control @@ -4,13 +4,16 @@ Priority: optional Maintainer: Linux Mint Build-Depends: autotools-dev, debhelper (>= 9), + gobject-introspection, gtk-doc-tools, intltool, iso-codes, libenchant-dev, + libgirepository1.0-dev, libglib2.0-dev, libgtk-3-dev, libgtksourceview-3.0-dev, + libpeas-dev, libsm-dev, libx11-dev, libxml2-dev, @@ -136,4 +139,4 @@ Description: generic text editor (documentation files) includes support for spell checking, comparing files, viewing CVS ChangeLogs, and adjusting indentation levels. . - This package contains the documentation files. + This package contains the documentation files. \ No newline at end of file diff --git a/debian/rules b/debian/rules index 6052977..b6118b3 100755 --- a/debian/rules +++ b/debian/rules @@ -3,11 +3,11 @@ DHFLAGS=--parallel %: - dh $@ $(DHFLAGS) + dh $@ $(DHFLAGS) --with gir override_dh_install: - rm -rfv debian/tmp/usr/lib/*/xed/plugin-loaders/*.la rm -rfv debian/tmp/usr/lib/*/xed/plugins/*.la + rm -rfv debian/tmp/usr/lib/*/xed/*.la dh_install --fail-missing override_dh_auto_configure: @@ -16,9 +16,7 @@ override_dh_auto_configure: dh_auto_configure $(DHFLAGS) -- \ --disable-silent-rules \ --libexecdir=/usr/lib/ \ - --disable-python \ - --enable-gtk-doc \ - --with-gtk=3.0 + --enable-gtk-doc override_dh_installchangelogs: dh_installchangelogs NEWS diff --git a/debian/xed-common.install b/debian/xed-common.install index 2235f57..75d4ae1 100644 --- a/debian/xed-common.install +++ b/debian/xed-common.install @@ -1,7 +1,6 @@ -usr/share/appdata/ -usr/share/glib-2.0/ -usr/share/help/ -usr/share/locale/ -usr/share/xed/icons/ -usr/share/xed/plugins/ -usr/share/xed/ui/ +usr/share/appdata +usr/share/xed/plugins +usr/share/glib-2.0 +usr/share/help +usr/share/locale +usr/share/xed/icons diff --git a/debian/xed-dev.install b/debian/xed-dev.install index f91091d..7e51a02 100644 --- a/debian/xed-dev.install +++ b/debian/xed-dev.install @@ -1,2 +1,3 @@ -usr/include/xed/ +usr/include usr/lib/*/pkgconfig/ +usr/share/xed/gir-1.0 diff --git a/debian/xed-doc.install b/debian/xed-doc.install index d6da04c..95af827 100644 --- a/debian/xed-doc.install +++ b/debian/xed-doc.install @@ -1 +1 @@ -usr/share/gtk-doc/ +usr/share/gtk-doc diff --git a/debian/xed.install b/debian/xed.install index 6bdd29d..664190c 100644 --- a/debian/xed.install +++ b/debian/xed.install @@ -1,6 +1,9 @@ -usr/bin/ -usr/lib/*/xed/plugin-loaders/*.so -usr/lib/*/xed/plugins/ +usr/bin/xed +usr/lib/*/xed/girepository-1.0/ usr/lib/xed/xed-bugreport.sh -usr/share/applications/ +usr/lib/*/xed/plugins/*.plugin +usr/lib/*/xed/plugins/*.so +usr/lib/*/xed/*.so +usr/share/applications/xed.desktop +usr/share/dbus-1/ usr/share/man/ diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index e153873..805e124 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -20,8 +20,8 @@ DOC_SOURCE_DIR=../../xed SCANGOBJ_OPTIONS= # Extra options to supply to gtkdoc-scan. -# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" -SCAN_OPTIONS= +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS = --rebuild-types # Extra options to supply to gtkdoc-mkdb. MKDB_OPTIONS=--sgml-mode --output-format=xml @@ -41,15 +41,10 @@ CFILE_GLOB=$(top_srcdir)/xed/*.c # Header files to ignore when scanning (These are internal to xed). IGNORE_HFILES= \ xed-commands.h \ - xed-document-loader.h \ - xed-document-saver.h \ xed-documents-panel.h \ - xed-io-error-message-area.h \ + xed-io-error-info-bar.h \ xed-languages-manager.h \ - xed-object-module.h \ - xed-plugin-manager.h \ xed-plugins-engine.h \ - xed-prefs-manager-private.h \ xed-session.h \ xed-ui.h \ xed-window-private.h \ @@ -67,7 +62,6 @@ IGNORE_HFILES= \ # Do not parse them to make the docs. IGNORE_HFILES += \ bacon-message-connection.h \ - xedtextregion.h \ sexy-icon-entry.h # Images to copy into HTML directory. @@ -96,15 +90,7 @@ GTKDOC_LIBS= \ $(top_builddir)/xed/libxed.la \ $(XED_LIBS) -if ENABLE_PYTHON -GTKDOC_CFLAGS += \ - $(NO_STRICT_ALIASING_CFLAGS) \ - $(PYGTK_CFLAGS) \ - $(PYTHON_CFLAGS) \ - $(AM_CFLAGS) -GTKDOC_LIBS += \ - $(top_builddir)/plugin-loaders/python/bindings/xed.la -endif +MAINTAINERCLEANFILES = xed.types # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make diff --git a/docs/reference/xed-docs.sgml b/docs/reference/xed-docs.sgml index 8259134..b269b2b 100644 --- a/docs/reference/xed-docs.sgml +++ b/docs/reference/xed-docs.sgml @@ -1,5 +1,5 @@ - @@ -9,6 +9,7 @@ xed + @@ -17,21 +18,18 @@ - - + + - - - diff --git a/docs/reference/xed-sections.txt b/docs/reference/xed-sections.txt index 5b60e1f..53de7b5 100644 --- a/docs/reference/xed-sections.txt +++ b/docs/reference/xed-sections.txt @@ -19,45 +19,39 @@ XED_IS_APP_CLASS XED_APP_GET_CLASS +
+xed-app-activatable +XedAppActivatable +XedAppActivatable +xed_app_activatable_activate +xed_app_activatable_deactivate + +XED_TYPE_APP_ACTIVATABLE +XED_APP_ACTIVATABLE +XED_APP_ACTIVATABLE_IFACE +XED_IS_APP_ACTIVATABLE +XED_APP_ACTIVATABLE_GET_IFACE +xed_app_activatable_get_type +
+
xed-document -XedSearchFlags XedDocumentPrivate XedDocument XedDocument -XedDocumentSaveFlags -XED_DOCUMENT_ERROR -xed_document_error_quark xed_document_new -xed_document_get_uri +xed_document_get_file +xed_document_get_location xed_document_get_uri_for_display xed_document_get_short_name_for_display xed_document_get_mime_type xed_document_get_readonly -xed_document_load xed_document_insert_file -xed_document_load_cancel -xed_document_save -xed_document_save_as xed_document_is_untouched xed_document_is_untitled xed_document_get_deleted xed_document_goto_line -xed_document_set_search_text -xed_document_get_search_text -xed_document_get_can_search_again -xed_document_search_forward -xed_document_search_backward -xed_document_replace_all xed_document_set_language -xed_document_set_enable_search_highlighting -xed_document_get_enable_search_highlighting -XED_SEARCH_IS_DONT_SET_FLAGS -XED_SEARCH_SET_DONT_SET_FLAGS -XED_SEARCH_IS_ENTIRE_WORD -XED_SEARCH_SET_ENTIRE_WORD -XED_SEARCH_IS_CASE_SENSITIVE -XED_SEARCH_SET_CASE_SENSITIVE XED_DOCUMENT XED_IS_DOCUMENT @@ -236,30 +230,6 @@ XED_IS_PANEL_CLASS XED_PANEL_GET_CLASS
-
-xed-plugin -XedPlugin -XedPlugin -xed_plugin_activate -xed_plugin_deactivate -xed_plugin_update_ui -xed_plugin_is_configurable -xed_plugin_create_configure_dialog -XED_PLUGIN_REGISTER_TYPE - -XED_PLUGIN -XED_IS_PLUGIN -XED_TYPE_PLUGIN -xed_plugin_get_type -XED_PLUGIN_CLASS -XED_IS_PLUGIN_CLASS -XED_PLUGIN_GET_CLASS -XED_PLUGIN_REGISTER_TYPE_WITH_CODE -XED_PLUGIN_REGISTER_TYPE -XED_PLUGIN_DEFINE_TYPE_WITH_CODE -XED_PLUGIN_DEFINE_TYPE -
-
xed-print-job-preview XedPrintJobPreviewPrivate @@ -277,7 +247,7 @@ XED_PRINT_JOB_PREVIEW_GET_CLASS
-xed-print +xed-print-job XedPrintJob XedPrintJob xed_print_job_new @@ -299,7 +269,7 @@ XedProgressMessageAreaPrivate XedProgressMessageArea XedProgressMessageArea xed_progress_message_area_new -xed_progress_message_area_set_stock_image +xed_progress_message_area_set_image xed_progress_message_area_set_markup xed_progress_message_area_set_text xed_progress_message_area_set_fraction @@ -384,6 +354,22 @@ XED_IS_VIEW_CLASS XED_VIEW_GET_CLASS
+
+xed-view-activatable +XedViewActivatable +XedViewActivatable +xed_view_activatable_activate +xed_view_activatable_deactivate +xed_view_activatable_update_state + +XED_TYPE_VIEW_ACTIVATABLE +XED_VIEW_ACTIVATABLE +XED_VIEW_ACTIVATABLE_IFACE +XED_IS_VIEW_ACTIVATABLE +XED_VIEW_ACTIVATABLE_GET_IFACE +xed_view_activatable_get_type +
+
xed-window XedWindowState @@ -391,7 +377,7 @@ XedWindowPrivate XedWindow XedWindow xed_window_create_tab -xed_window_create_tab_from_uri +xed_window_create_tab_from_location xed_window_close_tab xed_window_close_all_tabs xed_window_close_tabs @@ -409,7 +395,6 @@ xed_window_get_statusbar xed_window_get_ui_manager xed_window_get_state xed_window_get_tab_from_location -xed_window_get_tab_from_uri xed_window_get_message_bus XED_WINDOW @@ -421,6 +406,20 @@ XED_IS_WINDOW_CLASS XED_WINDOW_GET_CLASS
+xed-window-activatable +XedWindowActivatable +XedWindowActivatable +xed_window_activatable_activate +xed_window_activatable_deactivate +xed_window_activatable_update_state + +XED_TYPE_WINDOW_ACTIVATABLE +XED_WINDOW_ACTIVATABLE +XED_WINDOW_ACTIVATABLE_IFACE +XED_IS_WINDOW_ACTIVATABLE +XED_WINDOW_ACTIVATABLE_GET_IFACE +xed_window_activatable_get_type +
xed-convert XedConvertError @@ -453,22 +452,6 @@ xed_debug xed_debug_message
-
-xed-encodings -XedEncoding -XED_TYPE_ENCODING -xed_encoding_get_type -xed_encoding_copy -xed_encoding_free -xed_encoding_get_from_charset -xed_encoding_get_from_index -xed_encoding_to_string -xed_encoding_get_name -xed_encoding_get_charset -xed_encoding_get_utf8 -xed_encoding_get_current -
-
xed-help xed_help_display @@ -481,277 +464,11 @@ xed_metadata_manager_get xed_metadata_manager_set
-
-xed-prefs-manager-app -xed_prefs_manager_app_init -xed_prefs_manager_app_shutdown -xed_prefs_manager_get_window_state -xed_prefs_manager_set_window_state -xed_prefs_manager_window_state_can_set -xed_prefs_manager_get_window_size -xed_prefs_manager_get_default_window_size -xed_prefs_manager_set_window_size -xed_prefs_manager_window_size_can_set -xed_prefs_manager_get_side_panel_size -xed_prefs_manager_get_default_side_panel_size -xed_prefs_manager_set_side_panel_size -xed_prefs_manager_side_panel_size_can_set -xed_prefs_manager_get_bottom_panel_size -xed_prefs_manager_get_default_bottom_panel_size -xed_prefs_manager_set_bottom_panel_size -xed_prefs_manager_bottom_panel_size_can_set -
- -
-xed-prefs-manager -XED_BASE_KEY -GPM_PREFS_DIR -GPM_FONT_DIR -GPM_USE_DEFAULT_FONT -GPM_EDITOR_FONT -GPM_COLORS_DIR -GPM_USE_DEFAULT_COLORS -GPM_BACKGROUND_COLOR -GPM_TEXT_COLOR -GPM_SELECTED_TEXT_COLOR -GPM_SELECTION_COLOR -GPM_SAVE_DIR -GPM_CREATE_BACKUP_COPY -GPM_BACKUP_COPY_EXTENSION -GPM_AUTO_SAVE -GPM_AUTO_SAVE_INTERVAL -GPM_UNDO_DIR -GPM_UNDO_ACTIONS_LIMIT -GPM_WRAP_MODE_DIR -GPM_WRAP_MODE -GPM_TABS_DIR -GPM_TABS_SIZE -GPM_INSERT_SPACES -GPM_AUTO_INDENT_DIR -GPM_AUTO_INDENT -GPM_LINE_NUMBERS_DIR -GPM_DISPLAY_LINE_NUMBERS -GPM_CURRENT_LINE_DIR -GPM_HIGHLIGHT_CURRENT_LINE -GPM_BRACKET_MATCHING_DIR -GPM_BRACKET_MATCHING -GPM_RIGHT_MARGIN_DIR -GPM_DISPLAY_RIGHT_MARGIN -GPM_RIGHT_MARGIN_POSITION -GPM_CURSOR_POSITION_DIR -GPM_RESTORE_CURSOR_POSITION -GPM_SEARCH_HIGHLIGHTING_DIR -GPM_SEARCH_HIGHLIGHTING_ENABLE -GPM_TOOLBAR_DIR -GPM_TOOLBAR_VISIBLE -GPM_TOOLBAR_BUTTONS_STYLE -GPM_STATUSBAR_DIR -GPM_STATUSBAR_VISIBLE -GPM_SIDE_PANE_DIR -GPM_SIDE_PANE_VISIBLE -GPM_BOTTOM_PANEL_DIR -GPM_BOTTOM_PANEL_VISIBLE -GPM_RECENTS_DIR -GPM_MAX_RECENTS -GPM_PRINT_PAGE_DIR -GPM_PRINT_SYNTAX -GPM_PRINT_HEADER -GPM_PRINT_WRAP_MODE -GPM_PRINT_LINE_NUMBERS -GPM_PRINT_FONT_DIR -GPM_PRINT_FONT_BODY -GPM_PRINT_FONT_BODY_PANGO -GPM_PRINT_FONT_HEADER -GPM_PRINT_FONT_HEADER_PANGO -GPM_PRINT_FONT_NUMBERS -GPM_PRINT_FONT_NUMBERS_PANGO -GPM_WINDOW_DIR -GPM_WINDOW_STATE -GPM_WINDOW_WIDTH -GPM_WINDOW_HEIGHT -GPM_SIDE_PANEL_SIZE -GPM_BOTTOM_PANEL_SIZE -GPM_ENCODINGS_DIR -GPM_AUTO_DETECTED_ENCODINGS -GPM_SHOWN_IN_MENU_ENCODINGS -GPM_SYNTAX_HL_DIR -GPM_SYNTAX_HL_ENABLE -GPM_WRITABLE_VFS_SCHEMES -GPM_DEFAULT_USE_DEFAULT_FONT -GPM_DEFAULT_EDITOR_FONT -GPM_DEFAULT_USE_DEFAULT_COLORS -GPM_DEFAULT_BACKGROUND_COLOR -GPM_DEFAULT_TEXT_COLOR -GPM_DEFAULT_SELECTED_TEXT_COLOR -GPM_DEFAULT_SELECTION_COLOR -GPM_DEFAULT_CREATE_BACKUP_COPY -GPM_DEFAULT_BACKUP_COPY_EXTENSION -GPM_DEFAULT_AUTO_SAVE -GPM_DEFAULT_AUTO_SAVE_INTERVAL -GPM_DEFAULT_UNDO_ACTIONS_LIMIT -GPM_DEFAULT_WRAP_MODE -GPM_DEFAULT_TABS_SIZE -GPM_DEFAULT_INSERT_SPACES -GPM_DEFAULT_AUTO_INDENT -GPM_DEFAULT_DISPLAY_LINE_NUMBERS -GPM_DEFAULT_AUTO_DETECTED_ENCODINGS -GPM_DEFAULT_TOOLBAR_VISIBLE -GPM_DEFAULT_TOOLBAR_BUTTONS_STYLE -GPM_DEFAULT_TOOLBAR_SHOW_TOOLTIPS -GPM_DEFAULT_STATUSBAR_VISIBLE -GPM_DEFAULT_SIDE_PANE_VISIBLE -GPM_DEFAULT_BOTTOM_PANEL_VISIBLE -GPM_DEFAULT_PRINT_SYNTAX -GPM_DEFAULT_PRINT_HEADER -GPM_DEFAULT_PRINT_WRAP_MODE -GPM_DEFAULT_PRINT_LINE_NUMBERS -GPM_DEFAULT_PRINT_FONT_BODY_PANGO -GPM_DEFAULT_PRINT_FONT_HEADER_PANGO -GPM_DEFAULT_PRINT_FONT_NUMBERS_PANGO -GPM_DEFAULT_MAX_RECENTS -GPM_DEFAULT_WINDOW_STATE -GPM_DEFAULT_WINDOW_WIDTH -GPM_DEFAULT_WINDOW_HEIGHT -GPM_DEFAULT_WINDOW_STATE_STR -GPM_DEFAULT_WINDOW_WIDTH_STR -GPM_DEFAULT_WINDOW_HEIGHT_STR -GPM_DEFAULT_SIDE_PANEL_SIZE -GPM_DEFAULT_BOTTOM_PANEL_SIZE -GPM_DEFAULT_SIDE_PANEL_SIZE_STR -GPM_DEFAULT_BOTTOM_PANEL_SIZE_STR -GPM_DEFAULT_HIGHLIGHT_CURRENT_LINE -GPM_DEFAULT_BRACKET_MATCHING -GPM_DEFAULT_DISPLAY_RIGHT_MARGIN -GPM_DEFAULT_RIGHT_MARGIN_POSITION -GPM_DEFAULT_SYNTAX_HL_ENABLE -GPM_DEFAULT_WRITABLE_VFS_SCHEMES -GPM_DEFAULT_RESTORE_CURSOR_POSITION -GPM_DEFAULT_SEARCH_HIGHLIGHTING_ENABLE -XedToolbarSetting -xed_prefs_manager_init -xed_prefs_manager_shutdown -xed_prefs_manager_get_use_default_font -xed_prefs_manager_set_use_default_font -xed_prefs_manager_use_default_font_can_set -xed_prefs_manager_get_editor_font -xed_prefs_manager_set_editor_font -xed_prefs_manager_editor_font_can_set -xed_prefs_manager_get_use_default_colors -xed_prefs_manager_set_use_default_colors -xed_prefs_manager_use_default_colors_can_set -xed_prefs_manager_get_background_color -xed_prefs_manager_set_background_color -xed_prefs_manager_background_color_can_set -xed_prefs_manager_get_text_color -xed_prefs_manager_set_text_color -xed_prefs_manager_text_color_can_set -xed_prefs_manager_get_selection_color -xed_prefs_manager_set_selection_color -xed_prefs_manager_selection_color_can_set -xed_prefs_manager_get_selected_text_color -xed_prefs_manager_set_selected_text_color -xed_prefs_manager_selected_text_color_can_set -xed_prefs_manager_get_create_backup_copy -xed_prefs_manager_set_create_backup_copy -xed_prefs_manager_create_backup_copy_can_set -xed_prefs_manager_get_backup_extension -xed_prefs_manager_get_auto_save -xed_prefs_manager_set_auto_save -xed_prefs_manager_auto_save_can_set -xed_prefs_manager_get_auto_save_interval -xed_prefs_manager_set_auto_save_interval -xed_prefs_manager_auto_save_interval_can_set -xed_prefs_manager_get_undo_actions_limit -xed_prefs_manager_set_undo_actions_limit -xed_prefs_manager_undo_actions_limit_can_set -xed_prefs_manager_get_wrap_mode -xed_prefs_manager_set_wrap_mode -xed_prefs_manager_wrap_mode_can_set -xed_prefs_manager_get_tabs_size -xed_prefs_manager_set_tabs_size -xed_prefs_manager_tabs_size_can_set -xed_prefs_manager_get_insert_spaces -xed_prefs_manager_set_insert_spaces -xed_prefs_manager_insert_spaces_can_set -xed_prefs_manager_get_auto_indent -xed_prefs_manager_set_auto_indent -xed_prefs_manager_auto_indent_can_set -xed_prefs_manager_get_display_line_numbers -xed_prefs_manager_set_display_line_numbers -xed_prefs_manager_display_line_numbers_can_set -xed_prefs_manager_get_toolbar_visible -xed_prefs_manager_set_toolbar_visible -xed_prefs_manager_toolbar_visible_can_set -xed_prefs_manager_get_toolbar_buttons_style -xed_prefs_manager_set_toolbar_buttons_style -xed_prefs_manager_toolbar_buttons_style_can_set -xed_prefs_manager_get_statusbar_visible -xed_prefs_manager_set_statusbar_visible -xed_prefs_manager_statusbar_visible_can_set -xed_prefs_manager_get_side_pane_visible -xed_prefs_manager_set_side_pane_visible -xed_prefs_manager_side_pane_visible_can_set -xed_prefs_manager_get_bottom_panel_visible -xed_prefs_manager_set_bottom_panel_visible -xed_prefs_manager_bottom_panel_visible_can_set -xed_prefs_manager_get_print_syntax_hl -xed_prefs_manager_set_print_syntax_hl -xed_prefs_manager_print_syntax_hl_can_set -xed_prefs_manager_get_print_header -xed_prefs_manager_set_print_header -xed_prefs_manager_print_header_can_set -xed_prefs_manager_get_print_wrap_mode -xed_prefs_manager_set_print_wrap_mode -xed_prefs_manager_print_wrap_mode_can_set -xed_prefs_manager_get_print_line_numbers -xed_prefs_manager_set_print_line_numbers -xed_prefs_manager_print_line_numbers_can_set -xed_prefs_manager_get_print_font_body -xed_prefs_manager_set_print_font_body -xed_prefs_manager_print_font_body_can_set -xed_prefs_manager_get_default_print_font_body -xed_prefs_manager_get_print_font_header -xed_prefs_manager_set_print_font_header -xed_prefs_manager_print_font_header_can_set -xed_prefs_manager_get_default_print_font_header -xed_prefs_manager_get_print_font_numbers -xed_prefs_manager_set_print_font_numbers -xed_prefs_manager_print_font_numbers_can_set -xed_prefs_manager_get_default_print_font_numbers -xed_prefs_manager_get_max_recents -xed_prefs_manager_get_auto_detected_encodings -xed_prefs_manager_get_shown_in_menu_encodings -xed_prefs_manager_set_shown_in_menu_encodings -xed_prefs_manager_shown_in_menu_encodings_can_set -xed_prefs_manager_get_highlight_current_line -xed_prefs_manager_set_highlight_current_line -xed_prefs_manager_highlight_current_line_can_set -xed_prefs_manager_get_bracket_matching -xed_prefs_manager_set_bracket_matching -xed_prefs_manager_bracket_matching_can_set -xed_prefs_manager_get_display_right_margin -xed_prefs_manager_set_display_right_margin -xed_prefs_manager_display_right_margin_can_set -xed_prefs_manager_get_right_margin_position -xed_prefs_manager_set_right_margin_position -xed_prefs_manager_right_margin_position_can_set -xed_prefs_manager_get_enable_syntax_highlighting -xed_prefs_manager_set_enable_syntax_highlighting -xed_prefs_manager_enable_syntax_highlighting_can_set -xed_prefs_manager_get_writable_vfs_schemes -xed_prefs_manager_get_restore_cursor_position -xed_prefs_manager_get_enable_search_highlighting -xed_prefs_manager_set_enable_search_highlighting -xed_prefs_manager_enable_search_highlighting_can_set -
-
xed-utils GBOOLEAN_TO_POINTER GPOINTER_TO_BOOLEAN IS_VALID_BOOLEAN -xed_utils_uri_has_writable_scheme -xed_utils_uri_has_file_scheme xed_utils_menu_position_under_widget xed_utils_menu_position_under_tree_view xed_gtk_button_new_with_stock_icon @@ -763,8 +480,6 @@ g_utf8_caselessnmatch xed_utils_set_atk_name_description xed_utils_set_atk_relation xed_utils_uri_exists -xed_utils_escape_search_text -xed_utils_unescape_search_text xed_utils_get_stdin xed_warning xed_utils_make_valid_utf8 diff --git a/docs/reference/xed.types b/docs/reference/xed.types index a47ea4a..8c34ddd 100644 --- a/docs/reference/xed.types +++ b/docs/reference/xed.types @@ -1,32 +1,26 @@ -#include "xed-app.h" -#include "xed-document.h" -#include "xed-encodings.h" -#include "xed-encodings-combo-box.h" -#include "xed-file-chooser-dialog.h" -#include "xed-message.h" -#include "xed-message-bus.h" -#include "xed-message-type.h" -#include "xed-notebook.h" -#include "xed-panel.h" -#include "xed-plugin.h" -#include "xed-progress-message-area.h" -#include "xed-statusbar.h" -#include "xed-tab.h" -#include "xed-view.h" -#include "xed-window.h" +xed_app_activatable_get_type xed_app_get_type +xed_close_button_get_type xed_document_get_type -xed_encoding_get_type xed_encodings_combo_box_get_type xed_file_chooser_dialog_get_type -xed_message_get_type +xed_history_entry_get_type xed_message_bus_get_type +xed_message_get_type xed_message_type_get_type xed_notebook_get_type xed_panel_get_type -xed_plugin_get_type +xed_print_job_get_type +xed_print_preview_get_type xed_progress_message_area_get_type +xed_searchbar_get_type +xed_settings_get_type +xed_status_combo_box_get_type xed_statusbar_get_type xed_tab_get_type +xed_tab_label_get_type +xed_view_activatable_get_type +xed_view_frame_get_type xed_view_get_type +xed_window_activatable_get_type xed_window_get_type diff --git a/m4/python.m4 b/m4/python.m4 deleted file mode 100644 index e1c5266..0000000 --- a/m4/python.m4 +++ /dev/null @@ -1,62 +0,0 @@ -## this one is commonly used with AM_PATH_PYTHONDIR ... -dnl AM_CHECK_PYMOD(MODNAME [,SYMBOL [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]]) -dnl Check if a module containing a given symbol is visible to python. -AC_DEFUN([AM_CHECK_PYMOD], -[AC_REQUIRE([AM_PATH_PYTHON]) -py_mod_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'` -AC_MSG_CHECKING(for ifelse([$2],[],,[$2 in ])python module $1) -AC_CACHE_VAL(py_cv_mod_$py_mod_var, [ -ifelse([$2],[], [prog=" -import sys -try: - import $1 -except ImportError: - sys.exit(1) -except: - sys.exit(0) -sys.exit(0)"], [prog=" -import $1 -$1.$2"]) -if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC - then - eval "py_cv_mod_$py_mod_var=yes" - else - eval "py_cv_mod_$py_mod_var=no" - fi -]) -py_val=`eval "echo \`echo '$py_cv_mod_'$py_mod_var\`"` -if test "x$py_val" != xno; then - AC_MSG_RESULT(yes) - ifelse([$3], [],, [$3 -])dnl -else - AC_MSG_RESULT(no) - ifelse([$4], [],, [$4 -])dnl -fi -]) - -dnl a macro to check for ability to create python extensions -dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) -dnl function also defines PYTHON_INCLUDES -AC_DEFUN([AM_CHECK_PYTHON_HEADERS], -[AC_REQUIRE([AM_PATH_PYTHON]) -AC_MSG_CHECKING(for headers required to compile python extensions) -dnl deduce PYTHON_INCLUDES -py_prefix=`$PYTHON -c "import sys; print sys.prefix"` -py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` -PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" -if test "$py_prefix" != "$py_exec_prefix"; then - PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" -fi -AC_SUBST(PYTHON_INCLUDES) -dnl check if the headers exist: -save_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" -AC_TRY_CPP([#include ],dnl -[AC_MSG_RESULT(found) -$1],dnl -[AC_MSG_RESULT(not found) -$2]) -CPPFLAGS="$save_CPPFLAGS" -]) diff --git a/plugin-loaders/Makefile.am b/plugin-loaders/Makefile.am deleted file mode 100644 index bf1e964..0000000 --- a/plugin-loaders/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -SUBDIRS = c - -if ENABLE_PYTHON -SUBDIRS += python -endif - --include $(top_srcdir)/git.mk diff --git a/plugin-loaders/c/Makefile.am b/plugin-loaders/c/Makefile.am deleted file mode 100644 index b25782c..0000000 --- a/plugin-loaders/c/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# C plugin loader - -loaderdir = $(libdir)/xed/plugin-loaders - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(XED_CFLAGS) \ - $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) \ - -DXED_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" - -loader_LTLIBRARIES = libcloader.la - -NOINST_H_FILES = \ - xed-plugin-loader-c.h - -libcloader_la_SOURCES = \ - xed-plugin-loader-c.c \ - $(NOINST_H_FILES) - -libcloader_la_LDFLAGS = $(LOADER_LIBTOOL_FLAGS) -libcloader_la_LIBADD = $(XED_LIBS) - --include $(top_srcdir)/git.mk diff --git a/plugin-loaders/c/xed-plugin-loader-c.c b/plugin-loaders/c/xed-plugin-loader-c.c deleted file mode 100644 index 86db43a..0000000 --- a/plugin-loaders/c/xed-plugin-loader-c.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * xed-plugin-loader-c.c - * This file is part of xed - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "xed-plugin-loader-c.h" -#include - -#define XED_PLUGIN_LOADER_C_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_PLUGIN_LOADER_C, XedPluginLoaderCPrivate)) - -struct _XedPluginLoaderCPrivate -{ - GHashTable *loaded_plugins; -}; - -static void xed_plugin_loader_iface_init (gpointer g_iface, gpointer iface_data); - -XED_PLUGIN_LOADER_REGISTER_TYPE (XedPluginLoaderC, xed_plugin_loader_c, G_TYPE_OBJECT, xed_plugin_loader_iface_init); - - -static const gchar * -xed_plugin_loader_iface_get_id (void) -{ - return "C"; -} - -static XedPlugin * -xed_plugin_loader_iface_load (XedPluginLoader *loader, - XedPluginInfo *info, - const gchar *path) -{ - XedPluginLoaderC *cloader = XED_PLUGIN_LOADER_C (loader); - XedObjectModule *module; - const gchar *module_name; - XedPlugin *result; - - module = (XedObjectModule *)g_hash_table_lookup (cloader->priv->loaded_plugins, info); - module_name = xed_plugin_info_get_module_name (info); - - if (module == NULL) - { - /* For now we force all modules to be resident */ - module = xed_object_module_new (module_name, - path, - "register_xed_plugin", - TRUE); - - /* Infos are available for all the lifetime of the loader. - * If this changes, we should use weak refs or something */ - - g_hash_table_insert (cloader->priv->loaded_plugins, info, module); - } - - if (!g_type_module_use (G_TYPE_MODULE (module))) - { - g_warning ("Could not load plugin module: %s", xed_plugin_info_get_name (info)); - - return NULL; - } - - /* TODO: for now we force data-dir-name = module-name... if needed we can - * add a datadir field to the plugin descriptor file. - */ - result = (XedPlugin *)xed_object_module_new_object (module, - "install-dir", path, - "data-dir-name", module_name, - NULL); - - if (!result) - { - g_warning ("Could not create plugin object: %s", xed_plugin_info_get_name (info)); - g_type_module_unuse (G_TYPE_MODULE (module)); - - return NULL; - } - - g_type_module_unuse (G_TYPE_MODULE (module)); - - return result; -} - -static void -xed_plugin_loader_iface_unload (XedPluginLoader *loader, - XedPluginInfo *info) -{ - //XedPluginLoaderC *cloader = XED_PLUGIN_LOADER_C (loader); - - /* this is a no-op, since the type module will be properly unused as - the last reference to the plugin dies. When the plugin is activated - again, the library will be reloaded */ -} - -static void -xed_plugin_loader_iface_init (gpointer g_iface, - gpointer iface_data) -{ - XedPluginLoaderInterface *iface = (XedPluginLoaderInterface *)g_iface; - - iface->get_id = xed_plugin_loader_iface_get_id; - iface->load = xed_plugin_loader_iface_load; - iface->unload = xed_plugin_loader_iface_unload; -} - -static void -xed_plugin_loader_c_finalize (GObject *object) -{ - XedPluginLoaderC *cloader = XED_PLUGIN_LOADER_C (object); - GList *infos; - GList *item; - - /* FIXME: this sanity check it's not efficient. Let's remove it - * once we are confident with the code */ - - infos = g_hash_table_get_keys (cloader->priv->loaded_plugins); - - for (item = infos; item; item = item->next) - { - XedPluginInfo *info = (XedPluginInfo *)item->data; - - if (xed_plugin_info_is_active (info)) - { - g_warning ("There are still C plugins loaded during destruction"); - break; - } - } - - g_list_free (infos); - - g_hash_table_destroy (cloader->priv->loaded_plugins); - - G_OBJECT_CLASS (xed_plugin_loader_c_parent_class)->finalize (object); -} - -static void -xed_plugin_loader_c_class_init (XedPluginLoaderCClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_plugin_loader_c_finalize; - - g_type_class_add_private (object_class, sizeof (XedPluginLoaderCPrivate)); -} - -static void -xed_plugin_loader_c_class_finalize (XedPluginLoaderCClass *klass) -{ -} - -static void -xed_plugin_loader_c_init (XedPluginLoaderC *self) -{ - self->priv = XED_PLUGIN_LOADER_C_GET_PRIVATE (self); - - /* loaded_plugins maps XedPluginInfo to a XedObjectModule */ - self->priv->loaded_plugins = g_hash_table_new (g_direct_hash, - g_direct_equal); -} - -XedPluginLoaderC * -xed_plugin_loader_c_new () -{ - GObject *loader = g_object_new (XED_TYPE_PLUGIN_LOADER_C, NULL); - - return XED_PLUGIN_LOADER_C (loader); -} diff --git a/plugin-loaders/c/xed-plugin-loader-c.h b/plugin-loaders/c/xed-plugin-loader-c.h deleted file mode 100644 index e6c3b02..0000000 --- a/plugin-loaders/c/xed-plugin-loader-c.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * xed-plugin-loader-c.h - * This file is part of xed - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XED_PLUGIN_LOADER_C_H__ -#define __XED_PLUGIN_LOADER_C_H__ - -#include - -G_BEGIN_DECLS - -#define XED_TYPE_PLUGIN_LOADER_C (xed_plugin_loader_c_get_type ()) -#define XED_PLUGIN_LOADER_C(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_PLUGIN_LOADER_C, XedPluginLoaderC)) -#define XED_PLUGIN_LOADER_C_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_PLUGIN_LOADER_C, XedPluginLoaderC const)) -#define XED_PLUGIN_LOADER_C_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_PLUGIN_LOADER_C, XedPluginLoaderCClass)) -#define XED_IS_PLUGIN_LOADER_C(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_PLUGIN_LOADER_C)) -#define XED_IS_PLUGIN_LOADER_C_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PLUGIN_LOADER_C)) -#define XED_PLUGIN_LOADER_C_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_PLUGIN_LOADER_C, XedPluginLoaderCClass)) - -typedef struct _XedPluginLoaderC XedPluginLoaderC; -typedef struct _XedPluginLoaderCClass XedPluginLoaderCClass; -typedef struct _XedPluginLoaderCPrivate XedPluginLoaderCPrivate; - -struct _XedPluginLoaderC { - GObject parent; - - XedPluginLoaderCPrivate *priv; -}; - -struct _XedPluginLoaderCClass { - GObjectClass parent_class; -}; - -GType xed_plugin_loader_c_get_type (void) G_GNUC_CONST; -XedPluginLoaderC *xed_plugin_loader_c_new(void); - -/* All the loaders must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin_loader (GTypeModule * module); - -G_END_DECLS - -#endif /* __XED_PLUGIN_LOADER_C_H__ */ diff --git a/plugin-loaders/python/Makefile.am b/plugin-loaders/python/Makefile.am deleted file mode 100644 index ef9acc2..0000000 --- a/plugin-loaders/python/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -# C plugin loader - -SUBDIRS = bindings -loaderdir = $(libdir)/xed/plugin-loaders - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/xed \ - -I$(top_builddir)/xed \ - $(XED_CFLAGS) \ - $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) \ - $(PYGTK_CFLAGS) \ - $(PYTHON_CFLAGS) \ - -DXED_PLUGINS_LIBS_DIR=\"$(XED_PLUGINS_LIBS_DIR)\" \ - -DXED_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" - -loader_LTLIBRARIES = libpythonloader.la - - -NOINST_H_FILES = \ - xed-plugin-loader-python.h \ - xed-plugin-python.h - -libpythonloader_la_SOURCES = \ - xed-plugin-loader-python.c \ - xed-plugin-python.c \ - $(NOINST_H_FILES) - -libpythonloader_la_LDFLAGS = $(LOADER_LIBTOOL_FLAGS) -libpythonloader_la_LIBADD = \ - $(XED_LIBS) \ - bindings/xed.la - --include $(top_srcdir)/git.mk diff --git a/plugin-loaders/python/bindings/Makefile.am b/plugin-loaders/python/bindings/Makefile.am deleted file mode 100644 index efcbf17..0000000 --- a/plugin-loaders/python/bindings/Makefile.am +++ /dev/null @@ -1,115 +0,0 @@ -## Process this file with automake to produce Makefile.in - -noinst_LTLIBRARIES = \ - xed.la - -nodist_xed_la_SOURCES = \ - xed.c \ - xedutils.c \ - xedcommands.c - -xed_la_LDFLAGS = \ - -module -avoid-version - -xed_la_LIBADD = \ - $(PYTHON_LIB_LOC) \ - $(PYTHON_LIBS) \ - $(PYTHON_EXTRA_LIBS) \ - $(PYGTK_LIBS) - -xed_la_CFLAGS = \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/xed \ - -I$(top_builddir)/xed \ - -I$(top_srcdir)/plugin-loaders/python \ - -I$(top_builddir)/plugin-loaders/python \ - $(XED_CFLAGS) \ - $(NO_STRICT_ALIASING_CFLAGS) \ - $(PYGTK_CFLAGS) \ - $(PYTHON_CFLAGS) \ - $(AM_CFLAGS) - -$(top_builddir)/xed/xed-enum-types.h: - cd $(top_builddir)/xed && $(MAKE) xed-enum-types.h - -xed.c: xed.defs xed.override xedplugin.override xedmessage.override $(top_builddir)/xed/xed-enum-types.h - ( cd $(srcdir) && $(PYGTK_CODEGEN) \ - --register $(PYGTK_DEFSDIR)/pango-types.defs \ - --register $(PYGTK_DEFSDIR)/gdk-types.defs \ - --register $(PYGTK_DEFSDIR)/gtk-types.defs \ - --register $(PYGTK_DEFSDIR)/gtksourceview2.defs \ - --register $(PYGOBJECT_DEFSDIR)/gio-types.defs \ - --override $*.override \ - --prefix py$* $( $@ - -xedutils.c: xedutils.defs xedutils.override - ( cd $(srcdir) && $(PYGTK_CODEGEN) \ - --override $*.override \ - --prefix py$* $( $@ - -xedcommands.c: xedcommands.defs xedcommands.override xed.defs - ( cd $(srcdir) && $(PYGTK_CODEGEN) \ - --register xed.defs \ - --register $(PYGTK_DEFSDIR)/gtk-types.defs \ - --override $*.override \ - --prefix py$* $( $@ - -BINDING_XED_HEADERS_SRCDIR_IN = \ - xed/xed-app.h \ - xed/xed-document.h \ - xed/xed-encodings.h \ - xed/xed-plugin.h \ - plugin-loaders/python/xed-plugin-python.h \ - xed/xed-view.h \ - xed/xed-statusbar.h \ - xed/xed-tab.h \ - xed/xed-panel.h \ - xed/xed-window.h \ - xed/xed-help.h \ - xed/xed-debug.h \ - xed/xed-message-type.h \ - xed/xed-message.h \ - xed/xed-message-bus.h \ - xed/xed-language-manager.h - -BINDING_UTILS_HEADERS_SRCDIR_IN = \ - xed/xed-utils.h - -BINDING_COMMANDS_HEADERS_SRCDIR_IN = \ - xed/xed-commands.h - -BINDING_HEADERS_BUILDDIR_IN = - -BINDING_XED_HEADERS_SRCDIR := $(addprefix $(top_srcdir)/,$(BINDING_XED_HEADERS_SRCDIR_IN)) -BINDING_UTILS_HEADERS_SRCDIR := $(addprefix $(top_srcdir)/,$(BINDING_UTILS_HEADERS_SRCDIR_IN)) -BINDING_COMMANDS_HEADERS_SRCDIR := $(addprefix $(top_srcdir)/,$(BINDING_COMMANDS_HEADERS_SRCDIR_IN)) - -BINDING_HEADERS_BUILDDIR := $(addprefix $(top_builddir)/,$(BINDING_HEADERS_BUILDDIR_IN)) - -regenerate-python-binding: - $(PYGTK_H2DEF) $(sort $(BINDING_XED_HEADERS_SRCDIR) $(BINDING_HEADERS_BUILDDIR)) > xed.defs.new - $(PYGTK_H2DEF) $(sort $(BINDING_UTILS_HEADERS_SRCDIR) $(BINDING_HEADERS_BUILDDIR)) > xedutils.defs.new - $(PYGTK_H2DEF) $(sort $(BINDING_COMMANDS_HEADERS_SRCDIR) $(BINDING_HEADERS_BUILDDIR)) > xedcommands.defs.new - -BUILT_SOURCES = \ - xed.c \ - xedutils.c \ - xedcommands.c - -EXTRA_DIST = \ - xed.override \ - xed.defs \ - xedutils.override \ - xedutils.defs \ - xedcommands.override \ - xedcommands.defs \ - xedmessage.override \ - xedplugin.override - -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - --include $(top_srcdir)/git.mk diff --git a/plugin-loaders/python/bindings/xed.defs b/plugin-loaders/python/bindings/xed.defs deleted file mode 100644 index 75af263..0000000 --- a/plugin-loaders/python/bindings/xed.defs +++ /dev/null @@ -1,1442 +0,0 @@ -;; -*- scheme -*- -; object definitions ... -(define-object App - (in-module "Xed") - (parent "GObject") - (c-name "XedApp") - (gtype-id "XED_TYPE_APP") -) - -(define-object Document - (in-module "Xed") - (parent "GtkSourceBuffer") - (c-name "XedDocument") - (gtype-id "XED_TYPE_DOCUMENT") -) - -(define-object Message - (in-module "Xed") - (parent "GObject") - (c-name "XedMessage") - (gtype-id "XED_TYPE_MESSAGE") -) - -(define-object MessageBus - (in-module "Xed") - (parent "GObject") - (c-name "XedMessageBus") - (gtype-id "XED_TYPE_MESSAGE_BUS") -) - -(define-object Panel - (in-module "Xed") - (parent "GtkVBox") - (c-name "XedPanel") - (gtype-id "XED_TYPE_PANEL") -) - -(define-object __Plugin - (in-module "Xed") - (parent "GObject") - (c-name "XedPlugin") - (gtype-id "XED_TYPE_PLUGIN") -) - -(define-object Plugin - (in-module "Xed") - (parent "XedPlugin") - (c-name "XedPluginPython") - (gtype-id "XED_TYPE_PLUGIN_PYTHON") -) - -(define-object Statusbar - (in-module "Xed") - (parent "GtkStatusbar") - (c-name "XedStatusbar") - (gtype-id "XED_TYPE_STATUSBAR") -) - -(define-object Tab - (in-module "Xed") - (parent "GtkVBox") - (c-name "XedTab") - (gtype-id "XED_TYPE_TAB") -) - -(define-object View - (in-module "Xed") - (parent "GtkSourceView") - (c-name "XedView") - (gtype-id "XED_TYPE_VIEW") -) - -(define-object Window - (in-module "Xed") - (parent "GtkWindow") - (c-name "XedWindow") - (gtype-id "XED_TYPE_WINDOW") -) - -;; Enumerations and flags ... - -(define-flags SearchFlags - (in-module "Xed") - (c-name "XedSearchFlags") - (gtype-id "XED_TYPE_SEARCH_FLAGS") - (values - '("dont-set-flags" "XED_SEARCH_DONT_SET_FLAGS") - '("entire-word" "XED_SEARCH_ENTIRE_WORD") - '("case-sensitive" "XED_SEARCH_CASE_SENSITIVE") - ) -) - -(define-flags DocumentSaveFlags - (in-module "Xed") - (c-name "XedDocumentSaveFlags") - (gtype-id "XED_TYPE_DOCUMENT_SAVE_FLAGS") - (values - '("ignore-mtime" "XED_DOCUMENT_SAVE_IGNORE_MTIME") - '("ignore-backup" "XED_DOCUMENT_SAVE_IGNORE_BACKUP") - '("preserve-backup" "XED_DOCUMENT_SAVE_PRESERVE_BACKUP") - ) -) - -(define-enum TabState - (in-module "Xed") - (c-name "XedTabState") - (gtype-id "XED_TYPE_TAB_STATE") - (values - '("normal" "XED_TAB_STATE_NORMAL") - '("loading" "XED_TAB_STATE_LOADING") - '("reverting" "XED_TAB_STATE_REVERTING") - '("saving" "XED_TAB_STATE_SAVING") - '("printing" "XED_TAB_STATE_PRINTING") - '("print-previewing" "XED_TAB_STATE_PRINT_PREVIEWING") - '("showing-print-preview" "XED_TAB_STATE_SHOWING_PRINT_PREVIEW") - '("generic-not-editable" "XED_TAB_STATE_GENERIC_NOT_EDITABLE") - '("loading-error" "XED_TAB_STATE_LOADING_ERROR") - '("reverting-error" "XED_TAB_STATE_REVERTING_ERROR") - '("saving-error" "XED_TAB_STATE_SAVING_ERROR") - '("generic-error" "XED_TAB_STATE_GENERIC_ERROR") - '("closing" "XED_TAB_STATE_CLOSING") - ) -) - -(define-flags WindowState - (in-module "Xed") - (c-name "XedWindowState") - (gtype-id "XED_TYPE_WINDOW_STATE") - (values - '("normal" "XED_WINDOW_STATE_NORMAL") - '("saving" "XED_WINDOW_STATE_SAVING") - '("printing" "XED_WINDOW_STATE_PRINTING") - '("loading" "XED_WINDOW_STATE_LOADING") - '("error" "XED_WINDOW_STATE_ERROR") - '("saving-session" "XED_WINDOW_STATE_SAVING_SESSION") - ) -) - -;; Boxed types -(define-boxed Encoding - (in-module "Xed") - (c-name "XedEncoding") - (gtype-id "XED_TYPE_ENCODING") - (copy-func "xed_encoding_copy") - (release-func "xed_encoding_free") -;; (fields -;; '("gint" "index") -;; '("gchar*" "charset") -;; '("gchar*" "name") -;; ) -) - -(define-boxed MessageType - (in-module "Xed") - (c-name "XedMessageType") - (gtype-id "XED_TYPE_MESSAGE_TYPE") - (copy-func "xed_message_type_ref") - (release-func "xed_message_type_unref") -) - - -;; From ../../xed/xed-app.h - -(define-function xed_app_get_type - (c-name "xed_app_get_type") - (return-type "GType") -) - -(define-function app_get_default - (c-name "xed_app_get_default") - (return-type "XedApp*") -) - -; deprecated version ! -(define-function xed_app_get_default - (c-name "xed_app_get_default_deprecated") - (return-type "XedApp*") -) - -(define-method create_window - (of-object "XedApp") - (c-name "xed_app_create_window") - (return-type "XedWindow*") - (parameters - '("GdkScreen*" "screen") - ) -) - -(define-method get_windows - (of-object "XedApp") - (c-name "xed_app_get_windows") - (return-type "const-GList*") -) - -(define-method get_active_window - (of-object "XedApp") - (c-name "xed_app_get_active_window") - (return-type "XedWindow*") -) - -(define-method get_documents - (of-object "XedApp") - (c-name "xed_app_get_documents") - (return-type "GList*") -) - -(define-method get_views - (of-object "XedApp") - (c-name "xed_app_get_views") - (return-type "GList*") -) - - -;; From ../../xed/xed-document.h - -(define-function document_error_quark - (c-name "xed_document_error_quark") - (return-type "GQuark") -) - -(define-function xed_document_get_type - (c-name "xed_document_get_type") - (return-type "GType") -) - -(define-function xed_document_new - (c-name "xed_document_new") - (is-constructor-of "XedDocument") - (return-type "XedDocument*") -) - -(define-method get_location - (of-object "XedDocument") - (c-name "xed_document_get_location") - (return-type "GFile*") -) - -(define-method get_uri - (of-object "XedDocument") - (c-name "xed_document_get_uri") - (return-type "gchar*") -) - -(define-method set_uri - (of-object "XedDocument") - (c-name "xed_document_set_uri") - (return-type "none") - (parameters - '("const-gchar*" "uri") - ) -) - -(define-method get_uri_for_display - (of-object "XedDocument") - (c-name "xed_document_get_uri_for_display") - (return-type "gchar*") -) - -(define-method get_short_name_for_display - (of-object "XedDocument") - (c-name "xed_document_get_short_name_for_display") - (return-type "gchar*") -) - -(define-method get_content_type - (of-object "XedDocument") - (c-name "xed_document_get_content_type") - (return-type "gchar*") -) - -(define-method get_mime_type - (of-object "XedDocument") - (c-name "xed_document_get_mime_type") - (return-type "gchar*") -) - -(define-method get_readonly - (of-object "XedDocument") - (c-name "xed_document_get_readonly") - (return-type "gboolean") -) - -(define-method load - (of-object "XedDocument") - (c-name "xed_document_load") - (return-type "none") - (parameters - '("const-gchar*" "uri") - '("const-XedEncoding*" "encoding") - '("gint" "line_pos") - '("gboolean" "create") - ) -) - -(define-method insert_file - (of-object "XedDocument") - (c-name "xed_document_insert_file") - (return-type "gboolean") - (parameters - '("GtkTextIter*" "iter") - '("const-gchar*" "uri") - '("const-XedEncoding*" "encoding") - ) -) - -(define-method load_cancel - (of-object "XedDocument") - (c-name "xed_document_load_cancel") - (return-type "gboolean") -) - -(define-method save - (of-object "XedDocument") - (c-name "xed_document_save") - (parameters - '("XedDocumentSaveFlags" "flags") - ) - (return-type "none") -) - -(define-method save_as - (of-object "XedDocument") - (c-name "xed_document_save_as") - (return-type "none") - (parameters - '("const-gchar*" "uri") - '("const-XedEncoding*" "encoding") - '("XedDocumentSaveFlags" "flags") - ) -) - -(define-method is_untouched - (of-object "XedDocument") - (c-name "xed_document_is_untouched") - (return-type "gboolean") -) - -(define-method is_untitled - (of-object "XedDocument") - (c-name "xed_document_is_untitled") - (return-type "gboolean") -) - -(define-method is_local - (of-object "XedDocument") - (c-name "xed_document_is_local") - (return-type "gboolean") -) - -(define-method get_deleted - (of-object "XedDocument") - (c-name "xed_document_get_deleted") - (return-type "gboolean") -) - -(define-method goto_line - (of-object "XedDocument") - (c-name "xed_document_goto_line") - (return-type "gboolean") - (parameters - '("gint" "line") - ) -) - -(define-method set_search_text - (of-object "XedDocument") - (c-name "xed_document_set_search_text") - (return-type "none") - (parameters - '("const-gchar*" "text") - '("guint" "flags") - ) -) - -(define-method get_search_text - (of-object "XedDocument") - (c-name "xed_document_get_search_text") - (return-type "gchar*") - (parameters - '("guint*" "flags") - ) -) - -(define-method get_can_search_again - (of-object "XedDocument") - (c-name "xed_document_get_can_search_again") - (return-type "gboolean") -) - -(define-method search_forward - (of-object "XedDocument") - (c-name "xed_document_search_forward") - (return-type "gboolean") - (parameters - '("const-GtkTextIter*" "start") - '("const-GtkTextIter*" "end") - '("GtkTextIter*" "match_start") - '("GtkTextIter*" "match_end") - ) -) - -(define-method replace_all - (of-object "XedDocument") - (c-name "xed_document_replace_all") - (return-type "gint") - (parameters - '("const-gchar*" "find") - '("const-gchar*" "replace") - '("guint" "flags") - ) -) - -(define-method search_backward - (of-object "XedDocument") - (c-name "xed_document_search_backward") - (return-type "gboolean") - (parameters - '("const-GtkTextIter*" "start") - '("const-GtkTextIter*" "end") - '("GtkTextIter*" "match_start") - '("GtkTextIter*" "match_end") - ) -) - -(define-method set_language - (of-object "XedDocument") - (c-name "xed_document_set_language") - (return-type "none") - (parameters - '("GtkSourceLanguage*" "lang" (null-ok)) - ) -) - -(define-method get_language - (of-object "XedDocument") - (c-name "xed_document_get_language") - (return-type "GtkSourceLanguage*") -) - -(define-method get_encoding - (of-object "XedDocument") - (c-name "xed_document_get_encoding") - (return-type "const-XedEncoding*") -) - -(define-method set_enable_search_highlighting - (of-object "XedDocument") - (c-name "xed_document_set_enable_search_highlighting") - (return-type "none") - (parameters - '("gboolean" "enable") - ) -) - -(define-method get_enable_search_highlighting - (of-object "XedDocument") - (c-name "xed_document_get_enable_search_highlighting") - (return-type "gboolean") -) - -;; From ../../xed/xed-encodings.h - -(define-function xed_encoding_get_type - (c-name "xed_encoding_get_type") - (return-type "GType") -) - -(define-method copy - (of-object "XedEncoding") - (c-name "xed_encoding_copy") - (return-type "XedEncoding*") -) - -(define-method free - (of-object "XedEncoding") - (c-name "xed_encoding_free") - (return-type "none") -) - -(define-function encoding_get_from_charset - (c-name "xed_encoding_get_from_charset") - (return-type "const-XedEncoding*") - (parameters - '("const-gchar*" "charset") - ) -) - -; Deprecated version ! -(define-function xed_encoding_get_from_charset - (c-name "xed_encoding_get_from_charset_deprecated") - (return-type "const-XedEncoding*") - (parameters - '("const-gchar*" "charset") - ) -) - -(define-function encoding_get_from_index - (c-name "xed_encoding_get_from_index") - (return-type "const-XedEncoding*") - (parameters - '("gint" "index") - ) -) - -; Deprecated version ! -(define-function xed_encoding_get_from_index - (c-name "xed_encoding_get_from_index_deprecated") - (return-type "const-XedEncoding*") - (parameters - '("gint" "index") - ) -) - -(define-method to_string - (of-object "XedEncoding") - (c-name "xed_encoding_to_string") - (return-type "gchar*") -) - -(define-method get_name - (of-object "XedEncoding") - (c-name "xed_encoding_get_name") - (return-type "const-gchar*") -) - -(define-method get_charset - (of-object "XedEncoding") - (c-name "xed_encoding_get_charset") - (return-type "const-gchar*") -) - -(define-function encoding_get_utf8 - (c-name "xed_encoding_get_utf8") - (return-type "const-XedEncoding*") -) - -; Deprecated version ! -(define-function xed_encoding_get_utf8 - (c-name "xed_encoding_get_utf8_deprecated") - (return-type "const-XedEncoding*") -) - -(define-function encoding_get_current - (c-name "xed_encoding_get_current") - (return-type "const-XedEncoding*") -) - -; Deprecated version ! -(define-function xed_encoding_get_current - (c-name "xed_encoding_get_current_deprecated") - (return-type "const-XedEncoding*") -) - -;; From ../../xed/xed-help.h - -(define-function help_display - (c-name "xed_help_display") - (return-type "gboolean") - (parameters - '("GtkWindow*" "parent") - '("const-gchar*" "name") - '("const-gchar*" "link_id") - ) -) - - - -;; From ../../xed/xed-panel.h - -(define-function xed_panel_get_type - (c-name "xed_panel_get_type") - (return-type "GType") -) - -(define-function xed_panel_new - (c-name "xed_panel_new") - (is-constructor-of "XedPanel") - (return-type "GtkWidget*") -) - -(define-method add_item - (of-object "XedPanel") - (c-name "xed_panel_add_item") - (return-type "none") - (parameters - '("GtkWidget*" "item") - '("const-gchar*" "name") - '("GtkWidget*" "image") - ) -) - -(define-method add_item_with_stock_icon - (of-object "XedPanel") - (c-name "xed_panel_add_item_with_stock_icon") - (return-type "none") - (parameters - '("GtkWidget*" "item") - '("const-gchar*" "name") - '("const-gchar*" "stock_id") - ) -) - -(define-method remove_item - (of-object "XedPanel") - (c-name "xed_panel_remove_item") - (return-type "gboolean") - (parameters - '("GtkWidget*" "item") - ) -) - -(define-method activate_item - (of-object "XedPanel") - (c-name "xed_panel_activate_item") - (return-type "gboolean") - (parameters - '("GtkWidget*" "item") - ) -) - -(define-method item_is_active - (of-object "XedPanel") - (c-name "xed_panel_item_is_active") - (return-type "gboolean") - (parameters - '("GtkWidget*" "item") - ) -) - -(define-method get_orientation - (of-object "XedPanel") - (c-name "xed_panel_get_orientation") - (return-type "GtkOrientation") -) - -(define-method get_n_items - (of-object "XedPanel") - (c-name "xed_panel_get_n_items") - (return-type "gint") -) - - -;; From ../../xed/xed-plugin.h - -(define-function xed_plugin_get_type - (c-name "xed_plugin_get_type") - (return-type "GType") -) - -(define-method get_install_dir - (of-object "XedPlugin") - (c-name "xed_plugin_get_install_dir") - (return-type "gchar*") -) - -(define-method get_data_dir - (of-object "XedPlugin") - (c-name "xed_plugin_get_data_dir") - (return-type "gchar*") -) - -(define-method activate - (of-object "XedPlugin") - (c-name "xed_plugin_activate") - (return-type "none") - (parameters - '("XedWindow*" "window") - ) -) - -(define-method deactivate - (of-object "XedPlugin") - (c-name "xed_plugin_deactivate") - (return-type "none") - (parameters - '("XedWindow*" "window") - ) -) - -(define-method update_ui - (of-object "XedPlugin") - (c-name "xed_plugin_update_ui") - (return-type "none") - (parameters - '("XedWindow*" "window") - ) -) - -(define-method is_configurable - (of-object "XedPlugin") - (c-name "xed_plugin_is_configurable") - (return-type "gboolean") -) - -(define-method create_configure_dialog - (of-object "XedPlugin") - (c-name "xed_plugin_create_configure_dialog") - (return-type "GtkWidget*") -) - -;; From ../xed/xed-plugin-python.h - -(define-function xed_plugin_python_get_type - (c-name "xed_plugin_python_get_type") - (return-type "GType") -) - -(define-function xed_plugin_python_new - (c-name "xed_plugin_python_new") - (is-constructor-of "XedPluginPython") - (return-type "XedPluginPython*") -) - -;; From ../../xed/xed-status-bar.h - -(define-method flash_message - (of-object "XedStatusbar") - (c-name "xed_statusbar_flash_message") - (return-type "none") - (parameters - '("int" "context_id") - '("const-gchar*" "message") - ) - ) - -;; From ../../xed/xed-tab.h - -(define-function xed_tab_get_type - (c-name "xed_tab_get_type") - (return-type "GType") -) - -(define-method get_view - (of-object "XedTab") - (c-name "xed_tab_get_view") - (return-type "XedView*") -) - -(define-method get_document - (of-object "XedTab") - (c-name "xed_tab_get_document") - (return-type "XedDocument*") -) - -(define-function tab_get_from_document - (c-name "xed_tab_get_from_document") - (return-type "XedTab*") - (parameters - '("XedDocument*" "doc") - ) -) - -; Deprecated version ! -(define-function xed_tab_get_from_document - (c-name "xed_tab_get_from_document_deprecated") - (return-type "XedTab*") - (parameters - '("XedDocument*" "doc") - ) -) - -(define-method get_state - (of-object "XedTab") - (c-name "xed_tab_get_state") - (return-type "XedTabState") -) - -(define-method set_auto_save_enabled - (of-object "XedTab") - (c-name "xed_tab_set_auto_save_enabled") - (return-type "none") - (parameters - '("gboolean" "enable") - ) -) - -(define-method get_auto_save_enabled - (of-object "XedTab") - (c-name "xed_tab_get_auto_save_enabled") - (return-type "gboolean") -) - -(define-method set_auto_save_interval - (of-object "XedTab") - (c-name "xed_tab_set_auto_save_interval") - (return-type "none") - (parameters - '("gint" "interval") - ) -) - -(define-method get_auto_save_interval - (of-object "XedTab") - (c-name "xed_tab_get_auto_save_interval") - (return-type "gint") -) - -;; From ../../xed/xed-view.h - -(define-function xed_view_get_type - (c-name "xed_view_get_type") - (return-type "GtkType") -) - -(define-function xed_view_new - (c-name "xed_view_new") - (is-constructor-of "XedView") - (return-type "GtkWidget*") - (parameters - '("XedDocument*" "doc") - ) -) - -(define-method cut_clipboard - (of-object "XedView") - (c-name "xed_view_cut_clipboard") - (return-type "none") -) - -(define-method copy_clipboard - (of-object "XedView") - (c-name "xed_view_copy_clipboard") - (return-type "none") -) - -(define-method paste_clipboard - (of-object "XedView") - (c-name "xed_view_paste_clipboard") - (return-type "none") -) - -(define-method delete_selection - (of-object "XedView") - (c-name "xed_view_delete_selection") - (return-type "none") -) - -(define-method select_all - (of-object "XedView") - (c-name "xed_view_select_all") - (return-type "none") -) - -(define-method scroll_to_cursor - (of-object "XedView") - (c-name "xed_view_scroll_to_cursor") - (return-type "none") -) - -(define-method set_font - (of-object "XedView") - (c-name "xed_view_set_font") - (return-type "none") - (parameters - '("gboolean" "def") - '("const-gchar*" "font_name") - ) -) - - - -;; From ../../xed/xed-window.h - -(define-function xed_window_get_type - (c-name "xed_window_get_type") - (return-type "GType") -) - -(define-method create_tab - (of-object "XedWindow") - (c-name "xed_window_create_tab") - (return-type "XedTab*") - (parameters - '("gboolean" "jump_to") - ) -) - -(define-method create_tab_from_uri - (of-object "XedWindow") - (c-name "xed_window_create_tab_from_uri") - (return-type "XedTab*") - (parameters - '("const-gchar*" "uri") - '("const-XedEncoding*" "encoding" (null-ok)) - '("gint" "line_pos") - '("gboolean" "create") - '("gboolean" "jump_to") - ) -) - -(define-method close_tab - (of-object "XedWindow") - (c-name "xed_window_close_tab") - (return-type "none") - (parameters - '("XedTab*" "tab") - ) -) - -(define-method close_tabs - (of-object "XedWindow") - (c-name "xed_window_close_tabs") - (return-type "none") - (parameters - '("const-GList*" "tabs") - ) -) - -(define-method close_all_tabs - (of-object "XedWindow") - (c-name "xed_window_close_all_tabs") - (return-type "none") -) - -(define-method get_active_tab - (of-object "XedWindow") - (c-name "xed_window_get_active_tab") - (return-type "XedTab*") -) - -(define-method set_active_tab - (of-object "XedWindow") - (c-name "xed_window_set_active_tab") - (return-type "none") - (parameters - '("XedTab*" "tab") - ) -) - -(define-method get_active_view - (of-object "XedWindow") - (c-name "xed_window_get_active_view") - (return-type "XedView*") -) - -(define-method get_active_document - (of-object "XedWindow") - (c-name "xed_window_get_active_document") - (return-type "XedDocument*") -) - -(define-method get_documents - (of-object "XedWindow") - (c-name "xed_window_get_documents") - (return-type "GList*") -) - -(define-method get_unsaved_documents - (of-object "XedWindow") - (c-name "xed_window_get_unsaved_documents") - (return-type "GList*") -) - -(define-method get_views - (of-object "XedWindow") - (c-name "xed_window_get_views") - (return-type "GList*") -) - -(define-method get_group - (of-object "XedWindow") - (c-name "xed_window_get_group") - (return-type "GtkWindowGroup*") -) - -(define-method get_side_panel - (of-object "XedWindow") - (c-name "xed_window_get_side_panel") - (return-type "XedPanel*") -) - -(define-method get_bottom_panel - (of-object "XedWindow") - (c-name "xed_window_get_bottom_panel") - (return-type "XedPanel*") -) - -(define-method get_statusbar - (of-object "XedWindow") - (c-name "xed_window_get_statusbar") - (return-type "GtkWidget*") -) - -(define-method get_ui_manager - (of-object "XedWindow") - (c-name "xed_window_get_ui_manager") - (return-type "GtkUIManager*") -) - -(define-method get_state - (of-object "XedWindow") - (c-name "xed_window_get_state") - (return-type "XedWindowState") -) - -(define-method get_message_bus - (of-object "XedWindow") - (c-name "xed_window_get_message_bus") - (return-type "XedMessageBus*") -) - -(define-method get_tab_from_uri - (of-object "XedWindow") - (c-name "xed_window_get_tab_from_uri") - (return-type "XedTab*") - (parameters - '("const-gchar*" "uri") - ) -) - -;; From xed-language-manager.h - -(define-function get_language_manager - (c-name "xed_get_language_manager") - (return-type "GtkSourceLanguageManager*") -) - -(define-function language_manager_list_languages_sorted - (c-name "xed_language_manager_list_languages_sorted") - (return-type "GSList*") - (parameters - '("GtkSourceLanguageManager*" "lm") - '("gboolean" "include_hidden") - ) -) - - -;; From xed-message-bus.h - -(define-function xed_message_bus_get_type - (c-name "xed_message_bus_get_type") - (return-type "GType") -) - -(define-function message_bus_get_default - (c-name "xed_message_bus_get_default") - (return-type "XedMessageBus*") -) - -(define-function xed_message_bus_new - (c-name "xed_message_bus_new") - (is-constructor-of "XedMessageBus") - (return-type "XedMessageBus*") -) - -(define-method lookup - (of-object "XedMessageBus") - (c-name "xed_message_bus_lookup") - (return-type "XedMessageType*") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - ) -) - -(define-method register - (of-object "XedMessageBus") - (c-name "xed_message_bus_register") - (return-type "XedMessageType*") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - '("guint" "num_optional") - ) - (varargs #t) -) - -(define-method unregister - (of-object "XedMessageBus") - (c-name "xed_message_bus_unregister") - (return-type "none") - (parameters - '("XedMessageType*" "message_type") - ) -) - -(define-method unregister_all - (of-object "XedMessageBus") - (c-name "xed_message_bus_unregister_all") - (return-type "none") - (parameters - '("const-gchar*" "object_path") - ) -) - -(define-method is_registered - (of-object "XedMessageBus") - (c-name "xed_message_bus_is_registered") - (return-type "gboolean") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - ) -) - -(define-method connect - (of-object "XedMessageBus") - (c-name "xed_message_bus_connect") - (return-type "guint") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - '("XedMessageCallback" "callback") - '("gpointer" "userdata") - '("GDestroyNotify" "destroy_data") - ) -) - -(define-method disconnect - (of-object "XedMessageBus") - (c-name "xed_message_bus_disconnect") - (return-type "none") - (parameters - '("guint" "id") - ) -) - -(define-method disconnect_by_func - (of-object "XedMessageBus") - (c-name "xed_message_bus_disconnect_by_func") - (return-type "none") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - '("XedMessageCallback" "callback") - '("gpointer" "userdata") - ) -) - -(define-method block - (of-object "XedMessageBus") - (c-name "xed_message_bus_block") - (return-type "none") - (parameters - '("guint" "id") - ) -) - -(define-method block_by_func - (of-object "XedMessageBus") - (c-name "xed_message_bus_block_by_func") - (return-type "none") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - '("XedMessageCallback" "callback") - '("gpointer" "userdata") - ) -) - -(define-method unblock - (of-object "XedMessageBus") - (c-name "xed_message_bus_unblock") - (return-type "none") - (parameters - '("guint" "id") - ) -) - -(define-method unblock_by_func - (of-object "XedMessageBus") - (c-name "xed_message_bus_unblock_by_func") - (return-type "none") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - '("XedMessageCallback" "callback") - '("gpointer" "userdata") - ) -) - -(define-method send_message - (of-object "XedMessageBus") - (c-name "xed_message_bus_send_message") - (return-type "none") - (parameters - '("XedMessage*" "message") - ) -) - -(define-method send_message_sync - (of-object "XedMessageBus") - (c-name "xed_message_bus_send_message_sync") - (return-type "none") - (parameters - '("XedMessage*" "message") - ) -) - -(define-method send - (of-object "XedMessageBus") - (c-name "xed_message_bus_send") - (return-type "none") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - ) - (varargs #t) -) - -(define-method send_sync - (of-object "XedMessageBus") - (c-name "xed_message_bus_send_sync") - (return-type "XedMessage*") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - ) - (varargs #t) -) - - -;; From xed-message-type.h - -(define-function xed_message_type_get_type - (c-name "xed_message_type_get_type") - (return-type "GType") -) - -(define-function xed_message_type_is_supported - (c-name "xed_message_type_is_supported") - (return-type "gboolean") - (parameters - '("GType" "type") - ) -) - -(define-function xed_message_type_identifier - (c-name "xed_message_type_identifier") - (return-type "gchar*") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - ) -) - -(define-function xed_message_type_new - (c-name "xed_message_type_new") - (is-constructor-of "XedMessageType") - (return-type "XedMessageType*") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - '("guint" "num_optional") - ) - (varargs #t) -) - -(define-function xed_message_type_new_valist - (c-name "xed_message_type_new_valist") - (return-type "XedMessageType*") - (parameters - '("const-gchar*" "object_path") - '("const-gchar*" "method") - '("guint" "num_optional") - '("va_list" "va_args") - ) -) - -(define-method ref - (of-object "XedMessageType") - (c-name "xed_message_type_ref") - (return-type "XedMessageType*") -) - -(define-method unref - (of-object "XedMessageType") - (c-name "xed_message_type_unref") - (return-type "none") -) - -(define-method instantiate_valist - (of-object "XedMessageType") - (c-name "xed_message_type_instantiate_valist") - (return-type "XedMessage*") - (parameters - '("va_list" "va_args") - ) -) - -(define-method instantiate - (of-object "XedMessageType") - (c-name "xed_message_type_instantiate") - (return-type "XedMessage*") - (parameters - ) - (varargs #t) -) - -(define-method get_object_path - (of-object "XedMessageType") - (c-name "xed_message_type_get_object_path") - (return-type "const-gchar*") -) - -(define-method get_method - (of-object "XedMessageType") - (c-name "xed_message_type_get_method") - (return-type "const-gchar*") -) - -(define-method lookup - (of-object "XedMessageType") - (c-name "xed_message_type_lookup") - (return-type "GType") - (parameters - '("const-gchar*" "key") - ) -) - -(define-method foreach - (of-object "XedMessageType") - (c-name "xed_message_type_foreach") - (return-type "none") - (parameters - '("XedMessageTypeForeach" "func") - '("gpointer" "user_data") - ) -) - - -;; From xed-message.h - -(define-function xed_message_get_type - (c-name "xed_message_get_type") - (return-type "GType") -) - -(define-method get - (of-object "XedMessage") - (c-name "xed_message_get") - (return-type "none") - (parameters - ) - (varargs #t) -) - -(define-method get_valist - (of-object "XedMessage") - (c-name "xed_message_get_valist") - (return-type "none") - (parameters - '("va_list" "var_args") - ) -) - -(define-method get_value - (of-object "XedMessage") - (c-name "xed_message_get_value") - (return-type "none") - (parameters - '("const-gchar*" "key") - '("GValue*" "value") - ) -) - -(define-method set - (of-object "XedMessage") - (c-name "xed_message_set") - (return-type "none") - (parameters - ) - (varargs #t) -) - -(define-method set_valist - (of-object "XedMessage") - (c-name "xed_message_set_valist") - (return-type "none") - (parameters - '("va_list" "var_args") - ) -) - -(define-method set_value - (of-object "XedMessage") - (c-name "xed_message_set_value") - (return-type "none") - (parameters - '("const-gchar*" "key") - '("GValue*" "value") - ) -) - -(define-method set_valuesv - (of-object "XedMessage") - (c-name "xed_message_set_valuesv") - (return-type "none") - (parameters - '("const-gchar**" "keys") - '("GValue*" "values") - '("gint" "n_values") - ) -) - -(define-method get_object_path - (of-object "XedMessage") - (c-name "xed_message_get_object_path") - (return-type "const-gchar*") -) - -(define-method get_method - (of-object "XedMessage") - (c-name "xed_message_get_method") - (return-type "const-gchar*") -) - -(define-method has_key - (of-object "XedMessage") - (c-name "xed_message_has_key") - (return-type "gboolean") - (parameters - '("const-gchar*" "key") - ) -) - -(define-method get_key_type - (of-object "XedMessage") - (c-name "xed_message_get_key_type") - (return-type "GType") - (parameters - '("const-gchar*" "key") - ) -) - -(define-method validate - (of-object "XedMessage") - (c-name "xed_message_validate") - (return-type "gboolean") -) - - -;; From ../../xed/xed-debug.h - -(define-function debug - (c-name "xed_debug") - (parameters - '("const-gchar*" "message") - ) - (return-type "none") -) - diff --git a/plugin-loaders/python/bindings/xed.override b/plugin-loaders/python/bindings/xed.override deleted file mode 100644 index 93f37e3..0000000 --- a/plugin-loaders/python/bindings/xed.override +++ /dev/null @@ -1,461 +0,0 @@ -%% -headers -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xed-plugin-python.h" - -void pyxed_register_classes (PyObject *d); -void pyxed_add_constants (PyObject *module, const gchar *strip_prefix); - -static PyObject * -_helper_wrap_gobject_glist (const GList *list) -{ - PyObject *py_list; - const GList *tmp; - - if ((py_list = PyList_New(0)) == NULL) { - return NULL; - } - for (tmp = list; tmp != NULL; tmp = tmp->next) { - PyObject *py_obj = pygobject_new(G_OBJECT(tmp->data)); - - if (py_obj == NULL) { - Py_DECREF(py_list); - return NULL; - } - PyList_Append(py_list, py_obj); - Py_DECREF(py_obj); - } - return py_list; -} - -static PyObject * -_helper_wrap_gobject_gslist (const GSList *list) -{ - PyObject *py_list; - const GSList *tmp; - - if ((py_list = PyList_New(0)) == NULL) { - return NULL; - } - for (tmp = list; tmp != NULL; tmp = tmp->next) { - PyObject *py_obj = pygobject_new(G_OBJECT(tmp->data)); - - if (py_obj == NULL) { - Py_DECREF(py_list); - return NULL; - } - PyList_Append(py_list, py_obj); - Py_DECREF(py_obj); - } - return py_list; -} -%% -include - xedplugin.override - xedmessage.override -%% -modulename xed -%% -import gtk.Widget as PyGtkWidget_Type -import gobject.GObject as PyGObject_Type -import gtk.gdk.Screen as PyGdkScreen_Type -import gtk.VBox as PyGtkVBox_Type -import gtk.Window as PyGtkWindow_Type -import gtk.Image as PyGtkImage_Type -import gtk.Statusbar as PyGtkStatusbar_Type -import gtksourceview2.Buffer as PyGtkSourceBuffer_Type -import gtksourceview2.View as PyGtkSourceView_Type -import gtksourceview2.Language as PyGtkSourceLanguage_Type -import gtksourceview2.LanguageManager as PyGtkSourceLanguageManager_Type -%% -ignore-glob - *_get_type - xed_document_error_quark - xed_panel_add_item_with_stock_icon -%% -override xed_app_create_window kwargs -static PyObject * -_wrap_xed_app_create_window(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "screen", NULL}; - PyGObject *screen = NULL; - XedWindow *ret; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|O!", kwlist, - &PyGdkScreen_Type, &screen)) - return NULL; - - ret = xed_app_create_window(XED_APP(self->obj), - screen ? GDK_SCREEN(screen->obj) : NULL); - - /* pygobject_new handles NULL checking */ - return pygobject_new((GObject *)ret); -} -%% -override xed_app_get_windows -static PyObject * -_wrap_xed_app_get_windows(PyGObject *self) -{ - const GList *list; - PyObject *py_list; - - list = xed_app_get_windows (XED_APP (self->obj)); - - py_list = _helper_wrap_gobject_glist (list); - - return py_list; -} -%% -override xed_app_get_views -static PyObject * -_wrap_xed_app_get_views(PyGObject *self) -{ - GList *list; - PyObject *py_list; - - list = xed_app_get_views (XED_APP (self->obj)); - - py_list = _helper_wrap_gobject_glist (list); - - g_list_free (list); - - return py_list; -} -%% -override xed_app_get_documents -static PyObject * -_wrap_xed_app_get_documents(PyGObject *self) -{ - GList *list; - PyObject *py_list; - - list = xed_app_get_documents (XED_APP (self->obj)); - - py_list = _helper_wrap_gobject_glist (list); - - g_list_free (list); - - return py_list; -} -%% -override xed_window_get_documents -static PyObject * -_wrap_xed_window_get_documents(PyGObject *self) -{ - GList *list; - PyObject *py_list; - - list = xed_window_get_documents (XED_WINDOW (self->obj)); - - py_list = _helper_wrap_gobject_glist (list); - - g_list_free(list); - - return py_list; -} -%% -override xed_window_get_unsaved_documents -static PyObject * -_wrap_xed_window_get_unsaved_documents(PyGObject *self) -{ - GList *list; - PyObject *py_list; - - list = xed_window_get_unsaved_documents (XED_WINDOW (self->obj)); - - py_list = _helper_wrap_gobject_glist (list); - - g_list_free(list); - - return py_list; -} -%% -override xed_window_get_views -static PyObject * -_wrap_xed_window_get_views(PyGObject *self) -{ - GList *list; - PyObject *py_list; - - list = xed_window_get_views (XED_WINDOW (self->obj)); - - py_list = _helper_wrap_gobject_glist (list); - - g_list_free(list); - - return py_list; -} -%% -override xed_window_close_tabs kwargs -static PyObject * -_wrap_xed_window_close_tabs (PyGObject *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "tabs", NULL }; - PyObject *list, *item; - GList *glist = NULL; - int len, i; - - if (!PyArg_ParseTupleAndKeywords (args, kwargs, - "O:XedWindow.close_tabs", kwlist, - &list)) - return NULL; - - if (!PySequence_Check (list)) - { - PyErr_SetString (PyExc_TypeError, - "first argument must be a sequence"); - return NULL; - } - - len = PySequence_Length (list); - - for (i = 0; i < len; i++) - { - item = PySequence_GetItem (list, i); - Py_DECREF(item); - - if (!pygobject_check (item, &PyXedTab_Type)) - { - PyErr_SetString (PyExc_TypeError, - "sequence item not a Gtkwidget object"); - g_list_free (glist); - return NULL; - } - - glist = g_list_append (glist, pygobject_get (item)); - } - - xed_window_close_tabs (XED_WINDOW (self->obj), glist); - - g_list_free (glist); - Py_INCREF (Py_None); - return Py_None; -} -%% -override xed_document_get_search_text -static PyObject * -_wrap_xed_document_get_search_text(PyGObject *self) -{ - PyObject *tuple, *string; - guint flags; - gchar *ret; - - ret = xed_document_get_search_text (XED_DOCUMENT (self->obj), &flags); - - tuple = PyTuple_New(2); - if (ret) { - string = PyString_FromString(ret); - PyTuple_SetItem(tuple, 0, string); - } else { - Py_INCREF(Py_None); - PyTuple_SetItem(tuple, 0, Py_None); - } - PyTuple_SetItem(tuple, 1, PyInt_FromLong(flags)); - - g_free(ret); - - return tuple; -} -%% -override xed_panel_add_item kwargs -static PyObject * -_wrap_xed_panel_add_item(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist1[] = { "item", "name", "image", NULL }; - static char *kwlist2[] = { "item", "name", "stock_id", NULL }; - PyGObject *item, *image; - char *name = NULL; - char *stock_id = NULL; - - if (PyArg_ParseTupleAndKeywords(args, kwargs, "O!sO!:XedPanel.add_item", kwlist1, &PyGtkWidget_Type, &item, &name, &PyGtkImage_Type, &image)) { - xed_panel_add_item(XED_PANEL(self->obj), GTK_WIDGET(item->obj), name, GTK_WIDGET(image->obj)); - Py_INCREF(Py_None); - return Py_None; - } - - PyErr_Clear(); - - if (PyArg_ParseTupleAndKeywords(args, kwargs, "O!ss:XedPanel.add_item", kwlist2, &PyGtkWidget_Type, &item, &name, &stock_id)) { - xed_panel_add_item_with_stock_icon(XED_PANEL(self->obj), GTK_WIDGET(item->obj), name, stock_id); - Py_INCREF(Py_None); - return Py_None; - } - - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "the last arg should be either a gtk.Image or a stock_id string"); - return NULL; -} -%% -override xed_app_get_default_deprecated -/* deprecated wrappers */ -static PyObject * -_wrap_xed_app_get_default_deprecated(PyObject *self) -{ - if (PyErr_Warn(PyExc_DeprecationWarning, "use xed.app_get_default instead") < 0) - return NULL; - return _wrap_xed_app_get_default(self); -} -%% -override xed_encoding_get_from_charset_deprecated kwargs -static PyObject * -_wrap_xed_encoding_get_from_charset_deprecated(PyObject *self, PyObject *args, PyObject *kwargs) -{ - if (PyErr_Warn(PyExc_DeprecationWarning, "use xed.encoding_get_from_charset instead") < 0) - return NULL; - return _wrap_xed_encoding_get_from_charset(self, args, kwargs); -} -%% -override xed_encoding_get_from_index_deprecated kwargs -static PyObject * -_wrap_xed_encoding_get_from_index_deprecated(PyObject *self, PyObject *args, PyObject *kwargs) -{ - if (PyErr_Warn(PyExc_DeprecationWarning, "use xed.encoding_get_from_index instead") < 0) - return NULL; - return _wrap_xed_encoding_get_from_index(self, args, kwargs); -} -%% -override xed_encoding_get_utf8_deprecated -static PyObject * -_wrap_xed_encoding_get_utf8_deprecated(PyObject *self) -{ - if (PyErr_Warn(PyExc_DeprecationWarning, "use xed.encoding_get_utf8 instead") < 0) - return NULL; - return _wrap_xed_encoding_get_utf8(self); -} -%% -override xed_encoding_get_current_deprecated -static PyObject * -_wrap_xed_encoding_get_current_deprecated(PyObject *self) -{ - if (PyErr_Warn(PyExc_DeprecationWarning, "use xed.encoding_get_current instead") < 0) - return NULL; - return _wrap_xed_encoding_get_current(self); -} -%% -override xed_tab_get_from_document_deprecated kwargs -static PyObject * -_wrap_xed_tab_get_from_document_deprecated(PyObject *self, PyObject *args, PyObject *kwargs) -{ - if (PyErr_Warn(PyExc_DeprecationWarning, "use xed.tab_get_from_document instead") < 0) - return NULL; - return _wrap_xed_tab_get_from_document(self, args, kwargs); -} -%% -override xed_language_manager_list_languages_sorted kwargs -static PyObject * -_wrap_xed_language_manager_list_languages_sorted(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "lm", "include_hidden", NULL }; - PyGObject *lm; - int include_hidden; - PyObject *py_list; - GSList *list; - - if (!PyArg_ParseTupleAndKeywords (args, kwargs, - "O!i:language_manager_list_languages_sorted", - kwlist, &PyGtkSourceLanguageManager_Type, &lm, - &include_hidden)) - return NULL; - - list = xed_language_manager_list_languages_sorted (GTK_SOURCE_LANGUAGE_MANAGER (lm->obj), - include_hidden); - - py_list = _helper_wrap_gobject_gslist (list); - - g_slist_free (list); - - return py_list; -} -%% -override xed_debug kwargs -static PyObject * -_wrap_xed_debug(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "message", NULL }; - PyObject *traceback_module, *mdict, *func, *traceback, *tuple; - PyObject *filename, *lineno, *funcname; - char *message = NULL; - - if (g_getenv ("XED_DEBUG_PLUGINS") == NULL) - { - Py_INCREF (Py_None); - return Py_None; - } - - if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|s", kwlist, &message)) - return NULL; - - traceback_module = PyImport_ImportModule ("traceback"); - if (traceback_module == NULL) - { - g_warning ("traceback module cannot be imported"); - Py_INCREF (Py_None); - return Py_None; - } - - mdict = PyModule_GetDict (traceback_module); - func = PyDict_GetItemString (mdict, "extract_stack"); - traceback = PyObject_CallFunction (func, "zi", NULL, 1); - tuple = PyList_GetItem (traceback, 0); - - if (tuple == NULL || !PyTuple_Check (tuple)) - { - g_warning ("traceback tuple is null!"); - } - else - { - filename = PyTuple_GetItem (tuple, 0); - lineno = PyTuple_GetItem (tuple, 1); - funcname = PyTuple_GetItem (tuple, 2); - - if (message == NULL) - xed_debug (XED_DEBUG_PLUGINS, - PyString_AsString (filename), - PyInt_AsLong (lineno), - PyString_AsString (funcname)); - else - xed_debug_message (XED_DEBUG_PLUGINS, - PyString_AsString (filename), - PyInt_AsLong (lineno), - PyString_AsString (funcname), - "%s", - message); - } - Py_DECREF (traceback); - Py_DECREF (traceback_module); - - Py_INCREF (Py_None); - return Py_None; -} -%% -override xed_statusbar_flash_message kwargs -static PyObject * -_wrap_xed_statusbar_flash_message(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "context_id", "message", NULL }; - int context_id; - char *message; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"is:XedStatusbar.flash_message", kwlist, &context_id, &message)) - return NULL; - - xed_statusbar_flash_message(XED_STATUSBAR(self->obj), context_id, "%s", message); - - Py_INCREF(Py_None); - return Py_None; -} -%% diff --git a/plugin-loaders/python/bindings/xedcommands.defs b/plugin-loaders/python/bindings/xedcommands.defs deleted file mode 100644 index 31aa7e3..0000000 --- a/plugin-loaders/python/bindings/xedcommands.defs +++ /dev/null @@ -1,45 +0,0 @@ -;; -*- scheme -*- -; object definitions ... -;; Enumerations and flags ... - - -;; From ../../xed/xed-commands.h - -(define-function load_uri - (c-name "xed_commands_load_uri") - (return-type "none") - (parameters - '("XedWindow*" "window") - '("const-gchar*" "uri") - '("const-XedEncoding*" "encoding") - '("gint" "line_pos") - ) -) - -(define-function load_uris - (c-name "xed_commands_load_uris") - (return-type "gint") - (parameters - '("XedWindow*" "window") - '("const-GSList*" "uris") - '("const-XedEncoding*" "encoding") - '("gint" "line_pos") - ) -) - -(define-function save_document - (c-name "xed_commands_save_document") - (return-type "none") - (parameters - '("XedWindow*" "window") - '("XedDocument*" "document") - ) -) - -(define-function save_all_documents - (c-name "xed_commands_save_all_documents") - (return-type "none") - (parameters - '("XedWindow*" "window") - ) -) diff --git a/plugin-loaders/python/bindings/xedcommands.override b/plugin-loaders/python/bindings/xedcommands.override deleted file mode 100644 index 603b0c5..0000000 --- a/plugin-loaders/python/bindings/xedcommands.override +++ /dev/null @@ -1,122 +0,0 @@ -%% -headers -#define NO_IMPORT_PYGOBJECT -#define NO_IMPORT_PYGTK -#include -#include - -#include "xed-commands.h" -#include "xed-window.h" - -void pyxedcommands_register_classes (PyObject *d); -void pyxedcommands_add_constants (PyObject *module, const gchar *strip_prefix); - -%% -modulename xed.commands -%% -import xed.Window as PyXedWindow_Type -import xed.Document as PyXedDocument_Type -%% -ignore-glob - _* -%% -override xed_commands_load_uri kwargs -static PyObject * -_wrap_xed_commands_load_uri (PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "window", "uri", "encoding", "line_pos", NULL }; - PyGObject *window; - char *uri; - int line_pos = 0; - PyObject *py_encoding = NULL; - XedEncoding *encoding = NULL; - - if (!PyArg_ParseTupleAndKeywords (args, kwargs, "O!s|Oi:load_uri", - kwlist, &PyXedWindow_Type, - &window, &uri, &py_encoding, - &line_pos)) - return NULL; - - if (py_encoding != NULL && py_encoding != Py_None) - { - if (pyg_boxed_check (py_encoding, XED_TYPE_ENCODING)) - encoding = pyg_boxed_get (py_encoding, XedEncoding); - else - { - PyErr_SetString (PyExc_TypeError, - "encoding should be a XedEncoding"); - return NULL; - } - } - - xed_commands_load_uri (XED_WINDOW (window->obj), uri, encoding, - line_pos); - Py_INCREF (Py_None); - return Py_None; -} -%% -override xed_commands_load_uris kwargs -static PyObject * -_wrap_xed_commands_load_uris (PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "window", "uris", "encoding", "line_pos", NULL }; - PyGObject *window; - GSList *uris = NULL; - int line_pos = 0; - PyObject *py_encoding = NULL; - PyObject *list; - PyObject *item; - XedEncoding *encoding = NULL; - int len; - int i; - - if (!PyArg_ParseTupleAndKeywords (args, kwargs, "O!O|Oi:load_uri", - kwlist, &PyXedWindow_Type, - &window, &list, &py_encoding, - &line_pos)) - return NULL; - - if (py_encoding != NULL && py_encoding != Py_None) - { - if (pyg_boxed_check (py_encoding, XED_TYPE_ENCODING)) - encoding = pyg_boxed_get (py_encoding, XedEncoding); - else { - PyErr_SetString (PyExc_TypeError, - "encoding should be a XedEncoding"); - return NULL; - } - } - - if (!PySequence_Check (list)) - { - PyErr_SetString (PyExc_TypeError, - "second argument must be a sequence"); - return NULL; - } - - len = PySequence_Length (list); - - for (i = 0; i < len; i++) - { - item = PySequence_GetItem (list, i); - Py_DECREF (item); - - if (!PyString_Check (item)) - { - PyErr_SetString (PyExc_TypeError, - "sequence item not a string"); - g_slist_free (uris); - return NULL; - } - - uris = g_slist_prepend (uris, PyString_AsString (item)); - } - - uris = g_slist_reverse (uris); - xed_commands_load_uris (XED_WINDOW (window->obj), uris, - encoding, line_pos); - g_slist_free (uris); - - Py_INCREF (Py_None); - return Py_None; -} diff --git a/plugin-loaders/python/bindings/xedmessage.override b/plugin-loaders/python/bindings/xedmessage.override deleted file mode 100644 index c1af552..0000000 --- a/plugin-loaders/python/bindings/xedmessage.override +++ /dev/null @@ -1,556 +0,0 @@ -%% -headers - -#include -#include - -static GType -_helper_wrap_get_gtype_from_pytype (PyObject *pytype) -{ - PyTypeObject *type = (PyTypeObject *)pytype; - - if (type == &PyList_Type || type == &PyTuple_Type) - return G_TYPE_STRV; - - return pyg_type_from_object (pytype); -} - -static gchar * -_helper_wrap_get_string (PyObject *obj) -{ - PyObject *str; - gchar *result; - - str = PyObject_Str (obj); - - if (!str) - return NULL; - - result = g_strdup (PyString_AsString (str)); - Py_DECREF (str); - - return result; -} - -static int -_helper_wrap_list_to_gvalue (GValue *gvalue, PyObject *pyvalue) -{ - int num; - gchar **lst; - gint i; - - num = PySequence_Size (pyvalue); - lst = g_new0 (gchar *, num + 1); - - for (i = 0; i < num; i++) - { - lst[i] = _helper_wrap_get_string (PySequence_GetItem (pyvalue, i)); - - if (lst[i] == NULL) - { - g_strfreev (lst); - return 1; - } - } - - g_value_set_boxed (gvalue, lst); - g_strfreev (lst); - - return 0; -} - -static int -_helper_wrap_get_gvalue_from_pyobject (GValue *gvalue, PyObject *pyvalue) -{ - if (pyvalue->ob_type == &PyList_Type || pyvalue->ob_type == &PyTuple_Type) - return _helper_wrap_list_to_gvalue (gvalue, pyvalue); - - return pyg_value_from_pyobject(gvalue, pyvalue); -} - -static int -_helper_wrap_message_set_value(XedMessage *message, PyObject *pykey, PyObject *pyvalue) -{ - gchar *key; - GType gtype; - GValue value = {0,}; - - key = _helper_wrap_get_string(pykey); - - if (key == NULL) - return 0; - - gtype = xed_message_get_key_type(message, key); - - if (gtype == 0) { - PyErr_SetString(PyExc_TypeError, "invalid key"); - g_free (key); - return 0; - } - - g_value_init(&value, gtype); - - if (_helper_wrap_get_gvalue_from_pyobject (&value, pyvalue)) { - PyErr_SetString(PyExc_TypeError, - "value is of the wrong type for this key"); - g_free (key); - return 0; - } - - xed_message_set_value(message, key, &value); - g_value_unset(&value); - g_free (key); - - return 1; -} - -typedef void (*ParsePairFunc)(PyObject *key, PyObject *value, gpointer user_data); - -static void -_helper_parse_pairs_dict (PyObject *dict, ParsePairFunc func, gpointer user_data) -{ - if (!dict) - return; - - PyObject *key, *value; - Py_ssize_t i = 0; - - while (PyDict_Next(dict, &i, &key, &value)) - { - func(key, value, user_data); - } -} - -static void -_helper_parse_pairs(PyObject *args, PyObject *kwargs, ParsePairFunc func, gpointer user_data) -{ - guint len; - guint i; - - len = PyTuple_Size(args); - - for (i = 0; i < len; ++i) - { - PyObject *d = PyTuple_GetItem(args, i); - - if (PyDict_Check(d)) - _helper_parse_pairs_dict(d, func, user_data); - } - - _helper_parse_pairs_dict(kwargs, func, user_data); -} - -static void -_helper_message_set(PyObject *key, PyObject *value, XedMessage *message) -{ - _helper_wrap_message_set_value(message, key, value); -} - -static void -_helper_message_set_values(XedMessage *message, PyObject *args, PyObject *kwargs) -{ - _helper_parse_pairs(args, kwargs, (ParsePairFunc)_helper_message_set, message); -} - -static XedMessage * -_helper_wrap_create_message(XedMessageBus *bus, PyObject *args, PyObject *kwargs) -{ - PyObject *pypath, *pymethod, *pydict; - - if (!PyArg_ParseTuple(args, "OO|O:XedMessage.create", &pypath, &pymethod, &pydict)) - return NULL; - - gchar *object_path = _helper_wrap_get_string(pypath); - gchar *method = _helper_wrap_get_string(pymethod); - - XedMessageType *message_type = xed_message_bus_lookup (bus, object_path, method); - XedMessage *message; - - if (message_type) - { - message = xed_message_type_instantiate(message_type, NULL); - _helper_message_set_values(message, args, kwargs); - } - else - { - PyErr_SetString(PyExc_StandardError, "Message type does not exist"); - message = NULL; - } - - g_free(object_path); - g_free(method); - - return message; -} - -typedef struct { - PyObject *func; - PyObject *data; -} PyXedCustomNotify; - -static void -pyxed_custom_destroy_notify(gpointer user_data) -{ - PyXedCustomNotify *cunote = user_data; - PyGILState_STATE state; - - g_return_if_fail(user_data); - state = pyg_gil_state_ensure(); - Py_XDECREF(cunote->func); - Py_XDECREF(cunote->data); - pyg_gil_state_release(state); - - g_free(cunote); -} -%% -ignore-glob - *_get_type - xed_message_type_foreach - xed_message_type_instantiate_valist - xed_message_type_new_valist - xed_message_get_valist - xed_message_set_valist - xed_message_set_valuesv - xed_message_bus_disconnect_by_func - xed_message_bus_block_by_func - xed_message_bus_unblock_by_func -%% -override xed_message_type_new kwargs - -typedef struct -{ - XedMessageType *message_type; - PyObject *optional; -} MessageTypeSetInfo; - -static void -_message_type_set(PyObject *key, PyObject *value, MessageTypeSetInfo *info) -{ - GType gtype; - - gchar *k = _helper_wrap_get_string(key); - - if (!k) - return; - - gtype = _helper_wrap_get_gtype_from_pytype(value); - - gboolean optional = info->optional && PySequence_Contains(info->optional, key); - - xed_message_type_set(info->message_type, optional, k, gtype, NULL); - g_free(k); -} - -static int -_wrap_xed_message_type_new(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *pypath, *pymethod, *optional = NULL, *pydict; - - if (!PyArg_ParseTuple(args, "OO|OO:XedMessageType.new", &pypath, &pymethod, &optional, &pydict)) - return -1; - - XedMessageType *message_type = XED_MESSAGE_TYPE(g_object_new(pyg_type_from_object((PyObject *) self), NULL)); - - MessageTypeSetInfo info = {message_type, optional && PySequence_Check(optional) ? optional : NULL}; - _helper_parse_pairs (args, kwargs, (ParsePairFunc)_message_type_set, &info); - - self->obj = (GObject *)message_type; - pygobject_register_wrapper((PyObject *) self); - - return 0; -} -%% -override xed_message_type_instantiate kwargs -static PyObject * -_wrap_xed_message_type_instantiate(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - XedMessageType *message_type = XED_MESSAGE_TYPE (self->obj); - XedMessage *message = xed_message_type_instantiate(message_type, NULL); - - _helper_message_set_values(message, args, kwargs); - - return pygobject_new((GObject *)message); -} -%% -override xed_message_get args -static PyObject * -_wrap_xed_message_get(PyGObject *self, PyObject *args) -{ - guint len, i; - PyObject *ret; - - len = PyTuple_Size(args); - - ret = PyTuple_New(len); - - for (i = 0; i < len; i++) { - GValue value = { 0, }; - PyObject *py_key = PyTuple_GetItem(args, i); - gchar *key = _helper_wrap_get_string(py_key); - - if (!key) { - PyErr_SetString(PyExc_TypeError, "keys must be strings"); - Py_DECREF(ret); - return NULL; - } - - xed_message_get_value (XED_MESSAGE (self->obj), key, &value); - g_free (key); - - PyTuple_SetItem(ret, i, pyg_value_as_pyobject(&value, TRUE)); - g_value_unset(&value); - } - - return ret; -} -%% -override xed_message_get_value kwargs -static PyObject * -_wrap_xed_message_get_value(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "key", NULL }; - const gchar *key; - PyObject *ret; - GValue value = { 0, }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:XedMessage.get_value", kwlist, &key)) - return NULL; - - xed_message_get_value(XED_MESSAGE(self->obj), key, &value); - ret = pyg_value_as_pyobject(&value, TRUE); - g_value_unset(&value); - - return ret; -} -%% -override xed_message_set_value kwargs -static PyObject * -_wrap_xed_message_set_value(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "key", "value", NULL }; - PyObject *pykey, *pyvalue; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO:XedMessage.set_value", kwlist, &pykey, &pyvalue)) - return NULL; - - if (!_helper_wrap_message_set_value(XED_MESSAGE(self->obj), pykey, pyvalue)) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} -%% -override xed_message_set kwargs -static PyObject * -_wrap_xed_message_set (PyGObject *self, PyObject *args, PyObject *kwargs) { - _helper_message_set_values(XED_MESSAGE(self->obj), args, kwargs); - - Py_INCREF(Py_None); - return Py_None; -} -%% -override xed_message_bus_new -static int -_wrap_xed_message_bus_new(PyGObject *self) -{ - pygobject_construct (self, NULL); - - if (!self->obj) { - PyErr_SetString (PyExc_RuntimeError, "could not create xed.MessageBus object"); - return -1; - } - - return 0; -} -%% -new-constructor XED_TYPE_MESSAGE_BUS -%% -override xed_message_bus_register kwargs -static PyObject * -_wrap_xed_message_bus_register(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *pypath, *pymethod, *optional = NULL, *pydict; - XedMessageBus *bus = XED_MESSAGE_BUS(self->obj); - - if (!PyArg_ParseTuple(args, "OO|OO:XedMessageBus.register", &pypath, &pymethod, &optional, &pydict)) - return NULL; - - gchar *object_path = _helper_wrap_get_string(pypath); - gchar *method = _helper_wrap_get_string(pymethod); - - XedMessageType *message_type = xed_message_bus_register(bus, object_path, method, 0, NULL); - - g_free(object_path); - g_free(method); - - if (!message_type) - { - PyErr_SetString(PyExc_StandardError, "Message type already exists"); - return NULL; - } - - MessageTypeSetInfo info = {message_type, optional && PySequence_Check(optional) ? optional : NULL}; - _helper_parse_pairs (args, kwargs, (ParsePairFunc)_message_type_set, &info); - - return pyg_boxed_new(XED_TYPE_MESSAGE_TYPE, message_type, TRUE, TRUE); -} -%% -override xed_message_bus_connect kwargs -static void -pyxed_message_bus_connect_cb(XedMessageBus *bus, XedMessage *message, gpointer data) -{ - PyGILState_STATE state; - PyXedCustomNotify *cunote = data; - PyObject *pybus, *pymessage, *retobj; - - g_assert(cunote->func); - - state = pyg_gil_state_ensure(); - - pybus = pygobject_new((GObject *)bus); - pymessage = pygobject_new((GObject *)message); - - if (cunote->data) { - retobj = PyEval_CallFunction(cunote->func, "(NNO)", pybus, pymessage, cunote->data); - } else { - retobj = PyEval_CallFunction(cunote->func, "(NN)", pybus, pymessage); - } - - if (PyErr_Occurred()) { - PyErr_Print(); - } - - Py_XDECREF(retobj); - - pyg_gil_state_release(state); -} - -static PyObject * -_wrap_xed_message_bus_connect(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "domain", "name", "func", "data", NULL }; - PyObject *pyfunc, *pyarg = NULL; - const gchar *domain; - const gchar *name; - PyXedCustomNotify *cunote; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "ssO|O:XedMessageBus.connect", - kwlist, &domain, &name, &pyfunc, &pyarg)) - return NULL; - - if (!PyCallable_Check(pyfunc)) { - PyErr_SetString(PyExc_TypeError, "func must be a callable object"); - return NULL; - } - cunote = g_new(PyXedCustomNotify, 1); - Py_INCREF(pyfunc); - cunote->func = pyfunc; - Py_XINCREF(pyarg); - cunote->data = pyarg; - - guint id = xed_message_bus_connect(XED_MESSAGE_BUS(self->obj), - domain, - name, - pyxed_message_bus_connect_cb, - (gpointer)cunote, - pyxed_custom_destroy_notify); - return PyLong_FromUnsignedLong(id); -} -%% -override xed_message_bus_send kwargs -static PyObject * -_wrap_xed_message_bus_send(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - /* create a new message object */ - XedMessage *message; - XedMessageBus *bus = XED_MESSAGE_BUS(self->obj); - message = _helper_wrap_create_message(bus, args, kwargs); - - if (!message) - return NULL; - - xed_message_bus_send_message(bus, message); - g_object_unref (message); - - Py_INCREF(Py_None); - return Py_None; -} -%% -override xed_message_bus_send_sync kwargs -static PyObject * -_wrap_xed_message_bus_send_sync(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - /* create a new message object */ - XedMessage *message; - XedMessageBus *bus = XED_MESSAGE_BUS(self->obj); - - message = _helper_wrap_create_message(bus, args, kwargs); - - if (!message) - return NULL; - - xed_message_bus_send_message_sync(bus, message); - return pygobject_new((GObject *)message); -} -%% -override-slot XedMessage.tp_getattro -static PyObject * -_wrap_xed_message_tp_getattro(PyObject *self, PyObject *attrname) -{ - XedMessage *message = XED_MESSAGE(((PyGObject *)self)->obj); - XedMessageType *type; - - gchar *name = _helper_wrap_get_string (attrname); - gboolean exists; - gboolean intype; - PyObject *ret; - - if (name == NULL) - { - PyErr_SetString(PyExc_TypeError, "attr name somehow not a string"); - return NULL; - } - - g_object_get (message, "type", &type, NULL); - intype = xed_message_type_lookup (type, name) != G_TYPE_INVALID; - xed_message_type_unref (type); - - exists = xed_message_has_key (message, name); - - if (!intype) - { - ret = PyObject_GenericGetAttr(self, attrname); - } - else if (exists) - { - GValue value = { 0, }; - xed_message_get_value (message, name, &value); - ret = pyg_value_as_pyobject(&value, TRUE); - g_value_unset (&value); - } - else - { - Py_INCREF(Py_None); - ret = Py_None; - } - - g_free (name); - return ret; -} -%% -override-slot XedMessage.tp_setattro -static int -_wrap_xed_message_tp_setattro(PyObject *self, PyObject *attrname, PyObject *value) -{ - XedMessage *message = XED_MESSAGE(((PyGObject *)self)->obj); - - if (!_helper_wrap_message_set_value(message, attrname, value)) - { - return PyObject_GenericSetAttr(self, attrname, value); - } - else - { - return 1; - } -} diff --git a/plugin-loaders/python/bindings/xedplugin.override b/plugin-loaders/python/bindings/xedplugin.override deleted file mode 100644 index 05d549a..0000000 --- a/plugin-loaders/python/bindings/xedplugin.override +++ /dev/null @@ -1,193 +0,0 @@ -%% -headers -#include -#include -%% -override xed_plugin_activate kwargs -static PyObject * -_wrap_xed_plugin_activate(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - gpointer klass, klass2; - static char *kwlist[] = { "window", NULL }; - PyGObject *window; - PyObject *cls = (PyObject *)(((PyObject *)self)->ob_type); - - if (!PyArg_ParseTupleAndKeywords (args, - kwargs, - "O!:XedPlugin.activate", - kwlist, - &PyXedWindow_Type, - &window)) - return NULL; - - klass = g_type_class_ref (pyg_type_from_object (cls)); - - if (XED_IS_PLUGIN_PYTHON_CLASS (klass)) - { - klass2 = g_type_class_peek_parent (klass); - g_type_class_unref (klass); - klass = g_type_class_ref (G_TYPE_FROM_CLASS (klass2)); - } - - if (XED_PLUGIN_CLASS (klass)->activate) - XED_PLUGIN_CLASS (klass)->activate (XED_PLUGIN (self->obj), - XED_WINDOW (window->obj)); - else { - PyErr_SetString (PyExc_NotImplementedError, - "virtual method XedPlugin.activate not implemented"); - g_type_class_unref (klass); - return NULL; - } - - g_type_class_unref (klass); - Py_INCREF(Py_None); - return Py_None; -} - -%% -override xed_plugin_deactivate kwargs -static PyObject * -_wrap_xed_plugin_deactivate(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - gpointer klass, klass2; - static char *kwlist[] = {"window", NULL}; - PyGObject *window; - PyObject *cls = (PyObject *)(((PyObject *)self)->ob_type); - - if (!PyArg_ParseTupleAndKeywords (args, - kwargs, - "O!:XedPlugin.deactivate", - kwlist, - &PyXedWindow_Type, - &window)) - return NULL; - - klass = g_type_class_ref (pyg_type_from_object (cls)); - - if (XED_IS_PLUGIN_PYTHON_CLASS (klass)) - { - klass2 = g_type_class_peek_parent (klass); - g_type_class_unref (klass); - klass = g_type_class_ref (G_TYPE_FROM_CLASS (klass2)); - } - - if (XED_PLUGIN_CLASS (klass)->deactivate) - XED_PLUGIN_CLASS (klass)->deactivate (XED_PLUGIN (self->obj), - XED_WINDOW (window->obj)); - else { - PyErr_SetString (PyExc_NotImplementedError, - "virtual method XedPlugin.deactivate not implemented"); - g_type_class_unref (klass); - return NULL; - } - - g_type_class_unref (klass); - Py_INCREF(Py_None); - return Py_None; -} - -%% -override xed_plugin_update_ui kwargs -static PyObject * -_wrap_xed_plugin_update_ui (PyGObject *self, PyObject *args, PyObject *kwargs) -{ - gpointer klass, klass2; - static char *kwlist[] = {"window", NULL}; - PyGObject *window; - PyObject *cls = (PyObject *)(((PyObject *)self)->ob_type); - - if (!PyArg_ParseTupleAndKeywords (args, - kwargs, - "O!:XedPlugin.update_ui", - kwlist, - &PyXedWindow_Type, - &window)) - return NULL; - - klass = g_type_class_ref (pyg_type_from_object (cls)); - - if (XED_IS_PLUGIN_PYTHON_CLASS (klass)) - { - klass2 = g_type_class_peek_parent (klass); - g_type_class_unref (klass); - klass = g_type_class_ref (G_TYPE_FROM_CLASS (klass2)); - } - - if (XED_PLUGIN_CLASS (klass)->update_ui) - XED_PLUGIN_CLASS (klass)->update_ui (XED_PLUGIN (self->obj), - XED_WINDOW (window->obj)); - else { - PyErr_SetString (PyExc_NotImplementedError, - "virtual method XedPlugin.update_ui not implemented"); - g_type_class_unref (klass); - return NULL; - } - - g_type_class_unref (klass); - Py_INCREF(Py_None); - return Py_None; -} - -%% -override xed_plugin_is_configurable -static PyObject * -_wrap_xed_plugin_is_configurable (PyGObject *self) -{ - int ret; - gpointer klass, klass2; - PyObject *cls = (PyObject *)(((PyObject *)self)->ob_type); - - klass = g_type_class_ref (pyg_type_from_object (cls)); - - if (XED_IS_PLUGIN_PYTHON_CLASS (klass)) - { - klass2 = g_type_class_peek_parent (klass); - g_type_class_unref (klass); - klass = g_type_class_ref (G_TYPE_FROM_CLASS (klass2)); - } - - if (XED_PLUGIN_CLASS (klass)->is_configurable) - ret = XED_PLUGIN_CLASS (klass)->is_configurable (XED_PLUGIN (self->obj)); - else { - PyErr_SetString (PyExc_NotImplementedError, - "virtual method XedPlugin.is_configurable not implemented"); - g_type_class_unref (klass); - return NULL; - } - - g_type_class_unref (klass); - return PyBool_FromLong (ret); -} - -%% -override xed_plugin_configure_dialog -static PyObject * -_wrap_xed_plugin_create_configure_dialog (PyGObject *self) -{ - GtkWidget *ret; - gpointer klass, klass2; - PyObject *cls = (PyObject *)(((PyObject *)self)->ob_type); - - klass = g_type_class_ref(pyg_type_from_object (cls)); - - if (XED_IS_PLUGIN_PYTHON_CLASS (klass)) - { - klass2 = g_type_class_peek_parent (klass); - g_type_class_unref (klass); - klass = g_type_class_ref (G_TYPE_FROM_CLASS (klass2)); - } - - if (XED_PLUGIN_CLASS (klass)->create_configure_dialog) - ret = XED_PLUGIN_CLASS (klass)->create_configure_dialog (XED_PLUGIN (self->obj)); - else { - PyErr_SetString (PyExc_NotImplementedError, - "virtual method XedPlugin.create_configure_dialog not implemented"); - g_type_class_unref (klass); - return NULL; - } - - g_type_class_unref (klass); - - /* pygobject_new handles NULL checking */ - return pygobject_new ((GObject *)ret); -} diff --git a/plugin-loaders/python/bindings/xedutils.defs b/plugin-loaders/python/bindings/xedutils.defs deleted file mode 100644 index ecb38db..0000000 --- a/plugin-loaders/python/bindings/xedutils.defs +++ /dev/null @@ -1,67 +0,0 @@ -;; -*- scheme -*- - -;; From ../../xed/xed-utils.h - -(define-function uri_has_writable_scheme - (c-name "xed_utils_uri_has_writable_scheme") - (return-type "gboolean") - (parameters - '("const-gchar*" "uri") - ) -) - -(define-function uri_has_file_scheme - (c-name "xed_utils_uri_has_file_scheme") - (return-type "gboolean") - (parameters - '("const-gchar*" "uri") - ) -) - -(define-function uri_exists - (c-name "xed_utils_uri_exists") - (return-type "gboolean") - (parameters - '("const-gchar*" "text_uri") - ) -) - -(define-function uri_is_valid - (c-name "xed_utils_is_valid_uri") - (return-type "gboolean") - (parameters - '("const-gchar*" "uri") - ) -) - -(define-function uri_get_dirname - (c-name "xed_utils_uri_get_dirname") - (return-type "gchar*") - (parameters - '("const-char*" "uri") - ) -) - -(define-function menu_position_under_widget - (c-name "xed_utils_menu_position_under_widget") - (return-type "none") - (parameters - '("GtkMenu*" "menu") - '("gint*" "x") - '("gint*" "y") - '("gboolean*" "push_in") - '("gpointer" "user_data") - ) -) - -(define-function menu_position_under_tree_view - (c-name "xed_utils_menu_position_under_tree_view") - (return-type "none") - (parameters - '("GtkMenu*" "menu") - '("gint*" "x") - '("gint*" "y") - '("gboolean*" "push_in") - '("gpointer" "user_data") - ) -) diff --git a/plugin-loaders/python/bindings/xedutils.override b/plugin-loaders/python/bindings/xedutils.override deleted file mode 100644 index f177494..0000000 --- a/plugin-loaders/python/bindings/xedutils.override +++ /dev/null @@ -1,85 +0,0 @@ -%% -headers -#define NO_IMPORT_PYGOBJECT -#define NO_IMPORT_PYGTK -#include -#include - -#include "xed-utils.h" - -void pyxedutils_register_classes (PyObject *d); -void pyxedutils_add_constants (PyObject *module, const gchar *strip_prefix); - -%% -modulename xed.utils -%% -import gtk.Widget as PyGtkWidget_Type -import gtk.TreeView as PyGtkTreeView_Type -import gtk.Menu as PyGtkMenu_Type -%% -ignore-glob - _* -%% -override xed_utils_menu_position_under_widget kwargs -static PyObject * -_wrap_xed_utils_menu_position_under_widget (PyObject *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "menu", "widget", NULL }; - PyObject *py_menu, *py_widget; - GtkMenu *menu; - GtkWidget *widget; - gint x, y; - gboolean push_in; - PyObject *tuple; - - if (!PyArg_ParseTupleAndKeywords (args, kwargs, - "O!O!", kwlist, - &PyGtkMenu_Type, &py_menu, - &PyGtkWidget_Type, &py_widget)) - return NULL; - - menu = GTK_MENU (pygobject_get (py_menu)); - widget = GTK_WIDGET (pygobject_get (py_widget)); - - xed_utils_menu_position_under_widget (menu, &x, &y, &push_in, widget); - - tuple = PyTuple_New (3); - PyTuple_SetItem (tuple, 0, PyInt_FromLong (x)); - PyTuple_SetItem (tuple, 1, PyInt_FromLong (y)); - PyTuple_SetItem (tuple, 2, PyBool_FromLong (push_in)); - return tuple; -} -%% -override xed_utils_menu_position_under_tree_view kwargs -static PyObject * -_wrap_xed_utils_menu_position_under_tree_view (PyObject *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "menu", "tree_view", NULL }; - PyObject *py_menu, *py_view; - GtkMenu *menu; - GtkTreeView *view; - gint x, y; - gboolean push_in; - PyObject *tuple; - - if (!PyArg_ParseTupleAndKeywords (args, kwargs, - "O!O!", kwlist, - &PyGtkMenu_Type, &py_menu, - &PyGtkTreeView_Type, &py_view)) - return NULL; - - menu = GTK_MENU (pygobject_get (py_menu)); - view = GTK_TREE_VIEW (pygobject_get (py_view)); - - xed_utils_menu_position_under_widget (menu, &x, &y, &push_in, view); - - tuple = PyTuple_New (3); - PyTuple_SetItem (tuple, 0, PyInt_FromLong (x)); - PyTuple_SetItem (tuple, 1, PyInt_FromLong (y)); - PyTuple_SetItem (tuple, 2, PyBool_FromLong (push_in)); - return tuple; -} diff --git a/plugin-loaders/python/xed-plugin-loader-python.c b/plugin-loaders/python/xed-plugin-loader-python.c deleted file mode 100644 index 3b14715..0000000 --- a/plugin-loaders/python/xed-plugin-loader-python.c +++ /dev/null @@ -1,719 +0,0 @@ -/* - * xed-plugin-loader-python.c - * This file is part of xed - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "xed-plugin-loader-python.h" -#include "xed-plugin-python.h" -#include - -#define NO_IMPORT_PYGOBJECT -#define NO_IMPORT_PYGTK - -#include -#include -#include -#include -#include "config.h" - -#if PY_VERSION_HEX < 0x02050000 -typedef int Py_ssize_t; -#define PY_SSIZE_T_MAX INT_MAX -#define PY_SSIZE_T_MIN INT_MIN -#endif - -#define XED_PLUGIN_LOADER_PYTHON_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_PLUGIN_LOADER_PYTHON, XedPluginLoaderPythonPrivate)) - -struct _XedPluginLoaderPythonPrivate -{ - GHashTable *loaded_plugins; - guint idle_gc; - gboolean init_failed; -}; - -typedef struct -{ - PyObject *type; - PyObject *instance; - gchar *path; -} PythonInfo; - -static void xed_plugin_loader_iface_init (gpointer g_iface, gpointer iface_data); - -/* Exported by pyxed module */ -void pyxed_register_classes (PyObject *d); -void pyxed_add_constants (PyObject *module, const gchar *strip_prefix); -extern PyMethodDef pyxed_functions[]; - -/* Exported by pyxedutils module */ -void pyxedutils_register_classes (PyObject *d); -extern PyMethodDef pyxedutils_functions[]; - -/* Exported by pyxedcommands module */ -void pyxedcommands_register_classes (PyObject *d); -extern PyMethodDef pyxedcommands_functions[]; - -/* We retreive this to check for correct class hierarchy */ -static PyTypeObject *PyXedPlugin_Type; - -XED_PLUGIN_LOADER_REGISTER_TYPE (XedPluginLoaderPython, xed_plugin_loader_python, G_TYPE_OBJECT, xed_plugin_loader_iface_init); - - -static PyObject * -find_python_plugin_type (XedPluginInfo *info, - PyObject *pymodule) -{ - PyObject *locals, *key, *value; - Py_ssize_t pos = 0; - - locals = PyModule_GetDict (pymodule); - - while (PyDict_Next (locals, &pos, &key, &value)) - { - if (!PyType_Check(value)) - continue; - - if (PyObject_IsSubclass (value, (PyObject*) PyXedPlugin_Type)) - return value; - } - - g_warning ("No XedPlugin derivative found in Python plugin '%s'", - xed_plugin_info_get_name (info)); - return NULL; -} - -static XedPlugin * -new_plugin_from_info (XedPluginLoaderPython *loader, - XedPluginInfo *info) -{ - PythonInfo *pyinfo; - PyTypeObject *pytype; - PyObject *pyobject; - PyGObject *pygobject; - XedPlugin *instance; - PyObject *emptyarg; - - pyinfo = (PythonInfo *)g_hash_table_lookup (loader->priv->loaded_plugins, info); - - if (pyinfo == NULL) - return NULL; - - pytype = (PyTypeObject *)pyinfo->type; - - if (pytype->tp_new == NULL) - return NULL; - - emptyarg = PyTuple_New(0); - pyobject = pytype->tp_new (pytype, emptyarg, NULL); - Py_DECREF (emptyarg); - - if (pyobject == NULL) - { - g_error ("Could not create instance for %s.", xed_plugin_info_get_name (info)); - return NULL; - } - - pygobject = (PyGObject *)pyobject; - - if (pygobject->obj != NULL) - { - Py_DECREF (pyobject); - g_error ("Could not create instance for %s (GObject already initialized).", xed_plugin_info_get_name (info)); - return NULL; - } - - pygobject_construct (pygobject, - "install-dir", pyinfo->path, - "data-dir-name", xed_plugin_info_get_module_name (info), - NULL); - - if (pygobject->obj == NULL) - { - g_error ("Could not create instance for %s (GObject not constructed).", xed_plugin_info_get_name (info)); - Py_DECREF (pyobject); - - return NULL; - } - - /* now call tp_init manually */ - if (PyType_IsSubtype (pyobject->ob_type, pytype) && - pyobject->ob_type->tp_init != NULL) - { - emptyarg = PyTuple_New(0); - pyobject->ob_type->tp_init (pyobject, emptyarg, NULL); - Py_DECREF (emptyarg); - } - - instance = XED_PLUGIN (pygobject->obj); - pyinfo->instance = (PyObject *)pygobject; - - /* make sure to register the python instance for the XedPluginPython - object to it can wrap the virtual xed plugin funcs back to python */ - _xed_plugin_python_set_instance (XED_PLUGIN_PYTHON (instance), (PyObject *)pygobject); - - /* we return a reference here because the other is owned by python */ - return XED_PLUGIN (g_object_ref (instance)); -} - -static XedPlugin * -add_python_info (XedPluginLoaderPython *loader, - XedPluginInfo *info, - PyObject *module, - const gchar *path, - PyObject *type) -{ - PythonInfo *pyinfo; - - pyinfo = g_new (PythonInfo, 1); - pyinfo->path = g_strdup (path); - pyinfo->type = type; - - Py_INCREF (pyinfo->type); - - g_hash_table_insert (loader->priv->loaded_plugins, info, pyinfo); - - return new_plugin_from_info (loader, info); -} - -static const gchar * -xed_plugin_loader_iface_get_id (void) -{ - return "Python"; -} - -static XedPlugin * -xed_plugin_loader_iface_load (XedPluginLoader *loader, - XedPluginInfo *info, - const gchar *path) -{ - XedPluginLoaderPython *pyloader = XED_PLUGIN_LOADER_PYTHON (loader); - PyObject *main_module, *main_locals, *pytype; - PyObject *pymodule, *fromlist; - gchar *module_name; - XedPlugin *result; - - if (pyloader->priv->init_failed) - { - g_warning ("Cannot load python plugin Python '%s' since xed was" - "not able to initialize the Python interpreter.", - xed_plugin_info_get_name (info)); - return NULL; - } - - /* see if py definition for the plugin is already loaded */ - result = new_plugin_from_info (pyloader, info); - - if (result != NULL) - return result; - - main_module = PyImport_AddModule ("xed.plugins"); - if (main_module == NULL) - { - g_warning ("Could not get xed.plugins."); - return NULL; - } - - /* If we have a special path, we register it */ - if (path != NULL) - { - PyObject *sys_path = PySys_GetObject ("path"); - PyObject *pypath = PyString_FromString (path); - - if (PySequence_Contains (sys_path, pypath) == 0) - PyList_Insert (sys_path, 0, pypath); - - Py_DECREF (pypath); - } - - main_locals = PyModule_GetDict (main_module); - - /* we need a fromlist to be able to import modules with a '.' in the - name. */ - fromlist = PyTuple_New(0); - module_name = g_strdup (xed_plugin_info_get_module_name (info)); - - pymodule = PyImport_ImportModuleEx (module_name, - main_locals, - main_locals, - fromlist); - - Py_DECREF(fromlist); - - if (!pymodule) - { - g_free (module_name); - PyErr_Print (); - return NULL; - } - - PyDict_SetItemString (main_locals, module_name, pymodule); - g_free (module_name); - - pytype = find_python_plugin_type (info, pymodule); - - if (pytype) - return add_python_info (pyloader, info, pymodule, path, pytype); - - return NULL; -} - -static void -xed_plugin_loader_iface_unload (XedPluginLoader *loader, - XedPluginInfo *info) -{ - XedPluginLoaderPython *pyloader = XED_PLUGIN_LOADER_PYTHON (loader); - PythonInfo *pyinfo; - PyGILState_STATE state; - - pyinfo = (PythonInfo *)g_hash_table_lookup (pyloader->priv->loaded_plugins, info); - - if (!pyinfo) - return; - - state = pyg_gil_state_ensure (); - Py_XDECREF (pyinfo->instance); - pyg_gil_state_release (state); - - pyinfo->instance = NULL; -} - -static gboolean -run_gc (XedPluginLoaderPython *loader) -{ - while (PyGC_Collect ()) - ; - - loader->priv->idle_gc = 0; - return FALSE; -} - -static void -xed_plugin_loader_iface_garbage_collect (XedPluginLoader *loader) -{ - XedPluginLoaderPython *pyloader; - - if (!Py_IsInitialized()) - return; - - pyloader = XED_PLUGIN_LOADER_PYTHON (loader); - - /* - * We both run the GC right now and we schedule - * a further collection in the main loop. - */ - - while (PyGC_Collect ()) - ; - - if (pyloader->priv->idle_gc == 0) - pyloader->priv->idle_gc = g_idle_add ((GSourceFunc)run_gc, pyloader); -} - -static void -xed_plugin_loader_iface_init (gpointer g_iface, - gpointer iface_data) -{ - XedPluginLoaderInterface *iface = (XedPluginLoaderInterface *)g_iface; - - iface->get_id = xed_plugin_loader_iface_get_id; - iface->load = xed_plugin_loader_iface_load; - iface->unload = xed_plugin_loader_iface_unload; - iface->garbage_collect = xed_plugin_loader_iface_garbage_collect; -} - -static void -xed_python_shutdown (XedPluginLoaderPython *loader) -{ - if (!Py_IsInitialized ()) - return; - - if (loader->priv->idle_gc != 0) - { - g_source_remove (loader->priv->idle_gc); - loader->priv->idle_gc = 0; - } - - while (PyGC_Collect ()) - ; - - Py_Finalize (); -} - - -/* C equivalent of - * import pygtk - * pygtk.require ("2.0") - */ -static gboolean -xed_check_pygtk2 (void) -{ - PyObject *pygtk, *mdict, *require; - - /* pygtk.require("2.0") */ - pygtk = PyImport_ImportModule ("pygtk"); - if (pygtk == NULL) - { - g_warning ("Error initializing Python interpreter: could not import pygtk."); - return FALSE; - } - - mdict = PyModule_GetDict (pygtk); - require = PyDict_GetItemString (mdict, "require"); - PyObject_CallObject (require, - Py_BuildValue ("(S)", PyString_FromString ("2.0"))); - if (PyErr_Occurred()) - { - g_warning ("Error initializing Python interpreter: pygtk 2 is required."); - return FALSE; - } - - return TRUE; -} - -/* Note: the following two functions are needed because - * init_pyobject and init_pygtk which are *macros* which in case - * case of error set the PyErr and then make the calling - * function return behind our back. - * It's up to the caller to check the result with PyErr_Occurred() - */ -static void -xed_init_pygobject (void) -{ - init_pygobject_check (2, 11, 5); /* FIXME: get from config */ -} - -static void -xed_init_pygtk (void) -{ - PyObject *gtk, *mdict, *version, *required_version; - - init_pygtk (); - - /* there isn't init_pygtk_check(), do the version - * check ourselves */ - gtk = PyImport_ImportModule("gtk"); - mdict = PyModule_GetDict(gtk); - version = PyDict_GetItemString (mdict, "pygtk_version"); - if (!version) - { - PyErr_SetString (PyExc_ImportError, - "PyGObject version too old"); - return; - } - - required_version = Py_BuildValue ("(iii)", 2, 4, 0); /* FIXME */ - - if (PyObject_Compare (version, required_version) == -1) - { - PyErr_SetString (PyExc_ImportError, - "PyGObject version too old"); - Py_DECREF (required_version); - return; - } - - Py_DECREF (required_version); -} - -static void -old_gtksourceview_init (void) -{ - PyErr_SetString(PyExc_ImportError, - "gtksourceview module not allowed, use gtksourceview2"); -} - -static void -xed_init_pygtksourceview (void) -{ - PyObject *gtksourceview, *mdict, *version, *required_version; - - gtksourceview = PyImport_ImportModule("gtksourceview2"); - if (gtksourceview == NULL) - { - PyErr_SetString (PyExc_ImportError, - "could not import gtksourceview"); - return; - } - - mdict = PyModule_GetDict (gtksourceview); - version = PyDict_GetItemString (mdict, "pygtksourceview2_version"); - if (!version) - { - PyErr_SetString (PyExc_ImportError, - "PyGtkSourceView version too old"); - return; - } - - required_version = Py_BuildValue ("(iii)", 0, 8, 0); /* FIXME */ - - if (PyObject_Compare (version, required_version) == -1) - { - PyErr_SetString (PyExc_ImportError, - "PyGtkSourceView version too old"); - Py_DECREF (required_version); - return; - } - - Py_DECREF (required_version); - - /* Create a dummy 'gtksourceview' module to prevent - * loading of the old 'gtksourceview' modules that - * has conflicting symbols with the gtksourceview2 module. - * Raise an exception when trying to import it. - */ - PyImport_AppendInittab ("gtksourceview", old_gtksourceview_init); -} - -static gboolean -xed_python_init (XedPluginLoaderPython *loader) -{ - PyObject *mdict, *tuple; - PyObject *xed, *xedutils, *xedcommands, *xedplugins; - PyObject *gettext, *install, *gettext_args; - //char *argv[] = { "xed", NULL }; - char *argv[] = { XED_PLUGINS_LIBS_DIR, NULL }; -#ifdef HAVE_SIGACTION - gint res; - struct sigaction old_sigint; -#endif - - if (loader->priv->init_failed) - { - /* We already failed to initialized Python, don't need to - * retry again */ - return FALSE; - } - - if (Py_IsInitialized ()) - { - /* Python has already been successfully initialized */ - return TRUE; - } - - /* We are trying to initialize Python for the first time, - set init_failed to FALSE only if the entire initialization process - ends with success */ - loader->priv->init_failed = TRUE; - - /* Hack to make python not overwrite SIGINT: this is needed to avoid - * the crash reported on bug #326191 */ - - /* CHECK: can't we use Py_InitializeEx instead of Py_Initialize in order - to avoid to manage signal handlers ? - Paolo (Dec. 31, 2006) */ - -#ifdef HAVE_SIGACTION - /* Save old handler */ - res = sigaction (SIGINT, NULL, &old_sigint); - if (res != 0) - { - g_warning ("Error initializing Python interpreter: cannot get " - "handler to SIGINT signal (%s)", - g_strerror (errno)); - - return FALSE; - } -#endif - - /* Python initialization */ - Py_Initialize (); - -#ifdef HAVE_SIGACTION - /* Restore old handler */ - res = sigaction (SIGINT, &old_sigint, NULL); - if (res != 0) - { - g_warning ("Error initializing Python interpreter: cannot restore " - "handler to SIGINT signal (%s).", - g_strerror (errno)); - - goto python_init_error; - } -#endif - - PySys_SetArgv (1, argv); - - if (!xed_check_pygtk2 ()) - { - /* Warning message already printed in check_pygtk2 */ - goto python_init_error; - } - - /* import gobject */ - xed_init_pygobject (); - if (PyErr_Occurred ()) - { - g_warning ("Error initializing Python interpreter: could not import pygobject."); - - goto python_init_error; - } - - /* import gtk */ - xed_init_pygtk (); - if (PyErr_Occurred ()) - { - g_warning ("Error initializing Python interpreter: could not import pygtk."); - - goto python_init_error; - } - - /* import gtksourceview */ - xed_init_pygtksourceview (); - if (PyErr_Occurred ()) - { - PyErr_Print (); - - g_warning ("Error initializing Python interpreter: could not import pygtksourceview."); - - goto python_init_error; - } - - /* import xed */ - xed = Py_InitModule ("xed", pyxed_functions); - mdict = PyModule_GetDict (xed); - - pyxed_register_classes (mdict); - pyxed_add_constants (xed, "XED_"); - - /* xed version */ - tuple = Py_BuildValue("(iii)", - XED_MAJOR_VERSION, - XED_MINOR_VERSION, - XED_MICRO_VERSION); - PyDict_SetItemString(mdict, "version", tuple); - Py_DECREF(tuple); - - /* Retrieve the Python type for xed.Plugin */ - PyXedPlugin_Type = (PyTypeObject *) PyDict_GetItemString (mdict, "Plugin"); - if (PyXedPlugin_Type == NULL) - { - PyErr_Print (); - - goto python_init_error; - } - - /* import xed.utils */ - xedutils = Py_InitModule ("xed.utils", pyxedutils_functions); - PyDict_SetItemString (mdict, "utils", xedutils); - - /* import xed.commands */ - xedcommands = Py_InitModule ("xed.commands", pyxedcommands_functions); - PyDict_SetItemString (mdict, "commands", xedcommands); - - /* initialize empty xed.plugins module */ - xedplugins = Py_InitModule ("xed.plugins", NULL); - PyDict_SetItemString (mdict, "plugins", xedplugins); - - mdict = PyModule_GetDict (xedutils); - pyxedutils_register_classes (mdict); - - mdict = PyModule_GetDict (xedcommands); - pyxedcommands_register_classes (mdict); - - /* i18n support */ - gettext = PyImport_ImportModule ("gettext"); - if (gettext == NULL) - { - g_warning ("Error initializing Python interpreter: could not import gettext."); - - goto python_init_error; - } - - mdict = PyModule_GetDict (gettext); - install = PyDict_GetItemString (mdict, "install"); - gettext_args = Py_BuildValue ("ss", GETTEXT_PACKAGE, XED_LOCALEDIR); - PyObject_CallObject (install, gettext_args); - Py_DECREF (gettext_args); - - /* Python has been successfully initialized */ - loader->priv->init_failed = FALSE; - - return TRUE; - -python_init_error: - - g_warning ("Please check the installation of all the Python related packages required " - "by xed and try again."); - - PyErr_Clear (); - - xed_python_shutdown (loader); - - return FALSE; -} - -static void -xed_plugin_loader_python_finalize (GObject *object) -{ - XedPluginLoaderPython *pyloader = XED_PLUGIN_LOADER_PYTHON (object); - - g_hash_table_destroy (pyloader->priv->loaded_plugins); - xed_python_shutdown (pyloader); - - G_OBJECT_CLASS (xed_plugin_loader_python_parent_class)->finalize (object); -} - -static void -xed_plugin_loader_python_class_init (XedPluginLoaderPythonClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_plugin_loader_python_finalize; - - g_type_class_add_private (object_class, sizeof (XedPluginLoaderPythonPrivate)); -} - -static void -xed_plugin_loader_python_class_finalize (XedPluginLoaderPythonClass *klass) -{ -} - -static void -destroy_python_info (PythonInfo *info) -{ - PyGILState_STATE state = pyg_gil_state_ensure (); - Py_XDECREF (info->type); - pyg_gil_state_release (state); - - g_free (info->path); - g_free (info); -} - -static void -xed_plugin_loader_python_init (XedPluginLoaderPython *self) -{ - self->priv = XED_PLUGIN_LOADER_PYTHON_GET_PRIVATE (self); - - /* initialize python interpreter */ - xed_python_init (self); - - /* loaded_plugins maps XedPluginInfo to a PythonInfo */ - self->priv->loaded_plugins = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)destroy_python_info); -} - -XedPluginLoaderPython * -xed_plugin_loader_python_new () -{ - GObject *loader = g_object_new (XED_TYPE_PLUGIN_LOADER_PYTHON, NULL); - - return XED_PLUGIN_LOADER_PYTHON (loader); -} - diff --git a/plugin-loaders/python/xed-plugin-loader-python.h b/plugin-loaders/python/xed-plugin-loader-python.h deleted file mode 100644 index b6c3afe..0000000 --- a/plugin-loaders/python/xed-plugin-loader-python.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * xed-plugin-loader-python.h - * This file is part of xed - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XED_PLUGIN_LOADER_PYTHON_H__ -#define __XED_PLUGIN_LOADER_PYTHON_H__ - -#include - -G_BEGIN_DECLS - -#define XED_TYPE_PLUGIN_LOADER_PYTHON (xed_plugin_loader_python_get_type ()) -#define XED_PLUGIN_LOADER_PYTHON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_PLUGIN_LOADER_PYTHON, XedPluginLoaderPython)) -#define XED_PLUGIN_LOADER_PYTHON_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_PLUGIN_LOADER_PYTHON, XedPluginLoaderPython const)) -#define XED_PLUGIN_LOADER_PYTHON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_PLUGIN_LOADER_PYTHON, XedPluginLoaderPythonClass)) -#define XED_IS_PLUGIN_LOADER_PYTHON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_PLUGIN_LOADER_PYTHON)) -#define XED_IS_PLUGIN_LOADER_PYTHON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PLUGIN_LOADER_PYTHON)) -#define XED_PLUGIN_LOADER_PYTHON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_PLUGIN_LOADER_PYTHON, XedPluginLoaderPythonClass)) - -typedef struct _XedPluginLoaderPython XedPluginLoaderPython; -typedef struct _XedPluginLoaderPythonClass XedPluginLoaderPythonClass; -typedef struct _XedPluginLoaderPythonPrivate XedPluginLoaderPythonPrivate; - -struct _XedPluginLoaderPython { - GObject parent; - - XedPluginLoaderPythonPrivate *priv; -}; - -struct _XedPluginLoaderPythonClass { - GObjectClass parent_class; -}; - -GType xed_plugin_loader_python_get_type (void) G_GNUC_CONST; -XedPluginLoaderPython *xed_plugin_loader_python_new(void); - -/* All the loaders must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin_loader (GTypeModule * module); - -G_END_DECLS - -#endif /* __XED_PLUGIN_LOADER_PYTHON_H__ */ - diff --git a/plugin-loaders/python/xed-plugin-python.c b/plugin-loaders/python/xed-plugin-python.c deleted file mode 100644 index 2700d83..0000000 --- a/plugin-loaders/python/xed-plugin-python.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * xed-plugin-python.c - * This file is part of xed - * - * Copyright (C) 2005 Raphael Slinckx - * Copyright (C) 2008 Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include - -#include "xed-plugin-python.h" - -#include -#include -#include -#include - -#define XED_PLUGIN_PYTHON_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_PLUGIN_PYTHON, XedPluginPythonPrivate)) - -static GObjectClass *parent_class; - -struct _XedPluginPythonPrivate -{ - PyObject *instance; -}; - -static void xed_plugin_python_class_init (XedPluginPythonClass *klass); -static void xed_plugin_python_init (XedPluginPython *plugin); - -G_DEFINE_TYPE (XedPluginPython, xed_plugin_python, XED_TYPE_PLUGIN) - -static PyObject * -call_python_method (XedPluginPythonPrivate *priv, - XedWindow *window, - gchar *method) -{ - PyObject *py_ret = NULL; - - g_return_val_if_fail (PyObject_HasAttrString (priv->instance, method), NULL); - - if (window == NULL) - { - py_ret = PyObject_CallMethod (priv->instance, - method, - NULL); - } - else - { - py_ret = PyObject_CallMethod (priv->instance, - method, - "(N)", - pygobject_new (G_OBJECT (window))); - } - - if (!py_ret) - PyErr_Print (); - - return py_ret; -} - -static gboolean -check_py_object_is_gtk_widget (PyObject *py_obj) -{ - static PyTypeObject *_PyGtkWidget_Type = NULL; - - if (_PyGtkWidget_Type == NULL) - { - PyObject *module; - - if ((module = PyImport_ImportModule ("gtk"))) - { - PyObject *moddict = PyModule_GetDict (module); - _PyGtkWidget_Type = (PyTypeObject *) PyDict_GetItemString (moddict, "Widget"); - } - - if (_PyGtkWidget_Type == NULL) - { - PyErr_SetString(PyExc_TypeError, "could not find Python gtk widget type"); - PyErr_Print(); - - return FALSE; - } - } - - return PyObject_TypeCheck (py_obj, _PyGtkWidget_Type) ? TRUE : FALSE; -} - -static void -impl_update_ui (XedPlugin *plugin, - XedWindow *window) -{ - PyGILState_STATE state = pyg_gil_state_ensure (); - XedPluginPythonPrivate *priv = XED_PLUGIN_PYTHON(plugin)->priv; - - if (PyObject_HasAttrString (priv->instance, "update_ui")) - { - PyObject *py_ret = call_python_method (priv, window, "update_ui"); - - if (py_ret) - { - Py_XDECREF (py_ret); - } - } - else - XED_PLUGIN_CLASS (parent_class)->update_ui (plugin, window); - - pyg_gil_state_release (state); -} - -static void -impl_deactivate (XedPlugin *plugin, - XedWindow *window) -{ - PyGILState_STATE state = pyg_gil_state_ensure (); - XedPluginPythonPrivate *priv = XED_PLUGIN_PYTHON(plugin)->priv; - - if (PyObject_HasAttrString (priv->instance, "deactivate")) - { - PyObject *py_ret = call_python_method (priv, window, "deactivate"); - - if (py_ret) - { - Py_XDECREF (py_ret); - } - } - else - XED_PLUGIN_CLASS (parent_class)->deactivate (plugin, window); - - pyg_gil_state_release (state); -} - -static void -impl_activate (XedPlugin *plugin, - XedWindow *window) -{ - PyGILState_STATE state = pyg_gil_state_ensure (); - XedPluginPythonPrivate *priv = XED_PLUGIN_PYTHON(plugin)->priv; - - if (PyObject_HasAttrString (priv->instance, "activate")) - { - PyObject *py_ret = call_python_method (priv, window, "activate"); - - if (py_ret) - { - Py_XDECREF (py_ret); - } - } - else - XED_PLUGIN_CLASS (parent_class)->activate (plugin, window); - - pyg_gil_state_release (state); -} - -static GtkWidget * -impl_create_configure_dialog (XedPlugin *plugin) -{ - PyGILState_STATE state = pyg_gil_state_ensure (); - XedPluginPythonPrivate *priv = XED_PLUGIN_PYTHON(plugin)->priv; - GtkWidget *ret = NULL; - - if (PyObject_HasAttrString (priv->instance, "create_configure_dialog")) - { - PyObject *py_ret = call_python_method (priv, NULL, "create_configure_dialog"); - - if (py_ret) - { - if (check_py_object_is_gtk_widget (py_ret)) - { - ret = GTK_WIDGET (pygobject_get (py_ret)); - g_object_ref (ret); - } - else - { - PyErr_SetString(PyExc_TypeError, "return value for create_configure_dialog is not a GtkWidget"); - PyErr_Print(); - } - - Py_DECREF (py_ret); - } - } - else - ret = XED_PLUGIN_CLASS (parent_class)->create_configure_dialog (plugin); - - pyg_gil_state_release (state); - - return ret; -} - -static gboolean -impl_is_configurable (XedPlugin *plugin) -{ - PyGILState_STATE state = pyg_gil_state_ensure (); - XedPluginPythonPrivate *priv = XED_PLUGIN_PYTHON(plugin)->priv; - PyObject *dict = priv->instance->ob_type->tp_dict; - gboolean result; - - if (dict == NULL) - result = FALSE; - else if (!PyDict_Check(dict)) - result = FALSE; - else - result = PyDict_GetItemString(dict, "create_configure_dialog") != NULL; - - pyg_gil_state_release (state); - - return result; -} - -void -_xed_plugin_python_set_instance (XedPluginPython *plugin, - PyObject *instance) -{ - PyGILState_STATE state = pyg_gil_state_ensure (); - - /* we don't increment the instance here because we are the instance, - when it dies, we also die */ - plugin->priv->instance = instance; - pyg_gil_state_release (state); -} - -PyObject * -_xed_plugin_python_get_instance (XedPluginPython *plugin) -{ - return plugin->priv->instance; -} - -static void -xed_plugin_python_init (XedPluginPython *plugin) -{ - plugin->priv = XED_PLUGIN_PYTHON_GET_PRIVATE(plugin); - - xed_debug_message (DEBUG_PLUGINS, "Creating Python plugin instance"); - plugin->priv->instance = 0; -} - -static void -xed_plugin_python_finalize (GObject *object) -{ - PyGILState_STATE state; - - xed_debug_message (DEBUG_PLUGINS, "Finalizing Python plugin instance"); - - state = pyg_gil_state_ensure (); - Py_XDECREF (XED_PLUGIN_PYTHON(object)->priv->instance); - pyg_gil_state_release (state); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -xed_plugin_python_class_init (XedPluginPythonClass *klass) -{ - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - g_type_class_add_private (klass, sizeof (XedPluginPythonPrivate)); - G_OBJECT_CLASS (klass)->finalize = xed_plugin_python_finalize; - - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - plugin_class->update_ui = impl_update_ui; - plugin_class->create_configure_dialog = impl_create_configure_dialog; - plugin_class->is_configurable = impl_is_configurable; -} - diff --git a/plugin-loaders/python/xed-plugin-python.h b/plugin-loaders/python/xed-plugin-python.h deleted file mode 100644 index 96a9eec..0000000 --- a/plugin-loaders/python/xed-plugin-python.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * xed-plugin-python.h - * This file is part of xed - * - * Copyright (C) 2005 - Raphael Slinckx - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XED_PLUGIN_PYTHON_H__ -#define __XED_PLUGIN_PYTHON_H__ - -#define NO_IMPORT_PYGOBJECT - -#include -#include - -#include - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_PLUGIN_PYTHON (xed_plugin_python_get_type()) -#define XED_PLUGIN_PYTHON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PLUGIN_PYTHON, XedPluginPython)) -#define XED_PLUGIN_PYTHON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_PLUGIN_PYTHON, XedPluginPythonClass)) -#define XED_IS_PLUGIN_PYTHON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_PLUGIN_PYTHON)) -#define XED_IS_PLUGIN_PYTHON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PLUGIN_PYTHON)) -#define XED_PLUGIN_PYTHON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PLUGIN_PYTHON, XedPluginPythonClass)) - -/* Private structure type */ -typedef struct _XedPluginPythonPrivate XedPluginPythonPrivate; - -/* - * Main object structure - */ -typedef struct _XedPluginPython XedPluginPython; - -struct _XedPluginPython -{ - XedPlugin parent; - - /*< private > */ - XedPluginPythonPrivate *priv; -}; - -/* - * Class definition - */ -typedef struct _XedPluginPythonClass XedPluginPythonClass; - -struct _XedPluginPythonClass -{ - XedPluginClass parent_class; -}; - -/* - * Public methods - */ -GType xed_plugin_python_get_type (void) G_GNUC_CONST; - - -/* - * Private methods - */ -void _xed_plugin_python_set_instance (XedPluginPython *plugin, - PyObject *instance); -PyObject *_xed_plugin_python_get_instance (XedPluginPython *plugin); - -G_END_DECLS - -#endif /* __XED_PLUGIN_PYTHON_H__ */ - diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 391a2a5..a162a09 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1,26 +1,25 @@ -DIST_SUBDIRS = \ - changecase \ - docinfo \ - filebrowser \ - modelines \ - sort \ - spell \ - taglist \ - time \ +DIST_SUBDIRS = \ + docinfo \ + filebrowser \ + modelines \ + sort \ + spell \ + taglist \ + time \ trailsave -SUBDIRS = \ - changecase \ - docinfo \ - filebrowser \ - modelines \ - sort \ - taglist \ - time \ +SUBDIRS = \ + docinfo \ + filebrowser \ + modelines \ + sort \ + spell \ + taglist \ + time \ trailsave if ENABLE_ENCHANT -SUBDIRS += spell +SUBDIRS += spell endif -include $(top_srcdir)/git.mk diff --git a/plugins/changecase/Makefile.am b/plugins/changecase/Makefile.am deleted file mode 100644 index d4ad1a0..0000000 --- a/plugins/changecase/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# changecase plugin -plugindir = $(XED_PLUGINS_LIBS_DIR) - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(XED_CFLAGS) \ - $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) - -plugin_LTLIBRARIES = libchangecase.la - -libchangecase_la_SOURCES = \ - xed-changecase-plugin.h \ - xed-changecase-plugin.c - -libchangecase_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) -libchangecase_la_LIBADD = $(XED_LIBS) - -uidir = $(XED_PLUGINS_DATA_DIR)/changecase -ui_DATA = - -plugin_in_files = changecase.xed-plugin.desktop.in - -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache - -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) - -EXTRA_DIST = $(ui_DATA) $(plugin_in_files) - -CLEANFILES = $(plugin_DATA) -DISTCLEANFILES = $(plugin_DATA) - - --include $(top_srcdir)/git.mk diff --git a/plugins/changecase/changecase.xed-plugin.desktop.in b/plugins/changecase/changecase.xed-plugin.desktop.in deleted file mode 100644 index 079ec7d..0000000 --- a/plugins/changecase/changecase.xed-plugin.desktop.in +++ /dev/null @@ -1,8 +0,0 @@ -[Xed Plugin] -Module=changecase -IAge=2 -_Name=Change Case -_Description=Changes the case of selected text. -Authors=Paolo Borelli -Copyright=Copyright © 2004-2005 Paolo Borelli -Website=http://www.mate-desktop.org diff --git a/plugins/changecase/xed-changecase-plugin.c b/plugins/changecase/xed-changecase-plugin.c deleted file mode 100644 index cf6da80..0000000 --- a/plugins/changecase/xed-changecase-plugin.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * xed-changecase-plugin.c - * - * Copyright (C) 2004-2005 - Paolo Borelli - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "xed-changecase-plugin.h" - -#include -#include - -#include - -#define WINDOW_DATA_KEY "XedChangecasePluginWindowData" - -XED_PLUGIN_REGISTER_TYPE(XedChangecasePlugin, xed_changecase_plugin) - -typedef enum { - TO_UPPER_CASE, - TO_LOWER_CASE, - INVERT_CASE, - TO_TITLE_CASE, -} ChangeCaseChoice; - -static void -do_upper_case (GtkTextBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end) -{ - GString *s = g_string_new (NULL); - - while (!gtk_text_iter_is_end (start) && - !gtk_text_iter_equal (start, end)) - { - gunichar c, nc; - - c = gtk_text_iter_get_char (start); - nc = g_unichar_toupper (c); - g_string_append_unichar (s, nc); - - gtk_text_iter_forward_char (start); - } - - gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); - gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len); - - g_string_free (s, TRUE); -} - -static void -do_lower_case (GtkTextBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end) -{ - GString *s = g_string_new (NULL); - - while (!gtk_text_iter_is_end (start) && - !gtk_text_iter_equal (start, end)) - { - gunichar c, nc; - - c = gtk_text_iter_get_char (start); - nc = g_unichar_tolower (c); - g_string_append_unichar (s, nc); - - gtk_text_iter_forward_char (start); - } - - gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); - gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len); - - g_string_free (s, TRUE); -} - -static void -do_invert_case (GtkTextBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end) -{ - GString *s = g_string_new (NULL); - - while (!gtk_text_iter_is_end (start) && - !gtk_text_iter_equal (start, end)) - { - gunichar c, nc; - - c = gtk_text_iter_get_char (start); - if (g_unichar_islower (c)) - nc = g_unichar_toupper (c); - else - nc = g_unichar_tolower (c); - g_string_append_unichar (s, nc); - - gtk_text_iter_forward_char (start); - } - - gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); - gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len); - - g_string_free (s, TRUE); -} - -static void -do_title_case (GtkTextBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end) -{ - GString *s = g_string_new (NULL); - - while (!gtk_text_iter_is_end (start) && - !gtk_text_iter_equal (start, end)) - { - gunichar c, nc; - - c = gtk_text_iter_get_char (start); - if (gtk_text_iter_starts_word (start)) - nc = g_unichar_totitle (c); - else - nc = g_unichar_tolower (c); - g_string_append_unichar (s, nc); - - gtk_text_iter_forward_char (start); - } - - gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); - gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len); - - g_string_free (s, TRUE); -} - -static void -change_case (XedWindow *window, - ChangeCaseChoice choice) -{ - XedDocument *doc; - GtkTextIter start, end; - - xed_debug (DEBUG_PLUGINS); - - doc = xed_window_get_active_document (window); - g_return_if_fail (doc != NULL); - - if (!gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), - &start, &end)) - { - return; - } - - gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (doc)); - - switch (choice) - { - case TO_UPPER_CASE: - do_upper_case (GTK_TEXT_BUFFER (doc), &start, &end); - break; - case TO_LOWER_CASE: - do_lower_case (GTK_TEXT_BUFFER (doc), &start, &end); - break; - case INVERT_CASE: - do_invert_case (GTK_TEXT_BUFFER (doc), &start, &end); - break; - case TO_TITLE_CASE: - do_title_case (GTK_TEXT_BUFFER (doc), &start, &end); - break; - default: - g_return_if_reached (); - } - - gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (doc)); -} - -static void -upper_case_cb (GtkAction *action, - XedWindow *window) -{ - change_case (window, TO_UPPER_CASE); -} - -static void -lower_case_cb (GtkAction *action, - XedWindow *window) -{ - change_case (window, TO_LOWER_CASE); -} - -static void -invert_case_cb (GtkAction *action, - XedWindow *window) -{ - change_case (window, INVERT_CASE); -} - -static void -title_case_cb (GtkAction *action, - XedWindow *window) -{ - change_case (window, TO_TITLE_CASE); -} - -static const GtkActionEntry action_entries[] = -{ - { "ChangeCase", NULL, N_("C_hange Case") }, - { "UpperCase", NULL, N_("All _Upper Case"), NULL, - N_("Change selected text to upper case"), - G_CALLBACK (upper_case_cb) }, - { "LowerCase", NULL, N_("All _Lower Case"), NULL, - N_("Change selected text to lower case"), - G_CALLBACK (lower_case_cb) }, - { "InvertCase", NULL, N_("_Invert Case"), NULL, - N_("Invert the case of selected text"), - G_CALLBACK (invert_case_cb) }, - { "TitleCase", NULL, N_("_Title Case"), NULL, - N_("Capitalize the first letter of each selected word"), - G_CALLBACK (title_case_cb) } -}; - -const gchar submenu[] = -"" -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -""; - -static void -xed_changecase_plugin_init (XedChangecasePlugin *plugin) -{ - xed_debug_message (DEBUG_PLUGINS, "XedChangecasePlugin initializing"); -} - -static void -xed_changecase_plugin_finalize (GObject *object) -{ - G_OBJECT_CLASS (xed_changecase_plugin_parent_class)->finalize (object); - - xed_debug_message (DEBUG_PLUGINS, "XedChangecasePlugin finalizing"); -} - -typedef struct -{ - GtkActionGroup *action_group; - guint ui_id; -} WindowData; - -static void -free_window_data (WindowData *data) -{ - g_return_if_fail (data != NULL); - - g_slice_free (WindowData, data); -} - -static void -update_ui_real (XedWindow *window, - WindowData *data) -{ - GtkTextView *view; - GtkAction *action; - gboolean sensitive = FALSE; - - xed_debug (DEBUG_PLUGINS); - - view = GTK_TEXT_VIEW (xed_window_get_active_view (window)); - - if (view != NULL) - { - GtkTextBuffer *buffer; - - buffer = gtk_text_view_get_buffer (view); - sensitive = (gtk_text_view_get_editable (view) && - gtk_text_buffer_get_has_selection (buffer)); - } - - action = gtk_action_group_get_action (data->action_group, - "ChangeCase"); - gtk_action_set_sensitive (action, sensitive); -} - -static void -impl_activate (XedPlugin *plugin, - XedWindow *window) -{ - GtkUIManager *manager; - WindowData *data; - GError *error = NULL; - - xed_debug (DEBUG_PLUGINS); - - data = g_slice_new (WindowData); - - manager = xed_window_get_ui_manager (window); - - data->action_group = gtk_action_group_new ("XedChangecasePluginActions"); - gtk_action_group_set_translation_domain (data->action_group, - GETTEXT_PACKAGE); - gtk_action_group_add_actions (data->action_group, - action_entries, - G_N_ELEMENTS (action_entries), - window); - - gtk_ui_manager_insert_action_group (manager, data->action_group, -1); - - data->ui_id = gtk_ui_manager_add_ui_from_string (manager, - submenu, - -1, - &error); - if (data->ui_id == 0) - { - g_warning ("%s", error->message); - free_window_data (data); - return; - } - - g_object_set_data_full (G_OBJECT (window), - WINDOW_DATA_KEY, - data, - (GDestroyNotify) free_window_data); - - update_ui_real (window, data); -} - -static void -impl_deactivate (XedPlugin *plugin, - XedWindow *window) -{ - GtkUIManager *manager; - WindowData *data; - - xed_debug (DEBUG_PLUGINS); - - manager = xed_window_get_ui_manager (window); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - gtk_ui_manager_remove_ui (manager, data->ui_id); - gtk_ui_manager_remove_action_group (manager, data->action_group); - - g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL); -} - -static void -impl_update_ui (XedPlugin *plugin, - XedWindow *window) -{ - WindowData *data; - - xed_debug (DEBUG_PLUGINS); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - update_ui_real (window, data); -} - -static void -xed_changecase_plugin_class_init (XedChangecasePluginClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); - - object_class->finalize = xed_changecase_plugin_finalize; - - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - plugin_class->update_ui = impl_update_ui; -} diff --git a/plugins/changecase/xed-changecase-plugin.h b/plugins/changecase/xed-changecase-plugin.h deleted file mode 100644 index 7363247..0000000 --- a/plugins/changecase/xed-changecase-plugin.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * xed-changecase-plugin.h - * - * Copyright (C) 2004-2005 - Paolo Borelli - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $Id$ - */ - -#ifndef __XED_CHANGECASE_PLUGIN_H__ -#define __XED_CHANGECASE_PLUGIN_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_CHANGECASE_PLUGIN (xed_changecase_plugin_get_type ()) -#define XED_CHANGECASE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_CHANGECASE_PLUGIN, XedChangecasePlugin)) -#define XED_CHANGECASE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_CHANGECASE_PLUGIN, XedChangecasePluginClass)) -#define XED_IS_CHANGECASE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_CHANGECASE_PLUGIN)) -#define XED_IS_CHANGECASE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_CHANGECASE_PLUGIN)) -#define XED_CHANGECASE_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_CHANGECASE_PLUGIN, XedChangecasePluginClass)) - -/* - * Main object structure - */ -typedef struct _XedChangecasePlugin XedChangecasePlugin; - -struct _XedChangecasePlugin -{ - XedPlugin parent_instance; -}; - -/* - * Class definition - */ -typedef struct _XedChangecasePluginClass XedChangecasePluginClass; - -struct _XedChangecasePluginClass -{ - XedPluginClass parent_class; -}; - -/* - * Public methods - */ -GType xed_changecase_plugin_get_type (void) G_GNUC_CONST; - -/* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule *module); - -G_END_DECLS - -#endif /* __XED_CHANGECASE_PLUGIN_H__ */ diff --git a/plugins/docinfo/Makefile.am b/plugins/docinfo/Makefile.am index 1fa6fbb..015cece 100644 --- a/plugins/docinfo/Makefile.am +++ b/plugins/docinfo/Makefile.am @@ -19,11 +19,11 @@ libdocinfo_la_LIBADD = $(XED_LIBS) uidir = $(XED_PLUGINS_DATA_DIR)/docinfo ui_DATA = docinfo.ui -plugin_in_files = docinfo.xed-plugin.desktop.in +plugin_in_files = docinfo.plugin.desktop.in -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache +%.plugin: %.plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) +plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin) EXTRA_DIST = $(ui_DATA) $(plugin_in_files) diff --git a/plugins/docinfo/docinfo.xed-plugin.desktop.in b/plugins/docinfo/docinfo.plugin.desktop.in similarity index 95% rename from plugins/docinfo/docinfo.xed-plugin.desktop.in rename to plugins/docinfo/docinfo.plugin.desktop.in index 944f628..b4da32b 100644 --- a/plugins/docinfo/docinfo.xed-plugin.desktop.in +++ b/plugins/docinfo/docinfo.plugin.desktop.in @@ -1,4 +1,4 @@ -[Xed Plugin] +[Plugin] Module=docinfo IAge=2 _Name=Document Statistics diff --git a/plugins/docinfo/xed-docinfo-plugin.c b/plugins/docinfo/xed-docinfo-plugin.c index fc7b8df..0db0a83 100644 --- a/plugins/docinfo/xed-docinfo-plugin.c +++ b/plugins/docinfo/xed-docinfo-plugin.c @@ -1,13 +1,13 @@ /* * xed-docinfo-plugin.c - * - * Copyright (C) 2002-2005 Paolo Maggi + * + * Copyright (C) 2002-2005 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -28,554 +27,537 @@ #include /* For strlen (...) */ -#include +#include #include #include +#include +#include #include #include -#define WINDOW_DATA_KEY "XedDocInfoWindowData" #define MENU_PATH "/MenuBar/ToolsMenu/ToolsOps_2" -XED_PLUGIN_REGISTER_TYPE(XedDocInfoPlugin, xed_docinfo_plugin) - -typedef struct +struct _XedDocInfoPluginPrivate { - GtkWidget *dialog; - GtkWidget *file_name_label; - GtkWidget *lines_label; - GtkWidget *words_label; - GtkWidget *chars_label; - GtkWidget *chars_ns_label; - GtkWidget *bytes_label; - GtkWidget *selection_vbox; - GtkWidget *selected_lines_label; - GtkWidget *selected_words_label; - GtkWidget *selected_chars_label; - GtkWidget *selected_chars_ns_label; - GtkWidget *selected_bytes_label; -} DocInfoDialog; + XedWindow *window; -typedef struct + GtkActionGroup *action_group; + guint ui_id; + + GtkWidget *dialog; + GtkWidget *file_name_label; + GtkWidget *lines_label; + GtkWidget *words_label; + GtkWidget *chars_label; + GtkWidget *chars_ns_label; + GtkWidget *bytes_label; + GtkWidget *selection_vbox; + GtkWidget *selected_lines_label; + GtkWidget *selected_words_label; + GtkWidget *selected_chars_label; + GtkWidget *selected_chars_ns_label; + GtkWidget *selected_bytes_label; +}; + +enum { - XedPlugin *plugin; + PROP_0, + PROP_WINDOW +}; - GtkActionGroup *ui_action_group; - guint ui_id; +static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface); - DocInfoDialog *dialog; -} WindowData; - -static void docinfo_dialog_response_cb (GtkDialog *widget, - gint res_id, - XedWindow *window); +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedDocInfoPlugin, + xed_docinfo_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, + xed_window_activatable_iface_init)) static void -docinfo_dialog_destroy_cb (GObject *obj, - WindowData *data) -{ - xed_debug (DEBUG_PLUGINS); - - if (data != NULL) - { - g_free (data->dialog); - data->dialog = NULL; - } -} - -static DocInfoDialog * -get_docinfo_dialog (XedWindow *window, - WindowData *data) -{ - DocInfoDialog *dialog; - gchar *data_dir; - gchar *ui_file; - GtkWidget *content; - GtkWidget *error_widget; - gboolean ret; - - xed_debug (DEBUG_PLUGINS); - - dialog = g_new (DocInfoDialog, 1); - - data_dir = xed_plugin_get_data_dir (data->plugin); - ui_file = g_build_filename (data_dir, "docinfo.ui", NULL); - ret = xed_utils_get_ui_objects (ui_file, - NULL, - &error_widget, - "dialog", &dialog->dialog, - "docinfo_dialog_content", &content, - "file_name_label", &dialog->file_name_label, - "words_label", &dialog->words_label, - "bytes_label", &dialog->bytes_label, - "lines_label", &dialog->lines_label, - "chars_label", &dialog->chars_label, - "chars_ns_label", &dialog->chars_ns_label, - "selection_vbox", &dialog->selection_vbox, - "selected_words_label", &dialog->selected_words_label, - "selected_bytes_label", &dialog->selected_bytes_label, - "selected_lines_label", &dialog->selected_lines_label, - "selected_chars_label", &dialog->selected_chars_label, - "selected_chars_ns_label", &dialog->selected_chars_ns_label, - NULL); - - g_free (data_dir); - g_free (ui_file); - - if (!ret) - { - const gchar *err_message; - - err_message = gtk_label_get_label (GTK_LABEL (error_widget)); - xed_warning (GTK_WINDOW (window), "%s", err_message); - - g_free (dialog); - gtk_widget_destroy (error_widget); - - return NULL; - } - - gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog), - GTK_RESPONSE_OK); - gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog), - GTK_WINDOW (window)); - - g_signal_connect (dialog->dialog, - "destroy", - G_CALLBACK (docinfo_dialog_destroy_cb), - data); - - g_signal_connect (dialog->dialog, - "response", - G_CALLBACK (docinfo_dialog_response_cb), - window); - - return dialog; -} - -static void calculate_info (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end, - gint *chars, - gint *words, - gint *white_chars, - gint *bytes) -{ - gchar *text; + GtkTextIter *start, + GtkTextIter *end, + gint *chars, + gint *words, + gint *white_chars, + gint *bytes) +{ + gchar *text; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - text = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), - start, - end, - TRUE); + text = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), start, end, TRUE); - *chars = g_utf8_strlen (text, -1); - *bytes = strlen (text); + *chars = g_utf8_strlen (text, -1); + *bytes = strlen (text); - if (*chars > 0) - { - PangoLogAttr *attrs; - gint i; + if (*chars > 0) + { + PangoLogAttr *attrs; + gint i; - attrs = g_new0 (PangoLogAttr, *chars + 1); + attrs = g_new0 (PangoLogAttr, *chars + 1); - pango_get_log_attrs (text, - -1, - 0, - pango_language_from_string ("C"), - attrs, - *chars + 1); + pango_get_log_attrs (text, -1, 0, pango_language_from_string ("C"), attrs, *chars + 1); - for (i = 0; i < (*chars); i++) - { - if (attrs[i].is_white) - ++(*white_chars); + for (i = 0; i < (*chars); i++) + { + if (attrs[i].is_white) + { + ++(*white_chars); + } - if (attrs[i].is_word_start) - ++(*words); - } + if (attrs[i].is_word_start) + { + ++(*words); + } + } - g_free (attrs); - } - else - { - *white_chars = 0; - *words = 0; - } + g_free (attrs); + } + else + { + *white_chars = 0; + *words = 0; + } - g_free (text); + g_free (text); } static void -docinfo_real (XedDocument *doc, - DocInfoDialog *dialog) +update_document_info (XedDocInfoPlugin *plugin, + XedDocument *doc) { - GtkTextIter start, end; - gint words = 0; - gint chars = 0; - gint white_chars = 0; - gint lines = 0; - gint bytes = 0; - gchar *tmp_str; - gchar *doc_name; + XedDocInfoPluginPrivate *priv; + GtkTextIter start, end; + gint words = 0; + gint chars = 0; + gint white_chars = 0; + gint lines = 0; + gint bytes = 0; + gchar *tmp_str; + gchar *doc_name; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), - &start, - &end); + priv = plugin->priv; - lines = gtk_text_buffer_get_line_count (GTK_TEXT_BUFFER (doc)); + gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), &start, &end); - calculate_info (doc, - &start, &end, - &chars, &words, &white_chars, &bytes); + lines = gtk_text_buffer_get_line_count (GTK_TEXT_BUFFER (doc)); - if (chars == 0) - lines = 0; + calculate_info (doc, &start, &end, &chars, &words, &white_chars, &bytes); - xed_debug_message (DEBUG_PLUGINS, "Chars: %d", chars); - xed_debug_message (DEBUG_PLUGINS, "Lines: %d", lines); - xed_debug_message (DEBUG_PLUGINS, "Words: %d", words); - xed_debug_message (DEBUG_PLUGINS, "Chars non-space: %d", chars - white_chars); - xed_debug_message (DEBUG_PLUGINS, "Bytes: %d", bytes); + if (chars == 0) + { + lines = 0; + } - doc_name = xed_document_get_short_name_for_display (doc); - tmp_str = g_strdup_printf ("%s", doc_name); - gtk_label_set_markup (GTK_LABEL (dialog->file_name_label), tmp_str); - g_free (doc_name); - g_free (tmp_str); + xed_debug_message (DEBUG_PLUGINS, "Chars: %d", chars); + xed_debug_message (DEBUG_PLUGINS, "Lines: %d", lines); + xed_debug_message (DEBUG_PLUGINS, "Words: %d", words); + xed_debug_message (DEBUG_PLUGINS, "Chars non-space: %d", chars - white_chars); + xed_debug_message (DEBUG_PLUGINS, "Bytes: %d", bytes); - tmp_str = g_strdup_printf("%d", lines); - gtk_label_set_text (GTK_LABEL (dialog->lines_label), tmp_str); - g_free (tmp_str); + doc_name = xed_document_get_short_name_for_display (doc); + tmp_str = g_strdup_printf ("%s", doc_name); + gtk_label_set_markup (GTK_LABEL (priv->file_name_label), tmp_str); + g_free (doc_name); + g_free (tmp_str); - tmp_str = g_strdup_printf("%d", words); - gtk_label_set_text (GTK_LABEL (dialog->words_label), tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("%d", lines); + gtk_label_set_text (GTK_LABEL (priv->lines_label), tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf("%d", chars); - gtk_label_set_text (GTK_LABEL (dialog->chars_label), tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("%d", words); + gtk_label_set_text (GTK_LABEL (priv->words_label), tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf("%d", chars - white_chars); - gtk_label_set_text (GTK_LABEL (dialog->chars_ns_label), tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("%d", chars); + gtk_label_set_text (GTK_LABEL (priv->chars_label), tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf("%d", bytes); - gtk_label_set_text (GTK_LABEL (dialog->bytes_label), tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("%d", chars - white_chars); + gtk_label_set_text (GTK_LABEL (priv->chars_ns_label), tmp_str); + g_free (tmp_str); + + tmp_str = g_strdup_printf("%d", bytes); + gtk_label_set_text (GTK_LABEL (priv->bytes_label), tmp_str); + g_free (tmp_str); } static void -selectioninfo_real (XedDocument *doc, - DocInfoDialog *dialog) +update_selection_info (XedDocInfoPlugin *plugin, + XedDocument *doc) { - gboolean sel; - GtkTextIter start, end; - gint words = 0; - gint chars = 0; - gint white_chars = 0; - gint lines = 0; - gint bytes = 0; - gchar *tmp_str; + XedDocInfoPluginPrivate *priv; + gboolean sel; + GtkTextIter start, end; + gint words = 0; + gint chars = 0; + gint white_chars = 0; + gint lines = 0; + gint bytes = 0; + gchar *tmp_str; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - sel = gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), - &start, - &end); + priv = plugin->priv; - if (sel) - { - lines = gtk_text_iter_get_line (&end) - gtk_text_iter_get_line (&start) + 1; - - calculate_info (doc, - &start, &end, - &chars, &words, &white_chars, &bytes); + sel = gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), &start, &end); - xed_debug_message (DEBUG_PLUGINS, "Selected chars: %d", chars); - xed_debug_message (DEBUG_PLUGINS, "Selected lines: %d", lines); - xed_debug_message (DEBUG_PLUGINS, "Selected words: %d", words); - xed_debug_message (DEBUG_PLUGINS, "Selected chars non-space: %d", chars - white_chars); - xed_debug_message (DEBUG_PLUGINS, "Selected bytes: %d", bytes); + if (sel) + { + lines = gtk_text_iter_get_line (&end) - gtk_text_iter_get_line (&start) + 1; - gtk_widget_set_sensitive (dialog->selection_vbox, TRUE); - } - else - { - gtk_widget_set_sensitive (dialog->selection_vbox, FALSE); + calculate_info (doc, &start, &end, &chars, &words, &white_chars, &bytes); - xed_debug_message (DEBUG_PLUGINS, "Selection empty"); - } + xed_debug_message (DEBUG_PLUGINS, "Selected chars: %d", chars); + xed_debug_message (DEBUG_PLUGINS, "Selected lines: %d", lines); + xed_debug_message (DEBUG_PLUGINS, "Selected words: %d", words); + xed_debug_message (DEBUG_PLUGINS, "Selected chars non-space: %d", chars - white_chars); + xed_debug_message (DEBUG_PLUGINS, "Selected bytes: %d", bytes); - if (chars == 0) - lines = 0; + gtk_widget_set_sensitive (priv->selection_vbox, TRUE); + } + else + { + gtk_widget_set_sensitive (priv->selection_vbox, FALSE); - tmp_str = g_strdup_printf("%d", lines); - gtk_label_set_text (GTK_LABEL (dialog->selected_lines_label), tmp_str); - g_free (tmp_str); + xed_debug_message (DEBUG_PLUGINS, "Selection empty"); + } - tmp_str = g_strdup_printf("%d", words); - gtk_label_set_text (GTK_LABEL (dialog->selected_words_label), tmp_str); - g_free (tmp_str); + if (chars == 0) + { + lines = 0; + } - tmp_str = g_strdup_printf("%d", chars); - gtk_label_set_text (GTK_LABEL (dialog->selected_chars_label), tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("%d", lines); + gtk_label_set_text (GTK_LABEL (priv->selected_lines_label), tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf("%d", chars - white_chars); - gtk_label_set_text (GTK_LABEL (dialog->selected_chars_ns_label), tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("%d", words); + gtk_label_set_text (GTK_LABEL (priv->selected_words_label), tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf("%d", bytes); - gtk_label_set_text (GTK_LABEL (dialog->selected_bytes_label), tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("%d", chars); + gtk_label_set_text (GTK_LABEL (priv->selected_chars_label), tmp_str); + g_free (tmp_str); + + tmp_str = g_strdup_printf("%d", chars - white_chars); + gtk_label_set_text (GTK_LABEL (priv->selected_chars_ns_label), tmp_str); + g_free (tmp_str); + + tmp_str = g_strdup_printf("%d", bytes); + gtk_label_set_text (GTK_LABEL (priv->selected_bytes_label), tmp_str); + g_free (tmp_str); } static void -docinfo_cb (GtkAction *action, - XedWindow *window) +docinfo_dialog_response_cb (GtkDialog *widget, + gint res_id, + XedDocInfoPlugin *plugin) { - XedDocument *doc; - WindowData *data; + XedDocInfoPluginPrivate *priv; - xed_debug (DEBUG_PLUGINS); + priv = plugin->priv; - data = (WindowData *) g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); + switch (res_id) + { + case GTK_RESPONSE_CLOSE: + { + xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_CLOSE"); + gtk_widget_destroy (priv->dialog); + break; + } - doc = xed_window_get_active_document (window); - g_return_if_fail (doc != NULL); + case GTK_RESPONSE_OK: + { + XedDocument *doc; - if (data->dialog != NULL) - { - gtk_window_present (GTK_WINDOW (data->dialog->dialog)); - gtk_widget_grab_focus (GTK_WIDGET (data->dialog->dialog)); - } - else - { - DocInfoDialog *dialog; + xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_OK"); - dialog = get_docinfo_dialog (window, data); - g_return_if_fail (dialog != NULL); - - data->dialog = dialog; + doc = xed_window_get_active_document (priv->window); - gtk_widget_show (GTK_WIDGET (dialog->dialog)); - } - - docinfo_real (doc, - data->dialog); - selectioninfo_real (doc, - data->dialog); + update_document_info (plugin, doc); + update_selection_info (plugin, doc); + break; + } + } } static void -docinfo_dialog_response_cb (GtkDialog *widget, - gint res_id, - XedWindow *window) +create_docinfo_dialog (XedDocInfoPlugin *plugin) { - WindowData *data; + XedDocInfoPluginPrivate *priv; + gchar *data_dir; + gchar *ui_file; + GtkWidget *content; + GtkWidget *error_widget; + gboolean ret; - xed_debug (DEBUG_PLUGINS); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); + xed_debug (DEBUG_PLUGINS); - switch (res_id) - { - case GTK_RESPONSE_CLOSE: - { - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_CLOSE"); - gtk_widget_destroy (data->dialog->dialog); + priv = plugin->priv; - break; - } + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); + ui_file = g_build_filename (data_dir, "docinfo.ui", NULL); + ret = xed_utils_get_ui_objects (ui_file, + NULL, + &error_widget, + "dialog", &priv->dialog, + "docinfo_dialog_content", &content, + "file_name_label", &priv->file_name_label, + "words_label", &priv->words_label, + "bytes_label", &priv->bytes_label, + "lines_label", &priv->lines_label, + "chars_label", &priv->chars_label, + "chars_ns_label", &priv->chars_ns_label, + "selection_vbox", &priv->selection_vbox, + "selected_words_label", &priv->selected_words_label, + "selected_bytes_label", &priv->selected_bytes_label, + "selected_lines_label", &priv->selected_lines_label, + "selected_chars_label", &priv->selected_chars_label, + "selected_chars_ns_label", &priv->selected_chars_ns_label, + NULL); - case GTK_RESPONSE_OK: - { - XedDocument *doc; - - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_OK"); - - doc = xed_window_get_active_document (window); - g_return_if_fail (doc != NULL); - - docinfo_real (doc, - data->dialog); + g_free (data_dir); + g_free (ui_file); - selectioninfo_real (doc, - data->dialog); - - break; - } - } + if (!ret) + { + const gchar *err_message; + + err_message = gtk_label_get_label (GTK_LABEL (error_widget)); + xed_warning (GTK_WINDOW (priv->window), "%s", err_message); + + gtk_widget_destroy (error_widget); + + return; + } + + gtk_dialog_set_default_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_OK); + gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (priv->window)); + + g_signal_connect (priv->dialog, "destroy", + G_CALLBACK (gtk_widget_destroyed), &priv->dialog); + g_signal_connect (priv->dialog, "response", + G_CALLBACK (docinfo_dialog_response_cb), plugin); +} + +static void +docinfo_cb (GtkAction *action, + XedDocInfoPlugin *plugin) +{ + XedDocInfoPluginPrivate *priv; + XedDocument *doc; + + xed_debug (DEBUG_PLUGINS); + + priv = plugin->priv; + + doc = xed_window_get_active_document (priv->window); + + if (priv->dialog != NULL) + { + gtk_window_present (GTK_WINDOW (priv->dialog)); + gtk_widget_grab_focus (GTK_WIDGET (priv->dialog)); + } + else + { + create_docinfo_dialog (plugin); + gtk_widget_show (GTK_WIDGET (priv->dialog)); + } + + update_document_info (plugin, doc); + update_selection_info (plugin, doc); } static const GtkActionEntry action_entries[] = { - { "DocumentStatistics", - NULL, - N_("_Document Statistics"), - NULL, - N_("Get statistical information on the current document"), - G_CALLBACK (docinfo_cb) } + { "DocumentStatistics", + NULL, + N_("_Document Statistics"), + NULL, + N_("Get statistical information on the current document"), + G_CALLBACK (docinfo_cb) } }; -static void -free_window_data (WindowData *data) -{ - g_return_if_fail (data != NULL); - - xed_debug (DEBUG_PLUGINS); - - g_object_unref (data->plugin); - - g_object_unref (data->ui_action_group); - - if (data->dialog != NULL) - { - gtk_widget_destroy (data->dialog->dialog); - } - - g_free (data); -} - -static void -update_ui_real (XedWindow *window, - WindowData *data) -{ - XedView *view; - - xed_debug (DEBUG_PLUGINS); - - view = xed_window_get_active_view (window); - - gtk_action_group_set_sensitive (data->ui_action_group, - (view != NULL)); - - if (data->dialog != NULL) - { - gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog->dialog), - GTK_RESPONSE_OK, - (view != NULL)); - } -} - static void xed_docinfo_plugin_init (XedDocInfoPlugin *plugin) { - xed_debug_message (DEBUG_PLUGINS, "XedDocInfoPlugin initializing"); + xed_debug_message (DEBUG_PLUGINS, "XedDocInfoPlugin initializing"); + plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin, XED_TYPE_DOCINFO_PLUGIN, XedDocInfoPluginPrivate); +} + +static void +xed_docinfo_plugin_dispose (GObject *object) +{ + XedDocInfoPlugin *plugin = XED_DOCINFO_PLUGIN (object); + + xed_debug_message (DEBUG_PLUGINS, "XedDocInfoPlugin dispose"); + + g_clear_object (&plugin->priv->action_group); + g_clear_object (&plugin->priv->window); + + G_OBJECT_CLASS (xed_docinfo_plugin_parent_class)->dispose (object); } static void xed_docinfo_plugin_finalize (GObject *object) { - xed_debug_message (DEBUG_PLUGINS, "XedDocInfoPlugin finalizing"); + xed_debug_message (DEBUG_PLUGINS, "XedDocInfoPlugin finalizing"); - G_OBJECT_CLASS (xed_docinfo_plugin_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_docinfo_plugin_parent_class)->finalize (object); } static void -impl_activate (XedPlugin *plugin, - XedWindow *window) +xed_docinfo_plugin_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - GtkUIManager *manager; - WindowData *data; - - xed_debug (DEBUG_PLUGINS); + XedDocInfoPlugin *plugin = XED_DOCINFO_PLUGIN (object); - data = g_new (WindowData, 1); - - data->plugin = g_object_ref (plugin); - data->dialog = NULL; - data->ui_action_group = gtk_action_group_new ("XedDocInfoPluginActions"); - - gtk_action_group_set_translation_domain (data->ui_action_group, - GETTEXT_PACKAGE); - gtk_action_group_add_actions (data->ui_action_group, - action_entries, - G_N_ELEMENTS (action_entries), - window); - - manager = xed_window_get_ui_manager (window); - gtk_ui_manager_insert_action_group (manager, - data->ui_action_group, - -1); - - data->ui_id = gtk_ui_manager_new_merge_id (manager); - - g_object_set_data_full (G_OBJECT (window), - WINDOW_DATA_KEY, - data, - (GDestroyNotify) free_window_data); - - gtk_ui_manager_add_ui (manager, - data->ui_id, - MENU_PATH, - "DocumentStatistics", - "DocumentStatistics", - GTK_UI_MANAGER_MENUITEM, - FALSE); - - update_ui_real (window, - data); + switch (prop_id) + { + case PROP_WINDOW: + plugin->priv->window = XED_WINDOW (g_value_dup_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -impl_deactivate (XedPlugin *plugin, - XedWindow *window) +xed_docinfo_plugin_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - GtkUIManager *manager; - WindowData *data; + XedDocInfoPlugin *plugin = XED_DOCINFO_PLUGIN (object); - xed_debug (DEBUG_PLUGINS); - - manager = xed_window_get_ui_manager (window); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - gtk_ui_manager_remove_ui (manager, - data->ui_id); - gtk_ui_manager_remove_action_group (manager, - data->ui_action_group); - - g_object_set_data (G_OBJECT (window), - WINDOW_DATA_KEY, - NULL); + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, plugin->priv->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -impl_update_ui (XedPlugin *plugin, - XedWindow *window) +update_ui (XedDocInfoPlugin *plugin) { - WindowData *data; + XedDocInfoPluginPrivate *priv; + XedView *view; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - data = (WindowData *) g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); + priv = plugin->priv; - update_ui_real (window, - data); + view = xed_window_get_active_view (priv->window); + + gtk_action_group_set_sensitive (priv->action_group, (view != NULL)); + + if (priv->dialog != NULL) + { + gtk_dialog_set_response_sensitive (GTK_DIALOG (priv->dialog), GTK_RESPONSE_OK, (view != NULL)); + } +} + +static void +xed_docinfo_plugin_activate (XedWindowActivatable *activatable) +{ + XedDocInfoPluginPrivate *priv; + GtkUIManager *manager; + + xed_debug (DEBUG_PLUGINS); + + priv = XED_DOCINFO_PLUGIN (activatable)->priv; + manager = xed_window_get_ui_manager (priv->window); + + priv->action_group = gtk_action_group_new ("XedDocinfoPluginActions"); + gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions (priv->action_group, action_entries, G_N_ELEMENTS (action_entries), activatable); + + gtk_ui_manager_insert_action_group (manager, priv->action_group, -1); + + priv->ui_id = gtk_ui_manager_new_merge_id (manager); + + gtk_ui_manager_add_ui (manager, + priv->ui_id, + MENU_PATH, + "DocumentStatistics", + "DocumentStatistics", + GTK_UI_MANAGER_MENUITEM, + FALSE); + + update_ui (XED_DOCINFO_PLUGIN (activatable)); +} + +static void +xed_docinfo_plugin_deactivate (XedWindowActivatable *activatable) +{ + XedDocInfoPluginPrivate *priv; + GtkUIManager *manager; + + xed_debug (DEBUG_PLUGINS); + + priv = XED_DOCINFO_PLUGIN (activatable)->priv; + manager = xed_window_get_ui_manager (priv->window); + + gtk_ui_manager_remove_ui (manager, priv->ui_id); + gtk_ui_manager_remove_action_group (manager, priv->action_group); +} + +static void +xed_docinfo_plugin_update_state (XedWindowActivatable *activatable) +{ + xed_debug (DEBUG_PLUGINS); + + update_ui (XED_DOCINFO_PLUGIN (activatable)); } static void xed_docinfo_plugin_class_init (XedDocInfoPluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_docinfo_plugin_finalize; + object_class->dispose = xed_docinfo_plugin_dispose; + object_class->finalize = xed_docinfo_plugin_finalize; + object_class->set_property = xed_docinfo_plugin_set_property; + object_class->get_property = xed_docinfo_plugin_get_property; - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - plugin_class->update_ui = impl_update_ui; + g_object_class_override_property (object_class, PROP_WINDOW, "window"); + + g_type_class_add_private (klass, sizeof (XedDocInfoPluginPrivate)); +} + +static void +xed_window_activatable_iface_init (XedWindowActivatableInterface *iface) +{ + iface->activate = xed_docinfo_plugin_activate; + iface->deactivate = xed_docinfo_plugin_deactivate; + iface->update_state = xed_docinfo_plugin_update_state; +} + +static void +xed_docinfo_plugin_class_finalize (XedDocInfoPluginClass *klass) +{ +} + +G_MODULE_EXPORT void +peas_register_types (PeasObjectModule *module) +{ + xed_docinfo_plugin_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + XED_TYPE_WINDOW_ACTIVATABLE, + XED_TYPE_DOCINFO_PLUGIN); } diff --git a/plugins/docinfo/xed-docinfo-plugin.h b/plugins/docinfo/xed-docinfo-plugin.h index dcb3856..61f8139 100644 --- a/plugins/docinfo/xed-docinfo-plugin.h +++ b/plugins/docinfo/xed-docinfo-plugin.h @@ -1,7 +1,7 @@ /* * xed-docinfo-plugin.h - * - * Copyright (C) 2002-2005 Paolo Maggi + * + * Copyright (C) 2002-2005 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,50 +25,39 @@ #include #include -#include +#include +#include G_BEGIN_DECLS -/* - * Type checking and casting macros - */ -#define XED_TYPE_DOCINFO_PLUGIN (xed_docinfo_plugin_get_type ()) -#define XED_DOCINFO_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_DOCINFO_PLUGIN, XedDocInfoPlugin)) -#define XED_DOCINFO_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_DOCINFO_PLUGIN, XedDocInfoPluginClass)) -#define XED_IS_DOCINFO_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_DOCINFO_PLUGIN)) -#define XED_IS_DOCINFO_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_DOCINFO_PLUGIN)) -#define XED_DOCINFO_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_DOCINFO_PLUGIN, XedDocInfoPluginClass)) +#define XED_TYPE_DOCINFO_PLUGIN (xed_docinfo_plugin_get_type ()) +#define XED_DOCINFO_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_DOCINFO_PLUGIN, XedDocInfoPlugin)) +#define XED_DOCINFO_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_DOCINFO_PLUGIN, XedDocInfoPluginClass)) +#define XED_IS_DOCINFO_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_DOCINFO_PLUGIN)) +#define XED_IS_DOCINFO_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_DOCINFO_PLUGIN)) +#define XED_DOCINFO_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_DOCINFO_PLUGIN, XedDocInfoPluginClass)) -/* Private structure type */ -typedef struct _XedDocInfoPluginPrivate XedDocInfoPluginPrivate; - -/* - * Main object structure - */ -typedef struct _XedDocInfoPlugin XedDocInfoPlugin; +typedef struct _XedDocInfoPlugin XedDocInfoPlugin; +typedef struct _XedDocInfoPluginPrivate XedDocInfoPluginPrivate; +typedef struct _XedDocInfoPluginClass XedDocInfoPluginClass; struct _XedDocInfoPlugin { - XedPlugin parent_instance; + PeasExtensionBase parent; + + XedDocInfoPluginPrivate *priv; }; -/* - * Class definition - */ -typedef struct _XedDocInfoPluginClass XedDocInfoPluginClass; +typedef struct _XedDocInfoPluginClass XedDocInfoPluginClass; struct _XedDocInfoPluginClass { - XedPluginClass parent_class; + PeasExtensionBaseClass parent_class; }; -/* - * Public methods - */ -GType xed_docinfo_plugin_get_type (void) G_GNUC_CONST; +GType xed_docinfo_plugin_get_type (void) G_GNUC_CONST; -/* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule *module); +G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); G_END_DECLS diff --git a/plugins/filebrowser/Makefile.am b/plugins/filebrowser/Makefile.am index 865b1de..9613fff 100644 --- a/plugins/filebrowser/Makefile.am +++ b/plugins/filebrowser/Makefile.am @@ -44,9 +44,9 @@ libfilebrowser_la_LIBADD = $(XED_LIBS) uidir = $(XED_PLUGINS_DATA_DIR)/filebrowser ui_DATA = xed-file-browser-widget-ui.xml -plugin_in_files = filebrowser.xed-plugin.desktop.in +plugin_in_files = filebrowser.plugin.desktop.in -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache +%.plugin: %.plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache xed-file-browser-enum-types.h: xed-file-browser-enum-types.h.template $(NOINST_H_FILES) $(GLIB_MKENUMS) (cd $(srcdir) && $(GLIB_MKENUMS) --template xed-file-browser-enum-types.h.template $(NOINST_H_FILES)) > $@ @@ -63,7 +63,7 @@ xed-file-browser-marshal.c: xed-file-browser-marshal.list $(GLIB_GENMARSHAL) $(AM_V_GEN) echo "#include \"xed-file-browser-marshal.h\"" > $@ && \ $(GLIB_GENMARSHAL) $< --body --prefix=xed_file_browser_marshal >> $@ -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) +plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin) @INTLTOOL_XML_NOMERGE_RULE@ filebrowser_gschema_in = org.x.editor.plugins.filebrowser.gschema.xml.in diff --git a/plugins/filebrowser/filebrowser.xed-plugin.desktop.in b/plugins/filebrowser/filebrowser.plugin.desktop.in similarity index 95% rename from plugins/filebrowser/filebrowser.xed-plugin.desktop.in rename to plugins/filebrowser/filebrowser.plugin.desktop.in index 8ff3c73..625f2d0 100644 --- a/plugins/filebrowser/filebrowser.xed-plugin.desktop.in +++ b/plugins/filebrowser/filebrowser.plugin.desktop.in @@ -1,4 +1,4 @@ -[Xed Plugin] +[Plugin] Loader=C Module=filebrowser IAge=2 diff --git a/plugins/filebrowser/xed-file-bookmarks-store.c b/plugins/filebrowser/xed-file-bookmarks-store.c index f5fce51..6074b5d 100644 --- a/plugins/filebrowser/xed-file-bookmarks-store.c +++ b/plugins/filebrowser/xed-file-bookmarks-store.c @@ -1,5 +1,5 @@ /* - * xed-file-bookmarks-store.c - Xed plugin providing easy file access + * xed-file-bookmarks-store.c - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -23,857 +23,931 @@ #include #include #include -#include #include "xed-file-bookmarks-store.h" #include "xed-file-browser-utils.h" #define XED_FILE_BOOKMARKS_STORE_GET_PRIVATE(object)( \ - G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_FILE_BOOKMARKS_STORE, \ - XedFileBookmarksStorePrivate)) + G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_FILE_BOOKMARKS_STORE, \ + XedFileBookmarksStorePrivate)) -struct _XedFileBookmarksStorePrivate +struct _XedFileBookmarksStorePrivate { - GVolumeMonitor * volume_monitor; - GFileMonitor * bookmarks_monitor; + GVolumeMonitor * volume_monitor; + GFileMonitor * bookmarks_monitor; }; -static void remove_node (GtkTreeModel * model, +static void remove_node (GtkTreeModel * model, GtkTreeIter * iter); -static void on_fs_changed (GVolumeMonitor *monitor, - GObject *object, - XedFileBookmarksStore *model); - +static void on_fs_changed (GVolumeMonitor *monitor, + GObject *object, + XedFileBookmarksStore *model); + static void on_bookmarks_file_changed (GFileMonitor * monitor, - GFile * file, - GFile * other_file, - GFileMonitorEvent event_type, - XedFileBookmarksStore * model); -static gboolean find_with_flags (GtkTreeModel * model, + GFile * file, + GFile * other_file, + GFileMonitorEvent event_type, + XedFileBookmarksStore * model); +static gboolean find_with_flags (GtkTreeModel * model, GtkTreeIter * iter, - gpointer obj, + gpointer obj, guint flags, guint notflags); -XED_PLUGIN_DEFINE_TYPE(XedFileBookmarksStore, xed_file_bookmarks_store, GTK_TYPE_TREE_STORE) +G_DEFINE_DYNAMIC_TYPE (XedFileBookmarksStore, xed_file_bookmarks_store, GTK_TYPE_TREE_STORE) static void xed_file_bookmarks_store_dispose (GObject * object) { - XedFileBookmarksStore *obj = XED_FILE_BOOKMARKS_STORE (object); + XedFileBookmarksStore *obj = XED_FILE_BOOKMARKS_STORE (object); - if (obj->priv->volume_monitor != NULL) { - g_signal_handlers_disconnect_by_func (obj->priv->volume_monitor, - on_fs_changed, - obj); + if (obj->priv->volume_monitor != NULL) + { + g_signal_handlers_disconnect_by_func (obj->priv->volume_monitor, on_fs_changed, obj); - g_object_unref (obj->priv->volume_monitor); - obj->priv->volume_monitor = NULL; - } + g_object_unref (obj->priv->volume_monitor); + obj->priv->volume_monitor = NULL; + } - if (obj->priv->bookmarks_monitor != NULL) { - g_object_unref (obj->priv->bookmarks_monitor); - obj->priv->bookmarks_monitor = NULL; - } + if (obj->priv->bookmarks_monitor != NULL) + { + g_object_unref (obj->priv->bookmarks_monitor); + obj->priv->bookmarks_monitor = NULL; + } - G_OBJECT_CLASS (xed_file_bookmarks_store_parent_class)->dispose (object); + G_OBJECT_CLASS (xed_file_bookmarks_store_parent_class)->dispose (object); } static void xed_file_bookmarks_store_finalize (GObject * object) { - G_OBJECT_CLASS (xed_file_bookmarks_store_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_file_bookmarks_store_parent_class)->finalize (object); } static void xed_file_bookmarks_store_class_init (XedFileBookmarksStoreClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->dispose = xed_file_bookmarks_store_dispose; - object_class->finalize = xed_file_bookmarks_store_finalize; + object_class->dispose = xed_file_bookmarks_store_dispose; + object_class->finalize = xed_file_bookmarks_store_finalize; - g_type_class_add_private (object_class, sizeof (XedFileBookmarksStorePrivate)); + g_type_class_add_private (object_class, sizeof (XedFileBookmarksStorePrivate)); +} + +static void +xed_file_bookmarks_store_class_finalize (XedFileBookmarksStoreClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE */ } static void xed_file_bookmarks_store_init (XedFileBookmarksStore * obj) { - obj->priv = XED_FILE_BOOKMARKS_STORE_GET_PRIVATE (obj); + obj->priv = XED_FILE_BOOKMARKS_STORE_GET_PRIVATE (obj); } /* Private */ static void -add_node (XedFileBookmarksStore *model, - GdkPixbuf *pixbuf, - const gchar *name, - GObject *obj, - guint flags, - GtkTreeIter *iter) +add_node (XedFileBookmarksStore *model, + GdkPixbuf *pixbuf, + const gchar *name, + GObject *obj, + guint flags, + GtkTreeIter *iter) { - GtkTreeIter newiter; + GtkTreeIter newiter; - gtk_tree_store_append (GTK_TREE_STORE (model), &newiter, NULL); + gtk_tree_store_append (GTK_TREE_STORE (model), &newiter, NULL); - gtk_tree_store_set (GTK_TREE_STORE (model), &newiter, - XED_FILE_BOOKMARKS_STORE_COLUMN_ICON, pixbuf, - XED_FILE_BOOKMARKS_STORE_COLUMN_NAME, name, - XED_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, obj, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, flags, - -1); + gtk_tree_store_set (GTK_TREE_STORE (model), &newiter, + XED_FILE_BOOKMARKS_STORE_COLUMN_ICON, pixbuf, + XED_FILE_BOOKMARKS_STORE_COLUMN_NAME, name, + XED_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, obj, + XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, flags, + -1); - if (iter != NULL) - *iter = newiter; + if (iter != NULL) + { + *iter = newiter; + } } static gboolean -add_file (XedFileBookmarksStore *model, - GFile *file, - const gchar *name, - guint flags, - GtkTreeIter *iter) +add_file (XedFileBookmarksStore *model, + GFile *file, + const gchar *name, + guint flags, + GtkTreeIter *iter) { - GdkPixbuf *pixbuf = NULL; - gboolean native; - gchar *newname; + GdkPixbuf *pixbuf = NULL; + gboolean native; + gchar *newname; - native = g_file_is_native (file); + native = g_file_is_native (file); - if (native && !g_file_query_exists (file, NULL)) { - return FALSE; - } + if (native && !g_file_query_exists (file, NULL)) + { + return FALSE; + } - if (flags & XED_FILE_BOOKMARKS_STORE_IS_HOME) - pixbuf = xed_file_browser_utils_pixbuf_from_theme ("user-home", GTK_ICON_SIZE_MENU); - else if (flags & XED_FILE_BOOKMARKS_STORE_IS_DESKTOP) - pixbuf = xed_file_browser_utils_pixbuf_from_theme ("user-desktop", GTK_ICON_SIZE_MENU); - else if (flags & XED_FILE_BOOKMARKS_STORE_IS_ROOT) - pixbuf = xed_file_browser_utils_pixbuf_from_theme ("drive-harddisk", GTK_ICON_SIZE_MENU); + if (flags & XED_FILE_BOOKMARKS_STORE_IS_HOME) + { + pixbuf = xed_file_browser_utils_pixbuf_from_theme ("user-home", GTK_ICON_SIZE_MENU); + } + else if (flags & XED_FILE_BOOKMARKS_STORE_IS_DESKTOP) + { + pixbuf = xed_file_browser_utils_pixbuf_from_theme ("user-desktop", GTK_ICON_SIZE_MENU); + } + else if (flags & XED_FILE_BOOKMARKS_STORE_IS_ROOT) + { + pixbuf = xed_file_browser_utils_pixbuf_from_theme ("drive-harddisk", GTK_ICON_SIZE_MENU); + } - if (pixbuf == NULL) { - /* getting the icon is a sync get_info call, so we just do it for local files */ - if (native) { - pixbuf = xed_file_browser_utils_pixbuf_from_file (file, GTK_ICON_SIZE_MENU); - } else { - pixbuf = xed_file_browser_utils_pixbuf_from_theme ("folder", GTK_ICON_SIZE_MENU); - } - } + if (pixbuf == NULL) + { + /* getting the icon is a sync get_info call, so we just do it for local files */ + if (native) + { + pixbuf = xed_file_browser_utils_pixbuf_from_file (file, GTK_ICON_SIZE_MENU); + } + else + { + pixbuf = xed_file_browser_utils_pixbuf_from_theme ("folder", GTK_ICON_SIZE_MENU); + } + } - if (name == NULL) { - newname = xed_file_browser_utils_file_basename (file); - } else { - newname = g_strdup (name); - } + if (name == NULL) + { + newname = xed_file_browser_utils_file_basename (file); + } + else + { + newname = g_strdup (name); + } - add_node (model, pixbuf, newname, G_OBJECT (file), flags, iter); + add_node (model, pixbuf, newname, G_OBJECT (file), flags, iter); - if (pixbuf) - g_object_unref (pixbuf); + if (pixbuf) + { + g_object_unref (pixbuf); + } - g_free (newname); + g_free (newname); - return TRUE; + return TRUE; } static void check_mount_separator (XedFileBookmarksStore * model, guint flags, - gboolean added) + gboolean added) { - GtkTreeIter iter; - gboolean found; + GtkTreeIter iter; + gboolean found; - found = - find_with_flags (GTK_TREE_MODEL (model), &iter, NULL, - flags | - XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR, 0); + found = find_with_flags (GTK_TREE_MODEL (model), &iter, NULL, + flags | XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR, 0); - if (added && !found) { - /* Add the separator */ - add_node (model, NULL, NULL, NULL, - flags | XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR, - NULL); - } else if (!added && found) { - remove_node (GTK_TREE_MODEL (model), &iter); - } + if (added && !found) + { + /* Add the separator */ + add_node (model, NULL, NULL, NULL, flags | XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR, NULL); + } + else if (!added && found) + { + remove_node (GTK_TREE_MODEL (model), &iter); + } } static void init_special_directories (XedFileBookmarksStore * model) { - gchar const *path; - GFile * file; + gchar const *path; + GFile * file; - path = g_get_home_dir (); - if (path != NULL) - { - file = g_file_new_for_path (path); - add_file (model, file, NULL, XED_FILE_BOOKMARKS_STORE_IS_HOME | - XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL); - g_object_unref (file); - } + path = g_get_home_dir (); + if (path != NULL) + { + file = g_file_new_for_path (path); + add_file (model, file, NULL, XED_FILE_BOOKMARKS_STORE_IS_HOME | XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL); + g_object_unref (file); + } - path = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); - if (path != NULL) - { - file = g_file_new_for_path (path); - add_file (model, file, NULL, XED_FILE_BOOKMARKS_STORE_IS_DESKTOP | - XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL); - g_object_unref (file); - } + path = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); + if (path != NULL) + { + file = g_file_new_for_path (path); + add_file (model, file, NULL, XED_FILE_BOOKMARKS_STORE_IS_DESKTOP | + XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL); + g_object_unref (file); + } - path = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); - if (path != NULL) - { - file = g_file_new_for_path (path); - add_file (model, file, NULL, XED_FILE_BOOKMARKS_STORE_IS_DOCUMENTS | - XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL); - g_object_unref (file); - } - - file = g_file_new_for_uri ("file:///"); - add_file (model, file, _("File System"), XED_FILE_BOOKMARKS_STORE_IS_ROOT, NULL); - g_object_unref (file); - - check_mount_separator (model, XED_FILE_BOOKMARKS_STORE_IS_ROOT, TRUE); + path = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); + if (path != NULL) + { + file = g_file_new_for_path (path); + add_file (model, file, NULL, XED_FILE_BOOKMARKS_STORE_IS_DOCUMENTS | + XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL); + g_object_unref (file); + } + + file = g_file_new_for_uri ("file:///"); + add_file (model, file, _("File System"), XED_FILE_BOOKMARKS_STORE_IS_ROOT, NULL); + g_object_unref (file); + + check_mount_separator (model, XED_FILE_BOOKMARKS_STORE_IS_ROOT, TRUE); } static void get_fs_properties (gpointer fs, - gchar **name, - GdkPixbuf **pixbuf, - guint *flags) + gchar **name, + GdkPixbuf **pixbuf, + guint *flags) { - GIcon *icon = NULL; + GIcon *icon = NULL; - *flags = XED_FILE_BOOKMARKS_STORE_IS_FS; - *name = NULL; - *pixbuf = NULL; - - if (G_IS_DRIVE (fs)) - { - icon = g_drive_get_icon (G_DRIVE (fs)); - *name = g_drive_get_name (G_DRIVE (fs)); - - *flags |= XED_FILE_BOOKMARKS_STORE_IS_DRIVE; - } - else if (G_IS_VOLUME (fs)) - { - icon = g_volume_get_icon (G_VOLUME (fs)); - *name = g_volume_get_name (G_VOLUME (fs)); - - *flags |= XED_FILE_BOOKMARKS_STORE_IS_VOLUME; - } - else if (G_IS_MOUNT (fs)) - { - icon = g_mount_get_icon (G_MOUNT (fs)); - *name = g_mount_get_name (G_MOUNT (fs)); - - *flags |= XED_FILE_BOOKMARKS_STORE_IS_MOUNT; - } - - if (icon) - { - *pixbuf = xed_file_browser_utils_pixbuf_from_icon (icon, GTK_ICON_SIZE_MENU); - g_object_unref (icon); - } + *flags = XED_FILE_BOOKMARKS_STORE_IS_FS; + *name = NULL; + *pixbuf = NULL; + + if (G_IS_DRIVE (fs)) + { + icon = g_drive_get_icon (G_DRIVE (fs)); + *name = g_drive_get_name (G_DRIVE (fs)); + + *flags |= XED_FILE_BOOKMARKS_STORE_IS_DRIVE; + } + else if (G_IS_VOLUME (fs)) + { + icon = g_volume_get_icon (G_VOLUME (fs)); + *name = g_volume_get_name (G_VOLUME (fs)); + + *flags |= XED_FILE_BOOKMARKS_STORE_IS_VOLUME; + } + else if (G_IS_MOUNT (fs)) + { + icon = g_mount_get_icon (G_MOUNT (fs)); + *name = g_mount_get_name (G_MOUNT (fs)); + + *flags |= XED_FILE_BOOKMARKS_STORE_IS_MOUNT; + } + + if (icon) + { + *pixbuf = xed_file_browser_utils_pixbuf_from_icon (icon, GTK_ICON_SIZE_MENU); + g_object_unref (icon); + } } - + static void add_fs (XedFileBookmarksStore *model, - gpointer fs, - guint flags, - GtkTreeIter *iter) + gpointer fs, + guint flags, + GtkTreeIter *iter) { - gchar *name; - GdkPixbuf *pixbuf; - guint fsflags; - - get_fs_properties (fs, &name, &pixbuf, &fsflags); - add_node (model, pixbuf, name, fs, flags | fsflags, iter); - - if (pixbuf) - g_object_unref (pixbuf); + gchar *name; + GdkPixbuf *pixbuf; + guint fsflags; - g_free (name); - check_mount_separator (model, XED_FILE_BOOKMARKS_STORE_IS_FS, TRUE); + get_fs_properties (fs, &name, &pixbuf, &fsflags); + add_node (model, pixbuf, name, fs, flags | fsflags, iter); + + if (pixbuf) + { + g_object_unref (pixbuf); + } + + g_free (name); + check_mount_separator (model, XED_FILE_BOOKMARKS_STORE_IS_FS, TRUE); } static void -process_volume_cb (GVolume *volume, - XedFileBookmarksStore *model) +process_volume_cb (GVolume *volume, + XedFileBookmarksStore *model) { - GMount *mount; - guint flags = XED_FILE_BOOKMARKS_STORE_NONE; - mount = g_volume_get_mount (volume); - - /* CHECK: should we use the LOCAL/REMOTE thing still? */ - if (mount) - { - /* Show mounted volume */ - add_fs (model, mount, flags, NULL); - g_object_unref (mount); - } - else if (g_volume_can_mount (volume)) - { - /* We also show the unmounted volume here so users can - mount it if they want to access it */ - add_fs (model, volume, flags, NULL); - } + GMount *mount; + guint flags = XED_FILE_BOOKMARKS_STORE_NONE; + mount = g_volume_get_mount (volume); + + /* CHECK: should we use the LOCAL/REMOTE thing still? */ + if (mount) + { + /* Show mounted volume */ + add_fs (model, mount, flags, NULL); + g_object_unref (mount); + } + else if (g_volume_can_mount (volume)) + { + /* We also show the unmounted volume here so users can + mount it if they want to access it */ + add_fs (model, volume, flags, NULL); + } } static void process_drive_novolumes (XedFileBookmarksStore *model, - GDrive *drive) + GDrive *drive) { - if (g_drive_is_media_removable (drive) && - !g_drive_is_media_check_automatic (drive) && - g_drive_can_poll_for_media (drive)) - { - /* This can be the case for floppy drives or other - drives where media detection fails. We show the - drive and poll for media when the user activates - it */ - add_fs (model, drive, XED_FILE_BOOKMARKS_STORE_NONE, NULL); - } + if (g_drive_is_media_removable (drive) && + !g_drive_is_media_check_automatic (drive) && + g_drive_can_poll_for_media (drive)) + { + /* This can be the case for floppy drives or other + drives where media detection fails. We show the + drive and poll for media when the user activates + it */ + add_fs (model, drive, XED_FILE_BOOKMARKS_STORE_NONE, NULL); + } } static void -process_drive_cb (GDrive *drive, - XedFileBookmarksStore *model) +process_drive_cb (GDrive *drive, + XedFileBookmarksStore *model) { - GList *volumes; + GList *volumes; - volumes = g_drive_get_volumes (drive); + volumes = g_drive_get_volumes (drive); - if (volumes) - { - /* Add all volumes for the drive */ - g_list_foreach (volumes, (GFunc)process_volume_cb, model); - g_list_free (volumes); - } - else - { - process_drive_novolumes (model, drive); - } + if (volumes) + { + /* Add all volumes for the drive */ + g_list_foreach (volumes, (GFunc)process_volume_cb, model); + g_list_free (volumes); + } + else + { + process_drive_novolumes (model, drive); + } } static void init_drives (XedFileBookmarksStore *model) { - GList *drives; - - drives = g_volume_monitor_get_connected_drives (model->priv->volume_monitor); + GList *drives; - g_list_foreach (drives, (GFunc)process_drive_cb, model); - g_list_foreach (drives, (GFunc)g_object_unref, NULL); - g_list_free (drives); + drives = g_volume_monitor_get_connected_drives (model->priv->volume_monitor); + + g_list_foreach (drives, (GFunc)process_drive_cb, model); + g_list_foreach (drives, (GFunc)g_object_unref, NULL); + g_list_free (drives); } static void -process_volume_nodrive_cb (GVolume *volume, - XedFileBookmarksStore *model) +process_volume_nodrive_cb (GVolume *volume, + XedFileBookmarksStore *model) { - GDrive *drive; - - drive = g_volume_get_drive (volume); - - if (drive) - { - g_object_unref (drive); - return; - } - - process_volume_cb (volume, model); + GDrive *drive; + + drive = g_volume_get_drive (volume); + + if (drive) + { + g_object_unref (drive); + return; + } + + process_volume_cb (volume, model); } static void init_volumes (XedFileBookmarksStore *model) { - GList *volumes; - - volumes = g_volume_monitor_get_volumes (model->priv->volume_monitor); - - g_list_foreach (volumes, (GFunc)process_volume_nodrive_cb, model); - g_list_foreach (volumes, (GFunc)g_object_unref, NULL); - g_list_free (volumes); + GList *volumes; + + volumes = g_volume_monitor_get_volumes (model->priv->volume_monitor); + + g_list_foreach (volumes, (GFunc)process_volume_nodrive_cb, model); + g_list_foreach (volumes, (GFunc)g_object_unref, NULL); + g_list_free (volumes); } static void -process_mount_novolume_cb (GMount *mount, - XedFileBookmarksStore *model) +process_mount_novolume_cb (GMount *mount, + XedFileBookmarksStore *model) { - GVolume *volume; - - volume = g_mount_get_volume (mount); - - if (volume) - { - g_object_unref (volume); - } - else if (!g_mount_is_shadowed (mount)) - { - /* Add the mount */ - add_fs (model, mount, XED_FILE_BOOKMARKS_STORE_NONE, NULL); - } + GVolume *volume; + + volume = g_mount_get_volume (mount); + + if (volume) + { + g_object_unref (volume); + } + else if (!g_mount_is_shadowed (mount)) + { + /* Add the mount */ + add_fs (model, mount, XED_FILE_BOOKMARKS_STORE_NONE, NULL); + } } static void init_mounts (XedFileBookmarksStore *model) { - GList *mounts; - - mounts = g_volume_monitor_get_mounts (model->priv->volume_monitor); - - g_list_foreach (mounts, (GFunc)process_mount_novolume_cb, model); - g_list_foreach (mounts, (GFunc)g_object_unref, NULL); - g_list_free (mounts); + GList *mounts; + + mounts = g_volume_monitor_get_mounts (model->priv->volume_monitor); + + g_list_foreach (mounts, (GFunc)process_mount_novolume_cb, model); + g_list_foreach (mounts, (GFunc)g_object_unref, NULL); + g_list_free (mounts); } static void init_fs (XedFileBookmarksStore * model) { - if (model->priv->volume_monitor == NULL) { - const gchar **ptr; - const gchar *signals[] = { - "drive-connected", "drive-changed", "drive-disconnected", - "volume-added", "volume-removed", "volume-changed", - "mount-added", "mount-removed", "mount-changed", - NULL - }; - - model->priv->volume_monitor = g_volume_monitor_get (); + if (model->priv->volume_monitor == NULL) + { + const gchar **ptr; + const gchar *signals[] = { + "drive-connected", "drive-changed", "drive-disconnected", + "volume-added", "volume-removed", "volume-changed", + "mount-added", "mount-removed", "mount-changed", + NULL + }; - /* Connect signals */ - for (ptr = signals; *ptr; ptr++) - { - g_signal_connect (model->priv->volume_monitor, - *ptr, - G_CALLBACK (on_fs_changed), model); - } - } + model->priv->volume_monitor = g_volume_monitor_get (); - /* First go through all the connected drives */ - init_drives (model); - - /* Then add all volumes, not associated with a drive */ - init_volumes (model); - - /* Then finally add all mounts that have no volume */ - init_mounts (model); + /* Connect signals */ + for (ptr = signals; *ptr; ptr++) + { + g_signal_connect (model->priv->volume_monitor, *ptr, G_CALLBACK (on_fs_changed), model); + } + } + + /* First go through all the connected drives */ + init_drives (model); + + /* Then add all volumes, not associated with a drive */ + init_volumes (model); + + /* Then finally add all mounts that have no volume */ + init_mounts (model); } static gboolean -add_bookmark (XedFileBookmarksStore * model, - gchar const * name, - gchar const * uri) +add_bookmark (XedFileBookmarksStore * model, + gchar const * name, + gchar const * uri) { - GFile * file; - gboolean ret; - guint flags = XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK; - GtkTreeIter iter; - - file = g_file_new_for_uri (uri); - - if (g_file_is_native (file)) { - flags |= XED_FILE_BOOKMARKS_STORE_IS_LOCAL_BOOKMARK; - } else { - flags |= XED_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK; - } + GFile * file; + gboolean ret; + guint flags = XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK; + GtkTreeIter iter; - ret = add_file (model, file, name, flags, &iter); + file = g_file_new_for_uri (uri); - g_object_unref (file); - - return ret; + if (g_file_is_native (file)) + { + flags |= XED_FILE_BOOKMARKS_STORE_IS_LOCAL_BOOKMARK; + } + else + { + flags |= XED_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK; + } + + ret = add_file (model, file, name, flags, &iter); + + g_object_unref (file); + + return ret; } static void init_bookmarks (XedFileBookmarksStore * model) { - gchar *bookmarks; - GError *error = NULL; - gchar *contents; - gchar **lines; - gchar **line; - gboolean added = FALSE; + gchar *bookmarks; + GError *error = NULL; + gchar *contents; + gchar **lines; + gchar **line; + gboolean added = FALSE; - /* Read the bookmarks file */ - bookmarks = g_build_filename (g_get_home_dir (), - ".gtk-bookmarks", - NULL); + /* Read the bookmarks file */ + bookmarks = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL); - if (g_file_get_contents (bookmarks, &contents, NULL, &error)) { - lines = g_strsplit (contents, "\n", 0); + if (g_file_get_contents (bookmarks, &contents, NULL, &error)) + { + lines = g_strsplit (contents, "\n", 0); - for (line = lines; *line; ++line) { - if (**line) { - gchar *pos; - gchar *name; + for (line = lines; *line; ++line) + { + if (**line) + { + GFile *location; + gchar *pos; + gchar *name; - /* CHECK: is this really utf8? */ - pos = g_utf8_strchr (*line, -1, ' '); + /* CHECK: is this really utf8? */ + pos = g_utf8_strchr (*line, -1, ' '); - if (pos != NULL) { - *pos = '\0'; - name = pos + 1; - } else { - name = NULL; - } + if (pos != NULL) + { + *pos = '\0'; + name = pos + 1; + } + else + { + name = NULL; + } - /* the bookmarks file should contain valid - * URIs, but paranoia is good */ - if (xed_utils_is_valid_uri (*line)) { - added |= add_bookmark (model, name, *line); - } - } - } + /* the bookmarks file should contain valid + * URIs, but paranoia is good */ + location = g_file_new_for_uri (*line); + if (xed_utils_is_valid_location (location)) + { + added |= add_bookmark (model, name, *line); + } + g_object_unref (location); + } + } - g_strfreev (lines); - g_free (contents); + g_strfreev (lines); + g_free (contents); - /* Add a watch */ - if (model->priv->bookmarks_monitor == NULL) { - GFile * file; + /* Add a watch */ + if (model->priv->bookmarks_monitor == NULL) + { + GFile * file; - file = g_file_new_for_path (bookmarks); - model->priv->bookmarks_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); - g_object_unref (file); + file = g_file_new_for_path (bookmarks); + model->priv->bookmarks_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_unref (file); - g_signal_connect (model->priv->bookmarks_monitor, - "changed", - (GCallback)on_bookmarks_file_changed, - model); - } - } else { - /* The bookmarks file doesn't exist (which is perfectly fine) */ - g_error_free (error); - } + g_signal_connect (model->priv->bookmarks_monitor, "changed", + (GCallback)on_bookmarks_file_changed, model); + } + } + else + { + /* The bookmarks file doesn't exist (which is perfectly fine) */ + g_error_free (error); + } - if (added) { - /* Bookmarks separator */ - add_node (model, NULL, NULL, NULL, - XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK | - XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR, NULL); - } + if (added) + { + /* Bookmarks separator */ + add_node (model, NULL, NULL, NULL, + XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK | + XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR, NULL); + } - g_free (bookmarks); + g_free (bookmarks); } static gint flags_order[] = { - XED_FILE_BOOKMARKS_STORE_IS_HOME, - XED_FILE_BOOKMARKS_STORE_IS_DESKTOP, - XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, - XED_FILE_BOOKMARKS_STORE_IS_ROOT, - XED_FILE_BOOKMARKS_STORE_IS_FS, - XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK, - -1 + XED_FILE_BOOKMARKS_STORE_IS_HOME, + XED_FILE_BOOKMARKS_STORE_IS_DESKTOP, + XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, + XED_FILE_BOOKMARKS_STORE_IS_ROOT, + XED_FILE_BOOKMARKS_STORE_IS_FS, + XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK, + -1 }; static gint utf8_casecmp (gchar const *s1, const gchar * s2) { - gchar *n1; - gchar *n2; - gint result; + gchar *n1; + gchar *n2; + gint result; - n1 = g_utf8_casefold (s1, -1); - n2 = g_utf8_casefold (s2, -1); + n1 = g_utf8_casefold (s1, -1); + n2 = g_utf8_casefold (s2, -1); - result = g_utf8_collate (n1, n2); + result = g_utf8_collate (n1, n2); - g_free (n1); - g_free (n2); + g_free (n1); + g_free (n2); - return result; + return result; } static gint -bookmarks_compare_names (GtkTreeModel * model, GtkTreeIter * a, - GtkTreeIter * b) +bookmarks_compare_names (GtkTreeModel * model, + GtkTreeIter * a, + GtkTreeIter * b) { - gchar *n1; - gchar *n2; - gint result; - guint f1; - guint f2; + gchar *n1; + gchar *n2; + gint result; + guint f1; + guint f2; - gtk_tree_model_get (model, a, - XED_FILE_BOOKMARKS_STORE_COLUMN_NAME, &n1, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f1, - -1); - gtk_tree_model_get (model, b, - XED_FILE_BOOKMARKS_STORE_COLUMN_NAME, &n2, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f2, - -1); + gtk_tree_model_get (model, a, + XED_FILE_BOOKMARKS_STORE_COLUMN_NAME, &n1, + XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f1, + -1); + gtk_tree_model_get (model, b, + XED_FILE_BOOKMARKS_STORE_COLUMN_NAME, &n2, + XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f2, + -1); - /* do not sort actual bookmarks to keep same order as in caja */ - if ((f1 & XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK) && - (f2 & XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK)) - result = 0; - else if (n1 == NULL && n2 == NULL) - result = 0; - else if (n1 == NULL) - result = -1; - else if (n2 == NULL) - result = 1; - else - result = utf8_casecmp (n1, n2); + /* do not sort actual bookmarks to keep same order as in caja */ + if ((f1 & XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK) && (f2 & XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK)) + { + result = 0; + } + else if (n1 == NULL && n2 == NULL) + { + result = 0; + } + else if (n1 == NULL) + { + result = -1; + } + else if (n2 == NULL) + { + result = 1; + } + else + { + result = utf8_casecmp (n1, n2); + } - g_free (n1); - g_free (n2); + g_free (n1); + g_free (n2); - return result; + return result; } static gint -bookmarks_compare_flags (GtkTreeModel * model, GtkTreeIter * a, - GtkTreeIter * b) +bookmarks_compare_flags (GtkTreeModel * model, + GtkTreeIter * a, + GtkTreeIter * b) { - guint f1; - guint f2; - gint *flags; - guint sep; + guint f1; + guint f2; + gint *flags; + guint sep; - sep = XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR; + sep = XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR; - gtk_tree_model_get (model, a, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f1, - -1); - gtk_tree_model_get (model, b, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f2, - -1); + gtk_tree_model_get (model, a, XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f1, -1); + gtk_tree_model_get (model, b, XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f2, -1); - for (flags = flags_order; *flags != -1; ++flags) { - if ((f1 & *flags) != (f2 & *flags)) { - if (f1 & *flags) { - return -1; - } else { - return 1; - } - } else if ((f1 & *flags) && (f1 & sep) != (f2 & sep)) { - if (f1 & sep) - return -1; - else - return 1; - } - } + for (flags = flags_order; *flags != -1; ++flags) + { + if ((f1 & *flags) != (f2 & *flags)) + { + if (f1 & *flags) + { + return -1; + } + else + { + return 1; + } + } + else if ((f1 & *flags) && (f1 & sep) != (f2 & sep)) + { + if (f1 & sep) + { + return -1; + } + else + { + return 1; + } + } + } - return 0; + return 0; } static gint -bookmarks_compare_func (GtkTreeModel * model, GtkTreeIter * a, - GtkTreeIter * b, gpointer user_data) +bookmarks_compare_func (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer user_data) { - gint result; + gint result; - result = bookmarks_compare_flags (model, a, b); + result = bookmarks_compare_flags (model, a, b); - if (result == 0) - result = bookmarks_compare_names (model, a, b); + if (result == 0) + { + result = bookmarks_compare_names (model, a, b); + } - return result; + return result; } static gboolean -find_with_flags (GtkTreeModel * model, GtkTreeIter * iter, gpointer obj, - guint flags, guint notflags) +find_with_flags (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer obj, + guint flags, + guint notflags) { - GtkTreeIter child; - guint childflags = 0; - GObject * childobj; - gboolean fequal; - - if (!gtk_tree_model_get_iter_first (model, &child)) - return FALSE; + GtkTreeIter child; + guint childflags = 0; + GObject * childobj; + gboolean fequal; - do { - gtk_tree_model_get (model, &child, - XED_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, - &childobj, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, - &childflags, -1); - - fequal = (obj == childobj); - - if (childobj) - g_object_unref (childobj); - - if ((obj == NULL || fequal) && - (childflags & flags) == flags - && !(childflags & notflags)) { - *iter = child; - return TRUE; - } - } while (gtk_tree_model_iter_next (model, &child)); + if (!gtk_tree_model_get_iter_first (model, &child)) + { + return FALSE; + } - return FALSE; + do { + gtk_tree_model_get (model, &child, + XED_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, + &childobj, + XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, + &childflags, -1); + + fequal = (obj == childobj); + + if (childobj) + { + g_object_unref (childobj); + } + + if ((obj == NULL || fequal) && + (childflags & flags) == flags + && !(childflags & notflags)) + { + *iter = child; + return TRUE; + } + } while (gtk_tree_model_iter_next (model, &child)); + + return FALSE; } static void -remove_node (GtkTreeModel * model, GtkTreeIter * iter) +remove_node (GtkTreeModel *model, + GtkTreeIter *iter) { - guint flags; + guint flags; - gtk_tree_model_get (model, iter, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &flags, - -1); + gtk_tree_model_get (model, iter, XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &flags, -1); - if (!(flags & XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR)) { - if (flags & XED_FILE_BOOKMARKS_STORE_IS_FS) { - check_mount_separator (XED_FILE_BOOKMARKS_STORE (model), - flags & XED_FILE_BOOKMARKS_STORE_IS_FS, - FALSE); - } - } + if (!(flags & XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR)) + { + if (flags & XED_FILE_BOOKMARKS_STORE_IS_FS) + { + check_mount_separator (XED_FILE_BOOKMARKS_STORE (model), + flags & XED_FILE_BOOKMARKS_STORE_IS_FS, + FALSE); + } + } - gtk_tree_store_remove (GTK_TREE_STORE (model), iter); + gtk_tree_store_remove (GTK_TREE_STORE (model), iter); } static void -remove_bookmarks (XedFileBookmarksStore * model) +remove_bookmarks (XedFileBookmarksStore *model) { - GtkTreeIter iter; + GtkTreeIter iter; - while (find_with_flags (GTK_TREE_MODEL (model), &iter, NULL, - XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK, - 0)) { - remove_node (GTK_TREE_MODEL (model), &iter); - } + while (find_with_flags (GTK_TREE_MODEL (model), &iter, NULL, + XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK, 0)) + { + remove_node (GTK_TREE_MODEL (model), &iter); + } } static void -initialize_fill (XedFileBookmarksStore * model) +initialize_fill (XedFileBookmarksStore *model) { - init_special_directories (model); - init_fs (model); - init_bookmarks (model); + init_special_directories (model); + init_fs (model); + init_bookmarks (model); } /* Public */ XedFileBookmarksStore * xed_file_bookmarks_store_new (void) { - XedFileBookmarksStore *model; - GType column_types[] = { - GDK_TYPE_PIXBUF, - G_TYPE_STRING, - G_TYPE_OBJECT, - G_TYPE_UINT - }; + XedFileBookmarksStore *model; + GType column_types[] = { + GDK_TYPE_PIXBUF, + G_TYPE_STRING, + G_TYPE_OBJECT, + G_TYPE_UINT + }; - model = g_object_new (XED_TYPE_FILE_BOOKMARKS_STORE, NULL); - gtk_tree_store_set_column_types (GTK_TREE_STORE (model), - XED_FILE_BOOKMARKS_STORE_N_COLUMNS, - column_types); + model = g_object_new (XED_TYPE_FILE_BOOKMARKS_STORE, NULL); + gtk_tree_store_set_column_types (GTK_TREE_STORE (model), + XED_FILE_BOOKMARKS_STORE_N_COLUMNS, + column_types); - gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model), - bookmarks_compare_func, - NULL, NULL); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), - GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, - GTK_SORT_ASCENDING); + gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model), + bookmarks_compare_func, + NULL, NULL); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), + GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, + GTK_SORT_ASCENDING); - initialize_fill (model); + initialize_fill (model); - return model; + return model; } -gchar * -xed_file_bookmarks_store_get_uri (XedFileBookmarksStore * model, - GtkTreeIter * iter) +GFile * +xed_file_bookmarks_store_get_location (XedFileBookmarksStore *model, + GtkTreeIter *iter) { - GObject * obj; - GFile * file = NULL; - guint flags; - gchar * ret = NULL; - gboolean isfs; - - g_return_val_if_fail (XED_IS_FILE_BOOKMARKS_STORE (model), NULL); - g_return_val_if_fail (iter != NULL, NULL); + GObject *obj; + GFile *file = NULL; + guint flags; + GFile *ret = NULL; + gboolean isfs; - gtk_tree_model_get (GTK_TREE_MODEL (model), iter, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, - &flags, - XED_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, - &obj, - -1); + g_return_val_if_fail (XED_IS_FILE_BOOKMARKS_STORE (model), NULL); + g_return_val_if_fail (iter != NULL, NULL); - if (obj == NULL) - return NULL; + gtk_tree_model_get (GTK_TREE_MODEL (model), iter, + XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, + &flags, + XED_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, + &obj, + -1); - isfs = (flags & XED_FILE_BOOKMARKS_STORE_IS_FS); - - if (isfs && (flags & XED_FILE_BOOKMARKS_STORE_IS_MOUNT)) - { - file = g_mount_get_root (G_MOUNT (obj)); - } - else if (!isfs) - { - file = g_object_ref (obj); - } - - g_object_unref (obj); - - if (file) - { - ret = g_file_get_uri (file); - g_object_unref (file); - } - - return ret; + if (obj == NULL) + { + return NULL; + } + + isfs = (flags & XED_FILE_BOOKMARKS_STORE_IS_FS); + + if (isfs && (flags & XED_FILE_BOOKMARKS_STORE_IS_MOUNT)) + { + file = g_mount_get_root (G_MOUNT (obj)); + } + else if (!isfs) + { + file = g_object_ref (obj); + } + + g_object_unref (obj); + + if (file) + { + ret = g_file_dup (file); + g_object_unref (file); + } + + return ret; } void -xed_file_bookmarks_store_refresh (XedFileBookmarksStore * model) +xed_file_bookmarks_store_refresh (XedFileBookmarksStore *model) { - gtk_tree_store_clear (GTK_TREE_STORE (model)); - initialize_fill (model); + gtk_tree_store_clear (GTK_TREE_STORE (model)); + initialize_fill (model); } static void -on_fs_changed (GVolumeMonitor *monitor, - GObject *object, - XedFileBookmarksStore *model) +on_fs_changed (GVolumeMonitor *monitor, + GObject *object, + XedFileBookmarksStore *model) { - GtkTreeModel *tree_model = GTK_TREE_MODEL (model); - guint flags = XED_FILE_BOOKMARKS_STORE_IS_FS; - guint noflags = XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR; - GtkTreeIter iter; + GtkTreeModel *tree_model = GTK_TREE_MODEL (model); + guint flags = XED_FILE_BOOKMARKS_STORE_IS_FS; + guint noflags = XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR; + GtkTreeIter iter; - /* clear all fs items */ - while (find_with_flags (tree_model, &iter, NULL, flags, noflags)) - remove_node (tree_model, &iter); - - /* then reinitialize */ - init_fs (model); + /* clear all fs items */ + while (find_with_flags (tree_model, &iter, NULL, flags, noflags)) + remove_node (tree_model, &iter); + + /* then reinitialize */ + init_fs (model); } static void on_bookmarks_file_changed (GFileMonitor * monitor, - GFile * file, - GFile * other_file, - GFileMonitorEvent event_type, - XedFileBookmarksStore * model) + GFile * file, + GFile * other_file, + GFileMonitorEvent event_type, + XedFileBookmarksStore * model) { - switch (event_type) { - case G_FILE_MONITOR_EVENT_CHANGED: - case G_FILE_MONITOR_EVENT_CREATED: - /* Re-initialize bookmarks */ - remove_bookmarks (model); - init_bookmarks (model); - break; - case G_FILE_MONITOR_EVENT_DELETED: // FIXME: shouldn't we also monitor the directory? - /* Remove bookmarks */ - remove_bookmarks (model); - g_object_unref (monitor); - model->priv->bookmarks_monitor = NULL; - break; - default: - break; - } + switch (event_type) { + case G_FILE_MONITOR_EVENT_CHANGED: + case G_FILE_MONITOR_EVENT_CREATED: + /* Re-initialize bookmarks */ + remove_bookmarks (model); + init_bookmarks (model); + break; + case G_FILE_MONITOR_EVENT_DELETED: // FIXME: shouldn't we also monitor the directory? + /* Remove bookmarks */ + remove_bookmarks (model); + g_object_unref (monitor); + model->priv->bookmarks_monitor = NULL; + break; + default: + break; + } +} + +void +_xed_file_bookmarks_store_register_type (GTypeModule *type_module) +{ + xed_file_bookmarks_store_register_type (type_module); } // ex:ts=8:noet: diff --git a/plugins/filebrowser/xed-file-bookmarks-store.h b/plugins/filebrowser/xed-file-bookmarks-store.h index 8560812..80276f5 100644 --- a/plugins/filebrowser/xed-file-bookmarks-store.h +++ b/plugins/filebrowser/xed-file-bookmarks-store.h @@ -1,5 +1,5 @@ /* - * xed-file-bookmarks-store.h - Xed plugin providing easy file access + * xed-file-bookmarks-store.h - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -25,66 +25,66 @@ #include G_BEGIN_DECLS -#define XED_TYPE_FILE_BOOKMARKS_STORE (xed_file_bookmarks_store_get_type ()) -#define XED_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStore)) -#define XED_FILE_BOOKMARKS_STORE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStore const)) -#define XED_FILE_BOOKMARKS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStoreClass)) -#define XED_IS_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BOOKMARKS_STORE)) -#define XED_IS_FILE_BOOKMARKS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BOOKMARKS_STORE)) -#define XED_FILE_BOOKMARKS_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStoreClass)) +#define XED_TYPE_FILE_BOOKMARKS_STORE (xed_file_bookmarks_store_get_type ()) +#define XED_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStore)) +#define XED_FILE_BOOKMARKS_STORE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStore const)) +#define XED_FILE_BOOKMARKS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStoreClass)) +#define XED_IS_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BOOKMARKS_STORE)) +#define XED_IS_FILE_BOOKMARKS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BOOKMARKS_STORE)) +#define XED_FILE_BOOKMARKS_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BOOKMARKS_STORE, XedFileBookmarksStoreClass)) typedef struct _XedFileBookmarksStore XedFileBookmarksStore; typedef struct _XedFileBookmarksStoreClass XedFileBookmarksStoreClass; typedef struct _XedFileBookmarksStorePrivate XedFileBookmarksStorePrivate; -enum +enum { - XED_FILE_BOOKMARKS_STORE_COLUMN_ICON = 0, - XED_FILE_BOOKMARKS_STORE_COLUMN_NAME, - XED_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, - XED_FILE_BOOKMARKS_STORE_N_COLUMNS + XED_FILE_BOOKMARKS_STORE_COLUMN_ICON = 0, + XED_FILE_BOOKMARKS_STORE_COLUMN_NAME, + XED_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, + XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, + XED_FILE_BOOKMARKS_STORE_N_COLUMNS }; -enum +enum { - XED_FILE_BOOKMARKS_STORE_NONE = 0, - XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR = 1 << 0, /* Separator item */ - XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR = 1 << 1, /* Special user dir */ - XED_FILE_BOOKMARKS_STORE_IS_HOME = 1 << 2, /* The special Home user directory */ - XED_FILE_BOOKMARKS_STORE_IS_DESKTOP = 1 << 3, /* The special Desktop user directory */ - XED_FILE_BOOKMARKS_STORE_IS_DOCUMENTS = 1 << 4, /* The special Documents user directory */ - XED_FILE_BOOKMARKS_STORE_IS_FS = 1 << 5, /* A mount object */ - XED_FILE_BOOKMARKS_STORE_IS_MOUNT = 1 << 6, /* A mount object */ - XED_FILE_BOOKMARKS_STORE_IS_VOLUME = 1 << 7, /* A volume object */ - XED_FILE_BOOKMARKS_STORE_IS_DRIVE = 1 << 8, /* A drive object */ - XED_FILE_BOOKMARKS_STORE_IS_ROOT = 1 << 9, /* The root file system (file:///) */ - XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK = 1 << 10, /* A gtk bookmark */ - XED_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK = 1 << 11, /* A remote gtk bookmark */ - XED_FILE_BOOKMARKS_STORE_IS_LOCAL_BOOKMARK = 1 << 12 /* A local gtk bookmark */ + XED_FILE_BOOKMARKS_STORE_NONE = 0, + XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR = 1 << 0, /* Separator item */ + XED_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR = 1 << 1, /* Special user dir */ + XED_FILE_BOOKMARKS_STORE_IS_HOME = 1 << 2, /* The special Home user directory */ + XED_FILE_BOOKMARKS_STORE_IS_DESKTOP = 1 << 3, /* The special Desktop user directory */ + XED_FILE_BOOKMARKS_STORE_IS_DOCUMENTS = 1 << 4, /* The special Documents user directory */ + XED_FILE_BOOKMARKS_STORE_IS_FS = 1 << 5, /* A mount object */ + XED_FILE_BOOKMARKS_STORE_IS_MOUNT = 1 << 6, /* A mount object */ + XED_FILE_BOOKMARKS_STORE_IS_VOLUME = 1 << 7, /* A volume object */ + XED_FILE_BOOKMARKS_STORE_IS_DRIVE = 1 << 8, /* A drive object */ + XED_FILE_BOOKMARKS_STORE_IS_ROOT = 1 << 9, /* The root file system (file:///) */ + XED_FILE_BOOKMARKS_STORE_IS_BOOKMARK = 1 << 10, /* A gtk bookmark */ + XED_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK = 1 << 11, /* A remote gtk bookmark */ + XED_FILE_BOOKMARKS_STORE_IS_LOCAL_BOOKMARK = 1 << 12 /* A local gtk bookmark */ }; -struct _XedFileBookmarksStore +struct _XedFileBookmarksStore { - GtkTreeStore parent; + GtkTreeStore parent; - XedFileBookmarksStorePrivate *priv; + XedFileBookmarksStorePrivate *priv; }; -struct _XedFileBookmarksStoreClass +struct _XedFileBookmarksStoreClass { - GtkTreeStoreClass parent_class; + GtkTreeStoreClass parent_class; }; -GType xed_file_bookmarks_store_get_type (void) G_GNUC_CONST; -GType xed_file_bookmarks_store_register_type (GTypeModule * module); +GType xed_file_bookmarks_store_get_type (void) G_GNUC_CONST; +void _xed_file_bookmarks_store_register_type (GTypeModule *type_module); XedFileBookmarksStore *xed_file_bookmarks_store_new (void); -gchar *xed_file_bookmarks_store_get_uri (XedFileBookmarksStore * model, - GtkTreeIter * iter); -void xed_file_bookmarks_store_refresh (XedFileBookmarksStore * model); +GFile *xed_file_bookmarks_store_get_location (XedFileBookmarksStore * model, + GtkTreeIter * iter); +void xed_file_bookmarks_store_refresh (XedFileBookmarksStore * model); G_END_DECLS -#endif /* __XED_FILE_BOOKMARKS_STORE_H__ */ +#endif /* __XED_FILE_BOOKMARKS_STORE_H__ */ // ex:ts=8:noet: diff --git a/plugins/filebrowser/xed-file-browser-marshal.list b/plugins/filebrowser/xed-file-browser-marshal.list index 5fa72c8..9b24776 100644 --- a/plugins/filebrowser/xed-file-browser-marshal.list +++ b/plugins/filebrowser/xed-file-browser-marshal.list @@ -1,5 +1,5 @@ VOID:UINT,STRING -VOID:STRING,STRING +VOID:OBJECT,OBJECT BOOL:OBJECT,POINTER BOOL:POINTER BOOL:VOID diff --git a/plugins/filebrowser/xed-file-browser-messages.c b/plugins/filebrowser/xed-file-browser-messages.c index 818751c..102027d 100644 --- a/plugins/filebrowser/xed-file-browser-messages.c +++ b/plugins/filebrowser/xed-file-browser-messages.c @@ -2,1032 +2,1029 @@ #include "xed-file-browser-store.h" #include -#define MESSAGE_OBJECT_PATH "/plugins/filebrowser" -#define WINDOW_DATA_KEY "XedFileBrowserMessagesWindowData" +#define MESSAGE_OBJECT_PATH "/plugins/filebrowser" +#define WINDOW_DATA_KEY "XedFileBrowserMessagesWindowData" #define BUS_CONNECT(bus, name, data) xed_message_bus_connect(bus, MESSAGE_OBJECT_PATH, #name, (XedMessageCallback) message_##name##_cb, data, NULL) typedef struct { - XedWindow *window; - XedMessage *message; + XedWindow *window; + XedMessage *message; } MessageCacheData; typedef struct { - guint row_inserted_id; - guint row_deleted_id; - guint root_changed_id; - guint begin_loading_id; - guint end_loading_id; + guint row_inserted_id; + guint row_deleted_id; + guint root_changed_id; + guint begin_loading_id; + guint end_loading_id; - GList *merge_ids; - GtkActionGroup *merged_actions; - - XedMessageBus *bus; - XedFileBrowserWidget *widget; - GHashTable *row_tracking; - - GHashTable *filters; + GList *merge_ids; + GtkActionGroup *merged_actions; + + XedMessageBus *bus; + XedFileBrowserWidget *widget; + GHashTable *row_tracking; + + GHashTable *filters; } WindowData; typedef struct { - gulong id; - - XedWindow *window; - XedMessage *message; + gulong id; + + XedWindow *window; + XedMessage *message; } FilterData; static WindowData * window_data_new (XedWindow *window, - XedFileBrowserWidget *widget) + XedFileBrowserWidget *widget) { - WindowData *data = g_slice_new (WindowData); - GtkUIManager *manager; - GList *groups; - - data->bus = xed_window_get_message_bus (window); - data->widget = widget; - data->row_tracking = g_hash_table_new_full (g_str_hash, - g_str_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)gtk_tree_row_reference_free); + WindowData *data = g_slice_new (WindowData); + GtkUIManager *manager; + GList *groups; - data->filters = g_hash_table_new_full (g_str_hash, - g_str_equal, - (GDestroyNotify)g_free, - NULL); - - manager = xed_file_browser_widget_get_ui_manager (widget); + data->bus = xed_window_get_message_bus (window); + data->widget = widget; + data->row_tracking = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)gtk_tree_row_reference_free); - data->merge_ids = NULL; - data->merged_actions = gtk_action_group_new ("MessageMergedActions"); - - groups = gtk_ui_manager_get_action_groups (manager); - gtk_ui_manager_insert_action_group (manager, data->merged_actions, g_list_length (groups)); - - g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, data); + data->filters = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + NULL); - return data; + manager = xed_file_browser_widget_get_ui_manager (widget); + + data->merge_ids = NULL; + data->merged_actions = gtk_action_group_new ("MessageMergedActions"); + + groups = gtk_ui_manager_get_action_groups (manager); + gtk_ui_manager_insert_action_group (manager, data->merged_actions, g_list_length (groups)); + + g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, data); + + return data; } static WindowData * get_window_data (XedWindow * window) { - return (WindowData *) (g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY)); + return (WindowData *) (g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY)); } static void window_data_free (XedWindow *window) { - WindowData *data = get_window_data (window); - GtkUIManager *manager; - GList *item; - - g_hash_table_destroy (data->row_tracking); - g_hash_table_destroy (data->filters); + WindowData *data = get_window_data (window); + GtkUIManager *manager; + GList *item; - manager = xed_file_browser_widget_get_ui_manager (data->widget); - gtk_ui_manager_remove_action_group (manager, data->merged_actions); - - for (item = data->merge_ids; item; item = item->next) - gtk_ui_manager_remove_ui (manager, GPOINTER_TO_INT (item->data)); + g_hash_table_destroy (data->row_tracking); + g_hash_table_destroy (data->filters); - g_list_free (data->merge_ids); - g_object_unref (data->merged_actions); + manager = xed_file_browser_widget_get_ui_manager (data->widget); + gtk_ui_manager_remove_action_group (manager, data->merged_actions); - g_slice_free (WindowData, data); + for (item = data->merge_ids; item; item = item->next) + gtk_ui_manager_remove_ui (manager, GPOINTER_TO_INT (item->data)); - g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL); + g_list_free (data->merge_ids); + g_object_unref (data->merged_actions); + + g_slice_free (WindowData, data); + + g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL); } static FilterData * -filter_data_new (XedWindow *window, - XedMessage *message) +filter_data_new (XedWindow *window, + XedMessage *message) { - FilterData *data = g_slice_new (FilterData); - WindowData *wdata; - - data->window = window; - data->id = 0; - data->message = message; - - wdata = get_window_data (window); - - g_hash_table_insert (wdata->filters, - xed_message_type_identifier (xed_message_get_object_path (message), - xed_message_get_method (message)), - data); + FilterData *data = g_slice_new (FilterData); + WindowData *wdata; - return data; + data->window = window; + data->id = 0; + data->message = message; + + wdata = get_window_data (window); + + g_hash_table_insert (wdata->filters, + xed_message_type_identifier (xed_message_get_object_path (message), + xed_message_get_method (message)), + data); + + return data; } static void filter_data_free (FilterData *data) { - WindowData *wdata = get_window_data (data->window); - gchar *identifier; - - identifier = xed_message_type_identifier (xed_message_get_object_path (data->message), - xed_message_get_method (data->message)); - - g_hash_table_remove (wdata->filters, identifier); - g_free (identifier); + WindowData *wdata = get_window_data (data->window); + gchar *identifier; - g_object_unref (data->message); - g_slice_free (FilterData, data); + identifier = xed_message_type_identifier (xed_message_get_object_path (data->message), + xed_message_get_method (data->message)); + + g_hash_table_remove (wdata->filters, identifier); + g_free (identifier); + + g_object_unref (data->message); + g_slice_free (FilterData, data); } static GtkTreePath * -track_row_lookup (WindowData *data, - const gchar *id) +track_row_lookup (WindowData *data, + const gchar *id) { - GtkTreeRowReference *ref; - - ref = (GtkTreeRowReference *)g_hash_table_lookup (data->row_tracking, id); - - if (!ref) - return NULL; - - return gtk_tree_row_reference_get_path (ref); + GtkTreeRowReference *ref; + + ref = (GtkTreeRowReference *)g_hash_table_lookup (data->row_tracking, id); + + if (!ref) + return NULL; + + return gtk_tree_row_reference_get_path (ref); } static void message_cache_data_free (MessageCacheData *data) { - g_object_unref (data->message); - g_slice_free (MessageCacheData, data); + g_object_unref (data->message); + g_slice_free (MessageCacheData, data); } static MessageCacheData * message_cache_data_new (XedWindow *window, - XedMessage *message) + XedMessage *message) { - MessageCacheData *data = g_slice_new (MessageCacheData); - - data->window = window; - data->message = message; - - return data; + MessageCacheData *data = g_slice_new (MessageCacheData); + + data->window = window; + data->message = message; + + return data; } static void message_get_root_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - XedFileBrowserStore *store; - gchar *uri; - - store = xed_file_browser_widget_get_browser_store (data->widget); - uri = xed_file_browser_store_get_virtual_root (store); - - xed_message_set (message, "uri", uri, NULL); - g_free (uri); + XedFileBrowserStore *store; + GFile *location; + + store = xed_file_browser_widget_get_browser_store (data->widget); + location = xed_file_browser_store_get_virtual_root (store); + + if (location) + { + xed_message_set (message, "location", location, NULL); + g_object_unref (location); + } } static void message_set_root_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - gchar *root = NULL; - gchar *virtual = NULL; - - xed_message_get (message, "uri", &root, NULL); - - if (!root) - return; - - if (xed_message_has_key (message, "virtual")) - xed_message_get (message, "virtual", &virtual, NULL); + GFile *root; + GFile *virtual = NULL; - if (virtual) - xed_file_browser_widget_set_root_and_virtual_root (data->widget, root, virtual); - else - xed_file_browser_widget_set_root (data->widget, root, TRUE); - - g_free (root); - g_free (virtual); + xed_message_get (message, "location", &root, NULL); + + if (!root) + return; + + if (xed_message_has_key (message, "virtual")) + xed_message_get (message, "virtual", &virtual, NULL); + + if (virtual) + xed_file_browser_widget_set_root_and_virtual_root (data->widget, root, virtual); + else + xed_file_browser_widget_set_root (data->widget, root, TRUE); } static void message_set_emblem_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - gchar *id = NULL; - gchar *emblem = NULL; - GtkTreePath *path; - XedFileBrowserStore *store; - - xed_message_get (message, "id", &id, "emblem", &emblem, NULL); - - if (!id || !emblem) - { - g_free (id); - g_free (emblem); - - return; - } - - path = track_row_lookup (data, id); - - if (path != NULL) - { - GError *error = NULL; - GdkPixbuf *pixbuf; - - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - emblem, - 10, - 0, - &error); - - if (pixbuf) - { - GValue value = { 0, }; - GtkTreeIter iter; - - store = xed_file_browser_widget_get_browser_store (data->widget); - - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) - { - g_value_init (&value, GDK_TYPE_PIXBUF); - g_value_set_object (&value, pixbuf); - - xed_file_browser_store_set_value (store, - &iter, - XED_FILE_BROWSER_STORE_COLUMN_EMBLEM, - &value); - - g_value_unset (&value); - } - - g_object_unref (pixbuf); - } - - if (error) - g_error_free (error); - } - - g_free (id); - g_free (emblem); + gchar *id = NULL; + gchar *emblem = NULL; + GtkTreePath *path; + XedFileBrowserStore *store; + + xed_message_get (message, "id", &id, "emblem", &emblem, NULL); + + if (!id || !emblem) + { + g_free (id); + g_free (emblem); + + return; + } + + path = track_row_lookup (data, id); + + if (path != NULL) + { + GError *error = NULL; + GdkPixbuf *pixbuf; + + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + emblem, + 10, + 0, + &error); + + if (pixbuf) + { + GValue value = { 0, }; + GtkTreeIter iter; + + store = xed_file_browser_widget_get_browser_store (data->widget); + + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) + { + g_value_init (&value, GDK_TYPE_PIXBUF); + g_value_set_object (&value, pixbuf); + + xed_file_browser_store_set_value (store, + &iter, + XED_FILE_BROWSER_STORE_COLUMN_EMBLEM, + &value); + + g_value_unset (&value); + } + + g_object_unref (pixbuf); + } + + if (error) + g_error_free (error); + } + + g_free (id); + g_free (emblem); } static gchar * item_id (const gchar *path, - const gchar *uri) + GFile *location) { - return g_strconcat (path, "::", uri, NULL); + gchar *uri; + gchar *id; + + uri = g_file_get_uri (location); + id = g_strconcat (path, "::", uri, NULL); + g_free (uri); + + return id; } static gchar * track_row (WindowData *data, - XedFileBrowserStore *store, - GtkTreePath *path, - const gchar *uri) + XedFileBrowserStore *store, + GtkTreePath *path, + GFile *location) { - GtkTreeRowReference *ref; - gchar *id; - gchar *pathstr; - - pathstr = gtk_tree_path_to_string (path); - id = item_id (pathstr, uri); - - ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path); - g_hash_table_insert (data->row_tracking, g_strdup (id), ref); - - g_free (pathstr); - - return id; + GtkTreeRowReference *ref; + gchar *id; + gchar *pathstr; + + pathstr = gtk_tree_path_to_string (path); + id = item_id (pathstr, location); + + ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path); + g_hash_table_insert (data->row_tracking, g_strdup (id), ref); + + g_free (pathstr); + + return id; } static void -set_item_message (WindowData *data, - GtkTreeIter *iter, - GtkTreePath *path, - XedMessage *message) +set_item_message (WindowData *data, + GtkTreeIter *iter, + GtkTreePath *path, + XedMessage *message) { - XedFileBrowserStore *store; - gchar *uri = NULL; - guint flags = 0; - gchar *track_id; - - store = xed_file_browser_widget_get_browser_store (data->widget); - - gtk_tree_model_get (GTK_TREE_MODEL (store), iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, - XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, - -1); - - if (!uri) - return; + XedFileBrowserStore *store; + GFile *location; + guint flags = 0; + gchar *track_id; - if (path && gtk_tree_path_get_depth (path) != 0) - track_id = track_row (data, store, path, uri); - else - track_id = NULL; + store = xed_file_browser_widget_get_browser_store (data->widget); - xed_message_set (message, - "id", track_id, - "uri", uri, - NULL); - - if (xed_message_has_key (message, "is_directory")) - { - xed_message_set (message, - "is_directory", FILE_IS_DIR (flags), - NULL); - } + gtk_tree_model_get (GTK_TREE_MODEL (store), iter, + XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, + XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, + -1); - g_free (uri); - g_free (track_id); + if (!location) + return; + + if (path && gtk_tree_path_get_depth (path) != 0) + track_id = track_row (data, store, path, location); + else + track_id = NULL; + + xed_message_set (message, + "id", track_id, + "location", location, + NULL); + + if (xed_message_has_key (message, "is_directory")) + { + xed_message_set (message, + "is_directory", FILE_IS_DIR (flags), + NULL); + } + + g_free (track_id); } static gboolean custom_message_filter_func (XedFileBrowserWidget *widget, - XedFileBrowserStore *store, - GtkTreeIter *iter, - FilterData *data) + XedFileBrowserStore *store, + GtkTreeIter *iter, + FilterData *data) { - WindowData *wdata = get_window_data (data->window); - gchar *uri = NULL; - guint flags = 0; - gboolean filter = FALSE; - GtkTreePath *path; - - gtk_tree_model_get (GTK_TREE_MODEL (store), iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, - XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, - -1); - - if (!uri || FILE_IS_DUMMY (flags)) - { - g_free (uri); - return FALSE; - } - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter); - set_item_message (wdata, iter, path, data->message); - gtk_tree_path_free (path); - - xed_message_set (data->message, "filter", filter, NULL); + WindowData *wdata = get_window_data (data->window); + GFile *location; + guint flags = 0; + gboolean filter = FALSE; + GtkTreePath *path; - xed_message_bus_send_message_sync (wdata->bus, data->message); - xed_message_get (data->message, "filter", &filter, NULL); - - return !filter; + gtk_tree_model_get (GTK_TREE_MODEL (store), iter, + XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, + XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, + -1); + + if (!location || FILE_IS_DUMMY (flags)) + { + return FALSE; + } + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter); + set_item_message (wdata, iter, path, data->message); + gtk_tree_path_free (path); + + xed_message_set (data->message, "filter", filter, NULL); + + xed_message_bus_send_message_sync (wdata->bus, data->message); + xed_message_get (data->message, "filter", &filter, NULL); + + return !filter; } static void message_add_filter_cb (XedMessageBus *bus, - XedMessage *message, - XedWindow *window) + XedMessage *message, + XedWindow *window) { - gchar *object_path = NULL; - gchar *method = NULL; - gulong id; - XedMessageType *message_type; - XedMessage *cbmessage; - FilterData *filter_data; - WindowData *data = get_window_data (window); - - xed_message_get (message, - "object_path", &object_path, - "method", &method, - NULL); - - // Check if there exists such a 'callback' message - if (!object_path || !method) - { - g_free (object_path); - g_free (method); - - return; - } - - message_type = xed_message_bus_lookup (bus, object_path, method); - - if (!message_type) - { - g_free (object_path); - g_free (method); - - return; - } - - // Check if the message type has the correct arguments - if (xed_message_type_lookup (message_type, "id") != G_TYPE_STRING || - xed_message_type_lookup (message_type, "uri") != G_TYPE_STRING || - xed_message_type_lookup (message_type, "is_directory") != G_TYPE_BOOLEAN || - xed_message_type_lookup (message_type, "filter") != G_TYPE_BOOLEAN) - { - return; - } - - cbmessage = xed_message_type_instantiate (message_type, - "id", NULL, - "uri", NULL, - "is_directory", FALSE, - "filter", FALSE, - NULL); + gchar *object_path = NULL; + gchar *method = NULL; + gulong id; + XedMessageType *message_type; + XedMessage *cbmessage; + FilterData *filter_data; + WindowData *data = get_window_data (window); - // Register the custom filter on the widget - filter_data = filter_data_new (window, cbmessage); - id = xed_file_browser_widget_add_filter (data->widget, - (XedFileBrowserWidgetFilterFunc)custom_message_filter_func, - filter_data, - (GDestroyNotify)filter_data_free); + xed_message_get (message, + "object_path", &object_path, + "method", &method, + NULL); - filter_data->id = id; + // Check if there exists such a 'callback' message + if (!object_path || !method) + { + g_free (object_path); + g_free (method); + + return; + } + + message_type = xed_message_bus_lookup (bus, object_path, method); + + if (!message_type) + { + g_free (object_path); + g_free (method); + + return; + } + + // Check if the message type has the correct arguments + if (xed_message_type_lookup (message_type, "id") != G_TYPE_STRING || + xed_message_type_lookup (message_type, "location") != G_TYPE_FILE || + xed_message_type_lookup (message_type, "is_directory") != G_TYPE_BOOLEAN || + xed_message_type_lookup (message_type, "filter") != G_TYPE_BOOLEAN) + { + return; + } + + cbmessage = xed_message_type_instantiate (message_type, + "id", NULL, + "location", NULL, + "is_directory", FALSE, + "filter", FALSE, + NULL); + + // Register the custom filter on the widget + filter_data = filter_data_new (window, cbmessage); + id = xed_file_browser_widget_add_filter (data->widget, + (XedFileBrowserWidgetFilterFunc)custom_message_filter_func, + filter_data, + (GDestroyNotify)filter_data_free); + + filter_data->id = id; } static void message_remove_filter_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - gulong id = 0; - - xed_message_get (message, "id", &id, NULL); - - if (!id) - return; - - xed_file_browser_widget_remove_filter (data->widget, id); + gulong id = 0; + + xed_message_get (message, "id", &id, NULL); + + if (!id) + return; + + xed_file_browser_widget_remove_filter (data->widget, id); } static void message_up_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - XedFileBrowserStore *store = xed_file_browser_widget_get_browser_store (data->widget); - - xed_file_browser_store_set_virtual_root_up (store); + XedFileBrowserStore *store = xed_file_browser_widget_get_browser_store (data->widget); + + xed_file_browser_store_set_virtual_root_up (store); } static void message_history_back_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - xed_file_browser_widget_history_back (data->widget); + xed_file_browser_widget_history_back (data->widget); } static void message_history_forward_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - xed_file_browser_widget_history_forward (data->widget); + xed_file_browser_widget_history_forward (data->widget); } static void message_refresh_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - xed_file_browser_widget_refresh (data->widget); + xed_file_browser_widget_refresh (data->widget); } static void message_set_show_hidden_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - gboolean active = FALSE; - XedFileBrowserStore *store; - XedFileBrowserStoreFilterMode mode; - - xed_message_get (message, "active", &active, NULL); - - store = xed_file_browser_widget_get_browser_store (data->widget); - mode = xed_file_browser_store_get_filter_mode (store); - - if (active) - mode &= ~XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; - else - mode |= XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; + gboolean active = FALSE; + XedFileBrowserStore *store; + XedFileBrowserStoreFilterMode mode; - xed_file_browser_store_set_filter_mode (store, mode); + xed_message_get (message, "active", &active, NULL); + + store = xed_file_browser_widget_get_browser_store (data->widget); + mode = xed_file_browser_store_get_filter_mode (store); + + if (active) + mode &= ~XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; + else + mode |= XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; + + xed_file_browser_store_set_filter_mode (store, mode); } static void message_set_show_binary_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - gboolean active = FALSE; - XedFileBrowserStore *store; - XedFileBrowserStoreFilterMode mode; - - xed_message_get (message, "active", &active, NULL); - - store = xed_file_browser_widget_get_browser_store (data->widget); - mode = xed_file_browser_store_get_filter_mode (store); - - if (active) - mode &= ~XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY; - else - mode |= XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY; + gboolean active = FALSE; + XedFileBrowserStore *store; + XedFileBrowserStoreFilterMode mode; - xed_file_browser_store_set_filter_mode (store, mode); + xed_message_get (message, "active", &active, NULL); + + store = xed_file_browser_widget_get_browser_store (data->widget); + mode = xed_file_browser_store_get_filter_mode (store); + + if (active) + mode &= ~XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY; + else + mode |= XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY; + + xed_file_browser_store_set_filter_mode (store, mode); } static void message_show_bookmarks_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - xed_file_browser_widget_show_bookmarks (data->widget); + xed_file_browser_widget_show_bookmarks (data->widget); } static void message_show_files_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - xed_file_browser_widget_show_files (data->widget); + xed_file_browser_widget_show_files (data->widget); } static void message_add_context_item_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - GtkAction *action = NULL; - gchar *path = NULL; - gchar *name; - GtkUIManager *manager; - guint merge_id; - - xed_message_get (message, - "action", &action, - "path", &path, - NULL); - - if (!action || !path) - { - if (action) - g_object_unref (action); + GtkAction *action = NULL; + gchar *path = NULL; + gchar *name; + GtkUIManager *manager; + guint merge_id; - g_free (path); - return; - } - - gtk_action_group_add_action (data->merged_actions, action); - manager = xed_file_browser_widget_get_ui_manager (data->widget); - name = g_strconcat (gtk_action_get_name (action), "MenuItem", NULL); - merge_id = gtk_ui_manager_new_merge_id (manager); - - gtk_ui_manager_add_ui (manager, - merge_id, - path, - name, - gtk_action_get_name (action), - GTK_UI_MANAGER_AUTO, - FALSE); - - if (gtk_ui_manager_get_widget (manager, path)) - { - data->merge_ids = g_list_prepend (data->merge_ids, GINT_TO_POINTER (merge_id)); - xed_message_set (message, "id", merge_id, NULL); - } - else - { - xed_message_set (message, "id", 0, NULL); - } - - g_object_unref (action); - g_free (path); - g_free (name); + xed_message_get (message, + "action", &action, + "path", &path, + NULL); + + if (!action || !path) + { + if (action) + g_object_unref (action); + + g_free (path); + return; + } + + gtk_action_group_add_action (data->merged_actions, action); + manager = xed_file_browser_widget_get_ui_manager (data->widget); + name = g_strconcat (gtk_action_get_name (action), "MenuItem", NULL); + merge_id = gtk_ui_manager_new_merge_id (manager); + + gtk_ui_manager_add_ui (manager, + merge_id, + path, + name, + gtk_action_get_name (action), + GTK_UI_MANAGER_AUTO, + FALSE); + + if (gtk_ui_manager_get_widget (manager, path)) + { + data->merge_ids = g_list_prepend (data->merge_ids, GINT_TO_POINTER (merge_id)); + xed_message_set (message, "id", merge_id, NULL); + } + else + { + xed_message_set (message, "id", 0, NULL); + } + + g_object_unref (action); + g_free (path); + g_free (name); } static void message_remove_context_item_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - guint merge_id = 0; - GtkUIManager *manager; - - xed_message_get (message, "id", &merge_id, NULL); - - if (merge_id == 0) - return; - - manager = xed_file_browser_widget_get_ui_manager (data->widget); - - data->merge_ids = g_list_remove (data->merge_ids, GINT_TO_POINTER (merge_id)); - gtk_ui_manager_remove_ui (manager, merge_id); + guint merge_id = 0; + GtkUIManager *manager; + + xed_message_get (message, "id", &merge_id, NULL); + + if (merge_id == 0) + return; + + manager = xed_file_browser_widget_get_ui_manager (data->widget); + + data->merge_ids = g_list_remove (data->merge_ids, GINT_TO_POINTER (merge_id)); + gtk_ui_manager_remove_ui (manager, merge_id); } static void message_get_view_cb (XedMessageBus *bus, - XedMessage *message, - WindowData *data) + XedMessage *message, + WindowData *data) { - XedFileBrowserView *view; - view = xed_file_browser_widget_get_browser_view (data->widget); + XedFileBrowserView *view; + view = xed_file_browser_widget_get_browser_view (data->widget); - xed_message_set (message, "view", view, NULL); + xed_message_set (message, "view", view, NULL); } static void register_methods (XedWindow *window, - XedFileBrowserWidget *widget) + XedFileBrowserWidget *widget) { - XedMessageBus *bus = xed_window_get_message_bus (window); - WindowData *data = get_window_data (window); + XedMessageBus *bus = xed_window_get_message_bus (window); + WindowData *data = get_window_data (window); - /* Register method calls */ - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "get_root", - 1, - "uri", G_TYPE_STRING, - NULL); - - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "set_root", - 1, - "uri", G_TYPE_STRING, - "virtual", G_TYPE_STRING, - NULL); - - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "set_emblem", - 0, - "id", G_TYPE_STRING, - "emblem", G_TYPE_STRING, - NULL); - - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "add_filter", - 1, - "object_path", G_TYPE_STRING, - "method", G_TYPE_STRING, - "id", G_TYPE_ULONG, - NULL); - - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "remove_filter", - 0, - "id", G_TYPE_ULONG, - NULL); - - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "add_context_item", - 1, - "action", GTK_TYPE_ACTION, - "path", G_TYPE_STRING, - "id", G_TYPE_UINT, - NULL); + /* Register method calls */ + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "get_root", + 1, + "location", G_TYPE_FILE, + NULL); - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "remove_context_item", - 0, - "id", G_TYPE_UINT, - NULL); - - xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "up", 0, NULL); - - xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "history_back", 0, NULL); - xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "history_forward", 0, NULL); - - xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "refresh", 0, NULL); + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "set_root", + 1, + "location", G_TYPE_FILE, + "virtual", G_TYPE_STRING, + NULL); - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "set_show_hidden", - 0, - "active", G_TYPE_BOOLEAN, - NULL); - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "set_show_binary", - 0, - "active", G_TYPE_BOOLEAN, - NULL); + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "set_emblem", + 0, + "id", G_TYPE_STRING, + "emblem", G_TYPE_STRING, + NULL); - xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "show_bookmarks", 0, NULL); - xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "show_files", 0, NULL); + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "add_filter", + 1, + "object_path", G_TYPE_STRING, + "method", G_TYPE_STRING, + "id", G_TYPE_ULONG, + NULL); - xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "get_view", - 1, - "view", XED_TYPE_FILE_BROWSER_VIEW, - NULL); + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "remove_filter", + 0, + "id", G_TYPE_ULONG, + NULL); - BUS_CONNECT (bus, get_root, data); - BUS_CONNECT (bus, set_root, data); - BUS_CONNECT (bus, set_emblem, data); - BUS_CONNECT (bus, add_filter, window); - BUS_CONNECT (bus, remove_filter, data); + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "add_context_item", + 1, + "action", GTK_TYPE_ACTION, + "path", G_TYPE_STRING, + "id", G_TYPE_UINT, + NULL); - BUS_CONNECT (bus, add_context_item, data); - BUS_CONNECT (bus, remove_context_item, data); + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "remove_context_item", + 0, + "id", G_TYPE_UINT, + NULL); - BUS_CONNECT (bus, up, data); - BUS_CONNECT (bus, history_back, data); - BUS_CONNECT (bus, history_forward, data); + xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "up", 0, NULL); - BUS_CONNECT (bus, refresh, data); - - BUS_CONNECT (bus, set_show_hidden, data); - BUS_CONNECT (bus, set_show_binary, data); - - BUS_CONNECT (bus, show_bookmarks, data); - BUS_CONNECT (bus, show_files, data); + xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "history_back", 0, NULL); + xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "history_forward", 0, NULL); - BUS_CONNECT (bus, get_view, data); + xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "refresh", 0, NULL); + + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "set_show_hidden", + 0, + "active", G_TYPE_BOOLEAN, + NULL); + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "set_show_binary", + 0, + "active", G_TYPE_BOOLEAN, + NULL); + + xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "show_bookmarks", 0, NULL); + xed_message_bus_register (bus, MESSAGE_OBJECT_PATH, "show_files", 0, NULL); + + xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "get_view", + 1, + "view", XED_TYPE_FILE_BROWSER_VIEW, + NULL); + + BUS_CONNECT (bus, get_root, data); + BUS_CONNECT (bus, set_root, data); + BUS_CONNECT (bus, set_emblem, data); + BUS_CONNECT (bus, add_filter, window); + BUS_CONNECT (bus, remove_filter, data); + + BUS_CONNECT (bus, add_context_item, data); + BUS_CONNECT (bus, remove_context_item, data); + + BUS_CONNECT (bus, up, data); + BUS_CONNECT (bus, history_back, data); + BUS_CONNECT (bus, history_forward, data); + + BUS_CONNECT (bus, refresh, data); + + BUS_CONNECT (bus, set_show_hidden, data); + BUS_CONNECT (bus, set_show_binary, data); + + BUS_CONNECT (bus, show_bookmarks, data); + BUS_CONNECT (bus, show_files, data); + + BUS_CONNECT (bus, get_view, data); } static void store_row_inserted (XedFileBrowserStore *store, - GtkTreePath *path, - GtkTreeIter *iter, - MessageCacheData *data) + GtkTreePath *path, + GtkTreeIter *iter, + MessageCacheData *data) { - gchar *uri = NULL; - guint flags = 0; + guint flags = 0; - gtk_tree_model_get (GTK_TREE_MODEL (store), iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, - XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, - -1); - - if (!FILE_IS_DUMMY (flags) && !FILE_IS_FILTERED (flags)) - { - WindowData *wdata = get_window_data (data->window); - - set_item_message (wdata, iter, path, data->message); - xed_message_bus_send_message_sync (wdata->bus, data->message); - } - - g_free (uri); + gtk_tree_model_get (GTK_TREE_MODEL (store), iter, + XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, + -1); + + if (!FILE_IS_DUMMY (flags) && !FILE_IS_FILTERED (flags)) + { + WindowData *wdata = get_window_data (data->window); + + set_item_message (wdata, iter, path, data->message); + xed_message_bus_send_message_sync (wdata->bus, data->message); + } } static void store_row_deleted (XedFileBrowserStore *store, - GtkTreePath *path, - MessageCacheData *data) + GtkTreePath *path, + MessageCacheData *data) { - GtkTreeIter iter; - gchar *uri = NULL; - guint flags = 0; - - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) - return; - - gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, - XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, - -1); - - if (!FILE_IS_DUMMY (flags) && !FILE_IS_FILTERED (flags)) - { - WindowData *wdata = get_window_data (data->window); - - set_item_message (wdata, &iter, path, data->message); - xed_message_bus_send_message_sync (wdata->bus, data->message); - } - - g_free (uri); + GtkTreeIter iter; + guint flags = 0; + + if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) + return; + + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, + XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, + -1); + + if (!FILE_IS_DUMMY (flags) && !FILE_IS_FILTERED (flags)) + { + WindowData *wdata = get_window_data (data->window); + + set_item_message (wdata, &iter, path, data->message); + xed_message_bus_send_message_sync (wdata->bus, data->message); + } } static void store_virtual_root_changed (XedFileBrowserStore *store, - GParamSpec *spec, - MessageCacheData *data) + GParamSpec *spec, + MessageCacheData *data) { - WindowData *wdata = get_window_data (data->window); - gchar *uri; - - uri = xed_file_browser_store_get_virtual_root (store); - - if (!uri) - return; - - xed_message_set (data->message, - "uri", uri, - NULL); - - xed_message_bus_send_message_sync (wdata->bus, data->message); - - g_free (uri); + WindowData *wdata = get_window_data (data->window); + GFile *vroot; + + vroot = xed_file_browser_store_get_virtual_root (store); + + if (!vroot) + return; + + xed_message_set (data->message, + "location", vroot, + NULL); + + xed_message_bus_send_message_sync (wdata->bus, data->message); + + g_object_unref (vroot); } static void store_begin_loading (XedFileBrowserStore *store, - GtkTreeIter *iter, - MessageCacheData *data) + GtkTreeIter *iter, + MessageCacheData *data) { - GtkTreePath *path; - WindowData *wdata = get_window_data (data->window); - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter); - - set_item_message (wdata, iter, path, data->message); - - xed_message_bus_send_message_sync (wdata->bus, data->message); - gtk_tree_path_free (path); + GtkTreePath *path; + WindowData *wdata = get_window_data (data->window); + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter); + + set_item_message (wdata, iter, path, data->message); + + xed_message_bus_send_message_sync (wdata->bus, data->message); + gtk_tree_path_free (path); } static void store_end_loading (XedFileBrowserStore *store, - GtkTreeIter *iter, - MessageCacheData *data) + GtkTreeIter *iter, + MessageCacheData *data) { - GtkTreePath *path; - WindowData *wdata = get_window_data (data->window); - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter); - - set_item_message (wdata, iter, path, data->message); - - xed_message_bus_send_message_sync (wdata->bus, data->message); - gtk_tree_path_free (path); + GtkTreePath *path; + WindowData *wdata = get_window_data (data->window); + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter); + + set_item_message (wdata, iter, path, data->message); + + xed_message_bus_send_message_sync (wdata->bus, data->message); + gtk_tree_path_free (path); } - + static void register_signals (XedWindow *window, - XedFileBrowserWidget *widget) + XedFileBrowserWidget *widget) { - XedMessageBus *bus = xed_window_get_message_bus (window); - XedFileBrowserStore *store; - XedMessageType *inserted_type; - XedMessageType *deleted_type; - XedMessageType *begin_loading_type; - XedMessageType *end_loading_type; - XedMessageType *root_changed_type; - - XedMessage *message; - WindowData *data; + XedMessageBus *bus = xed_window_get_message_bus (window); + XedFileBrowserStore *store; + XedMessageType *inserted_type; + XedMessageType *deleted_type; + XedMessageType *begin_loading_type; + XedMessageType *end_loading_type; + XedMessageType *root_changed_type; - /* Register signals */ - root_changed_type = xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "root_changed", - 0, - "id", G_TYPE_STRING, - "uri", G_TYPE_STRING, - NULL); - - begin_loading_type = xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "begin_loading", - 0, - "id", G_TYPE_STRING, - "uri", G_TYPE_STRING, - NULL); + XedMessage *message; + WindowData *data; - end_loading_type = xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "end_loading", - 0, - "id", G_TYPE_STRING, - "uri", G_TYPE_STRING, - NULL); + /* Register signals */ + root_changed_type = xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "root_changed", + 0, + "id", G_TYPE_STRING, + "location", G_TYPE_FILE, + NULL); - inserted_type = xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "inserted", - 0, - "id", G_TYPE_STRING, - "uri", G_TYPE_STRING, - "is_directory", G_TYPE_BOOLEAN, - NULL); + begin_loading_type = xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "begin_loading", + 0, + "id", G_TYPE_STRING, + "location", G_TYPE_FILE, + NULL); - deleted_type = xed_message_bus_register (bus, - MESSAGE_OBJECT_PATH, "deleted", - 0, - "id", G_TYPE_STRING, - "uri", G_TYPE_STRING, - "is_directory", G_TYPE_BOOLEAN, - NULL); + end_loading_type = xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "end_loading", + 0, + "id", G_TYPE_STRING, + "location", G_TYPE_FILE, + NULL); - store = xed_file_browser_widget_get_browser_store (widget); - - message = xed_message_type_instantiate (inserted_type, - "id", NULL, - "uri", NULL, - "is_directory", FALSE, - NULL); + inserted_type = xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "inserted", + 0, + "id", G_TYPE_STRING, + "location", G_TYPE_FILE, + "is_directory", G_TYPE_BOOLEAN, + NULL); - data = get_window_data (window); + deleted_type = xed_message_bus_register (bus, + MESSAGE_OBJECT_PATH, "deleted", + 0, + "id", G_TYPE_STRING, + "location", G_TYPE_FILE, + "is_directory", G_TYPE_BOOLEAN, + NULL); - data->row_inserted_id = - g_signal_connect_data (store, - "row-inserted", - G_CALLBACK (store_row_inserted), - message_cache_data_new (window, message), - (GClosureNotify)message_cache_data_free, - 0); + store = xed_file_browser_widget_get_browser_store (widget); - message = xed_message_type_instantiate (deleted_type, - "id", NULL, - "uri", NULL, - "is_directory", FALSE, - NULL); - data->row_deleted_id = - g_signal_connect_data (store, - "row-deleted", - G_CALLBACK (store_row_deleted), - message_cache_data_new (window, message), - (GClosureNotify)message_cache_data_free, - 0); - - message = xed_message_type_instantiate (root_changed_type, - "id", NULL, - "uri", NULL, - NULL); - data->root_changed_id = - g_signal_connect_data (store, - "notify::virtual-root", - G_CALLBACK (store_virtual_root_changed), - message_cache_data_new (window, message), - (GClosureNotify)message_cache_data_free, - 0); + message = xed_message_type_instantiate (inserted_type, + "id", NULL, + "location", NULL, + "is_directory", FALSE, + NULL); - message = xed_message_type_instantiate (begin_loading_type, - "id", NULL, - "uri", NULL, - NULL); - data->begin_loading_id = - g_signal_connect_data (store, - "begin_loading", - G_CALLBACK (store_begin_loading), - message_cache_data_new (window, message), - (GClosureNotify)message_cache_data_free, - 0); + data = get_window_data (window); - message = xed_message_type_instantiate (end_loading_type, - "id", NULL, - "uri", NULL, - NULL); - data->end_loading_id = - g_signal_connect_data (store, - "end_loading", - G_CALLBACK (store_end_loading), - message_cache_data_new (window, message), - (GClosureNotify)message_cache_data_free, - 0); + data->row_inserted_id = + g_signal_connect_data (store, + "row-inserted", + G_CALLBACK (store_row_inserted), + message_cache_data_new (window, message), + (GClosureNotify)message_cache_data_free, + 0); + + message = xed_message_type_instantiate (deleted_type, + "id", NULL, + "location", NULL, + "is_directory", FALSE, + NULL); + data->row_deleted_id = + g_signal_connect_data (store, + "row-deleted", + G_CALLBACK (store_row_deleted), + message_cache_data_new (window, message), + (GClosureNotify)message_cache_data_free, + 0); + + message = xed_message_type_instantiate (root_changed_type, + "id", NULL, + "location", NULL, + NULL); + data->root_changed_id = + g_signal_connect_data (store, + "notify::virtual-root", + G_CALLBACK (store_virtual_root_changed), + message_cache_data_new (window, message), + (GClosureNotify)message_cache_data_free, + 0); + + message = xed_message_type_instantiate (begin_loading_type, + "id", NULL, + "location", NULL, + NULL); + data->begin_loading_id = + g_signal_connect_data (store, + "begin_loading", + G_CALLBACK (store_begin_loading), + message_cache_data_new (window, message), + (GClosureNotify)message_cache_data_free, + 0); + + message = xed_message_type_instantiate (end_loading_type, + "id", NULL, + "location", NULL, + NULL); + data->end_loading_id = + g_signal_connect_data (store, + "end_loading", + G_CALLBACK (store_end_loading), + message_cache_data_new (window, message), + (GClosureNotify)message_cache_data_free, + 0); } static void message_unregistered (XedMessageBus *bus, - XedMessageType *message_type, - XedWindow *window) + XedMessageType *message_type, + XedWindow *window) { - gchar *identifier = xed_message_type_identifier (xed_message_type_get_object_path (message_type), - xed_message_type_get_method (message_type)); - FilterData *data; - WindowData *wdata = get_window_data (window); - - data = g_hash_table_lookup (wdata->filters, identifier); - - if (data) - xed_file_browser_widget_remove_filter (wdata->widget, data->id); - - g_free (identifier); + gchar *identifier = xed_message_type_identifier (xed_message_type_get_object_path (message_type), + xed_message_type_get_method (message_type)); + FilterData *data; + WindowData *wdata = get_window_data (window); + + data = g_hash_table_lookup (wdata->filters, identifier); + + if (data) + xed_file_browser_widget_remove_filter (wdata->widget, data->id); + + g_free (identifier); } -void -xed_file_browser_messages_register (XedWindow *window, - XedFileBrowserWidget *widget) +void +xed_file_browser_messages_register (XedWindow *window, + XedFileBrowserWidget *widget) { - window_data_new (window, widget); - - register_methods (window, widget); - register_signals (window, widget); - - g_signal_connect (xed_window_get_message_bus (window), - "unregistered", - G_CALLBACK (message_unregistered), - window); + window_data_new (window, widget); + + register_methods (window, widget); + register_signals (window, widget); + + g_signal_connect (xed_window_get_message_bus (window), + "unregistered", + G_CALLBACK (message_unregistered), + window); } static void cleanup_signals (XedWindow *window) { - WindowData *data = get_window_data (window); - XedFileBrowserStore *store; - - store = xed_file_browser_widget_get_browser_store (data->widget); - - g_signal_handler_disconnect (store, data->row_inserted_id); - g_signal_handler_disconnect (store, data->row_deleted_id); - g_signal_handler_disconnect (store, data->root_changed_id); - g_signal_handler_disconnect (store, data->begin_loading_id); - g_signal_handler_disconnect (store, data->end_loading_id); - - g_signal_handlers_disconnect_by_func (data->bus, message_unregistered, window); + WindowData *data = get_window_data (window); + XedFileBrowserStore *store; + + store = xed_file_browser_widget_get_browser_store (data->widget); + + g_signal_handler_disconnect (store, data->row_inserted_id); + g_signal_handler_disconnect (store, data->row_deleted_id); + g_signal_handler_disconnect (store, data->root_changed_id); + g_signal_handler_disconnect (store, data->begin_loading_id); + g_signal_handler_disconnect (store, data->end_loading_id); + + g_signal_handlers_disconnect_by_func (data->bus, message_unregistered, window); } void xed_file_browser_messages_unregister (XedWindow *window) { - XedMessageBus *bus = xed_window_get_message_bus (window); - - cleanup_signals (window); - xed_message_bus_unregister_all (bus, MESSAGE_OBJECT_PATH); + XedMessageBus *bus = xed_window_get_message_bus (window); - window_data_free (window); + cleanup_signals (window); + xed_message_bus_unregister_all (bus, MESSAGE_OBJECT_PATH); + + window_data_free (window); } diff --git a/plugins/filebrowser/xed-file-browser-plugin.c b/plugins/filebrowser/xed-file-browser-plugin.c index 762c4b6..2556ed4 100644 --- a/plugins/filebrowser/xed-file-browser-plugin.c +++ b/plugins/filebrowser/xed-file-browser-plugin.c @@ -24,13 +24,16 @@ #include #endif -#include -#include -#include +#include #include +#include +#include +#include #include #include -#include +#include +#include +#include #include "xed-file-browser-enum-types.h" #include "xed-file-browser-plugin.h" @@ -39,350 +42,384 @@ #include "xed-file-browser-widget.h" #include "xed-file-browser-messages.h" -#define WINDOW_DATA_KEY "XedFileBrowserPluginWindowData" +#define FILE_BROWSER_SCHEMA "org.x.editor.plugins.filebrowser" +#define FILE_BROWSER_ONLOAD_SCHEMA "org.x.editor.plugins.filebrowser.on-load" -#define FILE_BROWSER_SCHEMA "org.x.editor.plugins.filebrowser" -#define FILE_BROWSER_ONLOAD_SCHEMA "org.x.editor.plugins.filebrowser.on-load" - -#define XED_FILE_BROWSER_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_FILE_BROWSER_PLUGIN, XedFileBrowserPluginPrivate)) +#define XED_FILE_BROWSER_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_FILE_BROWSER_PLUGIN, XedFileBrowserPluginPrivate)) struct _XedFileBrowserPluginPrivate { - gpointer *dummy; + XedWindow *window; + + XedFileBrowserWidget *tree_widget; + gulong merge_id; + GtkActionGroup *action_group; + GtkActionGroup *single_selection_action_group; + gboolean auto_root; + gulong end_loading_handle; + + GSettings *settings; + GSettings *onload_settings; }; -typedef struct _XedFileBrowserPluginData +enum { - XedFileBrowserWidget * tree_widget; - gulong merge_id; - GtkActionGroup * action_group; - GtkActionGroup * single_selection_action_group; - gboolean auto_root; - gulong end_loading_handle; + PROP_0, + PROP_WINDOW +}; - GSettings *settings; - GSettings *onload_settings; -} XedFileBrowserPluginData; +static void on_location_activated_cb (XedFileBrowserWidget *widget, + GFile *location, + XedWindow *window); +static void on_error_cb (XedFileBrowserWidget *widget, + guint code, + gchar const *message, + XedFileBrowserPlugin *plugin); +static void on_model_set_cb (XedFileBrowserView *widget, + GParamSpec *arg1, + XedFileBrowserPlugin *plugin); +static void on_virtual_root_changed_cb (XedFileBrowserStore *model, + GParamSpec *param, + XedFileBrowserPlugin *plugin); +static void on_filter_mode_changed_cb (XedFileBrowserStore *model, + GParamSpec *param, + XedFileBrowserPlugin *plugin); +static void on_rename_cb (XedFileBrowserStore *model, + GFile *oldfile, + GFile *newfile, + XedWindow *window); +static void on_filter_pattern_changed_cb (XedFileBrowserWidget *widget, + GParamSpec *param, + XedFileBrowserPlugin *plugin); +static void on_tab_added_cb (XedWindow *window, + XedTab *tab, + XedFileBrowserPlugin *plugin); +static gboolean on_confirm_delete_cb (XedFileBrowserWidget *widget, + XedFileBrowserStore *store, + GList *rows, + XedFileBrowserPlugin *plugin); +static gboolean on_confirm_no_trash_cb (XedFileBrowserWidget *widget, + GList *files, + XedWindow *window); -static void on_uri_activated_cb (XedFileBrowserWidget * widget, - gchar const *uri, - XedWindow * window); -static void on_error_cb (XedFileBrowserWidget * widget, - guint code, - gchar const *message, - XedWindow * window); -static void on_model_set_cb (XedFileBrowserView * widget, - GParamSpec *arg1, - XedWindow * window); -static void on_virtual_root_changed_cb (XedFileBrowserStore * model, - GParamSpec * param, - XedWindow * window); -static void on_filter_mode_changed_cb (XedFileBrowserStore * model, - GParamSpec * param, - XedWindow * window); -static void on_rename_cb (XedFileBrowserStore * model, - const gchar * olduri, - const gchar * newuri, - XedWindow * window); -static void on_filter_pattern_changed_cb (XedFileBrowserWidget * widget, - GParamSpec * param, - XedWindow * window); -static void on_tab_added_cb (XedWindow * window, - XedTab * tab, - XedFileBrowserPluginData * data); -static gboolean on_confirm_delete_cb (XedFileBrowserWidget * widget, - XedFileBrowserStore * store, - GList * rows, - XedWindow * window); -static gboolean on_confirm_no_trash_cb (XedFileBrowserWidget * widget, - GList * files, - XedWindow * window); +static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface); -XED_PLUGIN_REGISTER_TYPE_WITH_CODE (XedFileBrowserPlugin, filetree_plugin, \ - xed_file_browser_enum_and_flag_register_type (type_module); \ - xed_file_browser_store_register_type (type_module); \ - xed_file_bookmarks_store_register_type (type_module); \ - xed_file_browser_view_register_type (type_module); \ - xed_file_browser_widget_register_type (type_module); \ +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedFileBrowserPlugin, + xed_file_browser_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, + xed_window_activatable_iface_init) \ + \ + xed_file_browser_enum_and_flag_register_type (type_module); \ + _xed_file_browser_store_register_type (type_module); \ + _xed_file_bookmarks_store_register_type (type_module); \ + _xed_file_browser_view_register_type (type_module); \ + _xed_file_browser_widget_register_type (type_module); ) static void -filetree_plugin_init (XedFileBrowserPlugin * plugin) +xed_file_browser_plugin_init (XedFileBrowserPlugin *plugin) { - plugin->priv = XED_FILE_BROWSER_PLUGIN_GET_PRIVATE (plugin); + plugin->priv = XED_FILE_BROWSER_PLUGIN_GET_PRIVATE (plugin); } static void -filetree_plugin_finalize (GObject * object) +xed_file_browser_plugin_dispose (GObject *object) { - //XedFileBrowserPlugin * plugin = XED_FILE_BROWSER_PLUGIN (object); + XedFileBrowserPlugin *plugin = XED_FILE_BROWSER_PLUGIN (object); - G_OBJECT_CLASS (filetree_plugin_parent_class)->finalize (object); -} + g_clear_object (&plugin->priv->window); -static XedFileBrowserPluginData * -get_plugin_data (XedWindow * window) -{ - return (XedFileBrowserPluginData *) (g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY)); + G_OBJECT_CLASS (xed_file_browser_plugin_parent_class)->dispose (object); } static void -on_end_loading_cb (XedFileBrowserStore * store, - GtkTreeIter * iter, - XedFileBrowserPluginData * data) +xed_file_browser_plugin_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - /* Disconnect the signal */ - g_signal_handler_disconnect (store, data->end_loading_handle); - data->end_loading_handle = 0; - data->auto_root = FALSE; + XedFileBrowserPlugin *plugin = XED_FILE_BROWSER_PLUGIN (object); + + switch (prop_id) + { + case PROP_WINDOW: + plugin->priv->window = XED_WINDOW (g_value_dup_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -prepare_auto_root (XedFileBrowserPluginData *data) +xed_file_browser_plugin_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedFileBrowserStore *store; + XedFileBrowserPlugin *plugin = XED_FILE_BROWSER_PLUGIN (object); - data->auto_root = TRUE; - - store = xed_file_browser_widget_get_browser_store (data->tree_widget); - - if (data->end_loading_handle != 0) { - g_signal_handler_disconnect (store, data->end_loading_handle); - data->end_loading_handle = 0; - } - - data->end_loading_handle = g_signal_connect (store, - "end-loading", - G_CALLBACK (on_end_loading_cb), - data); + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, plugin->priv->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -restore_default_location (XedFileBrowserPluginData *data) +on_end_loading_cb (XedFileBrowserStore *store, + GtkTreeIter *iter, + XedFileBrowserPlugin *plugin) { - gchar * root; - gchar * virtual_root; - gboolean bookmarks; - gboolean remote; + XedFileBrowserPluginPrivate *priv = plugin->priv; - bookmarks = !g_settings_get_boolean (data->onload_settings, "tree-view"); - - if (bookmarks) { - xed_file_browser_widget_show_bookmarks (data->tree_widget); - return; - } - - root = g_settings_get_string (data->onload_settings, "root"); - virtual_root = g_settings_get_string (data->onload_settings, "virtual-root"); - - remote = g_settings_get_boolean (data->onload_settings, "enable-remote"); - - if (root != NULL && *root != '\0') { - GFile *file; - - file = g_file_new_for_uri (root); - - if (remote || g_file_is_native (file)) { - if (virtual_root != NULL && *virtual_root != '\0') { - prepare_auto_root (data); - xed_file_browser_widget_set_root_and_virtual_root (data->tree_widget, - root, - virtual_root); - } else { - prepare_auto_root (data); - xed_file_browser_widget_set_root (data->tree_widget, - root, - TRUE); - } - } - - g_object_unref (file); - } - - g_free (root); - g_free (virtual_root); + /* Disconnect the signal */ + g_signal_handler_disconnect (store, priv->end_loading_handle); + priv->end_loading_handle = 0; + priv->auto_root = FALSE; } static void -restore_filter (XedFileBrowserPluginData * data) +prepare_auto_root (XedFileBrowserPlugin *plugin) { - gchar *filter_mode; - XedFileBrowserStoreFilterMode mode; - gchar *pattern; + XedFileBrowserPluginPrivate *priv = plugin->priv; + XedFileBrowserStore *store; - /* Get filter_mode */ - filter_mode = g_settings_get_string (data->settings, "filter-mode"); + priv->auto_root = TRUE; - /* Filter mode */ - mode = xed_file_browser_store_filter_mode_get_default (); + store = xed_file_browser_widget_get_browser_store (priv->tree_widget); - if (filter_mode != NULL) { - if (strcmp (filter_mode, "hidden") == 0) { - mode = XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; - } else if (strcmp (filter_mode, "binary") == 0) { - mode = XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY; - } else if (strcmp (filter_mode, "hidden_and_binary") == 0 || - strcmp (filter_mode, "binary_and_hidden") == 0) { - mode = XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN | - XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY; - } else if (strcmp (filter_mode, "none") == 0 || - *filter_mode == '\0') { - mode = XED_FILE_BROWSER_STORE_FILTER_MODE_NONE; - } - } + if (priv->end_loading_handle != 0) + { + g_signal_handler_disconnect (store, priv->end_loading_handle); + priv->end_loading_handle = 0; + } - /* Set the filter mode */ - xed_file_browser_store_set_filter_mode ( - xed_file_browser_widget_get_browser_store (data->tree_widget), - mode); - - pattern = g_settings_get_string (data->settings, "filter-pattern"); - - xed_file_browser_widget_set_filter_pattern (data->tree_widget, - pattern); - - g_free (filter_mode); - g_free (pattern); + priv->end_loading_handle = g_signal_connect (store, "end-loading", + G_CALLBACK (on_end_loading_cb), plugin); } static void -set_root_from_doc (XedFileBrowserPluginData * data, - XedDocument * doc) +restore_default_location (XedFileBrowserPlugin *plugin) { - GFile *file; - GFile *parent; + XedFileBrowserPluginPrivate *priv = plugin->priv; + gchar *root; + gchar *virtual_root; + gboolean bookmarks; + gboolean remote; - if (doc == NULL) - return; + bookmarks = !g_settings_get_boolean (priv->onload_settings, "tree-view"); - file = xed_document_get_location (doc); - if (file == NULL) - return; + if (bookmarks) + { + xed_file_browser_widget_show_bookmarks (priv->tree_widget); + return; + } - parent = g_file_get_parent (file); + root = g_settings_get_string (priv->onload_settings, "root"); + virtual_root = g_settings_get_string (priv->onload_settings, "virtual-root"); - if (parent != NULL) { - gchar * root; + remote = g_settings_get_boolean (priv->onload_settings, "enable-remote"); - root = g_file_get_uri (parent); + if (root != NULL && *root != '\0') { + GFile *rootfile; + GFile *vrootfile; - xed_file_browser_widget_set_root (data->tree_widget, - root, - TRUE); + rootfile = g_file_new_for_uri (root); + vrootfile = g_file_new_for_uri (virtual_root); - g_object_unref (parent); - g_free (root); - } + if (remote || g_file_is_native (rootfile)) + { + if (virtual_root != NULL && *virtual_root != '\0') + { + prepare_auto_root (plugin); + xed_file_browser_widget_set_root_and_virtual_root (priv->tree_widget, rootfile, vrootfile); + } + else + { + prepare_auto_root (plugin); + xed_file_browser_widget_set_root (priv->tree_widget, rootfile, TRUE); + } + } - g_object_unref (file); + g_object_unref (rootfile); + g_object_unref (vrootfile); + } + + g_free (root); + g_free (virtual_root); } static void -on_action_set_active_root (GtkAction * action, - XedWindow * window) +restore_filter (XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData *data; + XedFileBrowserPluginPrivate *priv = plugin->priv; + gchar *filter_mode; + XedFileBrowserStoreFilterMode mode; + gchar *pattern; - data = get_plugin_data (window); - set_root_from_doc (data, - xed_window_get_active_document (window)); + /* Get filter_mode */ + filter_mode = g_settings_get_string (priv->settings, "filter-mode"); + + /* Filter mode */ + mode = xed_file_browser_store_filter_mode_get_default (); + + if (filter_mode != NULL) { + if (strcmp (filter_mode, "hidden") == 0) { + mode = XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; + } else if (strcmp (filter_mode, "binary") == 0) { + mode = XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY; + } else if (strcmp (filter_mode, "hidden_and_binary") == 0 || + strcmp (filter_mode, "binary_and_hidden") == 0) { + mode = XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN | + XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY; + } else if (strcmp (filter_mode, "none") == 0 || + *filter_mode == '\0') { + mode = XED_FILE_BROWSER_STORE_FILTER_MODE_NONE; + } + } + + /* Set the filter mode */ + xed_file_browser_store_set_filter_mode (xed_file_browser_widget_get_browser_store (priv->tree_widget), mode); + + pattern = g_settings_get_string (priv->settings, "filter-pattern"); + + xed_file_browser_widget_set_filter_pattern (priv->tree_widget, pattern); + + g_free (filter_mode); + g_free (pattern); +} + +static void +set_root_from_doc (XedFileBrowserPlugin *plugin, + XedDocument *doc) +{ + XedFileBrowserPluginPrivate *priv = plugin->priv; + GtkSourceFile *file; + GFile *location; + GFile *parent; + + if (doc == NULL) + { + return; + } + + file = xed_document_get_file (doc); + location = gtk_source_file_get_location (file); + if (location == NULL) + { + return; + } + + parent = g_file_get_parent (location); + + if (parent != NULL) + { + xed_file_browser_widget_set_root (priv->tree_widget, + parent, + TRUE); + + g_object_unref (parent); + } +} + +static void +on_action_set_active_root (GtkAction *action, + XedFileBrowserPlugin *plugin) +{ + set_root_from_doc (plugin, xed_window_get_active_document (XED_WINDOW (plugin->priv->window))); } static gchar * -get_terminal (XedFileBrowserPluginData * data) +get_terminal (XedFileBrowserPlugin *plugin) { - // TODO : Identify the DE, find the preferred terminal application (xterminal shouldn't be hardcoded here, it should be set as default in the DE prefs) - return g_strdup ("xterminal"); + // TODO : Identify the DE, find the preferred terminal application (xterminal shouldn't be hardcoded here, it should be set as default in the DE prefs) + return g_strdup ("xterminal"); } static void -on_action_open_terminal (GtkAction * action, - XedWindow * window) +on_action_open_terminal (GtkAction *action, + XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData * data; - gchar * terminal; - gchar * wd = NULL; - gchar * local; - gchar * argv[2]; - GFile * file; + XedFileBrowserPluginPrivate *priv = plugin->priv; + gchar *terminal; + gchar *local; + gchar *argv[2]; + GFile *file; - GtkTreeIter iter; - XedFileBrowserStore * store; + GtkTreeIter iter; + XedFileBrowserStore *store; - data = get_plugin_data (window); + /* Get the current directory */ + if (!xed_file_browser_widget_get_selected_directory (priv->tree_widget, &iter)) + { + return; + } - /* Get the current directory */ - if (!xed_file_browser_widget_get_selected_directory (data->tree_widget, &iter)) - return; + store = xed_file_browser_widget_get_browser_store (priv->tree_widget); + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &file, -1); - store = xed_file_browser_widget_get_browser_store (data->tree_widget); - gtk_tree_model_get (GTK_TREE_MODEL (store), - &iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, - &wd, - -1); + if (file == NULL) + { + return; + } - if (wd == NULL) - return; + terminal = get_terminal (plugin); - terminal = get_terminal (data); + local = g_file_get_path (file); - file = g_file_new_for_uri (wd); - local = g_file_get_path (file); - g_object_unref (file); + argv[0] = terminal; + argv[1] = NULL; - argv[0] = terminal; - argv[1] = NULL; + g_spawn_async (local, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + NULL); - g_spawn_async (local, - argv, - NULL, - G_SPAWN_SEARCH_PATH, - NULL, - NULL, - NULL, - NULL); - - g_free (terminal); - g_free (wd); - g_free (local); + g_free (terminal); + g_free (local); } static void -on_selection_changed_cb (GtkTreeSelection *selection, - XedWindow *window) +on_selection_changed_cb (GtkTreeSelection *selection, + XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData * data; - GtkTreeView * tree_view; - GtkTreeModel * model; - GtkTreeIter iter; - gboolean sensitive; - gchar * uri; + XedFileBrowserPluginPrivate *priv = plugin->priv; + GtkTreeView *tree_view; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean sensitive; + GFile *location; - data = get_plugin_data (window); + tree_view = GTK_TREE_VIEW (xed_file_browser_widget_get_browser_view (priv->tree_widget)); + model = gtk_tree_view_get_model (tree_view); - tree_view = GTK_TREE_VIEW (xed_file_browser_widget_get_browser_view (data->tree_widget)); - model = gtk_tree_view_get_model (tree_view); + if (!XED_IS_FILE_BROWSER_STORE (model)) + { + return; + } - if (!XED_IS_FILE_BROWSER_STORE (model)) - return; + sensitive = xed_file_browser_widget_get_selected_directory (priv->tree_widget, &iter); - sensitive = xed_file_browser_widget_get_selected_directory (data->tree_widget, &iter); + if (sensitive) + { + gtk_tree_model_get (model, &iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1); - if (sensitive) { - gtk_tree_model_get (model, &iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, - &uri, -1); + sensitive = g_file_has_uri_scheme (location, "file"); + } - sensitive = xed_utils_uri_has_file_scheme (uri); - g_free (uri); - } - - gtk_action_set_sensitive ( - gtk_action_group_get_action (data->single_selection_action_group, - "OpenTerminal"), - sensitive); + gtk_action_set_sensitive (gtk_action_group_get_action (priv->single_selection_action_group, "OpenTerminal"), sensitive); } #define POPUP_UI "" \ @@ -404,588 +441,578 @@ on_selection_changed_cb (GtkTreeSelection *selection, static GtkActionEntry extra_actions[] = { - {"SetActiveRoot", "go-jump-symbolic", N_("_Set root to active document"), - NULL, - N_("Set the root to the active document location"), - G_CALLBACK (on_action_set_active_root)} + {"SetActiveRoot", "go-jump-symbolic", N_("_Set root to active document"), + NULL, + N_("Set the root to the active document location"), + G_CALLBACK (on_action_set_active_root)} }; static GtkActionEntry extra_single_selection_actions[] = { - {"OpenTerminal", "utilities-terminal", N_("_Open terminal here"), - NULL, - N_("Open a terminal at the currently opened directory"), - G_CALLBACK (on_action_open_terminal)} + {"OpenTerminal", "utilities-terminal", N_("_Open terminal here"), + NULL, + N_("Open a terminal at the currently opened directory"), + G_CALLBACK (on_action_open_terminal)} }; static void -add_popup_ui (XedWindow * window) +add_popup_ui (XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData * data; - GtkUIManager * manager; - GtkActionGroup * action_group; - GError * error = NULL; + XedFileBrowserPluginPrivate *priv = plugin->priv; + GtkUIManager * manager; + GtkActionGroup * action_group; + GError * error = NULL; - data = get_plugin_data (window); - manager = xed_file_browser_widget_get_ui_manager (data->tree_widget); + manager = xed_file_browser_widget_get_ui_manager (priv->tree_widget); - action_group = gtk_action_group_new ("FileBrowserPluginExtra"); - gtk_action_group_set_translation_domain (action_group, NULL); - gtk_action_group_add_actions (action_group, - extra_actions, - G_N_ELEMENTS (extra_actions), - window); - gtk_ui_manager_insert_action_group (manager, action_group, 0); - data->action_group = action_group; + action_group = gtk_action_group_new ("FileBrowserPluginExtra"); + gtk_action_group_set_translation_domain (action_group, NULL); + gtk_action_group_add_actions (action_group, + extra_actions, + G_N_ELEMENTS (extra_actions), + plugin); + gtk_ui_manager_insert_action_group (manager, action_group, 0); + priv->action_group = action_group; - action_group = gtk_action_group_new ("FileBrowserPluginSingleSelectionExtra"); - gtk_action_group_set_translation_domain (action_group, NULL); - gtk_action_group_add_actions (action_group, - extra_single_selection_actions, - G_N_ELEMENTS (extra_single_selection_actions), - window); - gtk_ui_manager_insert_action_group (manager, action_group, 0); - data->single_selection_action_group = action_group; + action_group = gtk_action_group_new ("FileBrowserPluginSingleSelectionExtra"); + gtk_action_group_set_translation_domain (action_group, NULL); + gtk_action_group_add_actions (action_group, + extra_single_selection_actions, + G_N_ELEMENTS (extra_single_selection_actions), + priv->window); + gtk_ui_manager_insert_action_group (manager, action_group, 0); + priv->single_selection_action_group = action_group; - data->merge_id = gtk_ui_manager_add_ui_from_string (manager, - POPUP_UI, - -1, - &error); + priv->merge_id = gtk_ui_manager_add_ui_from_string (manager, + POPUP_UI, + -1, + &error); - if (data->merge_id == 0) { - g_warning("Unable to merge UI: %s", error->message); - g_error_free(error); - } + if (priv->merge_id == 0) + { + g_warning("Unable to merge UI: %s", error->message); + g_error_free(error); + } } static void -remove_popup_ui (XedWindow * window) +remove_popup_ui (XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData * data; - GtkUIManager * manager; + XedFileBrowserPluginPrivate *priv = plugin->priv; + GtkUIManager * manager; - data = get_plugin_data (window); - manager = xed_file_browser_widget_get_ui_manager (data->tree_widget); - gtk_ui_manager_remove_ui (manager, data->merge_id); + manager = xed_file_browser_widget_get_ui_manager (priv->tree_widget); + gtk_ui_manager_remove_ui (manager, priv->merge_id); - gtk_ui_manager_remove_action_group (manager, data->action_group); - g_object_unref (data->action_group); + gtk_ui_manager_remove_action_group (manager, priv->action_group); + g_object_unref (priv->action_group); - gtk_ui_manager_remove_action_group (manager, data->single_selection_action_group); - g_object_unref (data->single_selection_action_group); + gtk_ui_manager_remove_action_group (manager, priv->single_selection_action_group); + g_object_unref (priv->single_selection_action_group); } static void -impl_updateui (XedPlugin * plugin, XedWindow * window) +xed_file_browser_plugin_update_state (XedWindowActivatable *activatable) { - XedFileBrowserPluginData * data; - XedDocument * doc; + XedFileBrowserPluginPrivate *priv = XED_FILE_BROWSER_PLUGIN (activatable)->priv; + XedDocument * doc; - data = get_plugin_data (window); + doc = xed_window_get_active_document (XED_WINDOW (priv->window)); - doc = xed_window_get_active_document (window); - - gtk_action_set_sensitive (gtk_action_group_get_action (data->action_group, - "SetActiveRoot"), - doc != NULL && - !xed_document_is_untitled (doc)); + gtk_action_set_sensitive (gtk_action_group_get_action (priv->action_group, + "SetActiveRoot"), + doc != NULL && !xed_document_is_untitled (doc)); } static void -impl_activate (XedPlugin * plugin, XedWindow * window) +xed_file_browser_plugin_activate (XedWindowActivatable *activatable) { - XedPanel * panel; - XedFileBrowserPluginData * data; - GtkWidget * image; - GdkPixbuf * pixbuf; - XedFileBrowserStore * store; - gchar *data_dir; - GSettingsSchemaSource *schema_source; - GSettingsSchema *schema; + XedFileBrowserPlugin *plugin = XED_FILE_BROWSER_PLUGIN (activatable); + XedFileBrowserPluginPrivate *priv; + XedPanel *panel; + XedFileBrowserStore *store; + gchar *data_dir; + GSettingsSchemaSource *schema_source; + GSettingsSchema *schema; - data = g_new0 (XedFileBrowserPluginData, 1); + priv = plugin->priv; - data_dir = xed_plugin_get_data_dir (plugin); - data->tree_widget = XED_FILE_BROWSER_WIDGET (xed_file_browser_widget_new (data_dir)); - g_free (data_dir); + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (activatable)); + priv->tree_widget = XED_FILE_BROWSER_WIDGET (xed_file_browser_widget_new (data_dir)); + g_free (data_dir); - data->settings = g_settings_new (FILE_BROWSER_SCHEMA); - data->onload_settings = g_settings_new (FILE_BROWSER_ONLOAD_SCHEMA); + priv->settings = g_settings_new (FILE_BROWSER_SCHEMA); + priv->onload_settings = g_settings_new (FILE_BROWSER_ONLOAD_SCHEMA); - g_signal_connect (data->tree_widget, - "uri-activated", - G_CALLBACK (on_uri_activated_cb), window); + g_signal_connect (priv->tree_widget, "location-activated", + G_CALLBACK (on_location_activated_cb), priv->window); - g_signal_connect (data->tree_widget, - "error", G_CALLBACK (on_error_cb), window); + g_signal_connect (priv->tree_widget, "error", + G_CALLBACK (on_error_cb), plugin); - g_signal_connect (data->tree_widget, - "notify::filter-pattern", - G_CALLBACK (on_filter_pattern_changed_cb), - window); + g_signal_connect (priv->tree_widget, "notify::filter-pattern", + G_CALLBACK (on_filter_pattern_changed_cb), plugin); - g_signal_connect (data->tree_widget, - "confirm-delete", - G_CALLBACK (on_confirm_delete_cb), - window); + g_signal_connect (priv->tree_widget, "confirm-delete", + G_CALLBACK (on_confirm_delete_cb), plugin); - g_signal_connect (data->tree_widget, - "confirm-no-trash", - G_CALLBACK (on_confirm_no_trash_cb), - window); + g_signal_connect (priv->tree_widget, "confirm-no-trash", + G_CALLBACK (on_confirm_no_trash_cb), priv->window); - g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW - (xed_file_browser_widget_get_browser_view - (data->tree_widget))), - "changed", - G_CALLBACK (on_selection_changed_cb), - window); + g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (xed_file_browser_widget_get_browser_view (priv->tree_widget))), + "changed", G_CALLBACK (on_selection_changed_cb), plugin); - panel = xed_window_get_side_panel (window); - pixbuf = xed_file_browser_utils_pixbuf_from_theme("system-file-manager", - GTK_ICON_SIZE_MENU); + panel = xed_window_get_side_panel (priv->window); + xed_panel_add_item (panel, GTK_WIDGET (priv->tree_widget), _("File Browser"), "system-file-manager"); + gtk_widget_show (GTK_WIDGET (priv->tree_widget)); - if (pixbuf) { - image = gtk_image_new_from_pixbuf(pixbuf); - g_object_unref(pixbuf); - } else { - image = gtk_image_new_from_stock(GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU); - } + add_popup_ui (plugin); - gtk_widget_show(image); - xed_panel_add_item (panel, - GTK_WIDGET (data->tree_widget), - _("File Browser"), - image); - gtk_widget_show (GTK_WIDGET (data->tree_widget)); - g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, data); + /* Restore filter options */ + restore_filter (plugin); - add_popup_ui (window); + /* Connect signals to store the last visited location */ + g_signal_connect (xed_file_browser_widget_get_browser_view (priv->tree_widget), "notify::model", + G_CALLBACK (on_model_set_cb), plugin); - /* Restore filter options */ - restore_filter (data); + store = xed_file_browser_widget_get_browser_store (priv->tree_widget); + g_signal_connect (store, "notify::virtual-root", + G_CALLBACK (on_virtual_root_changed_cb), plugin); - /* Connect signals to store the last visited location */ - g_signal_connect (xed_file_browser_widget_get_browser_view (data->tree_widget), - "notify::model", - G_CALLBACK (on_model_set_cb), - window); + g_signal_connect (store, "notify::filter-mode", + G_CALLBACK (on_filter_mode_changed_cb), plugin); - store = xed_file_browser_widget_get_browser_store (data->tree_widget); - g_signal_connect (store, - "notify::virtual-root", - G_CALLBACK (on_virtual_root_changed_cb), - window); + g_signal_connect (store, "rename", + G_CALLBACK (on_rename_cb), priv->window); - g_signal_connect (store, - "notify::filter-mode", - G_CALLBACK (on_filter_mode_changed_cb), - window); + g_signal_connect (priv->window, "tab-added", + G_CALLBACK (on_tab_added_cb), plugin); - g_signal_connect (store, - "rename", - G_CALLBACK (on_rename_cb), - window); + /* Register messages on the bus */ + xed_file_browser_messages_register (priv->window, priv->tree_widget); - g_signal_connect (window, - "tab-added", - G_CALLBACK (on_tab_added_cb), - data); - - /* Register messages on the bus */ - xed_file_browser_messages_register (window, data->tree_widget); - - impl_updateui (plugin, window); + xed_file_browser_plugin_update_state (activatable); } static void -impl_deactivate (XedPlugin * plugin, XedWindow * window) +xed_file_browser_plugin_deactivate (XedWindowActivatable *activatable) { - XedFileBrowserPluginData * data; - XedPanel * panel; + XedFileBrowserPlugin *plugin = XED_FILE_BROWSER_PLUGIN (activatable); + XedFileBrowserPluginPrivate *priv = plugin->priv; + XedPanel * panel; - data = get_plugin_data (window); + /* Unregister messages from the bus */ + xed_file_browser_messages_unregister (priv->window); - /* Unregister messages from the bus */ - xed_file_browser_messages_unregister (window); + /* Disconnect signals */ + g_signal_handlers_disconnect_by_func (priv->window, G_CALLBACK (on_tab_added_cb), plugin); - /* Disconnect signals */ - g_signal_handlers_disconnect_by_func (window, - G_CALLBACK (on_tab_added_cb), - data); + g_object_unref (priv->settings); + g_object_unref (priv->onload_settings); - g_object_unref (data->settings); - g_object_unref (data->onload_settings); + remove_popup_ui (plugin); - remove_popup_ui (window); - - panel = xed_window_get_side_panel (window); - xed_panel_remove_item (panel, GTK_WIDGET (data->tree_widget)); - - g_free (data); - g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL); + panel = xed_window_get_side_panel (priv->window); + xed_panel_remove_item (panel, GTK_WIDGET (priv->tree_widget)); } static void -filetree_plugin_class_init (XedFileBrowserPluginClass * klass) +xed_file_browser_plugin_class_init (XedFileBrowserPluginClass * klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass * plugin_class = XED_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = filetree_plugin_finalize; + object_class->dispose = xed_file_browser_plugin_dispose; + object_class->set_property = xed_file_browser_plugin_set_property; + object_class->get_property = xed_file_browser_plugin_get_property; - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - plugin_class->update_ui = impl_updateui; + g_object_class_override_property (object_class, PROP_WINDOW, "window"); - g_type_class_add_private (object_class, - sizeof (XedFileBrowserPluginPrivate)); + g_type_class_add_private (object_class, sizeof (XedFileBrowserPluginPrivate)); +} + +static void +xed_window_activatable_iface_init (XedWindowActivatableInterface *iface) +{ + iface->activate = xed_file_browser_plugin_activate; + iface->deactivate = xed_file_browser_plugin_deactivate; + iface->update_state = xed_file_browser_plugin_update_state; +} + +static void +xed_file_browser_plugin_class_finalize (XedFileBrowserPluginClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE_EXTENDED */ } /* Callbacks */ static void -on_uri_activated_cb (XedFileBrowserWidget * tree_widget, - gchar const *uri, XedWindow * window) +on_location_activated_cb (XedFileBrowserWidget *tree_widget, + GFile *location, + XedWindow *window) { - xed_commands_load_uri (window, uri, NULL, 0); + xed_commands_load_location (window, location, NULL, 0); } static void -on_error_cb (XedFileBrowserWidget * tree_widget, - guint code, gchar const *message, XedWindow * window) +on_error_cb (XedFileBrowserWidget *tree_widget, + guint code, + gchar const *message, + XedFileBrowserPlugin *plugin) { - gchar * title; - GtkWidget * dlg; - XedFileBrowserPluginData * data; + XedFileBrowserPluginPrivate *priv = plugin->priv; + gchar * title; + GtkWidget * dlg; - data = get_plugin_data (window); + /* Do not show the error when the root has been set automatically */ + if (priv->auto_root && (code == XED_FILE_BROWSER_ERROR_SET_ROOT || + code == XED_FILE_BROWSER_ERROR_LOAD_DIRECTORY)) + { + /* Show bookmarks */ + xed_file_browser_widget_show_bookmarks (priv->tree_widget); + return; + } - /* Do not show the error when the root has been set automatically */ - if (data->auto_root && (code == XED_FILE_BROWSER_ERROR_SET_ROOT || - code == XED_FILE_BROWSER_ERROR_LOAD_DIRECTORY)) - { - /* Show bookmarks */ - xed_file_browser_widget_show_bookmarks (data->tree_widget); - return; - } + switch (code) { + case XED_FILE_BROWSER_ERROR_NEW_DIRECTORY: + title = _("An error occurred while creating a new directory"); + break; + case XED_FILE_BROWSER_ERROR_NEW_FILE: + title = _("An error occurred while creating a new file"); + break; + case XED_FILE_BROWSER_ERROR_RENAME: + title = _("An error occurred while renaming a file or directory"); + break; + case XED_FILE_BROWSER_ERROR_DELETE: + title = _("An error occurred while deleting a file or directory"); + break; + case XED_FILE_BROWSER_ERROR_OPEN_DIRECTORY: + title = _("An error occurred while opening a directory in the file manager"); + break; + case XED_FILE_BROWSER_ERROR_SET_ROOT: + title = _("An error occurred while setting a root directory"); + break; + case XED_FILE_BROWSER_ERROR_LOAD_DIRECTORY: + title = _("An error occurred while loading a directory"); + break; + default: + title = _("An error occurred"); + break; + } - switch (code) { - case XED_FILE_BROWSER_ERROR_NEW_DIRECTORY: - title = - _("An error occurred while creating a new directory"); - break; - case XED_FILE_BROWSER_ERROR_NEW_FILE: - title = _("An error occurred while creating a new file"); - break; - case XED_FILE_BROWSER_ERROR_RENAME: - title = - _ - ("An error occurred while renaming a file or directory"); - break; - case XED_FILE_BROWSER_ERROR_DELETE: - title = - _ - ("An error occurred while deleting a file or directory"); - break; - case XED_FILE_BROWSER_ERROR_OPEN_DIRECTORY: - title = - _ - ("An error occurred while opening a directory in the file manager"); - break; - case XED_FILE_BROWSER_ERROR_SET_ROOT: - title = - _("An error occurred while setting a root directory"); - break; - case XED_FILE_BROWSER_ERROR_LOAD_DIRECTORY: - title = - _("An error occurred while loading a directory"); - break; - default: - title = _("An error occurred"); - break; - } + dlg = gtk_message_dialog_new (GTK_WINDOW (priv->window), + GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "%s", title); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), "%s", message); - dlg = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_MODAL | - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "%s", title); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), - "%s", message); - - gtk_dialog_run (GTK_DIALOG (dlg)); - gtk_widget_destroy (dlg); + gtk_dialog_run (GTK_DIALOG (dlg)); + gtk_widget_destroy (dlg); } static void -on_model_set_cb (XedFileBrowserView * widget, - GParamSpec *arg1, - XedWindow * window) +on_model_set_cb (XedFileBrowserView *widget, + GParamSpec *arg1, + XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData * data = get_plugin_data (window); - GtkTreeModel * model; + XedFileBrowserPluginPrivate *priv = plugin->priv; + GtkTreeModel * model; - model = gtk_tree_view_get_model (GTK_TREE_VIEW (xed_file_browser_widget_get_browser_view (data->tree_widget))); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (xed_file_browser_widget_get_browser_view (priv->tree_widget))); - if (model == NULL) - return; + if (model == NULL) + { + return; + } - g_settings_set_boolean (data->onload_settings, - "tree-view", - XED_IS_FILE_BROWSER_STORE (model)); + g_settings_set_boolean (priv->onload_settings, "tree-view", XED_IS_FILE_BROWSER_STORE (model)); } static void -on_filter_mode_changed_cb (XedFileBrowserStore * model, - GParamSpec * param, - XedWindow * window) +on_filter_mode_changed_cb (XedFileBrowserStore *model, + GParamSpec *param, + XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData * data = get_plugin_data (window); - XedFileBrowserStoreFilterMode mode; + XedFileBrowserPluginPrivate *priv = plugin->priv; + XedFileBrowserStoreFilterMode mode; - mode = xed_file_browser_store_get_filter_mode (model); + mode = xed_file_browser_store_get_filter_mode (model); - if ((mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN) && - (mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY)) { - g_settings_set_string (data->settings, "filter-mode", "hidden_and_binary"); - } else if (mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN) { - g_settings_set_string (data->settings, "filter-mode", "hidden"); - } else if (mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY) { - g_settings_set_string (data->settings, "filter-mode", "binary"); - } else { - g_settings_set_string (data->settings, "filter-mode", "none"); - } + if ((mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN) && + (mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY)) + { + g_settings_set_string (priv->settings, "filter-mode", "hidden_and_binary"); + } + else if (mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN) + { + g_settings_set_string (priv->settings, "filter-mode", "hidden"); + } + else if (mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY) + { + g_settings_set_string (priv->settings, "filter-mode", "binary"); + }else + { + g_settings_set_string (priv->settings, "filter-mode", "none"); + } } static void -on_rename_cb (XedFileBrowserStore * store, - const gchar * olduri, - const gchar * newuri, - XedWindow * window) +on_rename_cb (XedFileBrowserStore *store, + GFile *oldfile, + GFile *newfile, + XedWindow *window) { - XedApp * app; - GList * documents; - GList * item; - XedDocument * doc; - GFile * docfile; - GFile * oldfile; - GFile * newfile; - gchar * uri; + GList *documents; + GList *item; - /* Find all documents and set its uri to newuri where it matches olduri */ - app = xed_app_get_default (); - documents = xed_app_get_documents (app); + /* Find all documents and set its uri to newuri where it matches olduri */ + documents = xed_app_get_documents (XED_APP (g_application_get_default ())); - oldfile = g_file_new_for_uri (olduri); - newfile = g_file_new_for_uri (newuri); + for (item = documents; item; item = item->next) + { + XedDocument *doc; + GtkSourceFile *source_file; + GFile *docfile; - for (item = documents; item; item = item->next) { - doc = XED_DOCUMENT (item->data); - uri = xed_document_get_uri (doc); + doc = XED_DOCUMENT (item->data); + source_file = xed_document_get_file (doc); + docfile = gtk_source_file_get_location (source_file); - if (!uri) - continue; + if (docfile == NULL) + { + continue; + } - docfile = g_file_new_for_uri (uri); + if (g_file_equal (docfile, oldfile)) + { + gtk_source_file_set_location (source_file, newfile); + } + else + { + gchar *relative; - if (g_file_equal (docfile, oldfile)) { - xed_document_set_uri (doc, newuri); - } else { - gchar *relative; + relative = g_file_get_relative_path (oldfile, docfile); - relative = g_file_get_relative_path (oldfile, docfile); + if (relative != NULL) + { + /* relative now contains the part in docfile without + the prefix oldfile */ - if (relative) { - /* relative now contains the part in docfile without - the prefix oldfile */ + docfile = g_file_get_child (newfile, relative); - g_object_unref (docfile); - g_free (uri); + gtk_source_file_set_location (source_file, docfile); - docfile = g_file_get_child (newfile, relative); - uri = g_file_get_uri (docfile); + g_object_unref (docfile); + } - xed_document_set_uri (doc, uri); - } + g_free (relative); + } + } - g_free (relative); - } - - g_free (uri); - g_object_unref (docfile); - } - - g_object_unref (oldfile); - g_object_unref (newfile); - - g_list_free (documents); + g_list_free (documents); } static void -on_filter_pattern_changed_cb (XedFileBrowserWidget * widget, - GParamSpec * param, - XedWindow * window) +on_filter_pattern_changed_cb (XedFileBrowserWidget *widget, + GParamSpec *param, + XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData * data = get_plugin_data (window); - gchar * pattern; + XedFileBrowserPluginPrivate *priv = plugin->priv; + gchar * pattern; - g_object_get (G_OBJECT (widget), "filter-pattern", &pattern, NULL); + g_object_get (G_OBJECT (widget), "filter-pattern", &pattern, NULL); - if (pattern == NULL) - g_settings_set_string (data->settings, "filter-pattern", ""); - else - g_settings_set_string (data->settings, "filter-pattern", pattern); + if (pattern == NULL) + { + g_settings_set_string (priv->settings, "filter-pattern", ""); + } + else + { + g_settings_set_string (priv->settings, "filter-pattern", pattern); + } - g_free (pattern); + g_free (pattern); } static void -on_virtual_root_changed_cb (XedFileBrowserStore * store, - GParamSpec * param, - XedWindow * window) +on_virtual_root_changed_cb (XedFileBrowserStore *store, + GParamSpec *param, + XedFileBrowserPlugin *plugin) { - XedFileBrowserPluginData * data = get_plugin_data (window); - gchar * root; - gchar * virtual_root; + XedFileBrowserPluginPrivate *priv = plugin->priv; + GFile *root; + GFile *virtual_root; + gchar *uri_root = NULL; - root = xed_file_browser_store_get_root (store); + root = xed_file_browser_store_get_root (store); - if (!root) - return; + if (!root) + { + return; + } + else + { + uri_root = g_file_get_uri (root); + g_object_unref (root); + } - g_settings_set_string (data->onload_settings, "root", root); + g_settings_set_string (priv->onload_settings, "root", uri_root); + g_free (uri_root); - virtual_root = xed_file_browser_store_get_virtual_root (store); + virtual_root = xed_file_browser_store_get_virtual_root (store); - if (!virtual_root) { - /* Set virtual to same as root then */ - g_settings_set_string (data->onload_settings, "virtual-root", root); - } else { - g_settings_set_string (data->onload_settings, "virtual-root", virtual_root); - } + if (!virtual_root) + { + /* Set virtual to same as root then */ + g_settings_set_string (priv->onload_settings, "virtual-root", uri_root); + } + else + { + gchar *uri_vroot; - g_signal_handlers_disconnect_by_func (window, - G_CALLBACK (on_tab_added_cb), - data); + uri_vroot = g_file_get_uri (virtual_root); - g_free (root); - g_free (virtual_root); + g_settings_set_string (priv->onload_settings, "virtual-root", uri_vroot); + + g_free (uri_vroot); + g_object_unref (virtual_root); + } + + g_signal_handlers_disconnect_by_func (XED_WINDOW (priv->window), G_CALLBACK (on_tab_added_cb), plugin); } static void -on_tab_added_cb (XedWindow * window, - XedTab * tab, - XedFileBrowserPluginData * data) +on_tab_added_cb (XedWindow *window, + XedTab *tab, + XedFileBrowserPlugin *plugin) { - gboolean open; - gboolean load_default = TRUE; + XedFileBrowserPluginPrivate *priv = plugin->priv; + gboolean open; + gboolean load_default = TRUE; - open = g_settings_get_boolean (data->settings, "open-at-first-doc"); + open = g_settings_get_boolean (priv->settings, "open-at-first-doc"); - if (open) { - XedDocument *doc; - gchar *uri; + if (open) + { + XedDocument *doc; + GtkSourceFile *file; + GFile *location; - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); + file = xed_document_get_file (doc); + location = gtk_source_file_get_location (file); - uri = xed_document_get_uri (doc); + if (location != NULL) + { + if (g_file_has_uri_scheme (location, "file")) + { + prepare_auto_root (plugin); + set_root_from_doc (plugin, doc); + load_default = FALSE; + } + } + } - if (uri != NULL && xed_utils_uri_has_file_scheme (uri)) { - prepare_auto_root (data); - set_root_from_doc (data, doc); - load_default = FALSE; - } + if (load_default) + { + restore_default_location (plugin); + } - g_free (uri); - } - - if (load_default) - restore_default_location (data); - - /* Disconnect this signal, it's only called once */ - g_signal_handlers_disconnect_by_func (window, - G_CALLBACK (on_tab_added_cb), - data); + /* Disconnect this signal, it's only called once */ + g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_tab_added_cb), plugin); } static gchar * -get_filename_from_path (GtkTreeModel *model, GtkTreePath *path) +get_filename_from_path (GtkTreeModel *model, + GtkTreePath *path) { - GtkTreeIter iter; - gchar *uri; + GtkTreeIter iter; + GFile *location; - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, - -1); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1); - return xed_file_browser_utils_uri_basename (uri); + return xed_file_browser_utils_file_basename (location); } static gboolean -on_confirm_no_trash_cb (XedFileBrowserWidget * widget, - GList * files, - XedWindow * window) +on_confirm_no_trash_cb (XedFileBrowserWidget *widget, + GList *files, + XedWindow *window) { - gchar *normal; - gchar *message; - gchar *secondary; - gboolean result; + gchar *normal; + gchar *message; + gchar *secondary; + gboolean result; - message = _("Cannot move file to trash, do you\nwant to delete permanently?"); + message = _("Cannot move file to trash, do you\nwant to delete permanently?"); - if (files->next == NULL) { - normal = xed_file_browser_utils_file_basename (G_FILE (files->data)); - secondary = g_strdup_printf (_("The file \"%s\" cannot be moved to the trash."), normal); - g_free (normal); - } else { - secondary = g_strdup (_("The selected files cannot be moved to the trash.")); - } + if (files->next == NULL) + { + normal = xed_file_browser_utils_file_basename (G_FILE (files->data)); + secondary = g_strdup_printf (_("The file \"%s\" cannot be moved to the trash."), normal); + g_free (normal); + } + else + { + secondary = g_strdup (_("The selected files cannot be moved to the trash.")); + } - result = xed_file_browser_utils_confirmation_dialog (window, - GTK_MESSAGE_QUESTION, - message, - secondary, - GTK_STOCK_DELETE, - NULL); - g_free (secondary); + result = xed_file_browser_utils_confirmation_dialog (window, + GTK_MESSAGE_QUESTION, + message, + secondary, + GTK_STOCK_DELETE, + NULL); + g_free (secondary); - return result; + return result; } static gboolean on_confirm_delete_cb (XedFileBrowserWidget *widget, - XedFileBrowserStore *store, - GList *paths, - XedWindow *window) + XedFileBrowserStore *store, + GList *paths, + XedFileBrowserPlugin *plugin) { - gchar *normal; - gchar *message; - gchar *secondary; - gboolean result; - XedFileBrowserPluginData *data; + XedFileBrowserPluginPrivate *priv = plugin->priv; + gchar *normal; + gchar *message; + gchar *secondary; + gboolean result; - data = get_plugin_data (window); + if (paths->next == NULL) + { + normal = get_filename_from_path (GTK_TREE_MODEL (store), (GtkTreePath *)(paths->data)); + message = g_strdup_printf (_("Are you sure you want to permanently delete \"%s\"?"), normal); + g_free (normal); + } + else + { + message = g_strdup (_("Are you sure you want to permanently delete the selected files?")); + } - if (paths->next == NULL) { - normal = get_filename_from_path (GTK_TREE_MODEL (store), (GtkTreePath *)(paths->data)); - message = g_strdup_printf (_("Are you sure you want to permanently delete \"%s\"?"), normal); - g_free (normal); - } else { - message = g_strdup (_("Are you sure you want to permanently delete the selected files?")); - } + secondary = _("If you delete an item, it is permanently lost."); - secondary = _("If you delete an item, it is permanently lost."); + result = xed_file_browser_utils_confirmation_dialog (XED_WINDOW (priv->window), + GTK_MESSAGE_QUESTION, + message, + secondary, + GTK_STOCK_DELETE, + NULL); - result = xed_file_browser_utils_confirmation_dialog (window, - GTK_MESSAGE_QUESTION, - message, - secondary, - GTK_STOCK_DELETE, - NULL); + g_free (message); - g_free (message); + return result; +} - return result; +G_MODULE_EXPORT void +peas_register_types (PeasObjectModule *module) +{ + xed_file_browser_plugin_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + XED_TYPE_WINDOW_ACTIVATABLE, + XED_TYPE_FILE_BROWSER_PLUGIN); } // ex:ts=8:noet: diff --git a/plugins/filebrowser/xed-file-browser-plugin.h b/plugins/filebrowser/xed-file-browser-plugin.h index e7188e1..c4f0c03 100644 --- a/plugins/filebrowser/xed-file-browser-plugin.h +++ b/plugins/filebrowser/xed-file-browser-plugin.h @@ -1,5 +1,5 @@ /* - * xed-file-browser-plugin.h - Xed plugin providing easy file access + * xed-file-browser-plugin.h - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -24,46 +24,48 @@ #include #include -#include +#include +#include G_BEGIN_DECLS + /* * Type checking and casting macros */ -#define XED_TYPE_FILE_BROWSER_PLUGIN (filetree_plugin_get_type ()) -#define XED_FILE_BROWSER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_FILE_BROWSER_PLUGIN, XedFileBrowserPlugin)) -#define XED_FILE_BROWSER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_FILE_BROWSER_PLUGIN, XedFileBrowserPluginClass)) -#define XED_IS_FILE_BROWSER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_FILE_BROWSER_PLUGIN)) -#define XED_IS_FILE_BROWSER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_FILE_BROWSER_PLUGIN)) -#define XED_FILE_BROWSER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_FILE_BROWSER_PLUGIN, XedFileBrowserPluginClass)) +#define XED_TYPE_FILE_BROWSER_PLUGIN (xed_file_browser_plugin_get_type ()) +#define XED_FILE_BROWSER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_FILE_BROWSER_PLUGIN, XedFileBrowserPlugin)) +#define XED_FILE_BROWSER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_FILE_BROWSER_PLUGIN, XedFileBrowserPluginClass)) +#define XED_IS_FILE_BROWSER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_FILE_BROWSER_PLUGIN)) +#define XED_IS_FILE_BROWSER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_FILE_BROWSER_PLUGIN)) +#define XED_FILE_BROWSER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_FILE_BROWSER_PLUGIN, XedFileBrowserPluginClass)) /* Private structure type */ typedef struct _XedFileBrowserPluginPrivate XedFileBrowserPluginPrivate; typedef struct _XedFileBrowserPlugin XedFileBrowserPlugin; typedef struct _XedFileBrowserPluginClass XedFileBrowserPluginClass; -struct _XedFileBrowserPlugin +struct _XedFileBrowserPlugin { - XedPlugin parent_instance; + PeasExtensionBase parent_instance; - /*< private > */ - XedFileBrowserPluginPrivate *priv; + /*< private > */ + XedFileBrowserPluginPrivate *priv; }; -struct _XedFileBrowserPluginClass +struct _XedFileBrowserPluginClass { - XedPluginClass parent_class; + PeasExtensionBaseClass parent_class; }; /* * Public methods */ -GType filetree_plugin_get_type (void) G_GNUC_CONST; +GType xed_file_browser_plugin_get_type (void) G_GNUC_CONST; /* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule * module); +G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); G_END_DECLS #endif /* __XED_FILE_BROWSER_PLUGIN_H__ */ diff --git a/plugins/filebrowser/xed-file-browser-store.c b/plugins/filebrowser/xed-file-browser-store.c index c29adc6..dbd083c 100644 --- a/plugins/filebrowser/xed-file-browser-store.c +++ b/plugins/filebrowser/xed-file-browser-store.c @@ -1,5 +1,5 @@ /* - * xed-file-browser-store.c - Xed plugin providing easy file access + * xed-file-browser-store.c - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "xed-file-browser-store.h" @@ -36,197 +35,195 @@ #include "xed-file-browser-utils.h" #define XED_FILE_BROWSER_STORE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), \ - XED_TYPE_FILE_BROWSER_STORE, \ - XedFileBrowserStorePrivate)) + XED_TYPE_FILE_BROWSER_STORE, \ + XedFileBrowserStorePrivate)) -#define NODE_IS_DIR(node) (FILE_IS_DIR((node)->flags)) -#define NODE_IS_HIDDEN(node) (FILE_IS_HIDDEN((node)->flags)) -#define NODE_IS_TEXT(node) (FILE_IS_TEXT((node)->flags)) -#define NODE_LOADED(node) (FILE_LOADED((node)->flags)) -#define NODE_IS_FILTERED(node) (FILE_IS_FILTERED((node)->flags)) -#define NODE_IS_DUMMY(node) (FILE_IS_DUMMY((node)->flags)) +#define NODE_IS_DIR(node) (FILE_IS_DIR((node)->flags)) +#define NODE_IS_HIDDEN(node) (FILE_IS_HIDDEN((node)->flags)) +#define NODE_IS_TEXT(node) (FILE_IS_TEXT((node)->flags)) +#define NODE_LOADED(node) (FILE_LOADED((node)->flags)) +#define NODE_IS_FILTERED(node) (FILE_IS_FILTERED((node)->flags)) +#define NODE_IS_DUMMY(node) (FILE_IS_DUMMY((node)->flags)) -#define FILE_BROWSER_NODE_DIR(node) ((FileBrowserNodeDir *)(node)) +#define FILE_BROWSER_NODE_DIR(node) ((FileBrowserNodeDir *)(node)) #define DIRECTORY_LOAD_ITEMS_PER_CALLBACK 100 #define STANDARD_ATTRIBUTE_TYPES G_FILE_ATTRIBUTE_STANDARD_TYPE "," \ - G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," \ - G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP "," \ - G_FILE_ATTRIBUTE_STANDARD_NAME "," \ - G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \ - G_FILE_ATTRIBUTE_STANDARD_ICON + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," \ + G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP "," \ + G_FILE_ATTRIBUTE_STANDARD_NAME "," \ + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \ + G_FILE_ATTRIBUTE_STANDARD_ICON typedef struct _FileBrowserNode FileBrowserNode; typedef struct _FileBrowserNodeDir FileBrowserNodeDir; -typedef struct _AsyncData AsyncData; -typedef struct _AsyncNode AsyncNode; +typedef struct _AsyncData AsyncData; +typedef struct _AsyncNode AsyncNode; -typedef gint (*SortFunc) (FileBrowserNode * node1, - FileBrowserNode * node2); +typedef gint (*SortFunc) (FileBrowserNode *node1, FileBrowserNode *node2); struct _AsyncData { - XedFileBrowserStore * model; - GCancellable * cancellable; - gboolean trash; - GList * files; - GList * iter; - gboolean removed; + XedFileBrowserStore *model; + GCancellable *cancellable; + gboolean trash; + GList *files; + GList *iter; + gboolean removed; }; struct _AsyncNode { - FileBrowserNodeDir *dir; - GCancellable *cancellable; - GSList *original_children; + FileBrowserNodeDir *dir; + GCancellable *cancellable; + GSList *original_children; }; typedef struct { - XedFileBrowserStore * model; - gchar * virtual_root; - GMountOperation * operation; - GCancellable * cancellable; + XedFileBrowserStore *model; + GFile *virtual_root; + GMountOperation *operation; + GCancellable *cancellable; } MountInfo; -struct _FileBrowserNode +struct _FileBrowserNode { - GFile *file; - guint flags; - gchar *name; + GFile *file; + guint flags; + gchar *name; - GdkPixbuf *icon; - GdkPixbuf *emblem; + GdkPixbuf *icon; + GdkPixbuf *emblem; - FileBrowserNode *parent; - gint pos; - gboolean inserted; + FileBrowserNode *parent; + gint pos; + gboolean inserted; }; -struct _FileBrowserNodeDir +struct _FileBrowserNodeDir { - FileBrowserNode node; - GSList *children; - GHashTable *hidden_file_hash; + FileBrowserNode node; + GSList *children; + GHashTable *hidden_file_hash; - GCancellable *cancellable; - GFileMonitor *monitor; - XedFileBrowserStore *model; + GCancellable *cancellable; + GFileMonitor *monitor; + XedFileBrowserStore *model; }; -struct _XedFileBrowserStorePrivate +struct _XedFileBrowserStorePrivate { - FileBrowserNode *root; - FileBrowserNode *virtual_root; - GType column_types[XED_FILE_BROWSER_STORE_COLUMN_NUM]; + FileBrowserNode *root; + FileBrowserNode *virtual_root; + GType column_types[XED_FILE_BROWSER_STORE_COLUMN_NUM]; - XedFileBrowserStoreFilterMode filter_mode; - XedFileBrowserStoreFilterFunc filter_func; - gpointer filter_user_data; + XedFileBrowserStoreFilterMode filter_mode; + XedFileBrowserStoreFilterFunc filter_func; + gpointer filter_user_data; - SortFunc sort_func; + SortFunc sort_func; - GSList *async_handles; - MountInfo *mount_info; + GSList *async_handles; + MountInfo *mount_info; }; -static FileBrowserNode *model_find_node (XedFileBrowserStore *model, - FileBrowserNode *node, - GFile *uri); -static void model_remove_node (XedFileBrowserStore * model, - FileBrowserNode * node, - GtkTreePath * path, - gboolean free_nodes); +static FileBrowserNode *model_find_node (XedFileBrowserStore *model, + FileBrowserNode *node, + GFile *uri); +static void model_remove_node (XedFileBrowserStore *model, + FileBrowserNode *node, + GtkTreePath *path, + gboolean free_nodes); -static void set_virtual_root_from_node (XedFileBrowserStore * model, - FileBrowserNode * node); +static void set_virtual_root_from_node (XedFileBrowserStore *model, + FileBrowserNode *node); -static void xed_file_browser_store_iface_init (GtkTreeModelIface * iface); -static GtkTreeModelFlags xed_file_browser_store_get_flags (GtkTreeModel * tree_model); -static gint xed_file_browser_store_get_n_columns (GtkTreeModel * tree_model); -static GType xed_file_browser_store_get_column_type (GtkTreeModel * tree_model, - gint index); -static gboolean xed_file_browser_store_get_iter (GtkTreeModel * tree_model, - GtkTreeIter * iter, - GtkTreePath * path); -static GtkTreePath *xed_file_browser_store_get_path (GtkTreeModel * tree_model, - GtkTreeIter * iter); -static void xed_file_browser_store_get_value (GtkTreeModel * tree_model, - GtkTreeIter * iter, - gint column, - GValue * value); -static gboolean xed_file_browser_store_iter_next (GtkTreeModel * tree_model, - GtkTreeIter * iter); -static gboolean xed_file_browser_store_iter_children (GtkTreeModel * tree_model, - GtkTreeIter * iter, - GtkTreeIter * parent); -static gboolean xed_file_browser_store_iter_has_child (GtkTreeModel * tree_model, - GtkTreeIter * iter); -static gint xed_file_browser_store_iter_n_children (GtkTreeModel * tree_model, - GtkTreeIter * iter); +static void xed_file_browser_store_iface_init (GtkTreeModelIface *iface); +static GtkTreeModelFlags xed_file_browser_store_get_flags (GtkTreeModel *tree_model); +static gint xed_file_browser_store_get_n_columns (GtkTreeModel *tree_model); +static GType xed_file_browser_store_get_column_type (GtkTreeModel *tree_model, + gint index); +static gboolean xed_file_browser_store_get_iter (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreePath *path); +static GtkTreePath *xed_file_browser_store_get_path (GtkTreeModel *tree_model, + GtkTreeIter *iter); +static void xed_file_browser_store_get_value (GtkTreeModel *tree_model, + GtkTreeIter *iter, + gint column, + GValue *value); +static gboolean xed_file_browser_store_iter_next (GtkTreeModel *tree_model, + GtkTreeIter *iter); +static gboolean xed_file_browser_store_iter_children (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreeIter *parent); +static gboolean xed_file_browser_store_iter_has_child (GtkTreeModel *tree_model, + GtkTreeIter *iter); +static gint xed_file_browser_store_iter_n_children (GtkTreeModel *tree_model, + GtkTreeIter * iter); static gboolean xed_file_browser_store_iter_nth_child (GtkTreeModel * tree_model, - GtkTreeIter * iter, - GtkTreeIter * parent, - gint n); + GtkTreeIter * iter, + GtkTreeIter * parent, + gint n); static gboolean xed_file_browser_store_iter_parent (GtkTreeModel * tree_model, - GtkTreeIter * iter, - GtkTreeIter * child); -static void xed_file_browser_store_row_inserted (GtkTreeModel * tree_model, - GtkTreePath * path, - GtkTreeIter * iter); + GtkTreeIter * iter, + GtkTreeIter * child); +static void xed_file_browser_store_row_inserted (GtkTreeModel * tree_model, + GtkTreePath * path, + GtkTreeIter * iter); static void xed_file_browser_store_drag_source_init (GtkTreeDragSourceIface * iface); static gboolean xed_file_browser_store_row_draggable (GtkTreeDragSource * drag_source, - GtkTreePath * path); + GtkTreePath * path); static gboolean xed_file_browser_store_drag_data_delete (GtkTreeDragSource * drag_source, - GtkTreePath * path); + GtkTreePath * path); static gboolean xed_file_browser_store_drag_data_get (GtkTreeDragSource * drag_source, - GtkTreePath * path, - GtkSelectionData * selection_data); + GtkTreePath * path, + GtkSelectionData * selection_data); static void file_browser_node_free (XedFileBrowserStore * model, - FileBrowserNode * node); + FileBrowserNode * node); static void model_add_node (XedFileBrowserStore * model, - FileBrowserNode * child, - FileBrowserNode * parent); + FileBrowserNode * child, + FileBrowserNode * parent); static void model_clear (XedFileBrowserStore * model, - gboolean free_nodes); + gboolean free_nodes); static gint model_sort_default (FileBrowserNode * node1, - FileBrowserNode * node2); + FileBrowserNode * node2); static void model_check_dummy (XedFileBrowserStore * model, - FileBrowserNode * node); -static void next_files_async (GFileEnumerator * enumerator, - AsyncNode * async); + FileBrowserNode * node); +static void next_files_async (GFileEnumerator * enumerator, + AsyncNode * async); -XED_PLUGIN_DEFINE_TYPE_WITH_CODE (XedFileBrowserStore, xed_file_browser_store, - G_TYPE_OBJECT, - XED_PLUGIN_IMPLEMENT_INTERFACE (xed_file_browser_store_tree_model, - GTK_TYPE_TREE_MODEL, - xed_file_browser_store_iface_init) - XED_PLUGIN_IMPLEMENT_INTERFACE (xed_file_browser_store_drag_source, - GTK_TYPE_TREE_DRAG_SOURCE, - xed_file_browser_store_drag_source_init)) +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedFileBrowserStore, xed_file_browser_store, + G_TYPE_OBJECT, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (GTK_TYPE_TREE_MODEL, + xed_file_browser_store_iface_init) + G_IMPLEMENT_INTERFACE_DYNAMIC (GTK_TYPE_TREE_DRAG_SOURCE, + xed_file_browser_store_drag_source_init)) /* Properties */ enum { - PROP_0, + PROP_0, - PROP_ROOT, - PROP_VIRTUAL_ROOT, - PROP_FILTER_MODE + PROP_ROOT, + PROP_VIRTUAL_ROOT, + PROP_FILTER_MODE }; /* Signals */ -enum +enum { - BEGIN_LOADING, - END_LOADING, - ERROR, - NO_TRASH, - RENAME, - BEGIN_REFRESH, - END_REFRESH, - UNLOAD, - NUM_SIGNALS + BEGIN_LOADING, + END_LOADING, + ERROR, + NO_TRASH, + RENAME, + BEGIN_REFRESH, + END_REFRESH, + UNLOAD, + NUM_SIGNALS }; static guint model_signals[NUM_SIGNALS] = { 0 }; @@ -234,741 +231,804 @@ static guint model_signals[NUM_SIGNALS] = { 0 }; static void cancel_mount_operation (XedFileBrowserStore *obj) { - if (obj->priv->mount_info != NULL) - { - obj->priv->mount_info->model = NULL; - g_cancellable_cancel (obj->priv->mount_info->cancellable); - obj->priv->mount_info = NULL; - } + if (obj->priv->mount_info != NULL) + { + obj->priv->mount_info->model = NULL; + g_cancellable_cancel (obj->priv->mount_info->cancellable); + obj->priv->mount_info = NULL; + } } static void xed_file_browser_store_finalize (GObject * object) { - XedFileBrowserStore *obj = XED_FILE_BROWSER_STORE (object); - GSList *item; + XedFileBrowserStore *obj = XED_FILE_BROWSER_STORE (object); + GSList *item; - /* Free all the nodes */ - file_browser_node_free (obj, obj->priv->root); + /* Free all the nodes */ + file_browser_node_free (obj, obj->priv->root); - /* Cancel any asynchronous operations */ - for (item = obj->priv->async_handles; item; item = item->next) - { - AsyncData *data = (AsyncData *) (item->data); - g_cancellable_cancel (data->cancellable); - - data->removed = TRUE; - } - - cancel_mount_operation (obj); + /* Cancel any asynchronous operations */ + for (item = obj->priv->async_handles; item; item = item->next) + { + AsyncData *data = (AsyncData *) (item->data); + g_cancellable_cancel (data->cancellable); - g_slist_free (obj->priv->async_handles); - G_OBJECT_CLASS (xed_file_browser_store_parent_class)->finalize (object); + data->removed = TRUE; + } + + cancel_mount_operation (obj); + + g_slist_free (obj->priv->async_handles); + G_OBJECT_CLASS (xed_file_browser_store_parent_class)->finalize (object); } static void set_gvalue_from_node (GValue *value, FileBrowserNode *node) { - gchar * uri; - - if (node == NULL || !node->file) { - g_value_set_string (value, NULL); - } else { - uri = g_file_get_uri (node->file); - g_value_take_string (value, uri); - } + if (node == NULL) + { + g_value_set_object (value, NULL); + } + else + { + g_value_set_object (value, node->file); + } } static void xed_file_browser_store_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedFileBrowserStore *obj = XED_FILE_BROWSER_STORE (object); + XedFileBrowserStore *obj = XED_FILE_BROWSER_STORE (object); - switch (prop_id) - { - case PROP_ROOT: - set_gvalue_from_node (value, obj->priv->root); - break; - case PROP_VIRTUAL_ROOT: - set_gvalue_from_node (value, obj->priv->virtual_root); - break; - case PROP_FILTER_MODE: - g_value_set_flags (value, obj->priv->filter_mode); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_ROOT: + set_gvalue_from_node (value, obj->priv->root); + break; + case PROP_VIRTUAL_ROOT: + set_gvalue_from_node (value, obj->priv->virtual_root); + break; + case PROP_FILTER_MODE: + g_value_set_flags (value, obj->priv->filter_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_file_browser_store_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedFileBrowserStore *obj = XED_FILE_BROWSER_STORE (object); + XedFileBrowserStore *obj = XED_FILE_BROWSER_STORE (object); - switch (prop_id) - { - case PROP_FILTER_MODE: - xed_file_browser_store_set_filter_mode (obj, - g_value_get_flags (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_FILTER_MODE: + xed_file_browser_store_set_filter_mode (obj, g_value_get_flags (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_file_browser_store_class_init (XedFileBrowserStoreClass * klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_file_browser_store_finalize; + object_class->finalize = xed_file_browser_store_finalize; - object_class->get_property = xed_file_browser_store_get_property; - object_class->set_property = xed_file_browser_store_set_property; + object_class->get_property = xed_file_browser_store_get_property; + object_class->set_property = xed_file_browser_store_set_property; - g_object_class_install_property (object_class, PROP_ROOT, - g_param_spec_string ("root", - "Root", - "The root uri", - NULL, - G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ROOT, + g_param_spec_object ("root", + "Root", + "The root location", + G_TYPE_FILE, + G_PARAM_READABLE)); - g_object_class_install_property (object_class, PROP_VIRTUAL_ROOT, - g_param_spec_string ("virtual-root", - "Virtual Root", - "The virtual root uri", - NULL, - G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_VIRTUAL_ROOT, + g_param_spec_object ("virtual-root", + "Virtual Root", + "The virtual root location", + G_TYPE_FILE, + G_PARAM_READABLE)); - g_object_class_install_property (object_class, PROP_FILTER_MODE, - g_param_spec_flags ("filter-mode", - "Filter Mode", - "The filter mode", - XED_TYPE_FILE_BROWSER_STORE_FILTER_MODE, - xed_file_browser_store_filter_mode_get_default (), - G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_FILTER_MODE, + g_param_spec_flags ("filter-mode", + "Filter Mode", + "The filter mode", + XED_TYPE_FILE_BROWSER_STORE_FILTER_MODE, + xed_file_browser_store_filter_mode_get_default (), + G_PARAM_READWRITE)); - model_signals[BEGIN_LOADING] = - g_signal_new ("begin-loading", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserStoreClass, - begin_loading), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, - GTK_TYPE_TREE_ITER); - model_signals[END_LOADING] = - g_signal_new ("end-loading", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserStoreClass, - end_loading), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, - GTK_TYPE_TREE_ITER); - model_signals[ERROR] = - g_signal_new ("error", G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserStoreClass, - error), NULL, NULL, - xed_file_browser_marshal_VOID__UINT_STRING, - G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); - model_signals[NO_TRASH] = - g_signal_new ("no-trash", G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserStoreClass, - no_trash), g_signal_accumulator_true_handled, NULL, - xed_file_browser_marshal_BOOL__POINTER, - G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); - model_signals[RENAME] = - g_signal_new ("rename", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserStoreClass, - rename), NULL, NULL, - xed_file_browser_marshal_VOID__STRING_STRING, - G_TYPE_NONE, 2, - G_TYPE_STRING, - G_TYPE_STRING); - model_signals[BEGIN_REFRESH] = - g_signal_new ("begin-refresh", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserStoreClass, - begin_refresh), NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - model_signals[END_REFRESH] = - g_signal_new ("end-refresh", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserStoreClass, - end_refresh), NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - model_signals[UNLOAD] = - g_signal_new ("unload", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserStoreClass, - unload), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); + model_signals[BEGIN_LOADING] = + g_signal_new ("begin-loading", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserStoreClass, + begin_loading), NULL, NULL, + g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, + GTK_TYPE_TREE_ITER); + model_signals[END_LOADING] = + g_signal_new ("end-loading", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserStoreClass, + end_loading), NULL, NULL, + g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, + GTK_TYPE_TREE_ITER); + model_signals[ERROR] = + g_signal_new ("error", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserStoreClass, + error), NULL, NULL, + xed_file_browser_marshal_VOID__UINT_STRING, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); + model_signals[NO_TRASH] = + g_signal_new ("no-trash", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserStoreClass, + no_trash), g_signal_accumulator_true_handled, NULL, + xed_file_browser_marshal_BOOL__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); + model_signals[RENAME] = + g_signal_new ("rename", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserStoreClass, + rename), NULL, NULL, + xed_file_browser_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + G_TYPE_FILE, + G_TYPE_FILE); + model_signals[BEGIN_REFRESH] = + g_signal_new ("begin-refresh", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserStoreClass, + begin_refresh), NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + model_signals[END_REFRESH] = + g_signal_new ("end-refresh", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserStoreClass, + end_refresh), NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + model_signals[UNLOAD] = + g_signal_new ("unload", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserStoreClass, + unload), NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + G_TYPE_FILE); - g_type_class_add_private (object_class, - sizeof (XedFileBrowserStorePrivate)); + g_type_class_add_private (object_class, sizeof (XedFileBrowserStorePrivate)); +} + +static void +xed_file_browser_store_class_finalize (XedFileBrowserStoreClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE_EXTENDED */ } static void xed_file_browser_store_iface_init (GtkTreeModelIface * iface) { - iface->get_flags = xed_file_browser_store_get_flags; - iface->get_n_columns = xed_file_browser_store_get_n_columns; - iface->get_column_type = xed_file_browser_store_get_column_type; - iface->get_iter = xed_file_browser_store_get_iter; - iface->get_path = xed_file_browser_store_get_path; - iface->get_value = xed_file_browser_store_get_value; - iface->iter_next = xed_file_browser_store_iter_next; - iface->iter_children = xed_file_browser_store_iter_children; - iface->iter_has_child = xed_file_browser_store_iter_has_child; - iface->iter_n_children = xed_file_browser_store_iter_n_children; - iface->iter_nth_child = xed_file_browser_store_iter_nth_child; - iface->iter_parent = xed_file_browser_store_iter_parent; - iface->row_inserted = xed_file_browser_store_row_inserted; + iface->get_flags = xed_file_browser_store_get_flags; + iface->get_n_columns = xed_file_browser_store_get_n_columns; + iface->get_column_type = xed_file_browser_store_get_column_type; + iface->get_iter = xed_file_browser_store_get_iter; + iface->get_path = xed_file_browser_store_get_path; + iface->get_value = xed_file_browser_store_get_value; + iface->iter_next = xed_file_browser_store_iter_next; + iface->iter_children = xed_file_browser_store_iter_children; + iface->iter_has_child = xed_file_browser_store_iter_has_child; + iface->iter_n_children = xed_file_browser_store_iter_n_children; + iface->iter_nth_child = xed_file_browser_store_iter_nth_child; + iface->iter_parent = xed_file_browser_store_iter_parent; + iface->row_inserted = xed_file_browser_store_row_inserted; } static void xed_file_browser_store_drag_source_init (GtkTreeDragSourceIface * iface) { - iface->row_draggable = xed_file_browser_store_row_draggable; - iface->drag_data_delete = xed_file_browser_store_drag_data_delete; - iface->drag_data_get = xed_file_browser_store_drag_data_get; + iface->row_draggable = xed_file_browser_store_row_draggable; + iface->drag_data_delete = xed_file_browser_store_drag_data_delete; + iface->drag_data_get = xed_file_browser_store_drag_data_get; } static void xed_file_browser_store_init (XedFileBrowserStore * obj) { - obj->priv = XED_FILE_BROWSER_STORE_GET_PRIVATE (obj); + obj->priv = XED_FILE_BROWSER_STORE_GET_PRIVATE (obj); - obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_URI] = - G_TYPE_STRING; - obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_NAME] = - G_TYPE_STRING; - obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_FLAGS] = - G_TYPE_UINT; - obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_ICON] = - GDK_TYPE_PIXBUF; - obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_EMBLEM] = - GDK_TYPE_PIXBUF; + obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_LOCATION] = G_TYPE_FILE; + obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_NAME] = G_TYPE_STRING; + obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_FLAGS] = G_TYPE_UINT; + obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_ICON] = GDK_TYPE_PIXBUF; + obj->priv->column_types[XED_FILE_BROWSER_STORE_COLUMN_EMBLEM] = GDK_TYPE_PIXBUF; - // Default filter mode is hiding the hidden files - obj->priv->filter_mode = xed_file_browser_store_filter_mode_get_default (); - obj->priv->sort_func = model_sort_default; + // Default filter mode is hiding the hidden files + obj->priv->filter_mode = xed_file_browser_store_filter_mode_get_default (); + obj->priv->sort_func = model_sort_default; } static gboolean -node_has_parent (FileBrowserNode * node, FileBrowserNode * parent) +node_has_parent (FileBrowserNode *node, + FileBrowserNode *parent) { - if (node->parent == NULL) - return FALSE; + if (node->parent == NULL) + { + return FALSE; + } - if (node->parent == parent) - return TRUE; + if (node->parent == parent) + { + return TRUE; + } - return node_has_parent (node->parent, parent); + return node_has_parent (node->parent, parent); } static gboolean -node_in_tree (XedFileBrowserStore * model, FileBrowserNode * node) +node_in_tree (XedFileBrowserStore *model, + FileBrowserNode *node) { - return node_has_parent (node, model->priv->virtual_root); + return node_has_parent (node, model->priv->virtual_root); } static gboolean -model_node_visibility (XedFileBrowserStore * model, - FileBrowserNode * node) +model_node_visibility (XedFileBrowserStore *model, + FileBrowserNode *node) { - if (node == NULL) - return FALSE; + if (node == NULL) + { + return FALSE; + } - if (NODE_IS_DUMMY (node)) - return !NODE_IS_HIDDEN (node); + if (NODE_IS_DUMMY (node)) + { + return !NODE_IS_HIDDEN (node); + } - if (node == model->priv->virtual_root) - return TRUE; + if (node == model->priv->virtual_root) + { + return TRUE; + } - if (!node_has_parent (node, model->priv->virtual_root)) - return FALSE; + if (!node_has_parent (node, model->priv->virtual_root)) + { + return FALSE; + } - return !NODE_IS_FILTERED (node); + return !NODE_IS_FILTERED (node); } static gboolean -model_node_inserted (XedFileBrowserStore * model, - FileBrowserNode * node) +model_node_inserted (XedFileBrowserStore *model, + FileBrowserNode *node) { - return node == model->priv->virtual_root || (model_node_visibility (model, node) && node->inserted); + return node == model->priv->virtual_root || (model_node_visibility (model, node) && node->inserted); } /* Interface implementation */ static GtkTreeModelFlags -xed_file_browser_store_get_flags (GtkTreeModel * tree_model) +xed_file_browser_store_get_flags (GtkTreeModel *tree_model) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), - (GtkTreeModelFlags) 0); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), (GtkTreeModelFlags) 0); - return GTK_TREE_MODEL_ITERS_PERSIST; + return GTK_TREE_MODEL_ITERS_PERSIST; } static gint -xed_file_browser_store_get_n_columns (GtkTreeModel * tree_model) +xed_file_browser_store_get_n_columns (GtkTreeModel *tree_model) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), 0); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), 0); - return XED_FILE_BROWSER_STORE_COLUMN_NUM; + return XED_FILE_BROWSER_STORE_COLUMN_NUM; } static GType -xed_file_browser_store_get_column_type (GtkTreeModel * tree_model, gint idx) +xed_file_browser_store_get_column_type (GtkTreeModel *tree_model, + gint idx) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), - G_TYPE_INVALID); - g_return_val_if_fail (idx < XED_FILE_BROWSER_STORE_COLUMN_NUM && - idx >= 0, G_TYPE_INVALID); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), G_TYPE_INVALID); + g_return_val_if_fail (idx < XED_FILE_BROWSER_STORE_COLUMN_NUM && idx >= 0, G_TYPE_INVALID); - return XED_FILE_BROWSER_STORE (tree_model)->priv->column_types[idx]; + return XED_FILE_BROWSER_STORE (tree_model)->priv->column_types[idx]; } static gboolean -xed_file_browser_store_get_iter (GtkTreeModel * tree_model, - GtkTreeIter * iter, GtkTreePath * path) +xed_file_browser_store_get_iter (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreePath *path) { - gint * indices, depth, i; - FileBrowserNode * node; - XedFileBrowserStore * model; - gint num; + gint *indices, depth, i; + FileBrowserNode *node; + XedFileBrowserStore *model; + gint num; - g_assert (XED_IS_FILE_BROWSER_STORE (tree_model)); - g_assert (path != NULL); + g_assert (XED_IS_FILE_BROWSER_STORE (tree_model)); + g_assert (path != NULL); - model = XED_FILE_BROWSER_STORE (tree_model); - indices = gtk_tree_path_get_indices (path); - depth = gtk_tree_path_get_depth (path); - node = model->priv->virtual_root; + model = XED_FILE_BROWSER_STORE (tree_model); + indices = gtk_tree_path_get_indices (path); + depth = gtk_tree_path_get_depth (path); + node = model->priv->virtual_root; - for (i = 0; i < depth; ++i) { - GSList * item; + for (i = 0; i < depth; ++i) + { + GSList * item; - if (node == NULL) - return FALSE; + if (node == NULL) + { + return FALSE; + } - num = 0; + num = 0; - if (!NODE_IS_DIR (node)) - return FALSE; + if (!NODE_IS_DIR (node)) + { + return FALSE; + } - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) { - FileBrowserNode * child; + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) + { + FileBrowserNode * child; - child = (FileBrowserNode *) (item->data); + child = (FileBrowserNode *) (item->data); - if (model_node_inserted (model, child)) { - if (num == indices[i]) { - node = child; - break; - } + if (model_node_inserted (model, child)) + { + if (num == indices[i]) + { + node = child; + break; + } - num++; - } - } + num++; + } + } - if (item == NULL) - return FALSE; + if (item == NULL) + { + return FALSE; + } - node = (FileBrowserNode *) (item->data); - } + node = (FileBrowserNode *) (item->data); + } - iter->user_data = node; - iter->user_data2 = NULL; - iter->user_data3 = NULL; + iter->user_data = node; + iter->user_data2 = NULL; + iter->user_data3 = NULL; - return node != NULL; + return node != NULL; } static GtkTreePath * -xed_file_browser_store_get_path_real (XedFileBrowserStore * model, - FileBrowserNode * node) +xed_file_browser_store_get_path_real (XedFileBrowserStore *model, + FileBrowserNode *node) { - GtkTreePath *path; - gint num = 0; + GtkTreePath *path; + gint num = 0; - path = gtk_tree_path_new (); + path = gtk_tree_path_new (); - while (node != model->priv->virtual_root) { - GSList *item; + while (node != model->priv->virtual_root) + { + GSList *item; - if (node->parent == NULL) { - gtk_tree_path_free (path); - return NULL; - } + if (node->parent == NULL) + { + gtk_tree_path_free (path); + return NULL; + } - num = 0; + num = 0; - for (item = FILE_BROWSER_NODE_DIR (node->parent)->children; item; item = item->next) { - FileBrowserNode *check; + for (item = FILE_BROWSER_NODE_DIR (node->parent)->children; item; item = item->next) + { + FileBrowserNode *check; - check = (FileBrowserNode *) (item->data); + check = (FileBrowserNode *) (item->data); - if (model_node_visibility (model, check) && (check == node || check->inserted)) { - if (check == node) { - gtk_tree_path_prepend_index (path, - num); - break; - } + if (model_node_visibility (model, check) && (check == node || check->inserted)) + { + if (check == node) + { + gtk_tree_path_prepend_index (path, num); + break; + } - ++num; - } else if (check == node) { - if (NODE_IS_DUMMY (node)) - g_warning ("Dummy not visible???"); + ++num; + } + else if (check == node) + { + if (NODE_IS_DUMMY (node)) + { + g_warning ("Dummy not visible???"); + } - gtk_tree_path_free (path); - return NULL; - } - } + gtk_tree_path_free (path); + return NULL; + } + } - node = node->parent; - } + node = node->parent; + } - return path; + return path; } static GtkTreePath * -xed_file_browser_store_get_path (GtkTreeModel * tree_model, - GtkTreeIter * iter) +xed_file_browser_store_get_path (GtkTreeModel *tree_model, + GtkTreeIter *iter) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), NULL); - g_return_val_if_fail (iter != NULL, NULL); - g_return_val_if_fail (iter->user_data != NULL, NULL); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), NULL); + g_return_val_if_fail (iter != NULL, NULL); + g_return_val_if_fail (iter->user_data != NULL, NULL); - return xed_file_browser_store_get_path_real (XED_FILE_BROWSER_STORE (tree_model), - (FileBrowserNode *) (iter->user_data)); + return xed_file_browser_store_get_path_real (XED_FILE_BROWSER_STORE (tree_model), + (FileBrowserNode *) (iter->user_data)); } static void -xed_file_browser_store_get_value (GtkTreeModel * tree_model, - GtkTreeIter * iter, - gint column, - GValue * value) +xed_file_browser_store_get_value (GtkTreeModel *tree_model, + GtkTreeIter *iter, + gint column, + GValue *value) { - FileBrowserNode *node; + FileBrowserNode *node; - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model)); - g_return_if_fail (iter != NULL); - g_return_if_fail (iter->user_data != NULL); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model)); + g_return_if_fail (iter != NULL); + g_return_if_fail (iter->user_data != NULL); - node = (FileBrowserNode *) (iter->user_data); + node = (FileBrowserNode *) (iter->user_data); - g_value_init (value, XED_FILE_BROWSER_STORE (tree_model)->priv->column_types[column]); + g_value_init (value, XED_FILE_BROWSER_STORE (tree_model)->priv->column_types[column]); - switch (column) { - case XED_FILE_BROWSER_STORE_COLUMN_URI: - set_gvalue_from_node (value, node); - break; - case XED_FILE_BROWSER_STORE_COLUMN_NAME: - g_value_set_string (value, node->name); - break; - case XED_FILE_BROWSER_STORE_COLUMN_FLAGS: - g_value_set_uint (value, node->flags); - break; - case XED_FILE_BROWSER_STORE_COLUMN_ICON: - g_value_set_object (value, node->icon); - break; - case XED_FILE_BROWSER_STORE_COLUMN_EMBLEM: - g_value_set_object (value, node->emblem); - break; - default: - g_return_if_reached (); - } + switch (column) + { + case XED_FILE_BROWSER_STORE_COLUMN_LOCATION: + set_gvalue_from_node (value, node); + break; + case XED_FILE_BROWSER_STORE_COLUMN_NAME: + g_value_set_string (value, node->name); + break; + case XED_FILE_BROWSER_STORE_COLUMN_FLAGS: + g_value_set_uint (value, node->flags); + break; + case XED_FILE_BROWSER_STORE_COLUMN_ICON: + g_value_set_object (value, node->icon); + break; + case XED_FILE_BROWSER_STORE_COLUMN_EMBLEM: + g_value_set_object (value, node->emblem); + break; + default: + g_return_if_reached (); + } } static gboolean -xed_file_browser_store_iter_next (GtkTreeModel * tree_model, - GtkTreeIter * iter) +xed_file_browser_store_iter_next (GtkTreeModel *tree_model, + GtkTreeIter *iter) { - XedFileBrowserStore * model; - FileBrowserNode * node; - GSList * item; - GSList * first; + XedFileBrowserStore *model; + FileBrowserNode *node; + GSList *item; + GSList *first; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), - FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (iter->user_data != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (iter->user_data != NULL, FALSE); - model = XED_FILE_BROWSER_STORE (tree_model); - node = (FileBrowserNode *) (iter->user_data); + model = XED_FILE_BROWSER_STORE (tree_model); + node = (FileBrowserNode *) (iter->user_data); - if (node->parent == NULL) - return FALSE; + if (node->parent == NULL) + { + return FALSE; + } - first = g_slist_next (g_slist_find (FILE_BROWSER_NODE_DIR (node->parent)->children, node)); + first = g_slist_next (g_slist_find (FILE_BROWSER_NODE_DIR (node->parent)->children, node)); - for (item = first; item; item = item->next) { - if (model_node_inserted (model, (FileBrowserNode *) (item->data))) { - iter->user_data = item->data; - return TRUE; - } - } + for (item = first; item; item = item->next) + { + if (model_node_inserted (model, (FileBrowserNode *) (item->data))) + { + iter->user_data = item->data; + return TRUE; + } + } - return FALSE; + return FALSE; } static gboolean -xed_file_browser_store_iter_children (GtkTreeModel * tree_model, - GtkTreeIter * iter, - GtkTreeIter * parent) +xed_file_browser_store_iter_children (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreeIter *parent) { - FileBrowserNode * node; - XedFileBrowserStore * model; - GSList * item; + FileBrowserNode *node; + XedFileBrowserStore *model; + GSList *item; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), - FALSE); - g_return_val_if_fail (parent == NULL - || parent->user_data != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), FALSE); + g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE); - model = XED_FILE_BROWSER_STORE (tree_model); + model = XED_FILE_BROWSER_STORE (tree_model); - if (parent == NULL) - node = model->priv->virtual_root; - else - node = (FileBrowserNode *) (parent->user_data); + if (parent == NULL) + { + node = model->priv->virtual_root; + } + else + { + node = (FileBrowserNode *) (parent->user_data); + } - if (node == NULL) - return FALSE; + if (node == NULL) + { + return FALSE; + } - if (!NODE_IS_DIR (node)) - return FALSE; + if (!NODE_IS_DIR (node)) + { + return FALSE; + } - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) { - if (model_node_inserted (model, (FileBrowserNode *) (item->data))) { - iter->user_data = item->data; - return TRUE; - } - } + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) + { + if (model_node_inserted (model, (FileBrowserNode *) (item->data))) + { + iter->user_data = item->data; + return TRUE; + } + } - return FALSE; + return FALSE; } static gboolean -filter_tree_model_iter_has_child_real (XedFileBrowserStore * model, - FileBrowserNode * node) +filter_tree_model_iter_has_child_real (XedFileBrowserStore *model, + FileBrowserNode *node) { - GSList *item; - - if (!NODE_IS_DIR (node)) - return FALSE; + GSList *item; - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) { - if (model_node_inserted (model, (FileBrowserNode *) (item->data))) - return TRUE; - } + if (!NODE_IS_DIR (node)) + { + return FALSE; + } - return FALSE; + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) + { + if (model_node_inserted (model, (FileBrowserNode *) (item->data))) + { + return TRUE; + } + } + + return FALSE; } static gboolean -xed_file_browser_store_iter_has_child (GtkTreeModel * tree_model, - GtkTreeIter * iter) +xed_file_browser_store_iter_has_child (GtkTreeModel *tree_model, + GtkTreeIter *iter) { - FileBrowserNode *node; - XedFileBrowserStore *model; + FileBrowserNode *node; + XedFileBrowserStore *model; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), - FALSE); - g_return_val_if_fail (iter == NULL - || iter->user_data != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), FALSE); + g_return_val_if_fail (iter == NULL || iter->user_data != NULL, FALSE); - model = XED_FILE_BROWSER_STORE (tree_model); + model = XED_FILE_BROWSER_STORE (tree_model); - if (iter == NULL) - node = model->priv->virtual_root; - else - node = (FileBrowserNode *) (iter->user_data); + if (iter == NULL) + { + node = model->priv->virtual_root; + } + else + { + node = (FileBrowserNode *) (iter->user_data); + } - return filter_tree_model_iter_has_child_real (model, node); + return filter_tree_model_iter_has_child_real (model, node); } static gint -xed_file_browser_store_iter_n_children (GtkTreeModel * tree_model, - GtkTreeIter * iter) +xed_file_browser_store_iter_n_children (GtkTreeModel *tree_model, + GtkTreeIter *iter) { - FileBrowserNode *node; - XedFileBrowserStore *model; - GSList *item; - gint num = 0; + FileBrowserNode *node; + XedFileBrowserStore *model; + GSList *item; + gint num = 0; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), - FALSE); - g_return_val_if_fail (iter == NULL - || iter->user_data != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), FALSE); + g_return_val_if_fail (iter == NULL || iter->user_data != NULL, FALSE); - model = XED_FILE_BROWSER_STORE (tree_model); + model = XED_FILE_BROWSER_STORE (tree_model); - if (iter == NULL) - node = model->priv->virtual_root; - else - node = (FileBrowserNode *) (iter->user_data); + if (iter == NULL) + { + node = model->priv->virtual_root; + } + else + { + node = (FileBrowserNode *) (iter->user_data); + } - if (!NODE_IS_DIR (node)) - return 0; + if (!NODE_IS_DIR (node)) + { + return 0; + } - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) - if (model_node_inserted (model, (FileBrowserNode *) (item->data))) - ++num; + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) + { + if (model_node_inserted (model, (FileBrowserNode *) (item->data))) + { + ++num; + } + } - return num; + return num; } static gboolean -xed_file_browser_store_iter_nth_child (GtkTreeModel * tree_model, - GtkTreeIter * iter, - GtkTreeIter * parent, gint n) +xed_file_browser_store_iter_nth_child (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreeIter *parent, gint n) { - FileBrowserNode *node; - XedFileBrowserStore *model; - GSList *item; - gint num = 0; + FileBrowserNode *node; + XedFileBrowserStore *model; + GSList *item; + gint num = 0; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), - FALSE); - g_return_val_if_fail (parent == NULL - || parent->user_data != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), FALSE); + g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE); - model = XED_FILE_BROWSER_STORE (tree_model); + model = XED_FILE_BROWSER_STORE (tree_model); - if (parent == NULL) - node = model->priv->virtual_root; - else - node = (FileBrowserNode *) (parent->user_data); + if (parent == NULL) + { + node = model->priv->virtual_root; + } + else + { + node = (FileBrowserNode *) (parent->user_data); + } - if (!NODE_IS_DIR (node)) - return FALSE; + if (!NODE_IS_DIR (node)) + { + return FALSE; + } - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; - item = item->next) { - if (model_node_inserted (model, (FileBrowserNode *) (item->data))) { - if (num == n) { - iter->user_data = item->data; - return TRUE; - } + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) + { + if (model_node_inserted (model, (FileBrowserNode *) (item->data))) + { + if (num == n) + { + iter->user_data = item->data; + return TRUE; + } - ++num; - } - } + ++num; + } + } - return FALSE; + return FALSE; } static gboolean -xed_file_browser_store_iter_parent (GtkTreeModel * tree_model, - GtkTreeIter * iter, - GtkTreeIter * child) +xed_file_browser_store_iter_parent (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreeIter *child) { - FileBrowserNode *node; - XedFileBrowserStore *model; + FileBrowserNode *node; + XedFileBrowserStore *model; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), FALSE); - g_return_val_if_fail (child != NULL, FALSE); - g_return_val_if_fail (child->user_data != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model), FALSE); + g_return_val_if_fail (child != NULL, FALSE); + g_return_val_if_fail (child->user_data != NULL, FALSE); - node = (FileBrowserNode *) (child->user_data); - model = XED_FILE_BROWSER_STORE (tree_model); + node = (FileBrowserNode *) (child->user_data); + model = XED_FILE_BROWSER_STORE (tree_model); - if (!node_in_tree (model, node)) - return FALSE; + if (!node_in_tree (model, node)) + { + return FALSE; + } - if (node->parent == NULL) - return FALSE; + if (node->parent == NULL) + { + return FALSE; + } - iter->user_data = node->parent; - return TRUE; + iter->user_data = node->parent; + return TRUE; } static void -xed_file_browser_store_row_inserted (GtkTreeModel * tree_model, - GtkTreePath * path, - GtkTreeIter * iter) +xed_file_browser_store_row_inserted (GtkTreeModel *tree_model, + GtkTreePath *path, + GtkTreeIter *iter) { - FileBrowserNode * node = (FileBrowserNode *)(iter->user_data); - - node->inserted = TRUE; + FileBrowserNode * node = (FileBrowserNode *)(iter->user_data); + + node->inserted = TRUE; } static gboolean -xed_file_browser_store_row_draggable (GtkTreeDragSource * drag_source, - GtkTreePath * path) +xed_file_browser_store_row_draggable (GtkTreeDragSource *drag_source, + GtkTreePath *path) { - GtkTreeIter iter; - XedFileBrowserStoreFlag flags; + GtkTreeIter iter; + XedFileBrowserStoreFlag flags; - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), - &iter, path)) - { - return FALSE; - } + if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path)) + { + return FALSE; + } - gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter, - XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, - -1); + gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter, XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, -1); - return !FILE_IS_DUMMY(flags); + return !FILE_IS_DUMMY(flags); } static gboolean -xed_file_browser_store_drag_data_delete (GtkTreeDragSource * drag_source, - GtkTreePath * path) +xed_file_browser_store_drag_data_delete (GtkTreeDragSource *drag_source, + GtkTreePath *path) { - return FALSE; + return FALSE; } static gboolean -xed_file_browser_store_drag_data_get (GtkTreeDragSource * drag_source, - GtkTreePath * path, - GtkSelectionData * selection_data) +xed_file_browser_store_drag_data_get (GtkTreeDragSource *drag_source, + GtkTreePath *path, + GtkSelectionData *selection_data) { - GtkTreeIter iter; - gchar *uri; - gchar *uris[2] = {0, }; - gboolean ret; + GtkTreeIter iter; + GFile *location; + gchar *uris[2] = {0, }; + gboolean ret; - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), - &iter, path)) - { - return FALSE; - } + if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path)) + { + return FALSE; + } - gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, - -1); + gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1); - g_assert (uri); + g_assert (location); - uris[0] = uri; - ret = gtk_selection_data_set_uris (selection_data, uris); + uris[0] = g_file_get_uri (location); + ret = gtk_selection_data_set_uris (selection_data, uris); - g_free (uri); + g_free (uris[0]); - return ret; + return ret; } #define FILTER_HIDDEN(mode) (mode & XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN) @@ -976,425 +1036,474 @@ xed_file_browser_store_drag_data_get (GtkTreeDragSource * drag_source, /* Private */ static void -model_begin_loading (XedFileBrowserStore * model, FileBrowserNode * node) +model_begin_loading (XedFileBrowserStore *model, + FileBrowserNode *node) { - GtkTreeIter iter; + GtkTreeIter iter; - iter.user_data = node; - g_signal_emit (model, model_signals[BEGIN_LOADING], 0, &iter); + iter.user_data = node; + g_signal_emit (model, model_signals[BEGIN_LOADING], 0, &iter); } static void -model_end_loading (XedFileBrowserStore * model, FileBrowserNode * node) +model_end_loading (XedFileBrowserStore *model, + FileBrowserNode *node) { - GtkTreeIter iter; + GtkTreeIter iter; - iter.user_data = node; - g_signal_emit (model, model_signals[END_LOADING], 0, &iter); + iter.user_data = node; + g_signal_emit (model, model_signals[END_LOADING], 0, &iter); } static void -model_node_update_visibility (XedFileBrowserStore * model, - FileBrowserNode * node) +model_node_update_visibility (XedFileBrowserStore *model, + FileBrowserNode *node) { - GtkTreeIter iter; + GtkTreeIter iter; - node->flags &= ~XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED; + node->flags &= ~XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED; - if (FILTER_HIDDEN (model->priv->filter_mode) && - NODE_IS_HIDDEN (node)) - node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED; - else if (FILTER_BINARY (model->priv->filter_mode) && - (!NODE_IS_TEXT (node) && !NODE_IS_DIR (node))) - node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED; - else if (model->priv->filter_func) { - iter.user_data = node; + if (FILTER_HIDDEN (model->priv->filter_mode) && NODE_IS_HIDDEN (node)) + { + node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED; + } + else if (FILTER_BINARY (model->priv->filter_mode) && (!NODE_IS_TEXT (node) && !NODE_IS_DIR (node))) + { + node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED; + } + else if (model->priv->filter_func) + { + iter.user_data = node; - if (!model->priv-> - filter_func (model, &iter, - model->priv->filter_user_data)) - node->flags |= - XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED; - } + if (!model->priv->filter_func (model, &iter, model->priv->filter_user_data)) + { + node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED; + } + } } static gint -collate_nodes (FileBrowserNode * node1, FileBrowserNode * node2) +collate_nodes (FileBrowserNode *node1, + FileBrowserNode *node2) { - if (node1->name == NULL) - return -1; - else if (node2->name == NULL) - return 1; - else { - gchar *k1, *k2; - gint result; + if (node1->name == NULL) + { + return -1; + } + else if (node2->name == NULL) + { + return 1; + } + else + { + gchar *k1, *k2; + gint result; - k1 = g_utf8_collate_key_for_filename (node1->name, -1); - k2 = g_utf8_collate_key_for_filename (node2->name, -1); + k1 = g_utf8_collate_key_for_filename (node1->name, -1); + k2 = g_utf8_collate_key_for_filename (node2->name, -1); - result = strcmp (k1, k2); + result = strcmp (k1, k2); - g_free (k1); - g_free (k2); + g_free (k1); + g_free (k2); - return result; - } + return result; + } } static gint -model_sort_default (FileBrowserNode * node1, FileBrowserNode * node2) +model_sort_default (FileBrowserNode *node1, + FileBrowserNode *node2) { - gint f1; - gint f2; + gint f1; + gint f2; - f1 = NODE_IS_DUMMY (node1); - f2 = NODE_IS_DUMMY (node2); + f1 = NODE_IS_DUMMY (node1); + f2 = NODE_IS_DUMMY (node2); - if (f1 && f2) - { - return 0; - } - else if (f1 || f2) - { - return f1 ? -1 : 1; - } + if (f1 && f2) + { + return 0; + } + else if (f1 || f2) + { + return f1 ? -1 : 1; + } - f1 = NODE_IS_DIR (node1); - f2 = NODE_IS_DIR (node2); + f1 = NODE_IS_DIR (node1); + f2 = NODE_IS_DIR (node2); - if (f1 != f2) - { - return f1 ? -1 : 1; - } + if (f1 != f2) + { + return f1 ? -1 : 1; + } - f1 = NODE_IS_HIDDEN (node1); - f2 = NODE_IS_HIDDEN (node2); + f1 = NODE_IS_HIDDEN (node1); + f2 = NODE_IS_HIDDEN (node2); - if (f1 != f2) - { - return f2 ? -1 : 1; - } + if (f1 != f2) + { + return f2 ? -1 : 1; + } - return collate_nodes (node1, node2); + return collate_nodes (node1, node2); } static void -model_resort_node (XedFileBrowserStore * model, FileBrowserNode * node) +model_resort_node (XedFileBrowserStore *model, + FileBrowserNode *node) { - FileBrowserNodeDir *dir; - GSList *item; - FileBrowserNode *child; - gint pos = 0; - GtkTreeIter iter; - GtkTreePath *path; - gint *neworder; + FileBrowserNodeDir *dir; + GSList *item; + FileBrowserNode *child; + gint pos = 0; + GtkTreeIter iter; + GtkTreePath *path; + gint *neworder; - dir = FILE_BROWSER_NODE_DIR (node->parent); + dir = FILE_BROWSER_NODE_DIR (node->parent); - if (!model_node_visibility (model, node->parent)) { - /* Just sort the children of the parent */ - dir->children = g_slist_sort (dir->children, - (GCompareFunc) (model->priv-> - sort_func)); - } else { - /* Store current positions */ - for (item = dir->children; item; item = item->next) { - child = (FileBrowserNode *) (item->data); + if (!model_node_visibility (model, node->parent)) + { + /* Just sort the children of the parent */ + dir->children = g_slist_sort (dir->children, (GCompareFunc) (model->priv->sort_func)); + } + else + { + /* Store current positions */ + for (item = dir->children; item; item = item->next) + { + child = (FileBrowserNode *) (item->data); - if (model_node_visibility (model, child)) - child->pos = pos++; - } + if (model_node_visibility (model, child)) + { + child->pos = pos++; + } + } - dir->children = g_slist_sort (dir->children, - (GCompareFunc) (model->priv-> - sort_func)); - neworder = g_new (gint, pos); - pos = 0; + dir->children = g_slist_sort (dir->children, (GCompareFunc) (model->priv->sort_func)); + neworder = g_new (gint, pos); + pos = 0; - /* Store the new positions */ - for (item = dir->children; item; item = item->next) { - child = (FileBrowserNode *) (item->data); + /* Store the new positions */ + for (item = dir->children; item; item = item->next) + { + child = (FileBrowserNode *) (item->data); - if (model_node_visibility (model, child)) - neworder[pos++] = child->pos; - } + if (model_node_visibility (model, child)) + { + neworder[pos++] = child->pos; + } + } - iter.user_data = node->parent; - path = - xed_file_browser_store_get_path_real (model, - node->parent); + iter.user_data = node->parent; + path = xed_file_browser_store_get_path_real (model, node->parent); - gtk_tree_model_rows_reordered (GTK_TREE_MODEL (model), - path, &iter, neworder); + gtk_tree_model_rows_reordered (GTK_TREE_MODEL (model), path, &iter, neworder); - g_free (neworder); - gtk_tree_path_free (path); - } + g_free (neworder); + gtk_tree_path_free (path); + } } static void -row_changed (XedFileBrowserStore * model, - GtkTreePath ** path, - GtkTreeIter * iter) +row_changed (XedFileBrowserStore *model, + GtkTreePath **path, + GtkTreeIter *iter) { - GtkTreeRowReference *ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), *path); + GtkTreeRowReference *ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), *path); - /* Insert a copy of the actual path here because the row-inserted - signal may alter the path */ - gtk_tree_model_row_changed (GTK_TREE_MODEL(model), *path, iter); - gtk_tree_path_free (*path); - - *path = gtk_tree_row_reference_get_path (ref); - gtk_tree_row_reference_free (ref); + /* Insert a copy of the actual path here because the row-inserted + signal may alter the path */ + gtk_tree_model_row_changed (GTK_TREE_MODEL(model), *path, iter); + gtk_tree_path_free (*path); + + *path = gtk_tree_row_reference_get_path (ref); + gtk_tree_row_reference_free (ref); } static void -row_inserted (XedFileBrowserStore * model, - GtkTreePath ** path, - GtkTreeIter * iter) +row_inserted (XedFileBrowserStore *model, + GtkTreePath **path, + GtkTreeIter *iter) { - /* This function creates a row reference for the path because it's - uncertain what might change the actual model/view when we insert - a node, maybe another directory load is triggered for example. - Because functions that use this function rely on the notion that - the path remains pointed towards the inserted node, we use the - reference to keep track. */ - GtkTreeRowReference *ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), *path); - GtkTreePath * copy = gtk_tree_path_copy (*path); + /* This function creates a row reference for the path because it's + uncertain what might change the actual model/view when we insert + a node, maybe another directory load is triggered for example. + Because functions that use this function rely on the notion that + the path remains pointed towards the inserted node, we use the + reference to keep track. */ + GtkTreeRowReference *ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), *path); + GtkTreePath * copy = gtk_tree_path_copy (*path); - gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), copy, iter); - gtk_tree_path_free (copy); - - if (ref) - { - gtk_tree_path_free (*path); + gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), copy, iter); + gtk_tree_path_free (copy); - /* To restore the path, we get the path from the reference. But, since - we inserted a row, the path will be one index further than the - actual path of our node. We therefore call gtk_tree_path_prev */ - *path = gtk_tree_row_reference_get_path (ref); - gtk_tree_path_prev (*path); - } + if (ref) + { + gtk_tree_path_free (*path); - gtk_tree_row_reference_free (ref); + /* To restore the path, we get the path from the reference. But, since + we inserted a row, the path will be one index further than the + actual path of our node. We therefore call gtk_tree_path_prev */ + *path = gtk_tree_row_reference_get_path (ref); + gtk_tree_path_prev (*path); + } + + gtk_tree_row_reference_free (ref); } static void -row_deleted (XedFileBrowserStore * model, - const GtkTreePath * path) +row_deleted (XedFileBrowserStore *model, + const GtkTreePath *path) { - GtkTreePath *copy = gtk_tree_path_copy (path); - - /* Delete a copy of the actual path here because the row-deleted - signal may alter the path */ - gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), copy); - gtk_tree_path_free (copy); + GtkTreePath *copy = gtk_tree_path_copy (path); + + /* Delete a copy of the actual path here because the row-deleted + signal may alter the path */ + gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), copy); + gtk_tree_path_free (copy); } static void -model_refilter_node (XedFileBrowserStore * model, - FileBrowserNode * node, - GtkTreePath ** path) +model_refilter_node (XedFileBrowserStore *model, + FileBrowserNode *node, + GtkTreePath **path) { - gboolean old_visible; - gboolean new_visible; - FileBrowserNodeDir *dir; - GSList *item; - GtkTreeIter iter; - GtkTreePath *tmppath = NULL; - gboolean in_tree; + gboolean old_visible; + gboolean new_visible; + FileBrowserNodeDir *dir; + GSList *item; + GtkTreeIter iter; + GtkTreePath *tmppath = NULL; + gboolean in_tree; - if (node == NULL) - return; + if (node == NULL) + { + return; + } - old_visible = model_node_visibility (model, node); - model_node_update_visibility (model, node); + old_visible = model_node_visibility (model, node); + model_node_update_visibility (model, node); - in_tree = node_in_tree (model, node); + in_tree = node_in_tree (model, node); - if (path == NULL) - { - if (in_tree) - tmppath = xed_file_browser_store_get_path_real (model, - node); - else - tmppath = gtk_tree_path_new_first (); + if (path == NULL) + { + if (in_tree) + { + tmppath = xed_file_browser_store_get_path_real (model, node); + } + else + { + tmppath = gtk_tree_path_new_first (); + } - path = &tmppath; - } + path = &tmppath; + } - if (NODE_IS_DIR (node)) { - if (in_tree) - gtk_tree_path_down (*path); + if (NODE_IS_DIR (node)) + { + if (in_tree) + { + gtk_tree_path_down (*path); + } - dir = FILE_BROWSER_NODE_DIR (node); + dir = FILE_BROWSER_NODE_DIR (node); - for (item = dir->children; item; item = item->next) { - model_refilter_node (model, - (FileBrowserNode *) (item->data), - path); - } + for (item = dir->children; item; item = item->next) + { + model_refilter_node (model, (FileBrowserNode *) (item->data), path); + } - if (in_tree) - gtk_tree_path_up (*path); - } + if (in_tree) + { + gtk_tree_path_up (*path); + } + } - if (in_tree) { - new_visible = model_node_visibility (model, node); + if (in_tree) + { + new_visible = model_node_visibility (model, node); - if (old_visible != new_visible) { - if (old_visible) { - node->inserted = FALSE; - row_deleted (model, *path); - } else { - iter.user_data = node; - row_inserted (model, path, &iter); - gtk_tree_path_next (*path); - } - } else if (old_visible) { - gtk_tree_path_next (*path); - } - } - - model_check_dummy (model, node); + if (old_visible != new_visible) + { + if (old_visible) + { + node->inserted = FALSE; + row_deleted (model, *path); + } + else + { + iter.user_data = node; + row_inserted (model, path, &iter); + gtk_tree_path_next (*path); + } + } + else if (old_visible) + { + gtk_tree_path_next (*path); + } + } - if (tmppath) - gtk_tree_path_free (tmppath); + model_check_dummy (model, node); + + if (tmppath) + { + gtk_tree_path_free (tmppath); + } } static void -model_refilter (XedFileBrowserStore * model) +model_refilter (XedFileBrowserStore *model) { - model_refilter_node (model, model->priv->root, NULL); + model_refilter_node (model, model->priv->root, NULL); } static void -file_browser_node_set_name (FileBrowserNode * node) +file_browser_node_set_name (FileBrowserNode *node) { - g_free (node->name); + g_free (node->name); - if (node->file) { - node->name = xed_file_browser_utils_file_basename (node->file); - } else { - node->name = NULL; - } + if (node->file) + { + node->name = xed_file_browser_utils_file_basename (node->file); + } + else + { + node->name = NULL; + } } static void -file_browser_node_init (FileBrowserNode * node, GFile * file, - FileBrowserNode * parent) +file_browser_node_init (FileBrowserNode *node, + GFile *file, + FileBrowserNode *parent) { - if (file != NULL) { - node->file = g_object_ref (file); - file_browser_node_set_name (node); - } + if (file != NULL) + { + node->file = g_object_ref (file); + file_browser_node_set_name (node); + } - node->parent = parent; + node->parent = parent; } static FileBrowserNode * -file_browser_node_new (GFile * file, FileBrowserNode * parent) +file_browser_node_new (GFile *file, + FileBrowserNode *parent) { - FileBrowserNode *node = g_slice_new0 (FileBrowserNode); + FileBrowserNode *node = g_slice_new0 (FileBrowserNode); - file_browser_node_init (node, file, parent); - return node; + file_browser_node_init (node, file, parent); + return node; } static FileBrowserNode * -file_browser_node_dir_new (XedFileBrowserStore * model, - GFile * file, FileBrowserNode * parent) +file_browser_node_dir_new (XedFileBrowserStore *model, + GFile *file, + FileBrowserNode *parent) { - FileBrowserNode *node = - (FileBrowserNode *) g_slice_new0 (FileBrowserNodeDir); + FileBrowserNode *node = (FileBrowserNode *) g_slice_new0 (FileBrowserNodeDir); - file_browser_node_init (node, file, parent); + file_browser_node_init (node, file, parent); - node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY; + node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY; - FILE_BROWSER_NODE_DIR (node)->model = model; + FILE_BROWSER_NODE_DIR (node)->model = model; - return node; + return node; } static void -file_browser_node_free_children (XedFileBrowserStore * model, - FileBrowserNode * node) +file_browser_node_free_children (XedFileBrowserStore *model, + FileBrowserNode *node) { - GSList *item; + GSList *item; - if (node == NULL) - return; + if (node == NULL) + { + return; + } - if (NODE_IS_DIR (node)) { - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; - item = item->next) - file_browser_node_free (model, - (FileBrowserNode *) (item-> - data)); + if (NODE_IS_DIR (node)) + { + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) + { + file_browser_node_free (model, (FileBrowserNode *) (item->data)); + } - g_slist_free (FILE_BROWSER_NODE_DIR (node)->children); - FILE_BROWSER_NODE_DIR (node)->children = NULL; + g_slist_free (FILE_BROWSER_NODE_DIR (node)->children); + FILE_BROWSER_NODE_DIR (node)->children = NULL; - /* This node is no longer loaded */ - node->flags &= ~XED_FILE_BROWSER_STORE_FLAG_LOADED; - } + /* This node is no longer loaded */ + node->flags &= ~XED_FILE_BROWSER_STORE_FLAG_LOADED; + } } static void -file_browser_node_free (XedFileBrowserStore * model, - FileBrowserNode * node) +file_browser_node_free (XedFileBrowserStore *model, + FileBrowserNode *node) { - gchar *uri; + if (node == NULL) + { + return; + } - if (node == NULL) - return; + if (NODE_IS_DIR (node)) + { + FileBrowserNodeDir *dir; - if (NODE_IS_DIR (node)) - { - FileBrowserNodeDir *dir; + dir = FILE_BROWSER_NODE_DIR (node); - dir = FILE_BROWSER_NODE_DIR (node); + if (dir->cancellable) + { + g_cancellable_cancel (dir->cancellable); + g_object_unref (dir->cancellable); - if (dir->cancellable) { - g_cancellable_cancel (dir->cancellable); - g_object_unref (dir->cancellable); + model_end_loading (model, node); + } - model_end_loading (model, node); - } + file_browser_node_free_children (model, node); - file_browser_node_free_children (model, node); + if (dir->monitor) + { + g_file_monitor_cancel (dir->monitor); + g_object_unref (dir->monitor); + } - if (dir->monitor) { - g_file_monitor_cancel (dir->monitor); - g_object_unref (dir->monitor); - } + if (dir->hidden_file_hash) + { + g_hash_table_destroy (dir->hidden_file_hash); + } + } - if (dir->hidden_file_hash) - g_hash_table_destroy (dir->hidden_file_hash); - } - - if (node->file) - { - uri = g_file_get_uri (node->file); - g_signal_emit (model, model_signals[UNLOAD], 0, uri); + if (node->file) + { + g_signal_emit (model, model_signals[UNLOAD], 0, node->file); + g_object_unref (node->file); + } - g_free (uri); - g_object_unref (node->file); - } + if (node->icon) + { + g_object_unref (node->icon); + } - if (node->icon) - g_object_unref (node->icon); + if (node->emblem) + { + g_object_unref (node->emblem); + } - if (node->emblem) - g_object_unref (node->emblem); + g_free (node->name); - g_free (node->name); - - if (NODE_IS_DIR (node)) - g_slice_free (FileBrowserNodeDir, (FileBrowserNodeDir *)node); - else - g_slice_free (FileBrowserNode, (FileBrowserNode *)node); + if (NODE_IS_DIR (node)) + { + g_slice_free (FileBrowserNodeDir, (FileBrowserNodeDir *)node); + } + else + { + g_slice_free (FileBrowserNode, (FileBrowserNode *)node); + } } /** @@ -1409,112 +1518,132 @@ file_browser_node_free (XedFileBrowserStore * model, * a node. **/ static void -model_remove_node_children (XedFileBrowserStore * model, - FileBrowserNode * node, - GtkTreePath * path, - gboolean free_nodes) +model_remove_node_children (XedFileBrowserStore *model, + FileBrowserNode *node, + GtkTreePath *path, + gboolean free_nodes) { - FileBrowserNodeDir *dir; - GtkTreePath *path_child; - GSList *list; - GSList *item; + FileBrowserNodeDir *dir; + GtkTreePath *path_child; + GSList *list; + GSList *item; - if (node == NULL || !NODE_IS_DIR (node)) - return; + if (node == NULL || !NODE_IS_DIR (node)) + { + return; + } - dir = FILE_BROWSER_NODE_DIR (node); + dir = FILE_BROWSER_NODE_DIR (node); - if (dir->children == NULL) - return; + if (dir->children == NULL) + { + return; + } - if (!model_node_visibility (model, node)) { - // Node is invisible and therefore the children can just - // be freed - if (free_nodes) - file_browser_node_free_children (model, node); - - return; - } - - if (path == NULL) - path_child = - xed_file_browser_store_get_path_real (model, node); - else - path_child = gtk_tree_path_copy (path); + if (!model_node_visibility (model, node)) + { + // Node is invisible and therefore the children can just + // be freed + if (free_nodes) + { + file_browser_node_free_children (model, node); + } - gtk_tree_path_down (path_child); + return; + } - list = g_slist_copy (dir->children); + if (path == NULL) + { + path_child = xed_file_browser_store_get_path_real (model, node); + } + else + { + path_child = gtk_tree_path_copy (path); + } - for (item = list; item; item = item->next) { - model_remove_node (model, (FileBrowserNode *) (item->data), - path_child, free_nodes); - } + gtk_tree_path_down (path_child); - g_slist_free (list); - gtk_tree_path_free (path_child); + list = g_slist_copy (dir->children); + + for (item = list; item; item = item->next) + { + model_remove_node (model, (FileBrowserNode *) (item->data), path_child, free_nodes); + } + + g_slist_free (list); + gtk_tree_path_free (path_child); } /** * model_remove_node: * @model: the #XedFileBrowserStore * @node: the FileBrowserNode to remove - * @path: the path to use to remove this node, or NULL to use the path + * @path: the path to use to remove this node, or NULL to use the path * calculated from the node itself * @free_nodes: whether to also remove the nodes from memory - * + * * Removes this node and all its children from the model. This function is used * to remove the node from the _model_. Don't use it to just free * a node. **/ static void -model_remove_node (XedFileBrowserStore * model, - FileBrowserNode * node, - GtkTreePath * path, - gboolean free_nodes) +model_remove_node (XedFileBrowserStore *model, + FileBrowserNode *node, + GtkTreePath *path, + gboolean free_nodes) { - gboolean free_path = FALSE; - FileBrowserNode *parent; + gboolean free_path = FALSE; + FileBrowserNode *parent; - if (path == NULL) { - path = - xed_file_browser_store_get_path_real (model, node); - free_path = TRUE; - } + if (path == NULL) + { + path = xed_file_browser_store_get_path_real (model, node); + free_path = TRUE; + } - model_remove_node_children (model, node, path, free_nodes); + model_remove_node_children (model, node, path, free_nodes); - /* Only delete if the node is visible in the tree (but only when it's - not the virtual root) */ - if (model_node_visibility (model, node) && node != model->priv->virtual_root) - { - node->inserted = FALSE; - row_deleted (model, path); - } + /* Only delete if the node is visible in the tree (but only when it's + not the virtual root) */ + if (model_node_visibility (model, node) && node != model->priv->virtual_root) + { + node->inserted = FALSE; + row_deleted (model, path); + } - if (free_path) - gtk_tree_path_free (path); + if (free_path) + { + gtk_tree_path_free (path); + } - parent = node->parent; + parent = node->parent; - if (free_nodes) { - /* Remove the node from the parents children list */ - if (parent) - FILE_BROWSER_NODE_DIR (node->parent)->children = - g_slist_remove (FILE_BROWSER_NODE_DIR - (node->parent)->children, - node); - } - - /* If this is the virtual root, than set the parent as the virtual root */ - if (node == model->priv->virtual_root) - set_virtual_root_from_node (model, parent); - else if (parent && model_node_visibility (model, parent) && !(free_nodes && NODE_IS_DUMMY(node))) - model_check_dummy (model, parent); + if (free_nodes) + { + /* Remove the node from the parents children list */ + if (parent) + { + FILE_BROWSER_NODE_DIR (node->parent)->children = g_slist_remove (FILE_BROWSER_NODE_DIR + (node->parent)->children, + node); + } + } - /* Now free the node if necessary */ - if (free_nodes) - file_browser_node_free (model, node); + /* If this is the virtual root, than set the parent as the virtual root */ + if (node == model->priv->virtual_root) + { + set_virtual_root_from_node (model, parent); + } + else if (parent && model_node_visibility (model, parent) && !(free_nodes && NODE_IS_DUMMY(node))) + { + model_check_dummy (model, parent); + } + + /* Now free the node if necessary */ + if (free_nodes) + { + file_browser_node_free (model, node); + } } /** @@ -1527,2099 +1656,2293 @@ model_remove_node (XedFileBrowserStore * model, * nodes in the model. **/ static void -model_clear (XedFileBrowserStore * model, gboolean free_nodes) +model_clear (XedFileBrowserStore *model, + gboolean free_nodes) { - GtkTreePath *path; - FileBrowserNodeDir *dir; - FileBrowserNode *dummy; + GtkTreePath *path; + FileBrowserNodeDir *dir; + FileBrowserNode *dummy; - path = gtk_tree_path_new (); - model_remove_node_children (model, model->priv->virtual_root, path, - free_nodes); - gtk_tree_path_free (path); + path = gtk_tree_path_new (); + model_remove_node_children (model, model->priv->virtual_root, path, free_nodes); + gtk_tree_path_free (path); - /* Remove the dummy if there is one */ - if (model->priv->virtual_root) { - dir = FILE_BROWSER_NODE_DIR (model->priv->virtual_root); + /* Remove the dummy if there is one */ + if (model->priv->virtual_root) + { + dir = FILE_BROWSER_NODE_DIR (model->priv->virtual_root); - if (dir->children != NULL) { - dummy = (FileBrowserNode *) (dir->children->data); + if (dir->children != NULL) + { + dummy = (FileBrowserNode *) (dir->children->data); - if (NODE_IS_DUMMY (dummy) - && model_node_visibility (model, dummy)) { - path = gtk_tree_path_new_first (); - - dummy->inserted = FALSE; - row_deleted (model, path); - gtk_tree_path_free (path); - } - } - } + if (NODE_IS_DUMMY (dummy) && model_node_visibility (model, dummy)) + { + path = gtk_tree_path_new_first (); + + dummy->inserted = FALSE; + row_deleted (model, path); + gtk_tree_path_free (path); + } + } + } } static void -file_browser_node_unload (XedFileBrowserStore * model, - FileBrowserNode * node, gboolean remove_children) +file_browser_node_unload (XedFileBrowserStore *model, + FileBrowserNode *node, + gboolean remove_children) { - FileBrowserNodeDir *dir; - - if (node == NULL) - return; + FileBrowserNodeDir *dir; - if (!NODE_IS_DIR (node) || !NODE_LOADED (node)) - return; + if (node == NULL) + { + return; + } - dir = FILE_BROWSER_NODE_DIR (node); + if (!NODE_IS_DIR (node) || !NODE_LOADED (node)) + { + return; + } - if (remove_children) - model_remove_node_children (model, node, NULL, TRUE); + dir = FILE_BROWSER_NODE_DIR (node); - if (dir->cancellable) { - g_cancellable_cancel (dir->cancellable); - g_object_unref (dir->cancellable); + if (remove_children) + { + model_remove_node_children (model, node, NULL, TRUE); + } - model_end_loading (model, node); - dir->cancellable = NULL; - } + if (dir->cancellable) + { + g_cancellable_cancel (dir->cancellable); + g_object_unref (dir->cancellable); - if (dir->monitor) { - g_file_monitor_cancel (dir->monitor); - g_object_unref (dir->monitor); - - dir->monitor = NULL; - } + model_end_loading (model, node); + dir->cancellable = NULL; + } - node->flags &= ~XED_FILE_BROWSER_STORE_FLAG_LOADED; + if (dir->monitor) + { + g_file_monitor_cancel (dir->monitor); + g_object_unref (dir->monitor); + + dir->monitor = NULL; + } + + node->flags &= ~XED_FILE_BROWSER_STORE_FLAG_LOADED; } static void -model_recomposite_icon_real (XedFileBrowserStore * tree_model, - FileBrowserNode * node, - GFileInfo * info) +model_recomposite_icon_real (XedFileBrowserStore *tree_model, + FileBrowserNode *node, + GFileInfo *info) { - GdkPixbuf *icon; + GdkPixbuf *icon; - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model)); - g_return_if_fail (node != NULL); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model)); + g_return_if_fail (node != NULL); - if (node->file == NULL) - return; + if (node->file == NULL) + { + return; + } - if (info) { - GIcon *gicon = g_file_info_get_icon (info); - if (gicon != NULL) - icon = xed_file_browser_utils_pixbuf_from_icon (gicon, GTK_ICON_SIZE_MENU); - else - icon = NULL; - } else { - icon = xed_file_browser_utils_pixbuf_from_file (node->file, GTK_ICON_SIZE_MENU); - } + if (info) + { + GIcon *gicon = g_file_info_get_icon (info); + if (gicon != NULL) + { + icon = xed_file_browser_utils_pixbuf_from_icon (gicon, GTK_ICON_SIZE_MENU); + } + else + { + icon = NULL; + } + } + else + { + icon = xed_file_browser_utils_pixbuf_from_file (node->file, GTK_ICON_SIZE_MENU); + } - if (node->icon) - g_object_unref (node->icon); + if (node->icon) + { + g_object_unref (node->icon); + } - if (node->emblem) { - gint icon_size; + if (node->emblem) + { + gint icon_size; - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_size); + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_size); - if (icon == NULL) { - node->icon = - gdk_pixbuf_new (gdk_pixbuf_get_colorspace (node->emblem), - gdk_pixbuf_get_has_alpha (node->emblem), - gdk_pixbuf_get_bits_per_sample (node->emblem), - icon_size, - icon_size); - } else { - node->icon = gdk_pixbuf_copy (icon); - g_object_unref (icon); - } + if (icon == NULL) + { + node->icon = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (node->emblem), + gdk_pixbuf_get_has_alpha (node->emblem), + gdk_pixbuf_get_bits_per_sample (node->emblem), + icon_size, + icon_size); + } + else + { + node->icon = gdk_pixbuf_copy (icon); + g_object_unref (icon); + } - gdk_pixbuf_composite (node->emblem, node->icon, - icon_size - 10, icon_size - 10, 10, - 10, icon_size - 10, icon_size - 10, - 1, 1, GDK_INTERP_NEAREST, 255); - } else { - node->icon = icon; - } + gdk_pixbuf_composite (node->emblem, node->icon, + icon_size - 10, icon_size - 10, 10, + 10, icon_size - 10, icon_size - 10, + 1, 1, GDK_INTERP_NEAREST, 255); + } + else + { + node->icon = icon; + } } static void -model_recomposite_icon (XedFileBrowserStore * tree_model, - GtkTreeIter * iter) +model_recomposite_icon (XedFileBrowserStore *tree_model, + GtkTreeIter *iter) { - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model)); - g_return_if_fail (iter != NULL); - g_return_if_fail (iter->user_data != NULL); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model)); + g_return_if_fail (iter != NULL); + g_return_if_fail (iter->user_data != NULL); - model_recomposite_icon_real (tree_model, - (FileBrowserNode *) (iter->user_data), - NULL); + model_recomposite_icon_real (tree_model, (FileBrowserNode *) (iter->user_data), NULL); } static FileBrowserNode * -model_create_dummy_node (XedFileBrowserStore * model, - FileBrowserNode * parent) +model_create_dummy_node (XedFileBrowserStore *model, + FileBrowserNode *parent) { - FileBrowserNode *dummy; + FileBrowserNode *dummy; - dummy = file_browser_node_new (NULL, parent); - dummy->name = g_strdup (_("(Empty)")); + dummy = file_browser_node_new (NULL, parent); + dummy->name = g_strdup (_("(Empty)")); - dummy->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_DUMMY; - dummy->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + dummy->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_DUMMY; + dummy->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; - return dummy; + return dummy; } static FileBrowserNode * -model_add_dummy_node (XedFileBrowserStore * model, - FileBrowserNode * parent) +model_add_dummy_node (XedFileBrowserStore *model, + FileBrowserNode *parent) { - FileBrowserNode *dummy; + FileBrowserNode *dummy; - dummy = model_create_dummy_node (model, parent); + dummy = model_create_dummy_node (model, parent); - if (model_node_visibility (model, parent)) - dummy->flags &= ~XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + if (model_node_visibility (model, parent)) + { + dummy->flags &= ~XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + } - model_add_node (model, dummy, parent); + model_add_node (model, dummy, parent); - return dummy; + return dummy; } static void -model_check_dummy (XedFileBrowserStore * model, FileBrowserNode * node) +model_check_dummy (XedFileBrowserStore *model, + FileBrowserNode *node) { - // Hide the dummy child if needed - if (NODE_IS_DIR (node)) { - FileBrowserNode *dummy; - GtkTreeIter iter; - GtkTreePath *path; - guint flags; - FileBrowserNodeDir *dir; + // Hide the dummy child if needed + if (NODE_IS_DIR (node)) + { + FileBrowserNode *dummy; + GtkTreeIter iter; + GtkTreePath *path; + guint flags; + FileBrowserNodeDir *dir; - dir = FILE_BROWSER_NODE_DIR (node); + dir = FILE_BROWSER_NODE_DIR (node); - if (dir->children == NULL) { - model_add_dummy_node (model, node); - return; - } + if (dir->children == NULL) + { + model_add_dummy_node (model, node); + return; + } - dummy = (FileBrowserNode *) (dir->children->data); + dummy = (FileBrowserNode *) (dir->children->data); - if (!NODE_IS_DUMMY (dummy)) { - dummy = model_create_dummy_node (model, node); - dir->children = g_slist_prepend (dir->children, dummy); - } + if (!NODE_IS_DUMMY (dummy)) + { + dummy = model_create_dummy_node (model, node); + dir->children = g_slist_prepend (dir->children, dummy); + } - if (!model_node_visibility (model, node)) { - dummy->flags |= - XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; - return; - } + if (!model_node_visibility (model, node)) + { + dummy->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + return; + } - /* Temporarily set the node to invisible to check - * for real children */ - flags = dummy->flags; - dummy->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + /* Temporarily set the node to invisible to check + * for real children */ + flags = dummy->flags; + dummy->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; - if (!filter_tree_model_iter_has_child_real (model, node)) { - dummy->flags &= - ~XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + if (!filter_tree_model_iter_has_child_real (model, node)) + { + dummy->flags &= ~XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; - if (FILE_IS_HIDDEN (flags)) { - // Was hidden, needs to be inserted - iter.user_data = dummy; - path = - xed_file_browser_store_get_path_real - (model, dummy); - - row_inserted (model, &path, &iter); - gtk_tree_path_free (path); - } - } else { - if (!FILE_IS_HIDDEN (flags)) { - // Was shown, needs to be removed + if (FILE_IS_HIDDEN (flags)) + { + // Was hidden, needs to be inserted + iter.user_data = dummy; + path = xed_file_browser_store_get_path_real (model, dummy); - // To get the path we need to set it to visible temporarily - dummy->flags &= - ~XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; - path = - xed_file_browser_store_get_path_real - (model, dummy); - dummy->flags |= - XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; - - dummy->inserted = FALSE; - row_deleted (model, path); - gtk_tree_path_free (path); - } - } - } + row_inserted (model, &path, &iter); + gtk_tree_path_free (path); + } + } + else + { + if (!FILE_IS_HIDDEN (flags)) + { + // Was shown, needs to be removed + + // To get the path we need to set it to visible temporarily + dummy->flags &= ~XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + path = xed_file_browser_store_get_path_real (model, dummy); + dummy->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + + dummy->inserted = FALSE; + row_deleted (model, path); + gtk_tree_path_free (path); + } + } + } } static void -insert_node_sorted (XedFileBrowserStore * model, - FileBrowserNode * child, - FileBrowserNode * parent) +insert_node_sorted (XedFileBrowserStore *model, + FileBrowserNode *child, + FileBrowserNode *parent) { - FileBrowserNodeDir *dir; + FileBrowserNodeDir *dir; - dir = FILE_BROWSER_NODE_DIR (parent); + dir = FILE_BROWSER_NODE_DIR (parent); - if (model->priv->sort_func == NULL) { - dir->children = g_slist_append (dir->children, child); - } else { - dir->children = - g_slist_insert_sorted (dir->children, child, - (GCompareFunc) (model->priv-> - sort_func)); - } + if (model->priv->sort_func == NULL) + { + dir->children = g_slist_append (dir->children, child); + } + else + { + dir->children = g_slist_insert_sorted (dir->children, child, (GCompareFunc) (model->priv->sort_func)); + } } static void -model_add_node (XedFileBrowserStore * model, FileBrowserNode * child, - FileBrowserNode * parent) +model_add_node (XedFileBrowserStore *model, + FileBrowserNode *child, + FileBrowserNode *parent) { - /* Add child to parents children */ - insert_node_sorted (model, child, parent); + /* Add child to parents children */ + insert_node_sorted (model, child, parent); - if (model_node_visibility (model, parent) && - model_node_visibility (model, child)) { - GtkTreeIter iter; - GtkTreePath *path; + if (model_node_visibility (model, parent) && model_node_visibility (model, child)) + { + GtkTreeIter iter; + GtkTreePath *path; - iter.user_data = child; - path = xed_file_browser_store_get_path_real (model, child); + iter.user_data = child; + path = xed_file_browser_store_get_path_real (model, child); - /* Emit row inserted */ - row_inserted (model, &path, &iter); - gtk_tree_path_free (path); - } + /* Emit row inserted */ + row_inserted (model, &path, &iter); + gtk_tree_path_free (path); + } - model_check_dummy (model, parent); - model_check_dummy (model, child); + model_check_dummy (model, parent); + model_check_dummy (model, child); } static void -model_add_nodes_batch (XedFileBrowserStore * model, - GSList * children, - FileBrowserNode * parent) +model_add_nodes_batch (XedFileBrowserStore *model, + GSList *children, + FileBrowserNode *parent) { - GSList *sorted_children; - GSList *child; - GSList *prev; - GSList *l; - FileBrowserNodeDir *dir; + GSList *sorted_children; + GSList *child; + GSList *prev; + GSList *l; + FileBrowserNodeDir *dir; - dir = FILE_BROWSER_NODE_DIR (parent); + dir = FILE_BROWSER_NODE_DIR (parent); - sorted_children = g_slist_sort (children, (GCompareFunc) model->priv->sort_func); + sorted_children = g_slist_sort (children, (GCompareFunc) model->priv->sort_func); - child = sorted_children; - l = dir->children; - prev = NULL; + child = sorted_children; + l = dir->children; + prev = NULL; - model_check_dummy (model, parent); + model_check_dummy (model, parent); - while (child) { - FileBrowserNode *node = child->data; - GtkTreeIter iter; - GtkTreePath *path; + while (child) + { + FileBrowserNode *node = child->data; + GtkTreeIter iter; + GtkTreePath *path; - /* reached the end of the first list, just append the second */ - if (l == NULL) { + /* reached the end of the first list, just append the second */ + if (l == NULL) + { - dir->children = g_slist_concat (dir->children, child); + dir->children = g_slist_concat (dir->children, child); - for (l = child; l; l = l->next) { - if (model_node_visibility (model, parent) && - model_node_visibility (model, l->data)) { - iter.user_data = l->data; - path = xed_file_browser_store_get_path_real (model, l->data); + for (l = child; l; l = l->next) + { + if (model_node_visibility (model, parent) && model_node_visibility (model, l->data)) + { + iter.user_data = l->data; + path = xed_file_browser_store_get_path_real (model, l->data); - // Emit row inserted - row_inserted (model, &path, &iter); - gtk_tree_path_free (path); - } + // Emit row inserted + row_inserted (model, &path, &iter); + gtk_tree_path_free (path); + } - model_check_dummy (model, l->data); - } + model_check_dummy (model, l->data); + } - break; - } + break; + } - if (model->priv->sort_func (l->data, node) > 0) { - GSList *next_child; + if (model->priv->sort_func (l->data, node) > 0) + { + GSList *next_child; - if (prev == NULL) { - /* prepend to the list */ - dir->children = g_slist_prepend (dir->children, child); - } else { - prev->next = child; - } + if (prev == NULL) + { + /* prepend to the list */ + dir->children = g_slist_prepend (dir->children, child); + } + else + { + prev->next = child; + } - next_child = child->next; - prev = child; - child->next = l; - child = next_child; + next_child = child->next; + prev = child; + child->next = l; + child = next_child; - if (model_node_visibility (model, parent) && - model_node_visibility (model, node)) { - iter.user_data = node; - path = xed_file_browser_store_get_path_real (model, node); + if (model_node_visibility (model, parent) && model_node_visibility (model, node)) + { + iter.user_data = node; + path = xed_file_browser_store_get_path_real (model, node); - // Emit row inserted - row_inserted (model, &path, &iter); - gtk_tree_path_free (path); - } + // Emit row inserted + row_inserted (model, &path, &iter); + gtk_tree_path_free (path); + } - model_check_dummy (model, node); + model_check_dummy (model, node); - /* try again at the same l position with the - * next child */ - } else { + /* try again at the same l position with the + * next child */ + } + else + { - /* Move to the next item in the list */ - prev = l; - l = l->next; - } - } + /* Move to the next item in the list */ + prev = l; + l = l->next; + } + } } static gchar const * -backup_content_type (GFileInfo * info) +backup_content_type (GFileInfo *info) { - gchar const * content; - - if (!g_file_info_get_is_backup (info)) - return NULL; - - content = g_file_info_get_content_type (info); - - if (!content || g_content_type_equals (content, "application/x-trash")) - return "text/plain"; - - return content; + gchar const * content; + + if (!g_file_info_get_is_backup (info)) + { + return NULL; + } + + content = g_file_info_get_content_type (info); + + if (!content || g_content_type_equals (content, "application/x-trash")) + { + return "text/plain"; + } + + return content; } static void -file_browser_node_set_from_info (XedFileBrowserStore * model, - FileBrowserNode * node, - GFileInfo * info, - gboolean isadded) +file_browser_node_set_from_info (XedFileBrowserStore *model, + FileBrowserNode *node, + GFileInfo *info, + gboolean isadded) { - FileBrowserNodeDir * dir; - gchar const * content; - gchar const * name; - gboolean free_info = FALSE; - GtkTreePath * path; - gchar * uri; - GError * error = NULL; + FileBrowserNodeDir *dir; + gchar const *content; + gchar const *name; + gboolean free_info = FALSE; + GtkTreePath *path; + gchar *uri; + GError *error = NULL; - if (info == NULL) { - info = g_file_query_info (node->file, - STANDARD_ATTRIBUTE_TYPES, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - - if (!info) { - if (!(error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_FOUND)) { - uri = g_file_get_uri (node->file); - g_warning ("Could not get info for %s: %s", uri, error->message); - g_free (uri); - } - g_error_free (error); + if (info == NULL) + { + info = g_file_query_info (node->file, + STANDARD_ATTRIBUTE_TYPES, + G_FILE_QUERY_INFO_NONE, + NULL, + &error); - return; - } - - free_info = TRUE; - } + if (!info) + { + if (!(error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_FOUND)) + { + uri = g_file_get_uri (node->file); + g_warning ("Could not get info for %s: %s", uri, error->message); + g_free (uri); + } + g_error_free (error); - dir = FILE_BROWSER_NODE_DIR (node->parent); - name = g_file_info_get_name (info); + return; + } - if (g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info)) - node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; - else if (dir != NULL && dir->hidden_file_hash != NULL && - g_hash_table_lookup (dir->hidden_file_hash, name) != NULL) - node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + free_info = TRUE; + } - if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) - node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY; - else { - if (!(content = backup_content_type (info))) - content = g_file_info_get_content_type (info); - - if (!content || - g_content_type_is_unknown (content) || - g_content_type_is_a (content, "text/plain")) - node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_TEXT; - } - - model_recomposite_icon_real (model, node, info); + dir = FILE_BROWSER_NODE_DIR (node->parent); + name = g_file_info_get_name (info); - if (free_info) - g_object_unref (info); + if (g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info)) + { + node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + } + else if (dir != NULL && dir->hidden_file_hash != NULL && g_hash_table_lookup (dir->hidden_file_hash, name) != NULL) + { + node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + } - if (isadded) { - path = xed_file_browser_store_get_path_real (model, node); - model_refilter_node (model, node, &path); - gtk_tree_path_free (path); - - model_check_dummy (model, node->parent); - } else { - model_node_update_visibility (model, node); - } + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + { + node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY; + } + else + { + if (!(content = backup_content_type (info))) + { + content = g_file_info_get_content_type (info); + } + + if (!content || + g_content_type_is_unknown (content) || + g_content_type_is_a (content, "text/plain")) + { + node->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_TEXT; + } + } + + model_recomposite_icon_real (model, node, info); + + if (free_info) + { + g_object_unref (info); + } + + if (isadded) + { + path = xed_file_browser_store_get_path_real (model, node); + model_refilter_node (model, node, &path); + gtk_tree_path_free (path); + + model_check_dummy (model, node->parent); + } + else + { + model_node_update_visibility (model, node); + } } static FileBrowserNode * -node_list_contains_file (GSList *children, GFile * file) +node_list_contains_file (GSList *children, + GFile *file) { - GSList *item; + GSList *item; - for (item = children; item; item = item->next) { - FileBrowserNode *node; + for (item = children; item; item = item->next) + { + FileBrowserNode *node; - node = (FileBrowserNode *) (item->data); + node = (FileBrowserNode *) (item->data); - if (node->file != NULL - && g_file_equal (node->file, file)) - return node; - } + if (node->file != NULL && g_file_equal (node->file, file)) + { + return node; + } + } - return NULL; + return NULL; } static FileBrowserNode * -model_add_node_from_file (XedFileBrowserStore * model, - FileBrowserNode * parent, - GFile * file, - GFileInfo * info) +model_add_node_from_file (XedFileBrowserStore *model, + FileBrowserNode *parent, + GFile *file, + GFileInfo *info) { - FileBrowserNode *node; - gboolean free_info = FALSE; - GError * error = NULL; + FileBrowserNode *node; + gboolean free_info = FALSE; + GError * error = NULL; - if ((node = node_list_contains_file (FILE_BROWSER_NODE_DIR (parent)->children, file)) == NULL) { - if (info == NULL) { - info = g_file_query_info (file, - STANDARD_ATTRIBUTE_TYPES, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - free_info = TRUE; - } - - if (!info) { - g_warning ("Error querying file info: %s", error->message); - g_error_free (error); - - /* FIXME: What to do now then... */ - node = file_browser_node_new (file, parent); - } else if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { - node = file_browser_node_dir_new (model, file, parent); - } else { - node = file_browser_node_new (file, parent); - } + if ((node = node_list_contains_file (FILE_BROWSER_NODE_DIR (parent)->children, file)) == NULL) + { + if (info == NULL) + { + info = g_file_query_info (file, + STANDARD_ATTRIBUTE_TYPES, + G_FILE_QUERY_INFO_NONE, + NULL, + &error); + free_info = TRUE; + } - file_browser_node_set_from_info (model, node, info, FALSE); - model_add_node (model, node, parent); - - if (info && free_info) - g_object_unref (info); - } + if (!info) + { + g_warning ("Error querying file info: %s", error->message); + g_error_free (error); - return node; + /* FIXME: What to do now then... */ + node = file_browser_node_new (file, parent); + } + else if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + { + node = file_browser_node_dir_new (model, file, parent); + } + else + { + node = file_browser_node_new (file, parent); + } + + file_browser_node_set_from_info (model, node, info, FALSE); + model_add_node (model, node, parent); + + if (info && free_info) + { + g_object_unref (info); + } + } + + return node; } /* We pass in a copy of the list of parent->children so that we do * not have to check if a file already exists among the ones we just * added */ static void -model_add_nodes_from_files (XedFileBrowserStore * model, - FileBrowserNode * parent, - GSList * original_children, - GList * files) +model_add_nodes_from_files (XedFileBrowserStore *model, + FileBrowserNode *parent, + GSList *original_children, + GList *files) { - GList *item; - GSList *nodes = NULL; + GList *item; + GSList *nodes = NULL; - for (item = files; item; item = item->next) { - GFileInfo *info = G_FILE_INFO (item->data); - GFileType type; - gchar const * name; - GFile * file; - FileBrowserNode *node; + for (item = files; item; item = item->next) + { + GFileInfo *info = G_FILE_INFO (item->data); + GFileType type; + gchar const *name; + GFile *file; + FileBrowserNode *node; - type = g_file_info_get_file_type (info); + type = g_file_info_get_file_type (info); - /* Skip all non regular, non directory files */ - if (type != G_FILE_TYPE_REGULAR && - type != G_FILE_TYPE_DIRECTORY && - type != G_FILE_TYPE_SYMBOLIC_LINK) { - g_object_unref (info); - continue; - } + /* Skip all non regular, non directory files */ + if (type != G_FILE_TYPE_REGULAR && + type != G_FILE_TYPE_DIRECTORY && + type != G_FILE_TYPE_SYMBOLIC_LINK) + { + g_object_unref (info); + continue; + } - name = g_file_info_get_name (info); + name = g_file_info_get_name (info); - /* Skip '.' and '..' directories */ - if (type == G_FILE_TYPE_DIRECTORY && - (strcmp (name, ".") == 0 || - strcmp (name, "..") == 0)) { - continue; - } + /* Skip '.' and '..' directories */ + if (type == G_FILE_TYPE_DIRECTORY && + (strcmp (name, ".") == 0 || + strcmp (name, "..") == 0)) + { + continue; + } - file = g_file_get_child (parent->file, name); + file = g_file_get_child (parent->file, name); - if ((node = node_list_contains_file (original_children, file)) == NULL) { + if ((node = node_list_contains_file (original_children, file)) == NULL) + { - if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { - node = file_browser_node_dir_new (model, file, parent); - } else { - node = file_browser_node_new (file, parent); - } + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + { + node = file_browser_node_dir_new (model, file, parent); + } + else + { + node = file_browser_node_new (file, parent); + } - file_browser_node_set_from_info (model, node, info, FALSE); + file_browser_node_set_from_info (model, node, info, FALSE); - nodes = g_slist_prepend (nodes, node); - } + nodes = g_slist_prepend (nodes, node); + } - g_object_unref (file); - g_object_unref (info); - } + g_object_unref (file); + g_object_unref (info); + } - if (nodes) - model_add_nodes_batch (model, nodes, parent); + if (nodes) + { + model_add_nodes_batch (model, nodes, parent); + } } static FileBrowserNode * -model_add_node_from_dir (XedFileBrowserStore * model, - FileBrowserNode * parent, - GFile * file) +model_add_node_from_dir (XedFileBrowserStore *model, + FileBrowserNode *parent, + GFile *file) { - FileBrowserNode *node; + FileBrowserNode *node; - /* Check if it already exists */ - if ((node = node_list_contains_file (FILE_BROWSER_NODE_DIR (parent)->children, file)) == NULL) { - node = file_browser_node_dir_new (model, file, parent); - file_browser_node_set_from_info (model, node, NULL, FALSE); + /* Check if it already exists */ + if ((node = node_list_contains_file (FILE_BROWSER_NODE_DIR (parent)->children, file)) == NULL) + { + node = file_browser_node_dir_new (model, file, parent); + file_browser_node_set_from_info (model, node, NULL, FALSE); - if (node->name == NULL) { - file_browser_node_set_name (node); - } + if (node->name == NULL) + { + file_browser_node_set_name (node); + } - if (node->icon == NULL) { - node->icon = xed_file_browser_utils_pixbuf_from_theme ("folder", GTK_ICON_SIZE_MENU); - } + if (node->icon == NULL) + { + node->icon = xed_file_browser_utils_pixbuf_from_theme ("folder", GTK_ICON_SIZE_MENU); + } - model_add_node (model, node, parent); - } + model_add_node (model, node, parent); + } - return node; + return node; } /* Read is sync, but we only do it for local files */ static void parse_dot_hidden_file (FileBrowserNode *directory) { - gsize file_size; - char *file_contents; - GFile *child; - GFileInfo *info; - GFileType type; - int i; - FileBrowserNodeDir * dir = FILE_BROWSER_NODE_DIR (directory); + gsize file_size; + char *file_contents; + GFile *child; + GFileInfo *info; + GFileType type; + int i; + FileBrowserNodeDir * dir = FILE_BROWSER_NODE_DIR (directory); - /* FIXME: We only support .hidden on file: uri's for the moment. - * Need to figure out if we should do this async or sync to extend - * it to all types of uris. - */ - if (directory->file == NULL || !g_file_is_native (directory->file)) { - return; - } - - child = g_file_get_child (directory->file, ".hidden"); - info = g_file_query_info (child, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL); + /* FIXME: We only support .hidden on file: uri's for the moment. + * Need to figure out if we should do this async or sync to extend + * it to all types of uris. + */ + if (directory->file == NULL || !g_file_is_native (directory->file)) + { + return; + } - type = info ? g_file_info_get_file_type (info) : G_FILE_TYPE_UNKNOWN; - - if (info) - g_object_unref (info); - - if (type != G_FILE_TYPE_REGULAR) { - g_object_unref (child); + child = g_file_get_child (directory->file, ".hidden"); + info = g_file_query_info (child, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL); - return; - } + type = info ? g_file_info_get_file_type (info) : G_FILE_TYPE_UNKNOWN; - if (!g_file_load_contents (child, NULL, &file_contents, &file_size, NULL, NULL)) { - g_object_unref (child); - return; - } + if (info) + { + g_object_unref (info); + } - g_object_unref (child); + if (type != G_FILE_TYPE_REGULAR) + { + g_object_unref (child); + return; + } - if (dir->hidden_file_hash == NULL) { - dir->hidden_file_hash = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - } - - /* Now parse the data */ - i = 0; - while (i < file_size) { - int start; + if (!g_file_load_contents (child, NULL, &file_contents, &file_size, NULL, NULL)) + { + g_object_unref (child); + return; + } - start = i; - while (i < file_size && file_contents[i] != '\n') { - i++; - } + g_object_unref (child); - if (i > start) { - char *hidden_filename; - - hidden_filename = g_strndup (file_contents + start, i - start); - g_hash_table_insert (dir->hidden_file_hash, - hidden_filename, hidden_filename); - } + if (dir->hidden_file_hash == NULL) + { + dir->hidden_file_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + } - i++; - - } + /* Now parse the data */ + i = 0; + while (i < file_size) + { + int start; - g_free (file_contents); + start = i; + while (i < file_size && file_contents[i] != '\n') + { + i++; + } + + if (i > start) + { + char *hidden_filename; + + hidden_filename = g_strndup (file_contents + start, i - start); + g_hash_table_insert (dir->hidden_file_hash, hidden_filename, hidden_filename); + } + + i++; + + } + + g_free (file_contents); } static void -on_directory_monitor_event (GFileMonitor * monitor, - GFile * file, - GFile * other_file, - GFileMonitorEvent event_type, - FileBrowserNode * parent) +on_directory_monitor_event (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + FileBrowserNode *parent) { - FileBrowserNode *node; - FileBrowserNodeDir *dir = FILE_BROWSER_NODE_DIR (parent); + FileBrowserNode *node; + FileBrowserNodeDir *dir = FILE_BROWSER_NODE_DIR (parent); - switch (event_type) { - case G_FILE_MONITOR_EVENT_DELETED: - node = node_list_contains_file (dir->children, file); + switch (event_type) + { + case G_FILE_MONITOR_EVENT_DELETED: + node = node_list_contains_file (dir->children, file); - if (node != NULL) { - model_remove_node (dir->model, node, NULL, TRUE); - } - break; - case G_FILE_MONITOR_EVENT_CREATED: - if (g_file_query_exists (file, NULL)) { - model_add_node_from_file (dir->model, parent, file, NULL); - } - - break; - default: - break; - } + if (node != NULL) + { + model_remove_node (dir->model, node, NULL, TRUE); + } + break; + case G_FILE_MONITOR_EVENT_CREATED: + if (g_file_query_exists (file, NULL)) + { + model_add_node_from_file (dir->model, parent, file, NULL); + } + + break; + default: + break; + } } static void async_node_free (AsyncNode *async) { - g_object_unref (async->cancellable); - g_slist_free (async->original_children); - g_free (async); + g_object_unref (async->cancellable); + g_slist_free (async->original_children); + g_free (async); } static void -model_iterate_next_files_cb (GFileEnumerator * enumerator, - GAsyncResult * result, - AsyncNode * async) +model_iterate_next_files_cb (GFileEnumerator *enumerator, + GAsyncResult *result, + AsyncNode *async) { - GList * files; - GError * error = NULL; - FileBrowserNodeDir * dir = async->dir; - FileBrowserNode * parent = (FileBrowserNode *)dir; - - files = g_file_enumerator_next_files_finish (enumerator, result, &error); + GList *files; + GError *error = NULL; + FileBrowserNodeDir *dir = async->dir; + FileBrowserNode *parent = (FileBrowserNode *)dir; + + files = g_file_enumerator_next_files_finish (enumerator, result, &error); + + if (files == NULL) + { + g_file_enumerator_close (enumerator, NULL, NULL); + async_node_free (async); + + if (!error) + { + /* We're done loading */ + g_object_unref (dir->cancellable); + dir->cancellable = NULL; - if (files == NULL) { - g_file_enumerator_close (enumerator, NULL, NULL); - async_node_free (async); - - if (!error) - { - /* We're done loading */ - g_object_unref (dir->cancellable); - dir->cancellable = NULL; - /* * FIXME: This is temporarly, it is a bug in gio: * http://bugzilla.gnome.org/show_bug.cgi?id=565924 */ - if (g_file_is_native (parent->file) && dir->monitor == NULL) { - dir->monitor = g_file_monitor_directory (parent->file, - G_FILE_MONITOR_NONE, - NULL, - NULL); - if (dir->monitor != NULL) - { - g_signal_connect (dir->monitor, - "changed", - G_CALLBACK (on_directory_monitor_event), - parent); - } - } + if (g_file_is_native (parent->file) && dir->monitor == NULL) + { + dir->monitor = g_file_monitor_directory (parent->file, + G_FILE_MONITOR_NONE, + NULL, + NULL); + if (dir->monitor != NULL) + { + g_signal_connect (dir->monitor, "changed", + G_CALLBACK (on_directory_monitor_event), parent); + } + } - model_check_dummy (dir->model, parent); - model_end_loading (dir->model, parent); - } else { - /* Simply return if we were cancelled */ - if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED) - return; - - /* Otherwise handle the error appropriately */ - g_signal_emit (dir->model, - model_signals[ERROR], - 0, - XED_FILE_BROWSER_ERROR_LOAD_DIRECTORY, - error->message); + model_check_dummy (dir->model, parent); + model_end_loading (dir->model, parent); + } + else + { + /* Simply return if we were cancelled */ + if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED) + { + return; + } - file_browser_node_unload (dir->model, (FileBrowserNode *)parent, TRUE); - g_error_free (error); - } - } else if (g_cancellable_is_cancelled (async->cancellable)) { - /* Check cancel state manually */ - g_file_enumerator_close (enumerator, NULL, NULL); - async_node_free (async); - } else { - model_add_nodes_from_files (dir->model, parent, async->original_children, files); - - g_list_free (files); - next_files_async (enumerator, async); - } + /* Otherwise handle the error appropriately */ + g_signal_emit (dir->model, + model_signals[ERROR], + 0, + XED_FILE_BROWSER_ERROR_LOAD_DIRECTORY, + error->message); + + file_browser_node_unload (dir->model, (FileBrowserNode *)parent, TRUE); + g_error_free (error); + } + } + else if (g_cancellable_is_cancelled (async->cancellable)) + { + /* Check cancel state manually */ + g_file_enumerator_close (enumerator, NULL, NULL); + async_node_free (async); + } + else + { + model_add_nodes_from_files (dir->model, parent, async->original_children, files); + + g_list_free (files); + next_files_async (enumerator, async); + } } static void -next_files_async (GFileEnumerator * enumerator, - AsyncNode * async) +next_files_async (GFileEnumerator *enumerator, + AsyncNode *async) { - g_file_enumerator_next_files_async (enumerator, - DIRECTORY_LOAD_ITEMS_PER_CALLBACK, - G_PRIORITY_DEFAULT, - async->cancellable, - (GAsyncReadyCallback)model_iterate_next_files_cb, - async); + g_file_enumerator_next_files_async (enumerator, + DIRECTORY_LOAD_ITEMS_PER_CALLBACK, + G_PRIORITY_DEFAULT, + async->cancellable, + (GAsyncReadyCallback)model_iterate_next_files_cb, + async); } static void -model_iterate_children_cb (GFile * file, - GAsyncResult * result, - AsyncNode * async) +model_iterate_children_cb (GFile *file, + GAsyncResult *result, + AsyncNode *async) { - GError * error = NULL; - GFileEnumerator * enumerator; + GError * error = NULL; + GFileEnumerator * enumerator; - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_node_free (async); - return; - } - - enumerator = g_file_enumerate_children_finish (file, result, &error); + if (g_cancellable_is_cancelled (async->cancellable)) + { + async_node_free (async); + return; + } - if (enumerator == NULL) { - /* Simply return if we were cancelled or if the dir is not there */ - FileBrowserNodeDir *dir = async->dir; - - /* Otherwise handle the error appropriately */ - g_signal_emit (dir->model, - model_signals[ERROR], - 0, - XED_FILE_BROWSER_ERROR_LOAD_DIRECTORY, - error->message); + enumerator = g_file_enumerate_children_finish (file, result, &error); - file_browser_node_unload (dir->model, (FileBrowserNode *)dir, TRUE); - g_error_free (error); - async_node_free (async); - } else { - next_files_async (enumerator, async); - } + if (enumerator == NULL) + { + /* Simply return if we were cancelled or if the dir is not there */ + FileBrowserNodeDir *dir = async->dir; + + /* Otherwise handle the error appropriately */ + g_signal_emit (dir->model, + model_signals[ERROR], + 0, + XED_FILE_BROWSER_ERROR_LOAD_DIRECTORY, + error->message); + + file_browser_node_unload (dir->model, (FileBrowserNode *)dir, TRUE); + g_error_free (error); + async_node_free (async); + } + else + { + next_files_async (enumerator, async); + } } static void -model_load_directory (XedFileBrowserStore * model, - FileBrowserNode * node) +model_load_directory (XedFileBrowserStore *model, + FileBrowserNode *node) { - FileBrowserNodeDir *dir; - AsyncNode *async; + FileBrowserNodeDir *dir; + AsyncNode *async; - g_return_if_fail (NODE_IS_DIR (node)); + g_return_if_fail (NODE_IS_DIR (node)); - dir = FILE_BROWSER_NODE_DIR (node); + dir = FILE_BROWSER_NODE_DIR (node); - /* Cancel a previous load */ - if (dir->cancellable != NULL) { - file_browser_node_unload (dir->model, node, TRUE); - } + /* Cancel a previous load */ + if (dir->cancellable != NULL) + { + file_browser_node_unload (dir->model, node, TRUE); + } - node->flags |= XED_FILE_BROWSER_STORE_FLAG_LOADED; - model_begin_loading (model, node); + node->flags |= XED_FILE_BROWSER_STORE_FLAG_LOADED; + model_begin_loading (model, node); - /* Read the '.hidden' file first (if any) */ - parse_dot_hidden_file (node); - - dir->cancellable = g_cancellable_new (); - - async = g_new (AsyncNode, 1); - async->dir = dir; - async->cancellable = g_object_ref (dir->cancellable); - async->original_children = g_slist_copy (dir->children); + /* Read the '.hidden' file first (if any) */ + parse_dot_hidden_file (node); - /* Start loading async */ - g_file_enumerate_children_async (node->file, - STANDARD_ATTRIBUTE_TYPES, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_DEFAULT, - async->cancellable, - (GAsyncReadyCallback)model_iterate_children_cb, - async); + dir->cancellable = g_cancellable_new (); + + async = g_new (AsyncNode, 1); + async->dir = dir; + async->cancellable = g_object_ref (dir->cancellable); + async->original_children = g_slist_copy (dir->children); + + /* Start loading async */ + g_file_enumerate_children_async (node->file, + STANDARD_ATTRIBUTE_TYPES, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + async->cancellable, + (GAsyncReadyCallback)model_iterate_children_cb, + async); } static GList * -get_parent_files (XedFileBrowserStore * model, GFile * file) +get_parent_files (XedFileBrowserStore *model, + GFile *file) { - GList * result = NULL; - - result = g_list_prepend (result, g_object_ref (file)); + GList * result = NULL; - while ((file = g_file_get_parent (file))) { - if (g_file_equal (file, model->priv->root->file)) { - g_object_unref (file); - break; - } + result = g_list_prepend (result, g_object_ref (file)); - result = g_list_prepend (result, file); - } + while ((file = g_file_get_parent (file))) + { + if (g_file_equal (file, model->priv->root->file)) + { + g_object_unref (file); + break; + } - return result; + result = g_list_prepend (result, file); + } + + return result; } static void -model_fill (XedFileBrowserStore * model, FileBrowserNode * node, - GtkTreePath ** path) +model_fill (XedFileBrowserStore *model, + FileBrowserNode *node, + GtkTreePath **path) { - gboolean free_path = FALSE; - GtkTreeIter iter = {0,}; - GSList *item; - FileBrowserNode *child; + gboolean free_path = FALSE; + GtkTreeIter iter = {0,}; + GSList *item; + FileBrowserNode *child; - if (node == NULL) { - node = model->priv->virtual_root; - *path = gtk_tree_path_new (); - free_path = TRUE; - } + if (node == NULL) + { + node = model->priv->virtual_root; + *path = gtk_tree_path_new (); + free_path = TRUE; + } - if (*path == NULL) { - *path = - xed_file_browser_store_get_path_real (model, node); - free_path = TRUE; - } + if (*path == NULL) + { + *path = xed_file_browser_store_get_path_real (model, node); + free_path = TRUE; + } - if (!model_node_visibility (model, node)) { - if (free_path) - gtk_tree_path_free (*path); + if (!model_node_visibility (model, node)) + { + if (free_path) + { + gtk_tree_path_free (*path); + } - return; - } + return; + } - if (node != model->priv->virtual_root) { - /* Insert node */ - iter.user_data = node; - - row_inserted(model, path, &iter); - } + if (node != model->priv->virtual_root) + { + /* Insert node */ + iter.user_data = node; - if (NODE_IS_DIR (node)) { - /* Go to the first child */ - gtk_tree_path_down (*path); + row_inserted(model, path, &iter); + } - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; - item = item->next) { - child = (FileBrowserNode *) (item->data); + if (NODE_IS_DIR (node)) + { + /* Go to the first child */ + gtk_tree_path_down (*path); - if (model_node_visibility (model, child)) { - model_fill (model, child, path); + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) { + child = (FileBrowserNode *) (item->data); - /* Increase path for next child */ - gtk_tree_path_next (*path); - } - } + if (model_node_visibility (model, child)) + { + model_fill (model, child, path); - /* Move back up to node path */ - gtk_tree_path_up (*path); - } - - model_check_dummy (model, node); + /* Increase path for next child */ + gtk_tree_path_next (*path); + } + } - if (free_path) - gtk_tree_path_free (*path); + /* Move back up to node path */ + gtk_tree_path_up (*path); + } + + model_check_dummy (model, node); + + if (free_path) + { + gtk_tree_path_free (*path); + } } static void -set_virtual_root_from_node (XedFileBrowserStore * model, - FileBrowserNode * node) +set_virtual_root_from_node (XedFileBrowserStore *model, + FileBrowserNode *node) { - FileBrowserNode *next; - FileBrowserNode *prev; - FileBrowserNode *check; - FileBrowserNodeDir *dir; - GSList *item; - GSList *copy; - GtkTreePath *empty = NULL; + FileBrowserNode *next; + FileBrowserNode *prev; + FileBrowserNode *check; + FileBrowserNodeDir *dir; + GSList *item; + GSList *copy; + GtkTreePath *empty = NULL; - g_assert (node != NULL); + g_assert (node != NULL); - prev = node; - next = prev->parent; + prev = node; + next = prev->parent; - /* Free all the nodes below that we don't need in cache */ - while (prev != model->priv->root) { - dir = FILE_BROWSER_NODE_DIR (next); - copy = g_slist_copy (dir->children); + /* Free all the nodes below that we don't need in cache */ + while (prev != model->priv->root) + { + dir = FILE_BROWSER_NODE_DIR (next); + copy = g_slist_copy (dir->children); - for (item = copy; item; item = item->next) { - check = (FileBrowserNode *) (item->data); + for (item = copy; item; item = item->next) + { + check = (FileBrowserNode *) (item->data); - if (prev == node) { - /* Only free the children, keeping this depth in cache */ - if (check != node) { - file_browser_node_free_children - (model, check); - file_browser_node_unload (model, - check, - FALSE); - } - } else if (check != prev) { - /* Only free when the node is not in the chain */ - dir->children = - g_slist_remove (dir->children, check); - file_browser_node_free (model, check); - } - } + if (prev == node) + { + /* Only free the children, keeping this depth in cache */ + if (check != node) + { + file_browser_node_free_children (model, check); + file_browser_node_unload (model, check, FALSE); + } + } + else if (check != prev) + { + /* Only free when the node is not in the chain */ + dir->children = g_slist_remove (dir->children, check); + file_browser_node_free (model, check); + } + } - if (prev != node) - file_browser_node_unload (model, next, FALSE); + if (prev != node) + { + file_browser_node_unload (model, next, FALSE); + } - g_slist_free (copy); - prev = next; - next = prev->parent; - } + g_slist_free (copy); + prev = next; + next = prev->parent; + } - /* Free all the nodes up that we don't need in cache */ - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; - item = item->next) { - check = (FileBrowserNode *) (item->data); - - if (NODE_IS_DIR (check)) { - for (copy = - FILE_BROWSER_NODE_DIR (check)->children; copy; - copy = copy->next) { - file_browser_node_free_children (model, - (FileBrowserNode - *) - (copy-> - data)); - file_browser_node_unload (model, - (FileBrowserNode - *) (copy->data), - FALSE); - } - } else if (NODE_IS_DUMMY (check)) { - check->flags |= - XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; - } - } + /* Free all the nodes up that we don't need in cache */ + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) + { + check = (FileBrowserNode *) (item->data); - /* Now finally, set the virtual root, and load it up! */ - model->priv->virtual_root = node; + if (NODE_IS_DIR (check)) + { + for (copy = FILE_BROWSER_NODE_DIR (check)->children; copy; copy = copy->next) + { + file_browser_node_free_children (model, (FileBrowserNode *) (copy->data)); + file_browser_node_unload (model, (FileBrowserNode *) (copy->data), FALSE); + } + } + else if (NODE_IS_DUMMY (check)) + { + check->flags |= XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN; + } + } - /* Notify that the virtual-root has changed before loading up new nodes so that the - "root_changed" signal can be emitted before any "inserted" signals */ - g_object_notify (G_OBJECT (model), "virtual-root"); + /* Now finally, set the virtual root, and load it up! */ + model->priv->virtual_root = node; - model_fill (model, NULL, &empty); + /* Notify that the virtual-root has changed before loading up new nodes so that the + "root_changed" signal can be emitted before any "inserted" signals */ + g_object_notify (G_OBJECT (model), "virtual-root"); - if (!NODE_LOADED (node)) - model_load_directory (model, node); + model_fill (model, NULL, &empty); + + if (!NODE_LOADED (node)) + { + model_load_directory (model, node); + } } static void -set_virtual_root_from_file (XedFileBrowserStore * model, - GFile * file) +set_virtual_root_from_file (XedFileBrowserStore *model, + GFile *file) { - GList * files; - GList * item; - FileBrowserNode * parent; - GFile * check; + GList * files; + GList * item; + FileBrowserNode * parent; + GFile * check; - /* Always clear the model before altering the nodes */ - model_clear (model, FALSE); + /* Always clear the model before altering the nodes */ + model_clear (model, FALSE); - /* Create the node path, get all the uri's */ - files = get_parent_files (model, file); - parent = model->priv->root; + /* Create the node path, get all the uri's */ + files = get_parent_files (model, file); + parent = model->priv->root; - for (item = files; item; item = item->next) { - check = G_FILE (item->data); - - parent = model_add_node_from_dir (model, parent, check); - g_object_unref (check); - } + for (item = files; item; item = item->next) + { + check = G_FILE (item->data); - g_list_free (files); - set_virtual_root_from_node (model, parent); + parent = model_add_node_from_dir (model, parent, check); + g_object_unref (check); + } + + g_list_free (files); + set_virtual_root_from_node (model, parent); } static FileBrowserNode * -model_find_node_children (XedFileBrowserStore * model, - FileBrowserNode * parent, - GFile * file) +model_find_node_children (XedFileBrowserStore *model, + FileBrowserNode *parent, + GFile *file) { - FileBrowserNodeDir *dir; - FileBrowserNode *child; - FileBrowserNode *result; - GSList *children; - - if (!NODE_IS_DIR (parent)) - return NULL; - - dir = FILE_BROWSER_NODE_DIR (parent); - - for (children = dir->children; children; children = children->next) { - child = (FileBrowserNode *)(children->data); - - result = model_find_node (model, child, file); - - if (result) - return result; - } - - return NULL; + FileBrowserNodeDir *dir; + FileBrowserNode *child; + FileBrowserNode *result; + GSList *children; + + if (!NODE_IS_DIR (parent)) + { + return NULL; + } + + dir = FILE_BROWSER_NODE_DIR (parent); + + for (children = dir->children; children; children = children->next) + { + child = (FileBrowserNode *)(children->data); + + result = model_find_node (model, child, file); + + if (result) + { + return result; + } + } + + return NULL; } static FileBrowserNode * -model_find_node (XedFileBrowserStore * model, - FileBrowserNode * node, - GFile * file) +model_find_node (XedFileBrowserStore *model, + FileBrowserNode *node, + GFile *file) { - if (node == NULL) - node = model->priv->root; + if (node == NULL) + { + node = model->priv->root; + } - if (node->file && g_file_equal (node->file, file)) - return node; + if (node->file && g_file_equal (node->file, file)) + { + return node; + } - if (NODE_IS_DIR (node) && g_file_has_prefix (file, node->file)) - return model_find_node_children (model, node, file); - - return NULL; + if (NODE_IS_DIR (node) && g_file_has_prefix (file, node->file)) + { + return model_find_node_children (model, node, file); + } + + return NULL; } static GQuark xed_file_browser_store_error_quark (void) { - static GQuark quark = 0; + static GQuark quark = 0; - if (G_UNLIKELY (quark == 0)) { - quark = g_quark_from_string ("xed_file_browser_store_error"); - } + if (G_UNLIKELY (quark == 0)) + { + quark = g_quark_from_string ("xed_file_browser_store_error"); + } - return quark; + return quark; } static GFile * -unique_new_name (GFile * directory, gchar const * name) +unique_new_name (GFile *directory, + gchar const *name) { - GFile * newuri = NULL; - guint num = 0; - gchar * newname; + GFile * newuri = NULL; + guint num = 0; + gchar * newname; - while (newuri == NULL || g_file_query_exists (newuri, NULL)) { - if (newuri != NULL) - g_object_unref (newuri); + while (newuri == NULL || g_file_query_exists (newuri, NULL)) + { + if (newuri != NULL) + { + g_object_unref (newuri); + } - if (num == 0) - newname = g_strdup (name); - else - newname = g_strdup_printf ("%s(%d)", name, num); + if (num == 0) + { + newname = g_strdup (name); + } + else + { + newname = g_strdup_printf ("%s(%d)", name, num); + } - newuri = g_file_get_child (directory, newname); - g_free (newname); + newuri = g_file_get_child (directory, newname); + g_free (newname); - ++num; - } + ++num; + } - return newuri; + return newuri; } static XedFileBrowserStoreResult -model_root_mounted (XedFileBrowserStore * model, gchar const * virtual_root) +model_root_mounted (XedFileBrowserStore *model, + GFile *virtual_root) { - model_check_dummy (model, model->priv->root); - g_object_notify (G_OBJECT (model), "root"); + model_check_dummy (model, model->priv->root); + g_object_notify (G_OBJECT (model), "root"); - if (virtual_root != NULL) - return - xed_file_browser_store_set_virtual_root_from_string - (model, virtual_root); - else - set_virtual_root_from_node (model, - model->priv->root); + if (virtual_root != NULL) + { + return xed_file_browser_store_set_virtual_root_from_location (model, virtual_root); + } + else + { + set_virtual_root_from_node (model, model->priv->root); + } - return XED_FILE_BROWSER_STORE_RESULT_OK; + return XED_FILE_BROWSER_STORE_RESULT_OK; } static void -handle_root_error (XedFileBrowserStore * model, GError *error) +handle_root_error (XedFileBrowserStore *model, + GError *error) { - FileBrowserNode * root; + FileBrowserNode * root; - g_signal_emit (model, - model_signals[ERROR], - 0, - XED_FILE_BROWSER_ERROR_SET_ROOT, - error->message); - - /* Set the virtual root to the root */ - root = model->priv->root; - model->priv->virtual_root = root; - - /* Set the root to be loaded */ - root->flags |= XED_FILE_BROWSER_STORE_FLAG_LOADED; - - /* Check the dummy */ - model_check_dummy (model, root); - - g_object_notify (G_OBJECT (model), "root"); - g_object_notify (G_OBJECT (model), "virtual-root"); + g_signal_emit (model, + model_signals[ERROR], + 0, + XED_FILE_BROWSER_ERROR_SET_ROOT, + error->message); + + /* Set the virtual root to the root */ + root = model->priv->root; + model->priv->virtual_root = root; + + /* Set the root to be loaded */ + root->flags |= XED_FILE_BROWSER_STORE_FLAG_LOADED; + + /* Check the dummy */ + model_check_dummy (model, root); + + g_object_notify (G_OBJECT (model), "root"); + g_object_notify (G_OBJECT (model), "virtual-root"); } static void -mount_cb (GFile * file, - GAsyncResult * res, - MountInfo * mount_info) +mount_cb (GFile *file, + GAsyncResult *res, + MountInfo *mount_info) { - gboolean mounted; - GError * error = NULL; - XedFileBrowserStore * model = mount_info->model; - - mounted = g_file_mount_enclosing_volume_finish (file, res, &error); + gboolean mounted; + GError *error = NULL; + XedFileBrowserStore *model = mount_info->model; - if (mount_info->model) - { - model->priv->mount_info = NULL; - model_end_loading (model, model->priv->root); - } + mounted = g_file_mount_enclosing_volume_finish (file, res, &error); - if (!mount_info->model || g_cancellable_is_cancelled (mount_info->cancellable)) - { - // Reset because it might be reused? - g_cancellable_reset (mount_info->cancellable); - } - else if (mounted) - { - model_root_mounted (model, mount_info->virtual_root); - } - else if (error->code != G_IO_ERROR_CANCELLED) - { - handle_root_error (model, error); - } - - if (error) - g_error_free (error); + if (mount_info->model) + { + model->priv->mount_info = NULL; + model_end_loading (model, model->priv->root); + } - g_object_unref (mount_info->operation); - g_object_unref (mount_info->cancellable); - g_free (mount_info->virtual_root); + if (!mount_info->model || g_cancellable_is_cancelled (mount_info->cancellable)) + { + // Reset because it might be reused? + g_cancellable_reset (mount_info->cancellable); + } + else if (mounted) + { + model_root_mounted (model, mount_info->virtual_root); + } + else if (error->code != G_IO_ERROR_CANCELLED) + { + handle_root_error (model, error); + } - g_free (mount_info); + if (error) + { + g_error_free (error); + } + + g_object_unref (mount_info->operation); + g_object_unref (mount_info->cancellable); + g_free (mount_info->virtual_root); + + g_free (mount_info); } static XedFileBrowserStoreResult -model_mount_root (XedFileBrowserStore * model, gchar const * virtual_root) +model_mount_root (XedFileBrowserStore *model, + GFile *virtual_root) { - GFileInfo * info; - GError * error = NULL; - MountInfo * mount_info; - - info = g_file_query_info (model->priv->root->file, - G_FILE_ATTRIBUTE_STANDARD_TYPE, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); + GFileInfo *info; + GError *error = NULL; + MountInfo *mount_info; - if (!info) { - if (error->code == G_IO_ERROR_NOT_MOUNTED) { - /* Try to mount it */ - FILE_BROWSER_NODE_DIR (model->priv->root)->cancellable = g_cancellable_new (); - - mount_info = g_new(MountInfo, 1); - mount_info->model = model; - mount_info->virtual_root = g_strdup (virtual_root); - - /* FIXME: we should be setting the correct window */ - mount_info->operation = gtk_mount_operation_new (NULL); - mount_info->cancellable = g_object_ref (FILE_BROWSER_NODE_DIR (model->priv->root)->cancellable); - - model_begin_loading (model, model->priv->root); - g_file_mount_enclosing_volume (model->priv->root->file, - G_MOUNT_MOUNT_NONE, - mount_info->operation, - mount_info->cancellable, - (GAsyncReadyCallback)mount_cb, - mount_info); - - model->priv->mount_info = mount_info; - return XED_FILE_BROWSER_STORE_RESULT_MOUNTING; - } - else - { - handle_root_error (model, error); - } - - g_error_free (error); - } else { - g_object_unref (info); - - return model_root_mounted (model, virtual_root); - } - - return XED_FILE_BROWSER_STORE_RESULT_OK; + info = g_file_query_info (model->priv->root->file, + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, + NULL, + &error); + + if (!info) + { + if (error->code == G_IO_ERROR_NOT_MOUNTED) + { + /* Try to mount it */ + FILE_BROWSER_NODE_DIR (model->priv->root)->cancellable = g_cancellable_new (); + + mount_info = g_new(MountInfo, 1); + mount_info->model = model; + mount_info->virtual_root = g_file_dup (virtual_root); + + /* FIXME: we should be setting the correct window */ + mount_info->operation = gtk_mount_operation_new (NULL); + mount_info->cancellable = g_object_ref (FILE_BROWSER_NODE_DIR (model->priv->root)->cancellable); + + model_begin_loading (model, model->priv->root); + g_file_mount_enclosing_volume (model->priv->root->file, + G_MOUNT_MOUNT_NONE, + mount_info->operation, + mount_info->cancellable, + (GAsyncReadyCallback)mount_cb, + mount_info); + + model->priv->mount_info = mount_info; + return XED_FILE_BROWSER_STORE_RESULT_MOUNTING; + } + else + { + handle_root_error (model, error); + } + + g_error_free (error); + } + else + { + g_object_unref (info); + + return model_root_mounted (model, virtual_root); + } + + return XED_FILE_BROWSER_STORE_RESULT_OK; } /* Public */ XedFileBrowserStore * -xed_file_browser_store_new (gchar const *root) +xed_file_browser_store_new (GFile *root) { - XedFileBrowserStore *obj = - XED_FILE_BROWSER_STORE (g_object_new - (XED_TYPE_FILE_BROWSER_STORE, - NULL)); + XedFileBrowserStore *obj = XED_FILE_BROWSER_STORE (g_object_new (XED_TYPE_FILE_BROWSER_STORE, NULL)); - xed_file_browser_store_set_root (obj, root); - return obj; + xed_file_browser_store_set_root (obj, root); + return obj; } void -xed_file_browser_store_set_value (XedFileBrowserStore * tree_model, - GtkTreeIter * iter, gint column, - GValue * value) +xed_file_browser_store_set_value (XedFileBrowserStore *tree_model, + GtkTreeIter *iter, gint column, + GValue *value) { - gpointer data; - FileBrowserNode *node; - GtkTreePath *path; + gpointer data; + FileBrowserNode *node; + GtkTreePath *path; - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model)); - g_return_if_fail (column == - XED_FILE_BROWSER_STORE_COLUMN_EMBLEM); - g_return_if_fail (G_VALUE_HOLDS_OBJECT (value)); - g_return_if_fail (iter != NULL); - g_return_if_fail (iter->user_data != NULL); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_model)); + g_return_if_fail (column == XED_FILE_BROWSER_STORE_COLUMN_EMBLEM); + g_return_if_fail (G_VALUE_HOLDS_OBJECT (value)); + g_return_if_fail (iter != NULL); + g_return_if_fail (iter->user_data != NULL); - data = g_value_get_object (value); + data = g_value_get_object (value); - if (data) - g_return_if_fail (GDK_IS_PIXBUF (data)); + if (data) + { + g_return_if_fail (GDK_IS_PIXBUF (data)); + } - node = (FileBrowserNode *) (iter->user_data); + node = (FileBrowserNode *) (iter->user_data); - if (node->emblem) - g_object_unref (node->emblem); + if (node->emblem) + { + g_object_unref (node->emblem); + } - if (data) - node->emblem = g_object_ref (GDK_PIXBUF (data)); - else - node->emblem = NULL; + if (data) + { + node->emblem = g_object_ref (GDK_PIXBUF (data)); + } + else + { + node->emblem = NULL; + } - model_recomposite_icon (tree_model, iter); + model_recomposite_icon (tree_model, iter); - if (model_node_visibility (tree_model, node)) { - path = xed_file_browser_store_get_path (GTK_TREE_MODEL (tree_model), - iter); - row_changed (tree_model, &path, iter); - gtk_tree_path_free (path); - } + if (model_node_visibility (tree_model, node)) + { + path = xed_file_browser_store_get_path (GTK_TREE_MODEL (tree_model), iter); + row_changed (tree_model, &path, iter); + gtk_tree_path_free (path); + } } XedFileBrowserStoreResult -xed_file_browser_store_set_virtual_root (XedFileBrowserStore * model, - GtkTreeIter * iter) +xed_file_browser_store_set_virtual_root (XedFileBrowserStore *model, + GtkTreeIter *iter) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - g_return_val_if_fail (iter != NULL, - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - g_return_val_if_fail (iter->user_data != NULL, - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (iter != NULL, XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (iter->user_data != NULL, XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - model_clear (model, FALSE); - set_virtual_root_from_node (model, - (FileBrowserNode *) (iter->user_data)); + model_clear (model, FALSE); + set_virtual_root_from_node (model, (FileBrowserNode *) (iter->user_data)); - return TRUE; + return TRUE; } XedFileBrowserStoreResult -xed_file_browser_store_set_virtual_root_from_string - (XedFileBrowserStore * model, gchar const *root) { - GFile *file; +xed_file_browser_store_set_virtual_root_from_location (XedFileBrowserStore *model, + GFile *root) +{ + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + if (root == NULL) + { + gchar *uri; - file = g_file_new_for_uri (root); - if (file == NULL) { - g_warning ("Invalid uri (%s)", root); - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; - } + uri = g_file_get_uri (root); + g_warning ("Invalid uri (%s)", uri); + g_free (uri); + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } - /* Check if uri is already the virtual root */ - if (model->priv->virtual_root && - g_file_equal (model->priv->virtual_root->file, file)) { - g_object_unref (file); - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; - } + /* Check if uri is already the virtual root */ + if (model->priv->virtual_root && g_file_equal (model->priv->virtual_root->file, root)) + { + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } - /* Check if uri is the root itself */ - if (g_file_equal (model->priv->root->file, file)) { - g_object_unref (file); + /* Check if uri is the root itself */ + if (g_file_equal (model->priv->root->file, root)) + { + /* Always clear the model before altering the nodes */ + model_clear (model, FALSE); + set_virtual_root_from_node (model, model->priv->root); + return XED_FILE_BROWSER_STORE_RESULT_OK; + } - /* Always clear the model before altering the nodes */ - model_clear (model, FALSE); - set_virtual_root_from_node (model, model->priv->root); - return XED_FILE_BROWSER_STORE_RESULT_OK; - } + if (!g_file_has_prefix (root, model->priv->root->file)) + { + gchar *str, *str1; - if (!g_file_has_prefix (file, model->priv->root->file)) { - gchar *str, *str1; + str = g_file_get_parse_name (model->priv->root->file); + str1 = g_file_get_parse_name (root); - str = g_file_get_parse_name (model->priv->root->file); - str1 = g_file_get_parse_name (file); + g_warning ("Virtual root (%s) is not below actual root (%s)", str1, str); - g_warning - ("Virtual root (%s) is not below actual root (%s)", - str1, str); + g_free (str); + g_free (str1); - g_free (str); - g_free (str1); + return XED_FILE_BROWSER_STORE_RESULT_ERROR; + } - g_object_unref (file); - return XED_FILE_BROWSER_STORE_RESULT_ERROR; - } + set_virtual_root_from_file (model, root); - set_virtual_root_from_file (model, file); - g_object_unref (file); - - return XED_FILE_BROWSER_STORE_RESULT_OK; + return XED_FILE_BROWSER_STORE_RESULT_OK; } XedFileBrowserStoreResult -xed_file_browser_store_set_virtual_root_top (XedFileBrowserStore * - model) +xed_file_browser_store_set_virtual_root_top (XedFileBrowserStore *model) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - if (model->priv->virtual_root == model->priv->root) - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + if (model->priv->virtual_root == model->priv->root) + { + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } - model_clear (model, FALSE); - set_virtual_root_from_node (model, model->priv->root); + model_clear (model, FALSE); + set_virtual_root_from_node (model, model->priv->root); - return XED_FILE_BROWSER_STORE_RESULT_OK; + return XED_FILE_BROWSER_STORE_RESULT_OK; } XedFileBrowserStoreResult -xed_file_browser_store_set_virtual_root_up (XedFileBrowserStore * - model) +xed_file_browser_store_set_virtual_root_up (XedFileBrowserStore *model) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - if (model->priv->virtual_root == model->priv->root) - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + if (model->priv->virtual_root == model->priv->root) + { + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } - model_clear (model, FALSE); - set_virtual_root_from_node (model, - model->priv->virtual_root->parent); + model_clear (model, FALSE); + set_virtual_root_from_node (model, model->priv->virtual_root->parent); - return XED_FILE_BROWSER_STORE_RESULT_OK; + return XED_FILE_BROWSER_STORE_RESULT_OK; } gboolean -xed_file_browser_store_get_iter_virtual_root (XedFileBrowserStore * - model, GtkTreeIter * iter) +xed_file_browser_store_get_iter_virtual_root (XedFileBrowserStore *model, + GtkTreeIter *iter) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); - if (model->priv->virtual_root == NULL) - return FALSE; + if (model->priv->virtual_root == NULL) + { + return FALSE; + } - iter->user_data = model->priv->virtual_root; - return TRUE; + iter->user_data = model->priv->virtual_root; + return TRUE; } gboolean -xed_file_browser_store_get_iter_root (XedFileBrowserStore * model, - GtkTreeIter * iter) +xed_file_browser_store_get_iter_root (XedFileBrowserStore *model, + GtkTreeIter *iter) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); - if (model->priv->root == NULL) - return FALSE; + if (model->priv->root == NULL) + { + return FALSE; + } - iter->user_data = model->priv->root; - return TRUE; + iter->user_data = model->priv->root; + return TRUE; } gboolean -xed_file_browser_store_iter_equal (XedFileBrowserStore * model, - GtkTreeIter * iter1, - GtkTreeIter * iter2) +xed_file_browser_store_iter_equal (XedFileBrowserStore *model, + GtkTreeIter *iter1, + GtkTreeIter *iter2) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); - g_return_val_if_fail (iter1 != NULL, FALSE); - g_return_val_if_fail (iter2 != NULL, FALSE); - g_return_val_if_fail (iter1->user_data != NULL, FALSE); - g_return_val_if_fail (iter2->user_data != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); + g_return_val_if_fail (iter1 != NULL, FALSE); + g_return_val_if_fail (iter2 != NULL, FALSE); + g_return_val_if_fail (iter1->user_data != NULL, FALSE); + g_return_val_if_fail (iter2->user_data != NULL, FALSE); - return (iter1->user_data == iter2->user_data); + return (iter1->user_data == iter2->user_data); } void xed_file_browser_store_cancel_mount_operation (XedFileBrowserStore *store) { - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (store)); - - cancel_mount_operation (store); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (store)); + + cancel_mount_operation (store); } XedFileBrowserStoreResult -xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore * - model, - gchar const *root, - gchar const *virtual_root) +xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore *model, + GFile *root, + GFile *virtual_root) { - GFile * file = NULL; - GFile * vfile = NULL; - FileBrowserNode * node; - gboolean equal = FALSE; + FileBrowserNode * node; + gboolean equal = FALSE; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - if (root == NULL && model->priv->root == NULL) - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + if (root == NULL && model->priv->root == NULL) + { + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } - if (root != NULL) { - file = g_file_new_for_uri (root); - } + if (root != NULL && model->priv->root != NULL) + { + equal = g_file_equal (root, model->priv->root->file); - if (root != NULL && model->priv->root != NULL) { - equal = g_file_equal (file, model->priv->root->file); + if (equal && virtual_root == NULL) + { + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } + } - if (equal && virtual_root == NULL) { - g_object_unref (file); - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; - } - } + if (virtual_root) + { + if (equal && g_file_equal (virtual_root, model->priv->virtual_root->file)) + { + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } + } - if (virtual_root) { - vfile = g_file_new_for_uri (virtual_root); + /* make sure to cancel any previous mount operations */ + cancel_mount_operation (model); - if (equal && g_file_equal (vfile, model->priv->virtual_root->file)) { - if (file) - g_object_unref (file); + /* Always clear the model before altering the nodes */ + model_clear (model, TRUE); + file_browser_node_free (model, model->priv->root); - g_object_unref (vfile); - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; - } + model->priv->root = NULL; + model->priv->virtual_root = NULL; - g_object_unref (vfile); - } - - /* make sure to cancel any previous mount operations */ - cancel_mount_operation (model); + if (root != NULL) + { + /* Create the root node */ + node = file_browser_node_dir_new (model, root, NULL); - /* Always clear the model before altering the nodes */ - model_clear (model, TRUE); - file_browser_node_free (model, model->priv->root); + model->priv->root = node; + return model_mount_root (model, virtual_root); + } + else + { + g_object_notify (G_OBJECT (model), "root"); + g_object_notify (G_OBJECT (model), "virtual-root"); + } - model->priv->root = NULL; - model->priv->virtual_root = NULL; - - if (file != NULL) { - /* Create the root node */ - node = file_browser_node_dir_new (model, file, NULL); - - g_object_unref (file); - - model->priv->root = node; - return model_mount_root (model, virtual_root); - } else { - g_object_notify (G_OBJECT (model), "root"); - g_object_notify (G_OBJECT (model), "virtual-root"); - } - - return XED_FILE_BROWSER_STORE_RESULT_OK; + return XED_FILE_BROWSER_STORE_RESULT_OK; } XedFileBrowserStoreResult -xed_file_browser_store_set_root (XedFileBrowserStore * model, - gchar const *root) +xed_file_browser_store_set_root (XedFileBrowserStore *model, + GFile *root) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - return xed_file_browser_store_set_root_and_virtual_root (model, - root, - NULL); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + return xed_file_browser_store_set_root_and_virtual_root (model, root, NULL); } -gchar * +GFile * xed_file_browser_store_get_root (XedFileBrowserStore * model) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), NULL); - - if (model->priv->root == NULL || model->priv->root->file == NULL) - return NULL; - else - return g_file_get_uri (model->priv->root->file); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), NULL); + + if (model->priv->root == NULL || model->priv->root->file == NULL) + { + return NULL; + } + else + { + return g_file_dup (model->priv->root->file); + } } -gchar * -xed_file_browser_store_get_virtual_root (XedFileBrowserStore * model) +GFile * +xed_file_browser_store_get_virtual_root (XedFileBrowserStore *model) { - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), NULL); - - if (model->priv->virtual_root == NULL || model->priv->virtual_root->file == NULL) - return NULL; - else - return g_file_get_uri (model->priv->virtual_root->file); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), NULL); + + if (model->priv->virtual_root == NULL || model->priv->virtual_root->file == NULL) + { + return NULL; + } + else + { + return g_file_dup (model->priv->virtual_root->file); + } } void -_xed_file_browser_store_iter_expanded (XedFileBrowserStore * model, - GtkTreeIter * iter) +_xed_file_browser_store_iter_expanded (XedFileBrowserStore *model, + GtkTreeIter *iter) { - FileBrowserNode *node; + FileBrowserNode *node; - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); - g_return_if_fail (iter != NULL); - g_return_if_fail (iter->user_data != NULL); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); + g_return_if_fail (iter != NULL); + g_return_if_fail (iter->user_data != NULL); - node = (FileBrowserNode *) (iter->user_data); + node = (FileBrowserNode *) (iter->user_data); - if (NODE_IS_DIR (node) && !NODE_LOADED (node)) { - /* Load it now */ - model_load_directory (model, node); - } + if (NODE_IS_DIR (node) && !NODE_LOADED (node)) + { + /* Load it now */ + model_load_directory (model, node); + } } void -_xed_file_browser_store_iter_collapsed (XedFileBrowserStore * model, - GtkTreeIter * iter) +_xed_file_browser_store_iter_collapsed (XedFileBrowserStore *model, + GtkTreeIter *iter) { - FileBrowserNode *node; - GSList *item; + FileBrowserNode *node; + GSList *item; - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); - g_return_if_fail (iter != NULL); - g_return_if_fail (iter->user_data != NULL); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); + g_return_if_fail (iter != NULL); + g_return_if_fail (iter->user_data != NULL); - node = (FileBrowserNode *) (iter->user_data); + node = (FileBrowserNode *) (iter->user_data); - if (NODE_IS_DIR (node) && NODE_LOADED (node)) { - /* Unload children of the children, keeping 1 depth in cache */ + if (NODE_IS_DIR (node) && NODE_LOADED (node)) + { + /* Unload children of the children, keeping 1 depth in cache */ - for (item = FILE_BROWSER_NODE_DIR (node)->children; item; - item = item->next) { - node = (FileBrowserNode *) (item->data); + for (item = FILE_BROWSER_NODE_DIR (node)->children; item; item = item->next) + { + node = (FileBrowserNode *) (item->data); - if (NODE_IS_DIR (node) && NODE_LOADED (node)) { - file_browser_node_unload (model, node, - TRUE); - model_check_dummy (model, node); - } - } - } + if (NODE_IS_DIR (node) && NODE_LOADED (node)) + { + file_browser_node_unload (model, node, TRUE); + model_check_dummy (model, node); + } + } + } } XedFileBrowserStoreFilterMode -xed_file_browser_store_get_filter_mode (XedFileBrowserStore * model) +xed_file_browser_store_get_filter_mode (XedFileBrowserStore *model) { - return model->priv->filter_mode; + return model->priv->filter_mode; } void -xed_file_browser_store_set_filter_mode (XedFileBrowserStore * model, - XedFileBrowserStoreFilterMode - mode) +xed_file_browser_store_set_filter_mode (XedFileBrowserStore *model, + XedFileBrowserStoreFilterMode mode) { - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); - if (model->priv->filter_mode == mode) - return; + if (model->priv->filter_mode == mode) + { + return; + } - model->priv->filter_mode = mode; - model_refilter (model); + model->priv->filter_mode = mode; + model_refilter (model); - g_object_notify (G_OBJECT (model), "filter-mode"); + g_object_notify (G_OBJECT (model), "filter-mode"); } void -xed_file_browser_store_set_filter_func (XedFileBrowserStore * model, - XedFileBrowserStoreFilterFunc - func, gpointer user_data) +xed_file_browser_store_set_filter_func (XedFileBrowserStore *model, + XedFileBrowserStoreFilterFunc func, + gpointer user_data) { - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); - model->priv->filter_func = func; - model->priv->filter_user_data = user_data; - model_refilter (model); + model->priv->filter_func = func; + model->priv->filter_user_data = user_data; + model_refilter (model); } void -xed_file_browser_store_refilter (XedFileBrowserStore * model) +xed_file_browser_store_refilter (XedFileBrowserStore *model) { - model_refilter (model); + model_refilter (model); } XedFileBrowserStoreFilterMode xed_file_browser_store_filter_mode_get_default (void) { - return XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; + return XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; } void -xed_file_browser_store_refresh (XedFileBrowserStore * model) +xed_file_browser_store_refresh (XedFileBrowserStore *model) { - g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (model)); - if (model->priv->root == NULL || model->priv->virtual_root == NULL) - return; + if (model->priv->root == NULL || model->priv->virtual_root == NULL) + { + return; + } - /* Clear the model */ - g_signal_emit (model, model_signals[BEGIN_REFRESH], 0); - file_browser_node_unload (model, model->priv->virtual_root, TRUE); - model_load_directory (model, model->priv->virtual_root); - g_signal_emit (model, model_signals[END_REFRESH], 0); + /* Clear the model */ + g_signal_emit (model, model_signals[BEGIN_REFRESH], 0); + file_browser_node_unload (model, model->priv->virtual_root, TRUE); + model_load_directory (model, model->priv->virtual_root); + g_signal_emit (model, model_signals[END_REFRESH], 0); } static void -reparent_node (FileBrowserNode * node, gboolean reparent) +reparent_node (FileBrowserNode *node, + gboolean reparent) { - FileBrowserNodeDir * dir; - GSList * child; - GFile * parent; - gchar * base; + FileBrowserNodeDir *dir; + GSList *child; + GFile *parent; + gchar *base; - if (!node->file) { - return; - } - - if (reparent) { - parent = node->parent->file; - base = g_file_get_basename (node->file); - g_object_unref (node->file); + if (!node->file) + { + return; + } - node->file = g_file_get_child (parent, base); - g_free (base); - } - - if (NODE_IS_DIR (node)) { - dir = FILE_BROWSER_NODE_DIR (node); - - for (child = dir->children; child; child = child->next) { - reparent_node ((FileBrowserNode *)child->data, TRUE); - } - } + if (reparent) + { + parent = node->parent->file; + base = g_file_get_basename (node->file); + g_object_unref (node->file); + + node->file = g_file_get_child (parent, base); + g_free (base); + } + + if (NODE_IS_DIR (node)) + { + dir = FILE_BROWSER_NODE_DIR (node); + + for (child = dir->children; child; child = child->next) + { + reparent_node ((FileBrowserNode *)child->data, TRUE); + } + } } gboolean -xed_file_browser_store_rename (XedFileBrowserStore * model, - GtkTreeIter * iter, - const gchar * new_name, - GError ** error) +xed_file_browser_store_rename (XedFileBrowserStore *model, + GtkTreeIter *iter, + const gchar *new_name, + GError **error) { - FileBrowserNode *node; - GFile * file; - GFile * parent; - GFile * previous; - GError * err = NULL; - gchar * olduri; - gchar * newuri; - GtkTreePath *path; + FileBrowserNode *node; + GFile *file; + GFile *parent; + GFile *previous; + GError *err = NULL; + GtkTreePath *path; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (iter->user_data != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (iter->user_data != NULL, FALSE); - node = (FileBrowserNode *) (iter->user_data); + node = (FileBrowserNode *) (iter->user_data); - parent = g_file_get_parent (node->file); - g_return_val_if_fail (parent != NULL, FALSE); + parent = g_file_get_parent (node->file); + g_return_val_if_fail (parent != NULL, FALSE); - file = g_file_get_child (parent, new_name); - g_object_unref (parent); + file = g_file_get_child (parent, new_name); + g_object_unref (parent); - if (g_file_equal (node->file, file)) { - g_object_unref (file); - return TRUE; - } + if (g_file_equal (node->file, file)) \ + { + g_object_unref (file); + return TRUE; + } - if (g_file_move (node->file, file, G_FILE_COPY_NONE, NULL, NULL, NULL, &err)) { - previous = node->file; - node->file = file; + if (g_file_move (node->file, file, G_FILE_COPY_NONE, NULL, NULL, NULL, &err)) + { + previous = node->file; + node->file = file; - /* This makes sure the actual info for the node is requeried */ - file_browser_node_set_name (node); - file_browser_node_set_from_info (model, node, NULL, TRUE); - - reparent_node (node, FALSE); + /* This makes sure the actual info for the node is requeried */ + file_browser_node_set_name (node); + file_browser_node_set_from_info (model, node, NULL, TRUE); - if (model_node_visibility (model, node)) { - path = xed_file_browser_store_get_path_real (model, node); - row_changed (model, &path, iter); - gtk_tree_path_free (path); + reparent_node (node, FALSE); - /* Reorder this item */ - model_resort_node (model, node); - } else { - g_object_unref (previous); - - if (error != NULL) - *error = g_error_new_literal (xed_file_browser_store_error_quark (), - XED_FILE_BROWSER_ERROR_RENAME, - _("The renamed file is currently filtered out. You need to adjust your filter settings to make the file visible")); - return FALSE; - } + if (model_node_visibility (model, node)) + { + path = xed_file_browser_store_get_path_real (model, node); + row_changed (model, &path, iter); + gtk_tree_path_free (path); - olduri = g_file_get_uri (previous); - newuri = g_file_get_uri (node->file); + /* Reorder this item */ + model_resort_node (model, node); + } + else + { + g_object_unref (previous); - g_signal_emit (model, model_signals[RENAME], 0, olduri, newuri); + if (error != NULL) + { + *error = g_error_new_literal (xed_file_browser_store_error_quark (), + XED_FILE_BROWSER_ERROR_RENAME, + _("The renamed file is currently filtered out. You need to adjust your filter settings to make the file visible")); + } + return FALSE; + } - g_object_unref (previous); - g_free (olduri); - g_free (newuri); + g_signal_emit (model, model_signals[RENAME], 0, previous, node->file); - return TRUE; - } else { - g_object_unref (file); + g_object_unref (previous); - if (err) { - if (error != NULL) { - *error = - g_error_new_literal - (xed_file_browser_store_error_quark (), - XED_FILE_BROWSER_ERROR_RENAME, - err->message); - } - - g_error_free (err); - } + return TRUE; + } + else + { + g_object_unref (file); - return FALSE; - } + if (err) + { + if (error != NULL) + { + *error = g_error_new_literal (xed_file_browser_store_error_quark (), + XED_FILE_BROWSER_ERROR_RENAME, + err->message); + } + + g_error_free (err); + } + + return FALSE; + } } static void -async_data_free (AsyncData * data) +async_data_free (AsyncData *data) { - g_object_unref (data->cancellable); - - g_list_foreach (data->files, (GFunc)g_object_unref, NULL); - g_list_free (data->files); - - if (!data->removed) - data->model->priv->async_handles = g_slist_remove (data->model->priv->async_handles, data); - - g_free (data); + g_object_unref (data->cancellable); + + g_list_foreach (data->files, (GFunc)g_object_unref, NULL); + g_list_free (data->files); + + if (!data->removed) + { + data->model->priv->async_handles = g_slist_remove (data->model->priv->async_handles, data); + } + + g_free (data); } static gboolean -emit_no_trash (AsyncData * data) +emit_no_trash (AsyncData *data) { - /* Emit the no trash error */ - gboolean ret; + /* Emit the no trash error */ + gboolean ret; - g_signal_emit (data->model, model_signals[NO_TRASH], 0, data->files, &ret); - return ret; + g_signal_emit (data->model, model_signals[NO_TRASH], 0, data->files, &ret); + return ret; } -typedef struct { - XedFileBrowserStore * model; - GFile * file; +typedef struct +{ + XedFileBrowserStore *model; + GFile *file; } IdleDelete; static gboolean -file_deleted (IdleDelete * data) +file_deleted (IdleDelete *data) { - FileBrowserNode * node; - node = model_find_node (data->model, NULL, data->file); + FileBrowserNode *node; + node = model_find_node (data->model, NULL, data->file); - if (node != NULL) - model_remove_node (data->model, node, NULL, TRUE); - - return FALSE; + if (node != NULL) + { + model_remove_node (data->model, node, NULL, TRUE); + } + + return FALSE; } static gboolean -delete_files (GIOSchedulerJob * job, - GCancellable * cancellable, - AsyncData * data) +delete_files (GIOSchedulerJob *job, + GCancellable *cancellable, + AsyncData *data) { - GFile * file; - GError * error = NULL; - gboolean ret; - gint code; - IdleDelete delete; - - /* Check if our job is done */ - if (!data->iter) - return FALSE; - - /* Move a file to the trash */ - file = G_FILE (data->iter->data); - - if (data->trash) - ret = g_file_trash (file, cancellable, &error); - else - ret = g_file_delete (file, cancellable, &error); + GFile *file; + GError *error = NULL; + gboolean ret; + gint code; + IdleDelete delete; - if (ret) { - delete.model = data->model; - delete.file = file; + /* Check if our job is done */ + if (!data->iter) + { + return FALSE; + } - /* Remove the file from the model in the main loop */ - g_io_scheduler_job_send_to_mainloop (job, (GSourceFunc)file_deleted, &delete, NULL); - } else if (!ret && error) { - code = error->code; - g_error_free (error); + /* Move a file to the trash */ + file = G_FILE (data->iter->data); - if (data->trash && code == G_IO_ERROR_NOT_SUPPORTED) { - /* Trash is not supported on this system ... */ - if (g_io_scheduler_job_send_to_mainloop (job, (GSourceFunc)emit_no_trash, data, NULL)) - { - /* Changes this into a delete job */ - data->trash = FALSE; - data->iter = data->files; + if (data->trash) + { + ret = g_file_trash (file, cancellable, &error); + } + else + { + ret = g_file_delete (file, cancellable, &error); + } - return TRUE; - } - - /* End the job */ - return FALSE; - } else if (code == G_IO_ERROR_CANCELLED) { - /* Job has been cancelled, just let the job end */ - return FALSE; - } - } - - /* Process the next item */ - data->iter = data->iter->next; - return TRUE; + if (ret) + { + delete.model = data->model; + delete.file = file; + + /* Remove the file from the model in the main loop */ + g_io_scheduler_job_send_to_mainloop (job, (GSourceFunc)file_deleted, &delete, NULL); + } + else if (!ret && error) + { + code = error->code; + g_error_free (error); + + if (data->trash && code == G_IO_ERROR_NOT_SUPPORTED) + { + /* Trash is not supported on this system ... */ + if (g_io_scheduler_job_send_to_mainloop (job, (GSourceFunc)emit_no_trash, data, NULL)) + { + /* Changes this into a delete job */ + data->trash = FALSE; + data->iter = data->files; + + return TRUE; + } + + /* End the job */ + return FALSE; + } + else if (code == G_IO_ERROR_CANCELLED) + { + /* Job has been cancelled, just let the job end */ + return FALSE; + } + } + + /* Process the next item */ + data->iter = data->iter->next; + return TRUE; } XedFileBrowserStoreResult xed_file_browser_store_delete_all (XedFileBrowserStore *model, - GList *rows, gboolean trash) + GList *rows, + gboolean trash) { - FileBrowserNode * node; - AsyncData * data; - GList * files = NULL; - GList * row; - GtkTreeIter iter; - GtkTreePath * prev = NULL; - GtkTreePath * path; + FileBrowserNode *node; + AsyncData *data; + GList *files = NULL; + GList *row; + GtkTreeIter iter; + GtkTreePath *prev = NULL; + GtkTreePath *path; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - - if (rows == NULL) - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - /* First we sort the paths so that we can later on remove any - files/directories that are actually subfiles/directories of - a directory that's also deleted */ - rows = g_list_sort (g_list_copy (rows), (GCompareFunc)gtk_tree_path_compare); + if (rows == NULL) + { + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } - for (row = rows; row; row = row->next) { - path = (GtkTreePath *)(row->data); + /* First we sort the paths so that we can later on remove any + files/directories that are actually subfiles/directories of + a directory that's also deleted */ + rows = g_list_sort (g_list_copy (rows), (GCompareFunc)gtk_tree_path_compare); - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path)) - continue; - - /* Skip if the current path is actually a descendant of the - previous path */ - if (prev != NULL && gtk_tree_path_is_descendant (path, prev)) - continue; - - prev = path; - node = (FileBrowserNode *)(iter.user_data); - files = g_list_prepend (files, g_object_ref (node->file)); - } - - data = g_new (AsyncData, 1); + for (row = rows; row; row = row->next) + { + path = (GtkTreePath *)(row->data); - data->model = model; - data->cancellable = g_cancellable_new (); - data->files = files; - data->trash = trash; - data->iter = files; - data->removed = FALSE; - - model->priv->async_handles = - g_slist_prepend (model->priv->async_handles, data); + if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path)) + { + continue; + } - g_io_scheduler_push_job ((GIOSchedulerJobFunc)delete_files, - data, - (GDestroyNotify)async_data_free, - G_PRIORITY_DEFAULT, - data->cancellable); - g_list_free (rows); - - return XED_FILE_BROWSER_STORE_RESULT_OK; + /* Skip if the current path is actually a descendant of the + previous path */ + if (prev != NULL && gtk_tree_path_is_descendant (path, prev)) + { + continue; + } + + prev = path; + node = (FileBrowserNode *)(iter.user_data); + files = g_list_prepend (files, g_object_ref (node->file)); + } + + data = g_new (AsyncData, 1); + + data->model = model; + data->cancellable = g_cancellable_new (); + data->files = files; + data->trash = trash; + data->iter = files; + data->removed = FALSE; + + model->priv->async_handles = g_slist_prepend (model->priv->async_handles, data); + + g_io_scheduler_push_job ((GIOSchedulerJobFunc)delete_files, + data, + (GDestroyNotify)async_data_free, + G_PRIORITY_DEFAULT, + data->cancellable); + g_list_free (rows); + + return XED_FILE_BROWSER_STORE_RESULT_OK; } XedFileBrowserStoreResult -xed_file_browser_store_delete (XedFileBrowserStore * model, - GtkTreeIter * iter, gboolean trash) +xed_file_browser_store_delete (XedFileBrowserStore *model, + GtkTreeIter *iter, + gboolean trash) { - FileBrowserNode *node; - GList *rows = NULL; - XedFileBrowserStoreResult result; + FileBrowserNode *node; + GList *rows = NULL; + XedFileBrowserStoreResult result; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - g_return_val_if_fail (iter != NULL, XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - g_return_val_if_fail (iter->user_data != NULL, XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (iter != NULL, XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); + g_return_val_if_fail (iter->user_data != NULL, XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE); - node = (FileBrowserNode *) (iter->user_data); + node = (FileBrowserNode *) (iter->user_data); - if (NODE_IS_DUMMY (node)) - return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + if (NODE_IS_DUMMY (node)) + { + return XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE; + } - rows = g_list_append(NULL, xed_file_browser_store_get_path_real (model, node)); - result = xed_file_browser_store_delete_all (model, rows, trash); - - g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL); - g_list_free (rows); - - return result; + rows = g_list_append(NULL, xed_file_browser_store_get_path_real (model, node)); + result = xed_file_browser_store_delete_all (model, rows, trash); + + g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL); + g_list_free (rows); + + return result; } gboolean -xed_file_browser_store_new_file (XedFileBrowserStore * model, - GtkTreeIter * parent, - GtkTreeIter * iter) +xed_file_browser_store_new_file (XedFileBrowserStore *model, + GtkTreeIter *parent, + GtkTreeIter *iter) { - GFile * file; - GFileOutputStream * stream; - FileBrowserNodeDir *parent_node; - gboolean result = FALSE; - FileBrowserNode *node; - GError * error = NULL; + GFile *file; + GFileOutputStream *stream; + FileBrowserNodeDir *parent_node; + gboolean result = FALSE; + FileBrowserNode *node; + GError *error = NULL; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); - g_return_val_if_fail (parent != NULL, FALSE); - g_return_val_if_fail (parent->user_data != NULL, FALSE); - g_return_val_if_fail (NODE_IS_DIR - ((FileBrowserNode *) (parent->user_data)), - FALSE); - g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); + g_return_val_if_fail (parent != NULL, FALSE); + g_return_val_if_fail (parent->user_data != NULL, FALSE); + g_return_val_if_fail (NODE_IS_DIR ((FileBrowserNode *) (parent->user_data)), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); - parent_node = FILE_BROWSER_NODE_DIR (parent->user_data); - /* Translators: This is the default name of new files created by the file browser pane. */ - file = unique_new_name (((FileBrowserNode *) parent_node)->file, _("file")); + parent_node = FILE_BROWSER_NODE_DIR (parent->user_data); + /* Translators: This is the default name of new files created by the file browser pane. */ + file = unique_new_name (((FileBrowserNode *) parent_node)->file, _("file")); - stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &error); - - if (!stream) - { - g_signal_emit (model, model_signals[ERROR], 0, - XED_FILE_BROWSER_ERROR_NEW_FILE, - error->message); - g_error_free (error); - } else { - g_object_unref (stream); - node = model_add_node_from_file (model, - (FileBrowserNode *)parent_node, - file, - NULL); + stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &error); - if (model_node_visibility (model, node)) { - iter->user_data = node; - result = TRUE; - } else { - g_signal_emit (model, model_signals[ERROR], 0, - XED_FILE_BROWSER_ERROR_NEW_FILE, - _ - ("The new file is currently filtered out. You need to adjust your filter settings to make the file visible")); - } - } + if (!stream) + { + g_signal_emit (model, model_signals[ERROR], 0, + XED_FILE_BROWSER_ERROR_NEW_FILE, + error->message); + g_error_free (error); + } + else + { + g_object_unref (stream); + node = model_add_node_from_file (model, + (FileBrowserNode *)parent_node, + file, + NULL); - g_object_unref (file); - return result; + if (model_node_visibility (model, node)) + { + iter->user_data = node; + result = TRUE; + } + else + { + g_signal_emit (model, model_signals[ERROR], 0, + XED_FILE_BROWSER_ERROR_NEW_FILE, + _("The new file is currently filtered out. You need to adjust your filter settings to make the file visible")); + } + } + + g_object_unref (file); + return result; } gboolean -xed_file_browser_store_new_directory (XedFileBrowserStore * model, - GtkTreeIter * parent, - GtkTreeIter * iter) +xed_file_browser_store_new_directory (XedFileBrowserStore *model, + GtkTreeIter *parent, + GtkTreeIter *iter) { - GFile * file; - FileBrowserNodeDir *parent_node; - GError * error = NULL; - FileBrowserNode *node; - gboolean result = FALSE; + GFile *file; + FileBrowserNodeDir *parent_node; + GError *error = NULL; + FileBrowserNode *node; + gboolean result = FALSE; - g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); - g_return_val_if_fail (parent != NULL, FALSE); - g_return_val_if_fail (parent->user_data != NULL, FALSE); - g_return_val_if_fail (NODE_IS_DIR - ((FileBrowserNode *) (parent->user_data)), - FALSE); - g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (XED_IS_FILE_BROWSER_STORE (model), FALSE); + g_return_val_if_fail (parent != NULL, FALSE); + g_return_val_if_fail (parent->user_data != NULL, FALSE); + g_return_val_if_fail (NODE_IS_DIR ((FileBrowserNode *) (parent->user_data)), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); - parent_node = FILE_BROWSER_NODE_DIR (parent->user_data); - /* Translators: This is the default name of new directories created by the file browser pane. */ - file = unique_new_name (((FileBrowserNode *) parent_node)->file, _("directory")); + parent_node = FILE_BROWSER_NODE_DIR (parent->user_data); + /* Translators: This is the default name of new directories created by the file browser pane. */ + file = unique_new_name (((FileBrowserNode *) parent_node)->file, _("directory")); - if (!g_file_make_directory (file, NULL, &error)) { - g_signal_emit (model, model_signals[ERROR], 0, - XED_FILE_BROWSER_ERROR_NEW_DIRECTORY, - error->message); - g_error_free (error); - } else { - node = model_add_node_from_file (model, - (FileBrowserNode *)parent_node, - file, - NULL); + if (!g_file_make_directory (file, NULL, &error)) + { + g_signal_emit (model, model_signals[ERROR], 0, + XED_FILE_BROWSER_ERROR_NEW_DIRECTORY, + error->message); + g_error_free (error); + } + else + { + node = model_add_node_from_file (model, + (FileBrowserNode *)parent_node, + file, + NULL); - if (model_node_visibility (model, node)) { - iter->user_data = node; - result = TRUE; - } else { - g_signal_emit (model, model_signals[ERROR], 0, - XED_FILE_BROWSER_ERROR_NEW_FILE, - _ - ("The new directory is currently filtered out. You need to adjust your filter settings to make the directory visible")); - } - } + if (model_node_visibility (model, node)) + { + iter->user_data = node; + result = TRUE; + } + else + { + g_signal_emit (model, model_signals[ERROR], 0, + XED_FILE_BROWSER_ERROR_NEW_FILE, + _("The new directory is currently filtered out. You need to adjust your filter settings to make the directory visible")); + } + } - g_object_unref (file); - return result; + g_object_unref (file); + return result; +} + +void +_xed_file_browser_store_register_type (GTypeModule *type_module) +{ + xed_file_browser_store_register_type (type_module); } // ex:ts=8:noet: diff --git a/plugins/filebrowser/xed-file-browser-store.h b/plugins/filebrowser/xed-file-browser-store.h index 6185069..99ff5e9 100644 --- a/plugins/filebrowser/xed-file-browser-store.h +++ b/plugins/filebrowser/xed-file-browser-store.h @@ -1,5 +1,5 @@ /* - * xed-file-browser-store.h - Xed plugin providing easy file access + * xed-file-browser-store.h - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -25,176 +25,164 @@ #include G_BEGIN_DECLS -#define XED_TYPE_FILE_BROWSER_STORE (xed_file_browser_store_get_type ()) -#define XED_FILE_BROWSER_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_STORE, XedFileBrowserStore)) -#define XED_FILE_BROWSER_STORE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_STORE, XedFileBrowserStore const)) -#define XED_FILE_BROWSER_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BROWSER_STORE, XedFileBrowserStoreClass)) -#define XED_IS_FILE_BROWSER_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BROWSER_STORE)) -#define XED_IS_FILE_BROWSER_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BROWSER_STORE)) -#define XED_FILE_BROWSER_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BROWSER_STORE, XedFileBrowserStoreClass)) +#define XED_TYPE_FILE_BROWSER_STORE (xed_file_browser_store_get_type ()) +#define XED_FILE_BROWSER_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_STORE, XedFileBrowserStore)) +#define XED_FILE_BROWSER_STORE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_STORE, XedFileBrowserStore const)) +#define XED_FILE_BROWSER_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BROWSER_STORE, XedFileBrowserStoreClass)) +#define XED_IS_FILE_BROWSER_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BROWSER_STORE)) +#define XED_IS_FILE_BROWSER_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BROWSER_STORE)) +#define XED_FILE_BROWSER_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BROWSER_STORE, XedFileBrowserStoreClass)) -typedef enum +typedef enum { - XED_FILE_BROWSER_STORE_COLUMN_ICON = 0, - XED_FILE_BROWSER_STORE_COLUMN_NAME, - XED_FILE_BROWSER_STORE_COLUMN_URI, - XED_FILE_BROWSER_STORE_COLUMN_FLAGS, - XED_FILE_BROWSER_STORE_COLUMN_EMBLEM, - XED_FILE_BROWSER_STORE_COLUMN_NUM + XED_FILE_BROWSER_STORE_COLUMN_ICON = 0, + XED_FILE_BROWSER_STORE_COLUMN_NAME, + XED_FILE_BROWSER_STORE_COLUMN_LOCATION, + XED_FILE_BROWSER_STORE_COLUMN_FLAGS, + XED_FILE_BROWSER_STORE_COLUMN_EMBLEM, + XED_FILE_BROWSER_STORE_COLUMN_NUM } XedFileBrowserStoreColumn; -typedef enum +typedef enum { - XED_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY = 1 << 0, - XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN = 1 << 1, - XED_FILE_BROWSER_STORE_FLAG_IS_TEXT = 1 << 2, - XED_FILE_BROWSER_STORE_FLAG_LOADED = 1 << 3, - XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED = 1 << 4, - XED_FILE_BROWSER_STORE_FLAG_IS_DUMMY = 1 << 5 + XED_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY = 1 << 0, + XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN = 1 << 1, + XED_FILE_BROWSER_STORE_FLAG_IS_TEXT = 1 << 2, + XED_FILE_BROWSER_STORE_FLAG_LOADED = 1 << 3, + XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED = 1 << 4, + XED_FILE_BROWSER_STORE_FLAG_IS_DUMMY = 1 << 5 } XedFileBrowserStoreFlag; -typedef enum +typedef enum { - XED_FILE_BROWSER_STORE_RESULT_OK, - XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE, - XED_FILE_BROWSER_STORE_RESULT_ERROR, - XED_FILE_BROWSER_STORE_RESULT_NO_TRASH, - XED_FILE_BROWSER_STORE_RESULT_MOUNTING, - XED_FILE_BROWSER_STORE_RESULT_NUM + XED_FILE_BROWSER_STORE_RESULT_OK, + XED_FILE_BROWSER_STORE_RESULT_NO_CHANGE, + XED_FILE_BROWSER_STORE_RESULT_ERROR, + XED_FILE_BROWSER_STORE_RESULT_NO_TRASH, + XED_FILE_BROWSER_STORE_RESULT_MOUNTING, + XED_FILE_BROWSER_STORE_RESULT_NUM } XedFileBrowserStoreResult; -typedef enum +typedef enum { - XED_FILE_BROWSER_STORE_FILTER_MODE_NONE = 0, - XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN = 1 << 0, - XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY = 1 << 1 + XED_FILE_BROWSER_STORE_FILTER_MODE_NONE = 0, + XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN = 1 << 0, + XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY = 1 << 1 } XedFileBrowserStoreFilterMode; -#define FILE_IS_DIR(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY) -#define FILE_IS_HIDDEN(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN) -#define FILE_IS_TEXT(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_TEXT) -#define FILE_LOADED(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_LOADED) -#define FILE_IS_FILTERED(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED) -#define FILE_IS_DUMMY(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_DUMMY) +#define FILE_IS_DIR(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY) +#define FILE_IS_HIDDEN(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_HIDDEN) +#define FILE_IS_TEXT(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_TEXT) +#define FILE_LOADED(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_LOADED) +#define FILE_IS_FILTERED(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_FILTERED) +#define FILE_IS_DUMMY(flags) (flags & XED_FILE_BROWSER_STORE_FLAG_IS_DUMMY) typedef struct _XedFileBrowserStore XedFileBrowserStore; typedef struct _XedFileBrowserStoreClass XedFileBrowserStoreClass; typedef struct _XedFileBrowserStorePrivate XedFileBrowserStorePrivate; -typedef gboolean (*XedFileBrowserStoreFilterFunc) (XedFileBrowserStore - * model, - GtkTreeIter * iter, - gpointer user_data); +typedef gboolean (*XedFileBrowserStoreFilterFunc) (XedFileBrowserStore *model, + GtkTreeIter *iter, + gpointer user_data); -struct _XedFileBrowserStore +struct _XedFileBrowserStore { - GObject parent; + GObject parent; - XedFileBrowserStorePrivate *priv; + XedFileBrowserStorePrivate *priv; }; struct _XedFileBrowserStoreClass { - GObjectClass parent_class; + GObjectClass parent_class; - /* Signals */ - void (*begin_loading) (XedFileBrowserStore * model, - GtkTreeIter * iter); - void (*end_loading) (XedFileBrowserStore * model, - GtkTreeIter * iter); - void (*error) (XedFileBrowserStore * model, - guint code, - gchar * message); - gboolean (*no_trash) (XedFileBrowserStore * model, - GList * files); - void (*rename) (XedFileBrowserStore * model, - const gchar * olduri, - const gchar * newuri); - void (*begin_refresh) (XedFileBrowserStore * model); - void (*end_refresh) (XedFileBrowserStore * model); - void (*unload) (XedFileBrowserStore * model, - const gchar * uri); + /* Signals */ + void (*begin_loading) (XedFileBrowserStore *model, + GtkTreeIter *iter); + void (*end_loading) (XedFileBrowserStore *model, + GtkTreeIter *iter); + void (*error) (XedFileBrowserStore *model, + guint code, + gchar *message); + gboolean (*no_trash) (XedFileBrowserStore *model, + GList *files); + void (*rename) (XedFileBrowserStore *model, + GFile *oldfile, + GFile *newfile); + void (*begin_refresh) (XedFileBrowserStore *model); + void (*end_refresh) (XedFileBrowserStore *model); + void (*unload) (XedFileBrowserStore *model, + GFile *location); }; -GType xed_file_browser_store_get_type (void) G_GNUC_CONST; -GType xed_file_browser_store_register_type (GTypeModule * module); +GType xed_file_browser_store_get_type (void) G_GNUC_CONST; +void _xed_file_browser_store_register_type (GTypeModule *type_module); -XedFileBrowserStore *xed_file_browser_store_new (gchar const *root); +XedFileBrowserStore *xed_file_browser_store_new (GFile *root); -XedFileBrowserStoreResult -xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore * model, - gchar const *root, - gchar const *virtual_root); -XedFileBrowserStoreResult -xed_file_browser_store_set_root (XedFileBrowserStore * model, - gchar const *root); -XedFileBrowserStoreResult -xed_file_browser_store_set_virtual_root (XedFileBrowserStore * model, - GtkTreeIter * iter); -XedFileBrowserStoreResult -xed_file_browser_store_set_virtual_root_from_string (XedFileBrowserStore * model, - gchar const *root); -XedFileBrowserStoreResult -xed_file_browser_store_set_virtual_root_up (XedFileBrowserStore * model); -XedFileBrowserStoreResult -xed_file_browser_store_set_virtual_root_top (XedFileBrowserStore * model); +XedFileBrowserStoreResult xed_file_browser_store_set_root_and_virtual_root (XedFileBrowserStore *model, + GFile *root, + GFile *virtual_root); +XedFileBrowserStoreResult xed_file_browser_store_set_root (XedFileBrowserStore *model, + GFile *root); +XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root (XedFileBrowserStore *model, + GtkTreeIter *iter); +XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root_from_location (XedFileBrowserStore *model, + GFile *root); +XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root_up (XedFileBrowserStore *model); +XedFileBrowserStoreResult xed_file_browser_store_set_virtual_root_top (XedFileBrowserStore *model); -gboolean -xed_file_browser_store_get_iter_virtual_root (XedFileBrowserStore * model, - GtkTreeIter * iter); -gboolean xed_file_browser_store_get_iter_root (XedFileBrowserStore * model, - GtkTreeIter * iter); -gchar * xed_file_browser_store_get_root (XedFileBrowserStore * model); -gchar * xed_file_browser_store_get_virtual_root (XedFileBrowserStore * model); +gboolean xed_file_browser_store_get_iter_virtual_root (XedFileBrowserStore *model, + GtkTreeIter *iter); +gboolean xed_file_browser_store_get_iter_root (XedFileBrowserStore *model, + GtkTreeIter *iter); +GFile * xed_file_browser_store_get_root (XedFileBrowserStore *model); +GFile * xed_file_browser_store_get_virtual_root (XedFileBrowserStore *model); -gboolean xed_file_browser_store_iter_equal (XedFileBrowserStore * model, - GtkTreeIter * iter1, - GtkTreeIter * iter2); +gboolean xed_file_browser_store_iter_equal (XedFileBrowserStore *model, + GtkTreeIter *iter1, + GtkTreeIter *iter2); -void xed_file_browser_store_set_value (XedFileBrowserStore * tree_model, - GtkTreeIter * iter, - gint column, - GValue * value); +void xed_file_browser_store_set_value (XedFileBrowserStore *tree_model, + GtkTreeIter *iter, + gint column, + GValue *value); -void _xed_file_browser_store_iter_expanded (XedFileBrowserStore * model, - GtkTreeIter * iter); -void _xed_file_browser_store_iter_collapsed (XedFileBrowserStore * model, - GtkTreeIter * iter); +void _xed_file_browser_store_iter_expanded (XedFileBrowserStore *model, + GtkTreeIter *iter); +void _xed_file_browser_store_iter_collapsed (XedFileBrowserStore *model, + GtkTreeIter *iter); -XedFileBrowserStoreFilterMode -xed_file_browser_store_get_filter_mode (XedFileBrowserStore * model); -void xed_file_browser_store_set_filter_mode (XedFileBrowserStore * model, - XedFileBrowserStoreFilterMode mode); -void xed_file_browser_store_set_filter_func (XedFileBrowserStore * model, - XedFileBrowserStoreFilterFunc func, - gpointer user_data); -void xed_file_browser_store_refilter (XedFileBrowserStore * model); -XedFileBrowserStoreFilterMode -xed_file_browser_store_filter_mode_get_default (void); +XedFileBrowserStoreFilterMode xed_file_browser_store_get_filter_mode (XedFileBrowserStore *model); +void xed_file_browser_store_set_filter_mode (XedFileBrowserStore *model, + XedFileBrowserStoreFilterMode mode); +void xed_file_browser_store_set_filter_func (XedFileBrowserStore *model, + XedFileBrowserStoreFilterFunc func, + gpointer user_data); +void xed_file_browser_store_refilter (XedFileBrowserStore *model); +XedFileBrowserStoreFilterMode xed_file_browser_store_filter_mode_get_default (void); -void xed_file_browser_store_refresh (XedFileBrowserStore * model); -gboolean xed_file_browser_store_rename (XedFileBrowserStore * model, - GtkTreeIter * iter, - gchar const *new_name, - GError ** error); -XedFileBrowserStoreResult -xed_file_browser_store_delete (XedFileBrowserStore * model, - GtkTreeIter * iter, - gboolean trash); -XedFileBrowserStoreResult -xed_file_browser_store_delete_all (XedFileBrowserStore * model, - GList *rows, - gboolean trash); +void xed_file_browser_store_refresh (XedFileBrowserStore * model); +gboolean xed_file_browser_store_rename (XedFileBrowserStore *model, + GtkTreeIter *iter, + gchar const *new_name, + GError **error); +XedFileBrowserStoreResult xed_file_browser_store_delete (XedFileBrowserStore *model, + GtkTreeIter *iter, + gboolean trash); +XedFileBrowserStoreResult xed_file_browser_store_delete_all (XedFileBrowserStore *model, + GList *rows, + gboolean trash); -gboolean xed_file_browser_store_new_file (XedFileBrowserStore * model, - GtkTreeIter * parent, - GtkTreeIter * iter); -gboolean xed_file_browser_store_new_directory (XedFileBrowserStore * model, - GtkTreeIter * parent, - GtkTreeIter * iter); +gboolean xed_file_browser_store_new_file (XedFileBrowserStore *model, + GtkTreeIter *parent, + GtkTreeIter *iter); +gboolean xed_file_browser_store_new_directory (XedFileBrowserStore *model, + GtkTreeIter *parent, + GtkTreeIter *iter); -void xed_file_browser_store_cancel_mount_operation (XedFileBrowserStore *store); +void xed_file_browser_store_cancel_mount_operation (XedFileBrowserStore *store); G_END_DECLS -#endif /* __XED_FILE_BROWSER_STORE_H__ */ +#endif /* __XED_FILE_BROWSER_STORE_H__ */ // ex:ts=8:noet: diff --git a/plugins/filebrowser/xed-file-browser-utils.c b/plugins/filebrowser/xed-file-browser-utils.c index 6565713..2c3fbb7 100644 --- a/plugins/filebrowser/xed-file-browser-utils.c +++ b/plugins/filebrowser/xed-file-browser-utils.c @@ -1,5 +1,5 @@ /* - * xed-file-bookmarks-store.c - Xed plugin providing easy file access + * xed-file-bookmarks-store.c - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -24,8 +24,8 @@ static GdkPixbuf * process_icon_pixbuf (GdkPixbuf * pixbuf, - gchar const * name, - gint size, + gchar const * name, + gint size, GError * error) { GdkPixbuf * scale; @@ -36,11 +36,11 @@ process_icon_pixbuf (GdkPixbuf * pixbuf, error->message); g_error_free (error); } - + if (pixbuf && gdk_pixbuf_get_width (pixbuf) > size) { - scale = gdk_pixbuf_scale_simple (pixbuf, - size, - size, + scale = gdk_pixbuf_scale_simple (pixbuf, + size, + size, GDK_INTERP_BILINEAR); g_object_unref (pixbuf); pixbuf = scale; @@ -59,10 +59,10 @@ xed_file_browser_utils_pixbuf_from_theme (gchar const * name, gtk_icon_size_lookup (size, &width, NULL); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - name, - width, - 0, + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + name, + width, + 0, &error); pixbuf = process_icon_pixbuf (pixbuf, name, width, error); @@ -84,7 +84,7 @@ xed_file_browser_utils_pixbuf_from_icon (GIcon * icon, theme = gtk_icon_theme_get_default (); gtk_icon_size_lookup (size, &width, NULL); - + info = gtk_icon_theme_lookup_by_gicon (theme, icon, width, @@ -92,10 +92,10 @@ xed_file_browser_utils_pixbuf_from_icon (GIcon * icon, if (!info) return NULL; - + ret = gtk_icon_info_load_icon (info, NULL); gtk_icon_info_free (info); - + return ret; } @@ -107,12 +107,12 @@ xed_file_browser_utils_pixbuf_from_file (GFile * file, GFileInfo * info; GdkPixbuf * ret = NULL; - info = g_file_query_info (file, - G_FILE_ATTRIBUTE_STANDARD_ICON, + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_ICON, G_FILE_QUERY_INFO_NONE, - NULL, + NULL, NULL); - + if (!info) return NULL; @@ -121,35 +121,22 @@ xed_file_browser_utils_pixbuf_from_file (GFile * file, ret = xed_file_browser_utils_pixbuf_from_icon (icon, size); g_object_unref (info); - + return ret; } gchar * xed_file_browser_utils_file_basename (GFile * file) { - gchar *uri; - gchar *ret; - - uri = g_file_get_uri (file); - ret = xed_file_browser_utils_uri_basename (uri); - g_free (uri); - - return ret; -} - -gchar * -xed_file_browser_utils_uri_basename (gchar const * uri) -{ - return xed_utils_basename_for_display (uri); + return xed_utils_basename_for_display (file); } gboolean xed_file_browser_utils_confirmation_dialog (XedWindow * window, GtkMessageType type, gchar const *message, - gchar const *secondary, - gchar const * button_stock, + gchar const *secondary, + gchar const * button_stock, gchar const * button_label) { GtkWidget *dlg; @@ -177,18 +164,18 @@ xed_file_browser_utils_confirmation_dialog (XedWindow * window, /* Add custom button */ button = gtk_button_new_from_stock (button_stock); - + if (button_label) { gtk_button_set_use_stock (GTK_BUTTON (button), FALSE); gtk_button_set_label (GTK_BUTTON (button), button_label); } - + gtk_widget_show (button); gtk_widget_set_can_default (button, TRUE); gtk_dialog_add_action_widget (GTK_DIALOG (dlg), button, GTK_RESPONSE_OK); - + ret = gtk_dialog_run (GTK_DIALOG (dlg)); gtk_widget_destroy (dlg); diff --git a/plugins/filebrowser/xed-file-browser-utils.h b/plugins/filebrowser/xed-file-browser-utils.h index b1400c1..bd17b84 100644 --- a/plugins/filebrowser/xed-file-browser-utils.h +++ b/plugins/filebrowser/xed-file-browser-utils.h @@ -13,13 +13,12 @@ GdkPixbuf *xed_file_browser_utils_pixbuf_from_file (GFile * file, GtkIconSize size); gchar * xed_file_browser_utils_file_basename (GFile * file); -gchar * xed_file_browser_utils_uri_basename (gchar const * uri); gboolean xed_file_browser_utils_confirmation_dialog (XedWindow * window, GtkMessageType type, gchar const *message, - gchar const *secondary, - gchar const * button_stock, + gchar const *secondary, + gchar const * button_stock, gchar const * button_label); #endif /* __XED_FILE_BROWSER_UTILS_H__ */ diff --git a/plugins/filebrowser/xed-file-browser-view.c b/plugins/filebrowser/xed-file-browser-view.c index 5e26bac..7eddd49 100644 --- a/plugins/filebrowser/xed-file-browser-view.c +++ b/plugins/filebrowser/xed-file-browser-view.c @@ -1,5 +1,5 @@ /* - * xed-file-browser-view.c - Xed plugin providing easy file access + * xed-file-browser-view.c - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -20,8 +20,8 @@ */ #include +#include #include -#include #include #include @@ -32,1226 +32,1301 @@ #include "xed-file-browser-enum-types.h" #define XED_FILE_BROWSER_VIEW_GET_PRIVATE(object)( \ - G_TYPE_INSTANCE_GET_PRIVATE((object), \ - XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserViewPrivate)) + G_TYPE_INSTANCE_GET_PRIVATE((object), \ + XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserViewPrivate)) -struct _XedFileBrowserViewPrivate +struct _XedFileBrowserViewPrivate { - GtkTreeViewColumn *column; - GtkCellRenderer *pixbuf_renderer; - GtkCellRenderer *text_renderer; + GtkTreeViewColumn *column; + GtkCellRenderer *pixbuf_renderer; + GtkCellRenderer *text_renderer; - GtkTreeModel *model; - GtkTreeRowReference *editable; + GtkTreeModel *model; + GtkTreeRowReference *editable; - GdkCursor *busy_cursor; + GdkCursor *busy_cursor; - /* CLick policy */ - XedFileBrowserViewClickPolicy click_policy; - GtkTreePath *double_click_path[2]; /* Both clicks in a double click need to be on the same row */ - GtkTreePath *hover_path; - GdkCursor *hand_cursor; - gboolean ignore_release; - gboolean selected_on_button_down; - gint drag_button; - gboolean drag_started; - - gboolean restore_expand_state; - gboolean is_refresh; - GHashTable * expand_state; + /* CLick policy */ + XedFileBrowserViewClickPolicy click_policy; + GtkTreePath *double_click_path[2]; /* Both clicks in a double click need to be on the same row */ + GtkTreePath *hover_path; + GdkCursor *hand_cursor; + gboolean ignore_release; + gboolean selected_on_button_down; + gint drag_button; + gboolean drag_started; + + gboolean restore_expand_state; + gboolean is_refresh; + GHashTable * expand_state; }; /* Properties */ enum { - PROP_0, - - PROP_CLICK_POLICY, - PROP_RESTORE_EXPAND_STATE + PROP_0, + + PROP_CLICK_POLICY, + PROP_RESTORE_EXPAND_STATE }; /* Signals */ enum { - ERROR, - FILE_ACTIVATED, - DIRECTORY_ACTIVATED, - BOOKMARK_ACTIVATED, - NUM_SIGNALS + ERROR, + FILE_ACTIVATED, + DIRECTORY_ACTIVATED, + BOOKMARK_ACTIVATED, + NUM_SIGNALS }; static guint signals[NUM_SIGNALS] = { 0 }; static const GtkTargetEntry drag_source_targets[] = { - { "text/uri-list", 0, 0 } + { "text/uri-list", 0, 0 } }; -XED_PLUGIN_DEFINE_TYPE (XedFileBrowserView, xed_file_browser_view, - GTK_TYPE_TREE_VIEW) +G_DEFINE_DYNAMIC_TYPE (XedFileBrowserView, xed_file_browser_view, GTK_TYPE_TREE_VIEW) -static void on_cell_edited (GtkCellRendererText * cell, - gchar * path, - gchar * new_text, - XedFileBrowserView * tree_view); +static void on_cell_edited (GtkCellRendererText *cell, + gchar *path, + gchar *new_text, + XedFileBrowserView *tree_view); -static void on_begin_refresh (XedFileBrowserStore * model, - XedFileBrowserView * view); -static void on_end_refresh (XedFileBrowserStore * model, - XedFileBrowserView * view); +static void on_begin_refresh (XedFileBrowserStore *model, + XedFileBrowserView *view); +static void on_end_refresh (XedFileBrowserStore *model, + XedFileBrowserView *view); -static void on_unload (XedFileBrowserStore * model, - gchar const * uri, - XedFileBrowserView * view); +static void on_unload (XedFileBrowserStore *model, + GFile *location, + XedFileBrowserView *view); + +static void on_row_inserted (XedFileBrowserStore *model, + GtkTreePath *path, + GtkTreeIter *iter, + XedFileBrowserView *view); -static void on_row_inserted (XedFileBrowserStore * model, - GtkTreePath * path, - GtkTreeIter * iter, - XedFileBrowserView * view); - static void -xed_file_browser_view_finalize (GObject * object) +xed_file_browser_view_finalize (GObject *object) { - XedFileBrowserView *obj = XED_FILE_BROWSER_VIEW(object); - - if (obj->priv->hand_cursor) - g_object_unref (obj->priv->hand_cursor); + XedFileBrowserView *obj = XED_FILE_BROWSER_VIEW(object); - if (obj->priv->hover_path) - gtk_tree_path_free (obj->priv->hover_path); + if (obj->priv->hand_cursor) + { + g_object_unref (obj->priv->hand_cursor); + } - if (obj->priv->expand_state) - { - g_hash_table_destroy (obj->priv->expand_state); - obj->priv->expand_state = NULL; - } + if (obj->priv->hover_path) + { + gtk_tree_path_free (obj->priv->hover_path); + } - g_object_unref (obj->priv->busy_cursor); + if (obj->priv->expand_state) + { + g_hash_table_destroy (obj->priv->expand_state); + obj->priv->expand_state = NULL; + } - G_OBJECT_CLASS (xed_file_browser_view_parent_class)-> - finalize (object); + g_object_unref (obj->priv->busy_cursor); + + G_OBJECT_CLASS (xed_file_browser_view_parent_class)->finalize (object); } static void -add_expand_state (XedFileBrowserView * view, - gchar const * uri) +add_expand_state (XedFileBrowserView *view, + GFile *location) { - GFile * file; - - if (!uri) - return; + if (!location) + { + return; + } - file = g_file_new_for_uri (uri); - - if (view->priv->expand_state) - g_hash_table_insert (view->priv->expand_state, file, file); - else - g_object_unref (file); + if (view->priv->expand_state) + { + g_hash_table_insert (view->priv->expand_state, location, g_object_ref (location)); + } } static void -remove_expand_state (XedFileBrowserView * view, - gchar const * uri) +remove_expand_state (XedFileBrowserView *view, + GFile *location) { - GFile * file; - - if (!uri) - return; + if (!location) + { + return; + } - file = g_file_new_for_uri (uri); - - if (view->priv->expand_state) - g_hash_table_remove (view->priv->expand_state, file); - - g_object_unref (file); + if (view->priv->expand_state) + { + g_hash_table_remove (view->priv->expand_state, location); + } } static void -row_expanded (GtkTreeView * tree_view, - GtkTreeIter * iter, - GtkTreePath * path) +row_expanded (GtkTreeView *tree_view, + GtkTreeIter *iter, + GtkTreePath *path) { - XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (tree_view); - gchar * uri; + XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (tree_view); + GFile *location; - if (GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_expanded) - GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_expanded (tree_view, iter, path); + if (GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_expanded) + { + GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_expanded (tree_view, iter, path); + } - if (!XED_IS_FILE_BROWSER_STORE (view->priv->model)) - return; + if (!XED_IS_FILE_BROWSER_STORE (view->priv->model)) + { + return; + } - if (view->priv->restore_expand_state) - { - gtk_tree_model_get (view->priv->model, - iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, - &uri, - -1); + if (view->priv->restore_expand_state) + { + gtk_tree_model_get (view->priv->model, iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1); - add_expand_state (view, uri); - g_free (uri); - } + add_expand_state (view, location); + } - _xed_file_browser_store_iter_expanded (XED_FILE_BROWSER_STORE (view->priv->model), - iter); + _xed_file_browser_store_iter_expanded (XED_FILE_BROWSER_STORE (view->priv->model), iter); } static void -row_collapsed (GtkTreeView * tree_view, - GtkTreeIter * iter, - GtkTreePath * path) +row_collapsed (GtkTreeView *tree_view, + GtkTreeIter *iter, + GtkTreePath *path) { - XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (tree_view); - gchar * uri; + XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (tree_view); + GFile *location; - if (GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_collapsed) - GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_collapsed (tree_view, iter, path); + if (GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_collapsed) + { + GTK_TREE_VIEW_CLASS (xed_file_browser_view_parent_class)->row_collapsed (tree_view, iter, path); + } - if (!XED_IS_FILE_BROWSER_STORE (view->priv->model)) - return; - - if (view->priv->restore_expand_state) - { - gtk_tree_model_get (view->priv->model, - iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, - &uri, - -1); + if (!XED_IS_FILE_BROWSER_STORE (view->priv->model)) + { + return; + } - remove_expand_state (view, uri); - g_free (uri); - } + if (view->priv->restore_expand_state) + { + gtk_tree_model_get (view->priv->model, iter, XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1); - _xed_file_browser_store_iter_collapsed (XED_FILE_BROWSER_STORE (view->priv->model), - iter); + remove_expand_state (view, location); + } + + _xed_file_browser_store_iter_collapsed (XED_FILE_BROWSER_STORE (view->priv->model), iter); } static gboolean -leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event) +leave_notify_event (GtkWidget *widget, + GdkEventCrossing *event) { - XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); + XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); - if (view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE && - view->priv->hover_path != NULL) { - gtk_tree_path_free (view->priv->hover_path); - view->priv->hover_path = NULL; - } + if (view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE && + view->priv->hover_path != NULL) + { + gtk_tree_path_free (view->priv->hover_path); + view->priv->hover_path = NULL; + } - // Chainup - return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->leave_notify_event (widget, event); + // Chainup + return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->leave_notify_event (widget, event); } static gboolean -enter_notify_event (GtkWidget *widget, - GdkEventCrossing *event) +enter_notify_event (GtkWidget *widget, + GdkEventCrossing *event) { - XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); + XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); - if (view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) { - if (view->priv->hover_path != NULL) - gtk_tree_path_free (view->priv->hover_path); + if (view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) + { + if (view->priv->hover_path != NULL) + { + gtk_tree_path_free (view->priv->hover_path); + } - gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), - event->x, event->y, - &view->priv->hover_path, - NULL, NULL, NULL); + gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), + event->x, event->y, + &view->priv->hover_path, + NULL, NULL, NULL); - if (view->priv->hover_path != NULL) - gdk_window_set_cursor (gtk_widget_get_window (widget), - view->priv->hand_cursor); - } + if (view->priv->hover_path != NULL) + { + gdk_window_set_cursor (gtk_widget_get_window (widget), view->priv->hand_cursor); + } + } - // Chainup - return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->enter_notify_event (widget, event); + // Chainup + return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->enter_notify_event (widget, event); } static gboolean -motion_notify_event (GtkWidget * widget, - GdkEventMotion * event) +motion_notify_event (GtkWidget *widget, + GdkEventMotion *event) { - GtkTreePath *old_hover_path; - XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); + GtkTreePath *old_hover_path; + XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); - if (view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) { - old_hover_path = view->priv->hover_path; - gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), - event->x, event->y, - &view->priv->hover_path, - NULL, NULL, NULL); + if (view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) + { + old_hover_path = view->priv->hover_path; + gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), + event->x, event->y, + &view->priv->hover_path, + NULL, NULL, NULL); - if ((old_hover_path != NULL) != (view->priv->hover_path != NULL)) { - if (view->priv->hover_path != NULL) - gdk_window_set_cursor (gtk_widget_get_window (widget), - view->priv->hand_cursor); - else - gdk_window_set_cursor (gtk_widget_get_window (widget), - NULL); - } + if ((old_hover_path != NULL) != (view->priv->hover_path != NULL)) + { + if (view->priv->hover_path != NULL) + { + gdk_window_set_cursor (gtk_widget_get_window (widget), view->priv->hand_cursor); + } + else + { + gdk_window_set_cursor (gtk_widget_get_window (widget), NULL); + } + } - if (old_hover_path != NULL) - gtk_tree_path_free (old_hover_path); - } - - // Chainup - return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->motion_notify_event (widget, event); + if (old_hover_path != NULL) + { + gtk_tree_path_free (old_hover_path); + } + } + + // Chainup + return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->motion_notify_event (widget, event); } static void set_click_policy_property (XedFileBrowserView *obj, - XedFileBrowserViewClickPolicy click_policy) + XedFileBrowserViewClickPolicy click_policy) { - GtkTreeIter iter; - GdkDisplay *display; - GdkWindow *win; + GtkTreeIter iter; + GdkDisplay *display; + GdkWindow *win; - obj->priv->click_policy = click_policy; + obj->priv->click_policy = click_policy; - if (click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) { - if (obj->priv->hand_cursor == NULL) - obj->priv->hand_cursor = gdk_cursor_new(GDK_HAND2); - } else if (click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_DOUBLE) { - if (obj->priv->hover_path != NULL) { - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (obj->priv->model), - &iter, obj->priv->hover_path)) - gtk_tree_model_row_changed (GTK_TREE_MODEL (obj->priv->model), - obj->priv->hover_path, &iter); + if (click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) + { + if (obj->priv->hand_cursor == NULL) + { + obj->priv->hand_cursor = gdk_cursor_new(GDK_HAND2); + } + } + else if (click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_DOUBLE) + { + if (obj->priv->hover_path != NULL) + { + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (obj->priv->model), &iter, obj->priv->hover_path)) + { + gtk_tree_model_row_changed (GTK_TREE_MODEL (obj->priv->model), obj->priv->hover_path, &iter); + } - gtk_tree_path_free (obj->priv->hover_path); - obj->priv->hover_path = NULL; - } + gtk_tree_path_free (obj->priv->hover_path); + obj->priv->hover_path = NULL; + } - if (gtk_widget_get_realized (GTK_WIDGET (obj))) { - win = gtk_widget_get_window (GTK_WIDGET (obj)); - gdk_window_set_cursor (win, NULL); - - display = gtk_widget_get_display (GTK_WIDGET (obj)); + if (gtk_widget_get_realized (GTK_WIDGET (obj))) + { + win = gtk_widget_get_window (GTK_WIDGET (obj)); + gdk_window_set_cursor (win, NULL); - if (display != NULL) - gdk_display_flush (display); - } + display = gtk_widget_get_display (GTK_WIDGET (obj)); - if (obj->priv->hand_cursor) { - g_object_unref (obj->priv->hand_cursor); - obj->priv->hand_cursor = NULL; - } - } + if (display != NULL) + { + gdk_display_flush (display); + } + } + + if (obj->priv->hand_cursor) + { + g_object_unref (obj->priv->hand_cursor); + obj->priv->hand_cursor = NULL; + } + } } static void -directory_activated (XedFileBrowserView *view, - GtkTreeIter *iter) +directory_activated (XedFileBrowserView *view, + GtkTreeIter *iter) { - xed_file_browser_store_set_virtual_root (XED_FILE_BROWSER_STORE (view->priv->model), iter); + xed_file_browser_store_set_virtual_root (XED_FILE_BROWSER_STORE (view->priv->model), iter); } static void -activate_selected_files (XedFileBrowserView *view) { - GtkTreeView *tree_view = GTK_TREE_VIEW (view); - GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view); - GList *rows, *row; - GtkTreePath *directory = NULL; - GtkTreePath *path; - GtkTreeIter iter; - XedFileBrowserStoreFlag flags; +activate_selected_files (XedFileBrowserView *view) +{ + GtkTreeView *tree_view = GTK_TREE_VIEW (view); + GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view); + GList *rows, *row; + GtkTreePath *directory = NULL; + GtkTreePath *path; + GtkTreeIter iter; + XedFileBrowserStoreFlag flags; - rows = gtk_tree_selection_get_selected_rows (selection, &view->priv->model); - - for (row = rows; row; row = row->next) { - path = (GtkTreePath *)(row->data); - - /* Get iter from path */ - if (!gtk_tree_model_get_iter (view->priv->model, &iter, path)) - continue; - - gtk_tree_model_get (view->priv->model, &iter, XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, -1); + rows = gtk_tree_selection_get_selected_rows (selection, &view->priv->model); - if (FILE_IS_DIR (flags)) { - if (directory == NULL) - directory = path; - - } else if (!FILE_IS_DUMMY (flags)) { - g_signal_emit (view, signals[FILE_ACTIVATED], 0, &iter); - } - } - - if (directory != NULL) { - if (gtk_tree_model_get_iter (view->priv->model, &iter, directory)) - g_signal_emit (view, signals[DIRECTORY_ACTIVATED], 0, &iter); - } - - g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL); - g_list_free (rows); + for (row = rows; row; row = row->next) + { + path = (GtkTreePath *)(row->data); + + /* Get iter from path */ + if (!gtk_tree_model_get_iter (view->priv->model, &iter, path)) + { + continue; + } + + gtk_tree_model_get (view->priv->model, &iter, XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, -1); + + if (FILE_IS_DIR (flags)) + { + if (directory == NULL) + { + directory = path; + } + + } + else if (!FILE_IS_DUMMY (flags)) + { + g_signal_emit (view, signals[FILE_ACTIVATED], 0, &iter); + } + } + + if (directory != NULL) + { + if (gtk_tree_model_get_iter (view->priv->model, &iter, directory)) + { + g_signal_emit (view, signals[DIRECTORY_ACTIVATED], 0, &iter); + } + } + + g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL); + g_list_free (rows); } static void -activate_selected_bookmark (XedFileBrowserView *view) { - GtkTreeView *tree_view = GTK_TREE_VIEW (view); - GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view); - GtkTreeIter iter; +activate_selected_bookmark (XedFileBrowserView *view) +{ + GtkTreeView *tree_view = GTK_TREE_VIEW (view); + GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view); + GtkTreeIter iter; - if (gtk_tree_selection_get_selected (selection, &view->priv->model, &iter)) - g_signal_emit (view, signals[BOOKMARK_ACTIVATED], 0, &iter); + if (gtk_tree_selection_get_selected (selection, &view->priv->model, &iter)) + { + g_signal_emit (view, signals[BOOKMARK_ACTIVATED], 0, &iter); + } } static void activate_selected_items (XedFileBrowserView *view) { - if (XED_IS_FILE_BROWSER_STORE (view->priv->model)) - activate_selected_files (view); - else if (XED_IS_FILE_BOOKMARKS_STORE (view->priv->model)) - activate_selected_bookmark (view); + if (XED_IS_FILE_BROWSER_STORE (view->priv->model)) + { + activate_selected_files (view); + } + else if (XED_IS_FILE_BOOKMARKS_STORE (view->priv->model)) + { + activate_selected_bookmark (view); + } } static void toggle_hidden_filter (XedFileBrowserView *view) { - XedFileBrowserStoreFilterMode mode; + XedFileBrowserStoreFilterMode mode; - if (XED_IS_FILE_BROWSER_STORE (view->priv->model)) - { - mode = xed_file_browser_store_get_filter_mode - (XED_FILE_BROWSER_STORE (view->priv->model)); - mode ^= XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; - xed_file_browser_store_set_filter_mode - (XED_FILE_BROWSER_STORE (view->priv->model), mode); - } + if (XED_IS_FILE_BROWSER_STORE (view->priv->model)) + { + mode = xed_file_browser_store_get_filter_mode (XED_FILE_BROWSER_STORE (view->priv->model)); + mode ^= XED_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN; + xed_file_browser_store_set_filter_mode (XED_FILE_BROWSER_STORE (view->priv->model), mode); + } } static gboolean button_event_modifies_selection (GdkEventButton *event) { - return (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) != 0; + return (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) != 0; } static void drag_begin (GtkWidget *widget, - GdkDragContext *context) + GdkDragContext *context) { - XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); - - view->priv->drag_button = 0; - view->priv->drag_started = TRUE; - - /* Chain up */ - GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->drag_begin (widget, context); + XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); + + view->priv->drag_button = 0; + view->priv->drag_started = TRUE; + + /* Chain up */ + GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->drag_begin (widget, context); } static void did_not_drag (XedFileBrowserView *view, - GdkEventButton *event) + GdkEventButton *event) { - GtkTreeView *tree_view; - GtkTreeSelection *selection; - GtkTreePath *path; - - tree_view = GTK_TREE_VIEW (view); - selection = gtk_tree_view_get_selection (tree_view); + GtkTreeView *tree_view; + GtkTreeSelection *selection; + GtkTreePath *path; - if (gtk_tree_view_get_path_at_pos (tree_view, event->x, event->y, - &path, NULL, NULL, NULL)) { - if ((view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) - && !button_event_modifies_selection(event) - && (event->button == 1 || event->button == 2)) { - /* Activate all selected items, and leave them selected */ - activate_selected_items (view); - } else if ((event->button == 1 || event->button == 2) - && ((event->state & GDK_CONTROL_MASK) != 0 || - (event->state & GDK_SHIFT_MASK) == 0) - && view->priv->selected_on_button_down) { - if (!button_event_modifies_selection (event)) { - gtk_tree_selection_unselect_all (selection); - gtk_tree_selection_select_path (selection, path); - } else { - gtk_tree_selection_unselect_path (selection, path); - } - } + tree_view = GTK_TREE_VIEW (view); + selection = gtk_tree_view_get_selection (tree_view); - gtk_tree_path_free (path); - } + if (gtk_tree_view_get_path_at_pos (tree_view, event->x, event->y, &path, NULL, NULL, NULL)) + { + if ((view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) + && !button_event_modifies_selection(event) + && (event->button == 1 || event->button == 2)) + { + /* Activate all selected items, and leave them selected */ + activate_selected_items (view); + } + else if ((event->button == 1 || event->button == 2) + && ((event->state & GDK_CONTROL_MASK) != 0 || + (event->state & GDK_SHIFT_MASK) == 0) + && view->priv->selected_on_button_down) + { + if (!button_event_modifies_selection (event)) + { + gtk_tree_selection_unselect_all (selection); + gtk_tree_selection_select_path (selection, path); + } + else + { + gtk_tree_selection_unselect_path (selection, path); + } + } + + gtk_tree_path_free (path); + } } static gboolean -button_release_event (GtkWidget *widget, - GdkEventButton *event) +button_release_event (GtkWidget *widget, + GdkEventButton *event) { - XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); + XedFileBrowserView *view = XED_FILE_BROWSER_VIEW (widget); - if (event->button == view->priv->drag_button) { - view->priv->drag_button = 0; + if (event->button == view->priv->drag_button) + { + view->priv->drag_button = 0; - if (!view->priv->drag_started && - !view->priv->ignore_release) - did_not_drag (view, event); - } - - /* Chain up */ - return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->button_release_event (widget, event); + if (!view->priv->drag_started && !view->priv->ignore_release) + { + did_not_drag (view, event); + } + } + + /* Chain up */ + return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->button_release_event (widget, event); } static gboolean button_press_event (GtkWidget *widget, - GdkEventButton *event) + GdkEventButton *event) { - int double_click_time; - static int click_count = 0; - static guint32 last_click_time = 0; - XedFileBrowserView *view; - GtkTreeView *tree_view; - GtkTreeSelection *selection; - GtkTreePath *path; - int expander_size; - int horizontal_separator; - gboolean on_expander; - gboolean call_parent; - gboolean selected; - GtkWidgetClass *widget_parent = GTK_WIDGET_CLASS(xed_file_browser_view_parent_class); + int double_click_time; + static int click_count = 0; + static guint32 last_click_time = 0; + XedFileBrowserView *view; + GtkTreeView *tree_view; + GtkTreeSelection *selection; + GtkTreePath *path; + int expander_size; + int horizontal_separator; + gboolean on_expander; + gboolean call_parent; + gboolean selected; + GtkWidgetClass *widget_parent = GTK_WIDGET_CLASS(xed_file_browser_view_parent_class); - tree_view = GTK_TREE_VIEW (widget); - view = XED_FILE_BROWSER_VIEW (widget); - selection = gtk_tree_view_get_selection (tree_view); + tree_view = GTK_TREE_VIEW (widget); + view = XED_FILE_BROWSER_VIEW (widget); + selection = gtk_tree_view_get_selection (tree_view); - /* Get double click time */ - g_object_get (G_OBJECT (gtk_widget_get_settings (widget)), - "gtk-double-click-time", &double_click_time, - NULL); + /* Get double click time */ + g_object_get (G_OBJECT (gtk_widget_get_settings (widget)), + "gtk-double-click-time", &double_click_time, + NULL); - /* Determine click count */ - if (event->time - last_click_time < double_click_time) - click_count++; - else - click_count = 0; - - last_click_time = event->time; + /* Determine click count */ + if (event->time - last_click_time < double_click_time) + { + click_count++; + } + else + { + click_count = 0; + } - /* Ignore double click if we are in single click mode */ - if (view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE && - click_count >= 2) { - return TRUE; - } + last_click_time = event->time; - view->priv->ignore_release = FALSE; - call_parent = TRUE; + /* Ignore double click if we are in single click mode */ + if (view->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE && click_count >= 2) + { + return TRUE; + } - if (gtk_tree_view_get_path_at_pos (tree_view, event->x, event->y, - &path, NULL, NULL, NULL)) { - /* Keep track of path of last click so double clicks only happen - * on the same item */ - if ((event->button == 1 || event->button == 2) && - event->type == GDK_BUTTON_PRESS) { - if (view->priv->double_click_path[1]) - gtk_tree_path_free (view->priv->double_click_path[1]); + view->priv->ignore_release = FALSE; + call_parent = TRUE; - view->priv->double_click_path[1] = view->priv->double_click_path[0]; - view->priv->double_click_path[0] = gtk_tree_path_copy (path); - } + if (gtk_tree_view_get_path_at_pos (tree_view, event->x, event->y, &path, NULL, NULL, NULL)) + { + /* Keep track of path of last click so double clicks only happen + * on the same item */ + if ((event->button == 1 || event->button == 2) && event->type == GDK_BUTTON_PRESS) + { + if (view->priv->double_click_path[1]) + { + gtk_tree_path_free (view->priv->double_click_path[1]); + } - if (event->type == GDK_2BUTTON_PRESS) { - if (view->priv->double_click_path[1] && - gtk_tree_path_compare (view->priv->double_click_path[0], view->priv->double_click_path[1]) == 0) - activate_selected_items (view); - - /* Chain up */ - widget_parent->button_press_event (widget, event); - } else { - /* We're going to filter out some situations where - * we can't let the default code run because all - * but one row would be would be deselected. We don't - * want that; we want the right click menu or single - * click to apply to everything that's currently selected. */ - selected = gtk_tree_selection_path_is_selected (selection, path); + view->priv->double_click_path[1] = view->priv->double_click_path[0]; + view->priv->double_click_path[0] = gtk_tree_path_copy (path); + } - if (event->button == 3 && selected) - call_parent = FALSE; + if (event->type == GDK_2BUTTON_PRESS) + { + if (view->priv->double_click_path[1] && + gtk_tree_path_compare (view->priv->double_click_path[0], view->priv->double_click_path[1]) == 0) + { + activate_selected_items (view); + } - if ((event->button == 1 || event->button == 2) && - ((event->state & GDK_CONTROL_MASK) != 0 || - (event->state & GDK_SHIFT_MASK) == 0)) { - gtk_widget_style_get (widget, - "expander-size", &expander_size, - "horizontal-separator", &horizontal_separator, - NULL); - on_expander = (event->x <= horizontal_separator / 2 + - gtk_tree_path_get_depth (path) * expander_size); + /* Chain up */ + widget_parent->button_press_event (widget, event); + } + else + { + /* We're going to filter out some situations where + * we can't let the default code run because all + * but one row would be would be deselected. We don't + * want that; we want the right click menu or single + * click to apply to everything that's currently selected. */ + selected = gtk_tree_selection_path_is_selected (selection, path); - view->priv->selected_on_button_down = selected; + if (event->button == 3 && selected) + { + call_parent = FALSE; + } - if (selected) { - call_parent = on_expander || gtk_tree_selection_count_selected_rows (selection) == 1; - view->priv->ignore_release = call_parent && view->priv->click_policy != XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE; - } else if ((event->state & GDK_CONTROL_MASK) != 0) { - call_parent = FALSE; - gtk_tree_selection_select_path (selection, path); - } else { - view->priv->ignore_release = on_expander; - } - } - - if (call_parent) { - /* Chain up */ - widget_parent->button_press_event (widget, event); - } else if (selected) { - gtk_widget_grab_focus (widget); - } - - if ((event->button == 1 || event->button == 2) && - event->type == GDK_BUTTON_PRESS) { - view->priv->drag_started = FALSE; - view->priv->drag_button = event->button; - } - } + if ((event->button == 1 || event->button == 2) && + ((event->state & GDK_CONTROL_MASK) != 0 || + (event->state & GDK_SHIFT_MASK) == 0)) + { + gtk_widget_style_get (widget, + "expander-size", &expander_size, + "horizontal-separator", &horizontal_separator, + NULL); + on_expander = (event->x <= horizontal_separator / 2 + gtk_tree_path_get_depth (path) * expander_size); - gtk_tree_path_free (path); - } else { - if ((event->button == 1 || event->button == 2) && - event->type == GDK_BUTTON_PRESS) { - if (view->priv->double_click_path[1]) - gtk_tree_path_free (view->priv->double_click_path[1]); + view->priv->selected_on_button_down = selected; - view->priv->double_click_path[1] = view->priv->double_click_path[0]; - view->priv->double_click_path[0] = NULL; - } + if (selected) + { + call_parent = on_expander || gtk_tree_selection_count_selected_rows (selection) == 1; + view->priv->ignore_release = call_parent && view->priv->click_policy != XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE; + } + else if ((event->state & GDK_CONTROL_MASK) != 0) + { + call_parent = FALSE; + gtk_tree_selection_select_path (selection, path); + } + else + { + view->priv->ignore_release = on_expander; + } + } - gtk_tree_selection_unselect_all (selection); - /* Chain up */ - widget_parent->button_press_event (widget, event); - } + if (call_parent) + { + /* Chain up */ + widget_parent->button_press_event (widget, event); + } + else if (selected) + { + gtk_widget_grab_focus (widget); + } - /* We already chained up if nescessary, so just return TRUE */ - return TRUE; + if ((event->button == 1 || event->button == 2) && + event->type == GDK_BUTTON_PRESS) + { + view->priv->drag_started = FALSE; + view->priv->drag_button = event->button; + } + } + + gtk_tree_path_free (path); + } + else + { + if ((event->button == 1 || event->button == 2) && event->type == GDK_BUTTON_PRESS) + { + if (view->priv->double_click_path[1]) + { + gtk_tree_path_free (view->priv->double_click_path[1]); + } + + view->priv->double_click_path[1] = view->priv->double_click_path[0]; + view->priv->double_click_path[0] = NULL; + } + + gtk_tree_selection_unselect_all (selection); + /* Chain up */ + widget_parent->button_press_event (widget, event); + } + + /* We already chained up if nescessary, so just return TRUE */ + return TRUE; } static gboolean key_press_event (GtkWidget *widget, - GdkEventKey *event) + GdkEventKey *event) { - XedFileBrowserView *view; - guint modifiers; - gboolean handled; + XedFileBrowserView *view; + guint modifiers; + gboolean handled; - view = XED_FILE_BROWSER_VIEW (widget); - handled = FALSE; + view = XED_FILE_BROWSER_VIEW (widget); + handled = FALSE; - modifiers = gtk_accelerator_get_default_mod_mask (); + modifiers = gtk_accelerator_get_default_mod_mask (); - switch (event->keyval) { - case GDK_KEY_space: - if (event->state & GDK_CONTROL_MASK) { - handled = FALSE; - break; - } - if (!gtk_widget_has_focus (widget)) { - handled = FALSE; - break; - } + switch (event->keyval) + { + case GDK_KEY_space: + if (event->state & GDK_CONTROL_MASK) + { + handled = FALSE; + break; + } + if (!gtk_widget_has_focus (widget)) + { + handled = FALSE; + break; + } - activate_selected_items (view); - handled = TRUE; - break; + activate_selected_items (view); + handled = TRUE; + break; - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - activate_selected_items (view); - handled = TRUE; - break; + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + activate_selected_items (view); + handled = TRUE; + break; - case GDK_KEY_h: - if ((event->state & modifiers) == GDK_CONTROL_MASK) { - toggle_hidden_filter (view); - handled = TRUE; - break; - } + case GDK_KEY_h: + if ((event->state & modifiers) == GDK_CONTROL_MASK) + { + toggle_hidden_filter (view); + handled = TRUE; + break; + } - default: - handled = FALSE; - } + default: + handled = FALSE; + } - /* Chain up */ - if (!handled) - return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->key_press_event (widget, event); - - return TRUE; + /* Chain up */ + if (!handled) + { + return GTK_WIDGET_CLASS (xed_file_browser_view_parent_class)->key_press_event (widget, event); + } + + return TRUE; } static void -fill_expand_state (XedFileBrowserView * view, GtkTreeIter * iter) +fill_expand_state (XedFileBrowserView *view, + GtkTreeIter *iter) { - GtkTreePath * path; - GtkTreeIter child; - gchar * uri; - - if (!gtk_tree_model_iter_has_child (view->priv->model, iter)) - return; - - path = gtk_tree_model_get_path (view->priv->model, iter); - - if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), path)) - { - gtk_tree_model_get (view->priv->model, - iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, - &uri, - -1); + GtkTreePath * path; + GtkTreeIter child; + GFile *location; - add_expand_state (view, uri); - g_free (uri); - } - - if (gtk_tree_model_iter_children (view->priv->model, &child, iter)) - { - do { - fill_expand_state (view, &child); - } while (gtk_tree_model_iter_next (view->priv->model, &child)); - } - - gtk_tree_path_free (path); + if (!gtk_tree_model_iter_has_child (view->priv->model, iter)) + { + return; + } + + path = gtk_tree_model_get_path (view->priv->model, iter); + + if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), path)) + { + gtk_tree_model_get (view->priv->model, + iter, + XED_FILE_BROWSER_STORE_COLUMN_LOCATION, + &location, + -1); + + add_expand_state (view, location); + } + + if (gtk_tree_model_iter_children (view->priv->model, &child, iter)) + { + do + { + fill_expand_state (view, &child); + } while (gtk_tree_model_iter_next (view->priv->model, &child)); + } + + gtk_tree_path_free (path); } static void -uninstall_restore_signals (XedFileBrowserView * tree_view, - GtkTreeModel * model) +uninstall_restore_signals (XedFileBrowserView *tree_view, + GtkTreeModel *model) { - g_signal_handlers_disconnect_by_func (model, - on_begin_refresh, - tree_view); - - g_signal_handlers_disconnect_by_func (model, - on_end_refresh, - tree_view); - - g_signal_handlers_disconnect_by_func (model, - on_unload, - tree_view); - - g_signal_handlers_disconnect_by_func (model, - on_row_inserted, - tree_view); + g_signal_handlers_disconnect_by_func (model, on_begin_refresh, tree_view); + g_signal_handlers_disconnect_by_func (model, on_end_refresh, tree_view); + g_signal_handlers_disconnect_by_func (model, on_unload, tree_view); + g_signal_handlers_disconnect_by_func (model, on_row_inserted, tree_view); } static void -install_restore_signals (XedFileBrowserView * tree_view, - GtkTreeModel * model) +install_restore_signals (XedFileBrowserView *tree_view, + GtkTreeModel *model) { - g_signal_connect (model, - "begin-refresh", - G_CALLBACK (on_begin_refresh), - tree_view); - - g_signal_connect (model, - "end-refresh", - G_CALLBACK (on_end_refresh), - tree_view); - - g_signal_connect (model, - "unload", - G_CALLBACK (on_unload), - tree_view); - - g_signal_connect_after (model, - "row-inserted", - G_CALLBACK (on_row_inserted), - tree_view); + g_signal_connect (model, "begin-refresh", + G_CALLBACK (on_begin_refresh), tree_view); + g_signal_connect (model, "end-refresh", + G_CALLBACK (on_end_refresh), tree_view); + g_signal_connect (model, "unload", + G_CALLBACK (on_unload), tree_view); + g_signal_connect_after (model, "row-inserted", + G_CALLBACK (on_row_inserted), tree_view); } static void -set_restore_expand_state (XedFileBrowserView * view, - gboolean state) +set_restore_expand_state (XedFileBrowserView *view, + gboolean state) { - if (state == view->priv->restore_expand_state) - return; + if (state == view->priv->restore_expand_state) + { + return; + } - if (view->priv->expand_state) - { - g_hash_table_destroy (view->priv->expand_state); - view->priv->expand_state = NULL; - } + if (view->priv->expand_state) + { + g_hash_table_destroy (view->priv->expand_state); + view->priv->expand_state = NULL; + } - if (state) - { - view->priv->expand_state = g_hash_table_new_full (g_file_hash, - (GEqualFunc)g_file_equal, - g_object_unref, - NULL); - - if (view->priv->model && XED_IS_FILE_BROWSER_STORE (view->priv->model)) - { - fill_expand_state (view, NULL); + if (state) + { + view->priv->expand_state = g_hash_table_new_full (g_file_hash, + (GEqualFunc)g_file_equal, + g_object_unref, + NULL); - install_restore_signals (view, view->priv->model); - } - } - else if (view->priv->model && XED_IS_FILE_BROWSER_STORE (view->priv->model)) - { - uninstall_restore_signals (view, view->priv->model); - } + if (view->priv->model && XED_IS_FILE_BROWSER_STORE (view->priv->model)) + { + fill_expand_state (view, NULL); - view->priv->restore_expand_state = state; + install_restore_signals (view, view->priv->model); + } + } + else if (view->priv->model && XED_IS_FILE_BROWSER_STORE (view->priv->model)) + { + uninstall_restore_signals (view, view->priv->model); + } + + view->priv->restore_expand_state = state; } static void get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedFileBrowserView *obj = XED_FILE_BROWSER_VIEW (object); + XedFileBrowserView *obj = XED_FILE_BROWSER_VIEW (object); - switch (prop_id) - { - case PROP_CLICK_POLICY: - g_value_set_enum (value, obj->priv->click_policy); - break; - case PROP_RESTORE_EXPAND_STATE: - g_value_set_boolean (value, obj->priv->restore_expand_state); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_CLICK_POLICY: + g_value_set_enum (value, obj->priv->click_policy); + break; + case PROP_RESTORE_EXPAND_STATE: + g_value_set_boolean (value, obj->priv->restore_expand_state); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedFileBrowserView *obj = XED_FILE_BROWSER_VIEW (object); + XedFileBrowserView *obj = XED_FILE_BROWSER_VIEW (object); - switch (prop_id) - { - case PROP_CLICK_POLICY: - set_click_policy_property (obj, g_value_get_enum (value)); - break; - case PROP_RESTORE_EXPAND_STATE: - set_restore_expand_state (obj, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_CLICK_POLICY: + set_click_policy_property (obj, g_value_get_enum (value)); + break; + case PROP_RESTORE_EXPAND_STATE: + set_restore_expand_state (obj, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -xed_file_browser_view_class_init (XedFileBrowserViewClass * klass) +xed_file_browser_view_class_init (XedFileBrowserViewClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkTreeViewClass *tree_view_class = GTK_TREE_VIEW_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - object_class->finalize = xed_file_browser_view_finalize; - object_class->get_property = get_property; - object_class->set_property = set_property; - - /* Event handlers */ - widget_class->motion_notify_event = motion_notify_event; - widget_class->enter_notify_event = enter_notify_event; - widget_class->leave_notify_event = leave_notify_event; - widget_class->button_press_event = button_press_event; - widget_class->button_release_event = button_release_event; - widget_class->drag_begin = drag_begin; - widget_class->key_press_event = key_press_event; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkTreeViewClass *tree_view_class = GTK_TREE_VIEW_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - /* Tree view handlers */ - tree_view_class->row_expanded = row_expanded; - tree_view_class->row_collapsed = row_collapsed; - - /* Default handlers */ - klass->directory_activated = directory_activated; + object_class->finalize = xed_file_browser_view_finalize; + object_class->get_property = get_property; + object_class->set_property = set_property; - g_object_class_install_property (object_class, PROP_CLICK_POLICY, - g_param_spec_enum ("click-policy", - "Click Policy", - "The click policy", - XED_TYPE_FILE_BROWSER_VIEW_CLICK_POLICY, - XED_FILE_BROWSER_VIEW_CLICK_POLICY_DOUBLE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /* Event handlers */ + widget_class->motion_notify_event = motion_notify_event; + widget_class->enter_notify_event = enter_notify_event; + widget_class->leave_notify_event = leave_notify_event; + widget_class->button_press_event = button_press_event; + widget_class->button_release_event = button_release_event; + widget_class->drag_begin = drag_begin; + widget_class->key_press_event = key_press_event; - g_object_class_install_property (object_class, PROP_RESTORE_EXPAND_STATE, - g_param_spec_boolean ("restore-expand-state", - "Restore Expand State", - "Restore expanded state of loaded directories", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /* Tree view handlers */ + tree_view_class->row_expanded = row_expanded; + tree_view_class->row_collapsed = row_collapsed; - signals[ERROR] = - g_signal_new ("error", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserViewClass, - error), NULL, NULL, - xed_file_browser_marshal_VOID__UINT_STRING, - G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); - signals[FILE_ACTIVATED] = - g_signal_new ("file-activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserViewClass, - file_activated), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, GTK_TYPE_TREE_ITER); - signals[DIRECTORY_ACTIVATED] = - g_signal_new ("directory-activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserViewClass, - directory_activated), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, GTK_TYPE_TREE_ITER); - signals[BOOKMARK_ACTIVATED] = - g_signal_new ("bookmark-activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedFileBrowserViewClass, - bookmark_activated), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, GTK_TYPE_TREE_ITER); + /* Default handlers */ + klass->directory_activated = directory_activated; - g_type_class_add_private (object_class, - sizeof (XedFileBrowserViewPrivate)); + g_object_class_install_property (object_class, PROP_CLICK_POLICY, + g_param_spec_enum ("click-policy", + "Click Policy", + "The click policy", + XED_TYPE_FILE_BROWSER_VIEW_CLICK_POLICY, + XED_FILE_BROWSER_VIEW_CLICK_POLICY_DOUBLE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, PROP_RESTORE_EXPAND_STATE, + g_param_spec_boolean ("restore-expand-state", + "Restore Expand State", + "Restore expanded state of loaded directories", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + signals[ERROR] = + g_signal_new ("error", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserViewClass, + error), NULL, NULL, + xed_file_browser_marshal_VOID__UINT_STRING, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); + signals[FILE_ACTIVATED] = + g_signal_new ("file-activated", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserViewClass, + file_activated), NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, GTK_TYPE_TREE_ITER); + signals[DIRECTORY_ACTIVATED] = + g_signal_new ("directory-activated", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserViewClass, + directory_activated), NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, GTK_TYPE_TREE_ITER); + signals[BOOKMARK_ACTIVATED] = + g_signal_new ("bookmark-activated", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedFileBrowserViewClass, + bookmark_activated), NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, GTK_TYPE_TREE_ITER); + + g_type_class_add_private (object_class, sizeof (XedFileBrowserViewPrivate)); } static void -cell_data_cb (GtkTreeViewColumn * tree_column, GtkCellRenderer * cell, - GtkTreeModel * tree_model, GtkTreeIter * iter, - XedFileBrowserView * obj) +xed_file_browser_view_class_finalize (XedFileBrowserViewClass *klass) { - GtkTreePath *path; - PangoUnderline underline = PANGO_UNDERLINE_NONE; - gboolean editable = FALSE; - - path = gtk_tree_model_get_path (tree_model, iter); - - if (obj->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) { - if (obj->priv->hover_path != NULL && - gtk_tree_path_compare (path, obj->priv->hover_path) == 0) - underline = PANGO_UNDERLINE_SINGLE; - } - - if (XED_IS_FILE_BROWSER_STORE (tree_model)) - { - if (obj->priv->editable != NULL && - gtk_tree_row_reference_valid (obj->priv->editable)) - { - GtkTreePath *edpath = gtk_tree_row_reference_get_path (obj->priv->editable); - - editable = edpath && gtk_tree_path_compare (path, edpath) == 0; - } - } - - gtk_tree_path_free (path); - g_object_set (cell, "editable", editable, "underline", underline, NULL); + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE */ } static void -xed_file_browser_view_init (XedFileBrowserView * obj) +cell_data_cb (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + XedFileBrowserView *obj) { - obj->priv = XED_FILE_BROWSER_VIEW_GET_PRIVATE (obj); + GtkTreePath *path; + PangoUnderline underline = PANGO_UNDERLINE_NONE; + gboolean editable = FALSE; - obj->priv->column = gtk_tree_view_column_new (); + path = gtk_tree_model_get_path (tree_model, iter); - obj->priv->pixbuf_renderer = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (obj->priv->column, - obj->priv->pixbuf_renderer, - FALSE); - gtk_tree_view_column_add_attribute (obj->priv->column, - obj->priv->pixbuf_renderer, - "pixbuf", - XED_FILE_BROWSER_STORE_COLUMN_ICON); + if (obj->priv->click_policy == XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE) + { + if (obj->priv->hover_path != NULL && gtk_tree_path_compare (path, obj->priv->hover_path) == 0) + { + underline = PANGO_UNDERLINE_SINGLE; + } + } - obj->priv->text_renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (obj->priv->column, - obj->priv->text_renderer, TRUE); - gtk_tree_view_column_add_attribute (obj->priv->column, - obj->priv->text_renderer, - "text", - XED_FILE_BROWSER_STORE_COLUMN_NAME); + if (XED_IS_FILE_BROWSER_STORE (tree_model)) + { + if (obj->priv->editable != NULL && gtk_tree_row_reference_valid (obj->priv->editable)) + { + GtkTreePath *edpath = gtk_tree_row_reference_get_path (obj->priv->editable); - g_signal_connect (obj->priv->text_renderer, "edited", - G_CALLBACK (on_cell_edited), obj); + editable = edpath && gtk_tree_path_compare (path, edpath) == 0; + } + } - gtk_tree_view_append_column (GTK_TREE_VIEW (obj), - obj->priv->column); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (obj), FALSE); + gtk_tree_path_free (path); + g_object_set (cell, "editable", editable, "underline", underline, NULL); +} - gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (obj), - GDK_BUTTON1_MASK, - drag_source_targets, - G_N_ELEMENTS (drag_source_targets), - GDK_ACTION_COPY); +static void +xed_file_browser_view_init (XedFileBrowserView *obj) +{ + obj->priv = XED_FILE_BROWSER_VIEW_GET_PRIVATE (obj); - obj->priv->busy_cursor = gdk_cursor_new (GDK_WATCH); + obj->priv->column = gtk_tree_view_column_new (); + + obj->priv->pixbuf_renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (obj->priv->column, obj->priv->pixbuf_renderer, FALSE); + gtk_tree_view_column_add_attribute (obj->priv->column, + obj->priv->pixbuf_renderer, + "pixbuf", + XED_FILE_BROWSER_STORE_COLUMN_ICON); + + obj->priv->text_renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (obj->priv->column, obj->priv->text_renderer, TRUE); + gtk_tree_view_column_add_attribute (obj->priv->column, + obj->priv->text_renderer, + "text", + XED_FILE_BROWSER_STORE_COLUMN_NAME); + + g_signal_connect (obj->priv->text_renderer, "edited", + G_CALLBACK (on_cell_edited), obj); + + gtk_tree_view_append_column (GTK_TREE_VIEW (obj), obj->priv->column); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (obj), FALSE); + + gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (obj), + GDK_BUTTON1_MASK, + drag_source_targets, + G_N_ELEMENTS (drag_source_targets), + GDK_ACTION_COPY); + + obj->priv->busy_cursor = gdk_cursor_new (GDK_WATCH); } static gboolean -bookmarks_separator_func (GtkTreeModel * model, GtkTreeIter * iter, - gpointer user_data) +bookmarks_separator_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data) { - guint flags; + guint flags; - gtk_tree_model_get (model, iter, - XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, - &flags, -1); + gtk_tree_model_get (model, iter, XED_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &flags, -1); - return (flags & XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR); + return (flags & XED_FILE_BOOKMARKS_STORE_IS_SEPARATOR); } /* Public */ GtkWidget * xed_file_browser_view_new (void) { - XedFileBrowserView *obj = - XED_FILE_BROWSER_VIEW (g_object_new - (XED_TYPE_FILE_BROWSER_VIEW, NULL)); + XedFileBrowserView *obj = XED_FILE_BROWSER_VIEW (g_object_new (XED_TYPE_FILE_BROWSER_VIEW, NULL)); - return GTK_WIDGET (obj); + return GTK_WIDGET (obj); } void -xed_file_browser_view_set_model (XedFileBrowserView * tree_view, - GtkTreeModel * model) +xed_file_browser_view_set_model (XedFileBrowserView *tree_view, + GtkTreeModel *model) { - GtkTreeSelection *selection; + GtkTreeSelection *selection; - if (tree_view->priv->model == model) - return; + if (tree_view->priv->model == model) + { + return; + } - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); - if (XED_IS_FILE_BOOKMARKS_STORE (model)) { - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW - (tree_view), - bookmarks_separator_func, - NULL, NULL); - gtk_tree_view_column_set_cell_data_func (tree_view->priv-> - column, - tree_view->priv-> - text_renderer, - (GtkTreeCellDataFunc) - cell_data_cb, - tree_view, NULL); - } else { - gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); - gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW - (tree_view), NULL, - NULL, NULL); - gtk_tree_view_column_set_cell_data_func (tree_view->priv-> - column, - tree_view->priv-> - text_renderer, - (GtkTreeCellDataFunc) - cell_data_cb, - tree_view, NULL); + if (XED_IS_FILE_BOOKMARKS_STORE (model)) + { + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW + (tree_view), + bookmarks_separator_func, + NULL, NULL); + gtk_tree_view_column_set_cell_data_func (tree_view->priv-> + column, + tree_view->priv-> + text_renderer, + (GtkTreeCellDataFunc) + cell_data_cb, + tree_view, NULL); + } + else + { + gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); + gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW + (tree_view), NULL, + NULL, NULL); + gtk_tree_view_column_set_cell_data_func (tree_view->priv-> + column, + tree_view->priv-> + text_renderer, + (GtkTreeCellDataFunc) + cell_data_cb, + tree_view, NULL); - if (tree_view->priv->restore_expand_state) - install_restore_signals (tree_view, model); - - } + if (tree_view->priv->restore_expand_state) + { + install_restore_signals (tree_view, model); + } - if (tree_view->priv->hover_path != NULL) { - gtk_tree_path_free (tree_view->priv->hover_path); - tree_view->priv->hover_path = NULL; - } + } - if (XED_IS_FILE_BROWSER_STORE (tree_view->priv->model)) { - if (tree_view->priv->restore_expand_state) - uninstall_restore_signals (tree_view, - tree_view->priv->model); - } + if (tree_view->priv->hover_path != NULL) + { + gtk_tree_path_free (tree_view->priv->hover_path); + tree_view->priv->hover_path = NULL; + } - tree_view->priv->model = model; - gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model); + if (XED_IS_FILE_BROWSER_STORE (tree_view->priv->model)) + { + if (tree_view->priv->restore_expand_state) + { + uninstall_restore_signals (tree_view, tree_view->priv->model); + } + } + + tree_view->priv->model = model; + gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model); } void -xed_file_browser_view_start_rename (XedFileBrowserView * tree_view, - GtkTreeIter * iter) +xed_file_browser_view_start_rename (XedFileBrowserView *tree_view, + GtkTreeIter *iter) { - guint flags; - GtkTreeRowReference *rowref; - GtkTreePath *path; + guint flags; + GtkTreeRowReference *rowref; + GtkTreePath *path; - g_return_if_fail (XED_IS_FILE_BROWSER_VIEW (tree_view)); - g_return_if_fail (XED_IS_FILE_BROWSER_STORE - (tree_view->priv->model)); - g_return_if_fail (iter != NULL); + g_return_if_fail (XED_IS_FILE_BROWSER_VIEW (tree_view)); + g_return_if_fail (XED_IS_FILE_BROWSER_STORE (tree_view->priv->model)); + g_return_if_fail (iter != NULL); - gtk_tree_model_get (tree_view->priv->model, iter, - XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, - -1); + gtk_tree_model_get (tree_view->priv->model, iter, XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, -1); - if (!(FILE_IS_DIR (flags) || !FILE_IS_DUMMY (flags))) - return; + if (!(FILE_IS_DIR (flags) || !FILE_IS_DUMMY (flags))) + { + return; + } - path = gtk_tree_model_get_path (tree_view->priv->model, iter); - rowref = gtk_tree_row_reference_new (tree_view->priv->model, path); + path = gtk_tree_model_get_path (tree_view->priv->model, iter); + rowref = gtk_tree_row_reference_new (tree_view->priv->model, path); - /* Start editing */ - gtk_widget_grab_focus (GTK_WIDGET (tree_view)); - - if (gtk_tree_path_up (path)) - gtk_tree_view_expand_to_path (GTK_TREE_VIEW (tree_view), - path); - - gtk_tree_path_free (path); - tree_view->priv->editable = rowref; + /* Start editing */ + gtk_widget_grab_focus (GTK_WIDGET (tree_view)); - gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree_view), - gtk_tree_row_reference_get_path (tree_view->priv->editable), - tree_view->priv->column, TRUE); - - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree_view), - gtk_tree_row_reference_get_path (tree_view->priv->editable), - tree_view->priv->column, - FALSE, 0.0, 0.0); + if (gtk_tree_path_up (path)) + { + gtk_tree_view_expand_to_path (GTK_TREE_VIEW (tree_view), path); + } + + gtk_tree_path_free (path); + tree_view->priv->editable = rowref; + + gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree_view), + gtk_tree_row_reference_get_path (tree_view->priv->editable), + tree_view->priv->column, TRUE); + + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree_view), + gtk_tree_row_reference_get_path (tree_view->priv->editable), + tree_view->priv->column, + FALSE, 0.0, 0.0); } void -xed_file_browser_view_set_click_policy (XedFileBrowserView *tree_view, - XedFileBrowserViewClickPolicy policy) +xed_file_browser_view_set_click_policy (XedFileBrowserView *tree_view, + XedFileBrowserViewClickPolicy policy) { - g_return_if_fail (XED_IS_FILE_BROWSER_VIEW (tree_view)); - - set_click_policy_property (tree_view, policy); - - g_object_notify (G_OBJECT (tree_view), "click-policy"); + g_return_if_fail (XED_IS_FILE_BROWSER_VIEW (tree_view)); + + set_click_policy_property (tree_view, policy); + + g_object_notify (G_OBJECT (tree_view), "click-policy"); } void -xed_file_browser_view_set_restore_expand_state (XedFileBrowserView * tree_view, - gboolean restore_expand_state) +xed_file_browser_view_set_restore_expand_state (XedFileBrowserView *tree_view, + gboolean restore_expand_state) { - g_return_if_fail (XED_IS_FILE_BROWSER_VIEW (tree_view)); + g_return_if_fail (XED_IS_FILE_BROWSER_VIEW (tree_view)); - set_restore_expand_state (tree_view, restore_expand_state); - g_object_notify (G_OBJECT (tree_view), "restore-expand-state"); + set_restore_expand_state (tree_view, restore_expand_state); + g_object_notify (G_OBJECT (tree_view), "restore-expand-state"); } /* Signal handlers */ static void -on_cell_edited (GtkCellRendererText * cell, gchar * path, gchar * new_text, - XedFileBrowserView * tree_view) +on_cell_edited (GtkCellRendererText *cell, + gchar *path, + gchar *new_text, + XedFileBrowserView *tree_view) { - GtkTreePath * treepath; - GtkTreeIter iter; - gboolean ret; - GError * error = NULL; - - gtk_tree_row_reference_free (tree_view->priv->editable); - tree_view->priv->editable = NULL; + GtkTreePath * treepath; + GtkTreeIter iter; + gboolean ret; + GError * error = NULL; - if (new_text == NULL || *new_text == '\0') - return; - - treepath = gtk_tree_path_new_from_string (path); - ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_view->priv->model), &iter, treepath); - gtk_tree_path_free (treepath); + gtk_tree_row_reference_free (tree_view->priv->editable); + tree_view->priv->editable = NULL; - if (ret) { - if (xed_file_browser_store_rename (XED_FILE_BROWSER_STORE (tree_view->priv->model), - &iter, new_text, &error)) { - treepath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_view->priv->model), &iter); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree_view), - treepath, NULL, - FALSE, 0.0, 0.0); - gtk_tree_path_free (treepath); - } - else { - if (error) { - g_signal_emit (tree_view, signals[ERROR], 0, - error->code, error->message); - g_error_free (error); - } - } - } -} + if (new_text == NULL || *new_text == '\0') + { + return; + } -static void -on_begin_refresh (XedFileBrowserStore * model, - XedFileBrowserView * view) -{ - /* Store the refresh state, so we can handle unloading of nodes while - refreshing properly */ - view->priv->is_refresh = TRUE; -} + treepath = gtk_tree_path_new_from_string (path); + ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_view->priv->model), &iter, treepath); + gtk_tree_path_free (treepath); -static void -on_end_refresh (XedFileBrowserStore * model, - XedFileBrowserView * view) -{ - /* Store the refresh state, so we can handle unloading of nodes while - refreshing properly */ - view->priv->is_refresh = FALSE; + if (ret) + { + if (xed_file_browser_store_rename (XED_FILE_BROWSER_STORE (tree_view->priv->model), &iter, new_text, &error)) + { + treepath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_view->priv->model), &iter); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree_view), treepath, NULL, FALSE, 0.0, 0.0); + gtk_tree_path_free (treepath); + } + else + { + if (error) + { + g_signal_emit (tree_view, signals[ERROR], 0, error->code, error->message); + g_error_free (error); + } + } + } } static void -on_unload (XedFileBrowserStore * model, - gchar const * uri, - XedFileBrowserView * view) +on_begin_refresh (XedFileBrowserStore *model, + XedFileBrowserView *view) { - /* Don't remove the expand state if we are refreshing */ - if (!view->priv->restore_expand_state || view->priv->is_refresh) - return; - - remove_expand_state (view, uri); + /* Store the refresh state, so we can handle unloading of nodes while + refreshing properly */ + view->priv->is_refresh = TRUE; } static void -restore_expand_state (XedFileBrowserView * view, - XedFileBrowserStore * model, - GtkTreeIter * iter) +on_end_refresh (XedFileBrowserStore *model, + XedFileBrowserView *view) { - gchar * uri; - GFile * file; - GtkTreePath * path; - - gtk_tree_model_get (GTK_TREE_MODEL (model), - iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, - &uri, - -1); - - if (!uri) - return; - - file = g_file_new_for_uri (uri); - path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter); - - if (g_hash_table_lookup (view->priv->expand_state, file)) - { - gtk_tree_view_expand_row (GTK_TREE_VIEW (view), - path, - FALSE); - } - - gtk_tree_path_free (path); - - g_object_unref (file); - g_free (uri); + /* Store the refresh state, so we can handle unloading of nodes while + refreshing properly */ + view->priv->is_refresh = FALSE; } -static void -on_row_inserted (XedFileBrowserStore * model, - GtkTreePath * path, - GtkTreeIter * iter, - XedFileBrowserView * view) +static void +on_unload (XedFileBrowserStore *model, + GFile *location, + XedFileBrowserView *view) { - GtkTreeIter parent; - GtkTreePath * copy; + /* Don't remove the expand state if we are refreshing */ + if (!view->priv->restore_expand_state || view->priv->is_refresh) + { + return; + } - if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (model), iter)) - restore_expand_state (view, model, iter); - - copy = gtk_tree_path_copy (path); - - if (gtk_tree_path_up (copy) && - (gtk_tree_path_get_depth (copy) != 0) && - gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent, copy)) - { - restore_expand_state (view, model, &parent); - } - - gtk_tree_path_free (copy); + remove_expand_state (view, location); } - + +static void +restore_expand_state (XedFileBrowserView *view, + XedFileBrowserStore *model, + GtkTreeIter *iter) +{ + GFile *location; + GtkTreePath *path; + + gtk_tree_model_get (GTK_TREE_MODEL (model), + iter, + XED_FILE_BROWSER_STORE_COLUMN_LOCATION, + &location, + -1); + + if (!location) + { + return; + } + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter); + + if (g_hash_table_lookup (view->priv->expand_state, location)) + { + gtk_tree_view_expand_row (GTK_TREE_VIEW (view), path, FALSE); + } + + gtk_tree_path_free (path); +} + +static void +on_row_inserted (XedFileBrowserStore *model, + GtkTreePath *path, + GtkTreeIter *iter, + XedFileBrowserView *view) +{ + GtkTreeIter parent; + GtkTreePath * copy; + + if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (model), iter)) + { + restore_expand_state (view, model, iter); + } + + copy = gtk_tree_path_copy (path); + + if (gtk_tree_path_up (copy) && + (gtk_tree_path_get_depth (copy) != 0) && + gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent, copy)) + { + restore_expand_state (view, model, &parent); + } + + gtk_tree_path_free (copy); +} + +void +_xed_file_browser_view_register_type (GTypeModule *type_module) +{ + xed_file_browser_view_register_type (type_module); +} + // ex:ts=8:noet: diff --git a/plugins/filebrowser/xed-file-browser-view.h b/plugins/filebrowser/xed-file-browser-view.h index 3806b16..2f0e765 100644 --- a/plugins/filebrowser/xed-file-browser-view.h +++ b/plugins/filebrowser/xed-file-browser-view.h @@ -1,5 +1,5 @@ /* - * xed-file-browser-view.h - Xed plugin providing easy file access + * xed-file-browser-view.h - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -25,60 +25,61 @@ #include G_BEGIN_DECLS -#define XED_TYPE_FILE_BROWSER_VIEW (xed_file_browser_view_get_type ()) -#define XED_FILE_BROWSER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserView)) -#define XED_FILE_BROWSER_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserView const)) -#define XED_FILE_BROWSER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserViewClass)) -#define XED_IS_FILE_BROWSER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BROWSER_VIEW)) -#define XED_IS_FILE_BROWSER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BROWSER_VIEW)) -#define XED_FILE_BROWSER_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserViewClass)) +#define XED_TYPE_FILE_BROWSER_VIEW (xed_file_browser_view_get_type ()) +#define XED_FILE_BROWSER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserView)) +#define XED_FILE_BROWSER_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserView const)) +#define XED_FILE_BROWSER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserViewClass)) +#define XED_IS_FILE_BROWSER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BROWSER_VIEW)) +#define XED_IS_FILE_BROWSER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BROWSER_VIEW)) +#define XED_FILE_BROWSER_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BROWSER_VIEW, XedFileBrowserViewClass)) typedef struct _XedFileBrowserView XedFileBrowserView; typedef struct _XedFileBrowserViewClass XedFileBrowserViewClass; typedef struct _XedFileBrowserViewPrivate XedFileBrowserViewPrivate; -typedef enum { - XED_FILE_BROWSER_VIEW_CLICK_POLICY_DOUBLE, - XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE +typedef enum +{ + XED_FILE_BROWSER_VIEW_CLICK_POLICY_DOUBLE, + XED_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE } XedFileBrowserViewClickPolicy; -struct _XedFileBrowserView +struct _XedFileBrowserView { - GtkTreeView parent; + GtkTreeView parent; - XedFileBrowserViewPrivate *priv; + XedFileBrowserViewPrivate *priv; }; -struct _XedFileBrowserViewClass +struct _XedFileBrowserViewClass { - GtkTreeViewClass parent_class; + GtkTreeViewClass parent_class; - /* Signals */ - void (*error) (XedFileBrowserView * filetree, - guint code, - gchar const *message); - void (*file_activated) (XedFileBrowserView * filetree, - GtkTreeIter *iter); - void (*directory_activated) (XedFileBrowserView * filetree, - GtkTreeIter *iter); - void (*bookmark_activated) (XedFileBrowserView * filetree, - GtkTreeIter *iter); + /* Signals */ + void (*error) (XedFileBrowserView *filetree, + guint code, + gchar const *message); + void (*file_activated) (XedFileBrowserView *filetree, + GtkTreeIter *iter); + void (*directory_activated) (XedFileBrowserView *filetree, + GtkTreeIter *iter); + void (*bookmark_activated) (XedFileBrowserView *filetree, + GtkTreeIter *iter); }; -GType xed_file_browser_view_get_type (void) G_GNUC_CONST; -GType xed_file_browser_view_register_type (GTypeModule * module); +GType xed_file_browser_view_get_type (void) G_GNUC_CONST; +void _xed_file_browser_view_register_type (GTypeModule *type_module); -GtkWidget *xed_file_browser_view_new (void); -void xed_file_browser_view_set_model (XedFileBrowserView * tree_view, - GtkTreeModel * model); -void xed_file_browser_view_start_rename (XedFileBrowserView * tree_view, - GtkTreeIter * iter); -void xed_file_browser_view_set_click_policy (XedFileBrowserView * tree_view, - XedFileBrowserViewClickPolicy policy); -void xed_file_browser_view_set_restore_expand_state (XedFileBrowserView * tree_view, - gboolean restore_expand_state); +GtkWidget *xed_file_browser_view_new (void); +void xed_file_browser_view_set_model (XedFileBrowserView *tree_view, + GtkTreeModel *model); +void xed_file_browser_view_start_rename (XedFileBrowserView *tree_view, + GtkTreeIter *iter); +void xed_file_browser_view_set_click_policy (XedFileBrowserView *tree_view, + XedFileBrowserViewClickPolicy policy); +void xed_file_browser_view_set_restore_expand_state (XedFileBrowserView *tree_view, + gboolean restore_expand_state); G_END_DECLS -#endif /* __XED_FILE_BROWSER_VIEW_H__ */ +#endif /* __XED_FILE_BROWSER_VIEW_H__ */ // ex:ts=8:noet: diff --git a/plugins/filebrowser/xed-file-browser-widget.c b/plugins/filebrowser/xed-file-browser-widget.c index 4f39762..6d21fbd 100644 --- a/plugins/filebrowser/xed-file-browser-widget.c +++ b/plugins/filebrowser/xed-file-browser-widget.c @@ -32,7 +32,6 @@ #include #include -#include #include "xed-file-browser-utils.h" #include "xed-file-browser-error.h" @@ -44,8 +43,8 @@ #include "xed-file-browser-enum-types.h" #define XED_FILE_BROWSER_WIDGET_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), \ - XED_TYPE_FILE_BROWSER_WIDGET, \ - XedFileBrowserWidgetPrivate)) + XED_TYPE_FILE_BROWSER_WIDGET, \ + XedFileBrowserWidgetPrivate)) #define XML_UI_FILE "xed-file-browser-widget-ui.xml" #define LOCATION_DATA_KEY "xed-file-browser-widget-location" @@ -81,7 +80,7 @@ enum /* Signals */ enum { - URI_ACTIVATED, + LOCATION_ACTIVATED, ERROR, CONFIRM_DELETE, CONFIRM_NO_TRASH, @@ -236,7 +235,7 @@ static void on_action_filter_binary (GtkAction * action, static void on_action_bookmark_open (GtkAction * action, XedFileBrowserWidget * obj); -XED_PLUGIN_DEFINE_TYPE (XedFileBrowserWidget, xed_file_browser_widget, +G_DEFINE_DYNAMIC_TYPE (XedFileBrowserWidget, xed_file_browser_widget, GTK_TYPE_BOX) static void @@ -434,14 +433,14 @@ xed_file_browser_widget_class_init (XedFileBrowserWidgetClass * klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - signals[URI_ACTIVATED] = - g_signal_new ("uri-activated", + signals[LOCATION_ACTIVATED] = + g_signal_new ("location-activated", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (XedFileBrowserWidgetClass, - uri_activated), NULL, NULL, - g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, - G_TYPE_STRING); + location_activated), NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, + G_TYPE_FILE); signals[ERROR] = g_signal_new ("error", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, @@ -479,6 +478,12 @@ xed_file_browser_widget_class_init (XedFileBrowserWidgetClass * klass) sizeof (XedFileBrowserWidgetPrivate)); } +static void +xed_file_browser_widget_class_finalize (XedFileBrowserWidgetClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE */ +} + static void add_signal (XedFileBrowserWidget * obj, gpointer object, gulong id) { @@ -795,18 +800,15 @@ static GtkActionEntry toplevel_actions[] = static const GtkActionEntry tree_actions_selection[] = { {"FileMoveToTrash", "user-trash", N_("_Move to Trash"), NULL, - N_("Move selected file or folder to trash"), - G_CALLBACK (on_action_file_move_to_trash)}, + N_("Move selected file or folder to trash"), G_CALLBACK (on_action_file_move_to_trash)}, {"FileDelete", "edit-delete-symbolic", N_("_Delete"), NULL, - N_("Delete selected file or folder"), - G_CALLBACK (on_action_file_delete)} + N_("Delete selected file or folder"), G_CALLBACK (on_action_file_delete)} }; static const GtkActionEntry tree_actions_file_selection[] = { - {"FileOpen", "document-open-symbolic", N_("Open"), NULL, - N_("Open selected file"), - G_CALLBACK (on_action_file_open)} + {"FileOpen", "document-open-symbolic", N_("_Open"), NULL, + N_("Open selected file"), G_CALLBACK (on_action_file_open)} }; static const GtkActionEntry tree_actions[] = @@ -818,8 +820,7 @@ static const GtkActionEntry tree_actions[] = static const GtkActionEntry tree_actions_single_most_selection[] = { {"DirectoryNew", "folder-new-symbolic", N_("_New Folder"), NULL, - N_("Add new empty folder"), - G_CALLBACK (on_action_directory_new)}, + N_("Add new empty folder"), G_CALLBACK (on_action_directory_new)}, {"FileNew", "document-new-symbolic", N_("New F_ile"), NULL, N_("Add new empty file"), G_CALLBACK (on_action_file_new)} }; @@ -827,33 +828,27 @@ static const GtkActionEntry tree_actions_single_most_selection[] = static const GtkActionEntry tree_actions_single_selection[] = { {"FileRename", NULL, N_("_Rename"), NULL, - N_("Rename selected file or folder"), - G_CALLBACK (on_action_file_rename)} + N_("Rename selected file or folder"), G_CALLBACK (on_action_file_rename)} }; static const GtkActionEntry tree_actions_sensitive[] = { {"DirectoryPrevious", "go-previous-symbolic", N_("_Previous Location"), NULL, - N_("Go to the previous visited location"), - G_CALLBACK (on_action_directory_previous)}, + N_("Go to the previous visited location"), G_CALLBACK (on_action_directory_previous)}, {"DirectoryNext", "go-next-symbolic", N_("_Next Location"), NULL, N_("Go to the next visited location"), G_CALLBACK (on_action_directory_next)}, {"DirectoryRefresh", "view-refresh-symbolic", N_("Re_fresh View"), NULL, N_("Refresh the view"), G_CALLBACK (on_action_directory_refresh)}, {"DirectoryOpen", "folder-open-symbolic", N_("_View Folder"), NULL, - N_("View folder in file manager"), - G_CALLBACK (on_action_directory_open)} + N_("View folder in file manager"), G_CALLBACK (on_action_directory_open)} }; static const GtkToggleActionEntry tree_actions_toggle[] = { - {"FilterHidden", GTK_STOCK_DIALOG_AUTHENTICATION, - N_("Show _Hidden"), NULL, - N_("Show hidden files and folders"), - G_CALLBACK (on_action_filter_hidden), FALSE}, + {"FilterHidden", GTK_STOCK_DIALOG_AUTHENTICATION, N_("Show _Hidden"), NULL, + N_("Show hidden files and folders"), G_CALLBACK (on_action_filter_hidden), FALSE}, {"FilterBinary", NULL, N_("Show _Binary"), NULL, - N_("Show binary files"), G_CALLBACK (on_action_filter_binary), - FALSE} + N_("Show binary files"), G_CALLBACK (on_action_filter_binary), FALSE} }; static const GtkActionEntry bookmark_actions[] = @@ -1065,22 +1060,18 @@ add_bookmark_hash (XedFileBrowserWidget * obj, GtkTreeModel *model; GdkPixbuf * pixbuf; gchar * name; - gchar * uri; - GFile * file; + GFile * location; NameIcon * item; model = GTK_TREE_MODEL (obj->priv->bookmarks_store); - uri = xed_file_bookmarks_store_get_uri (obj->priv-> + location = xed_file_bookmarks_store_get_location (obj->priv-> bookmarks_store, iter); - if (uri == NULL) + if (location == NULL) return; - file = g_file_new_for_uri (uri); - g_free (uri); - gtk_tree_model_get (model, iter, XED_FILE_BOOKMARKS_STORE_COLUMN_ICON, &pixbuf, @@ -1092,7 +1083,7 @@ add_bookmark_hash (XedFileBrowserWidget * obj, item->icon = pixbuf; g_hash_table_insert (obj->priv->bookmarks_hash, - file, + location, item); } @@ -1586,8 +1577,6 @@ jump_to_location (XedFileBrowserWidget * obj, GList * item, GList *(*iter_func) (GList *); GtkWidget *menu_from; GtkWidget *menu_to; - gchar *root; - gchar *virtual_root; if (!obj->priv->locations) return; @@ -1648,15 +1637,9 @@ jump_to_location (XedFileBrowserWidget * obj, GList * item, loc = (Location *) (obj->priv->current_location->data); /* Set the new root + virtual root */ - root = g_file_get_uri (loc->root); - virtual_root = g_file_get_uri (loc->virtual_root); - xed_file_browser_widget_set_root_and_virtual_root (obj, - root, - virtual_root); - - g_free (root); - g_free (virtual_root); + loc->root, + loc->virtual_root); obj->priv->changing_location = FALSE; } @@ -1845,8 +1828,8 @@ xed_file_browser_widget_show_files (XedFileBrowserWidget * obj) void xed_file_browser_widget_set_root_and_virtual_root (XedFileBrowserWidget *obj, - gchar const *root, - gchar const *virtual_root) + GFile *root, + GFile *virtual_root) { XedFileBrowserStoreResult result; @@ -1865,12 +1848,10 @@ xed_file_browser_widget_set_root_and_virtual_root (XedFileBrowserWidget *obj, void xed_file_browser_widget_set_root (XedFileBrowserWidget * obj, - gchar const *root, + GFile *root, gboolean virtual_root) { - GFile *file; GFile *parent; - gchar *str; if (!virtual_root) { xed_file_browser_widget_set_root_and_virtual_root (obj, @@ -1882,16 +1863,11 @@ xed_file_browser_widget_set_root (XedFileBrowserWidget * obj, if (!root) return; - file = g_file_new_for_uri (root); - parent = get_topmost_file (file); - str = g_file_get_uri (parent); + parent = get_topmost_file (root); xed_file_browser_widget_set_root_and_virtual_root - (obj, str, root); + (obj, parent, root); - g_free (str); - - g_object_unref (file); g_object_unref (parent); } @@ -2118,7 +2094,6 @@ activate_mount (XedFileBrowserWidget *widget, GMount *mount) { GFile *root; - gchar *uri; if (!mount) { @@ -2140,11 +2115,9 @@ activate_mount (XedFileBrowserWidget *widget, } root = g_mount_get_root (mount); - uri = g_file_get_uri (root); - xed_file_browser_widget_set_root (widget, uri, FALSE); + xed_file_browser_widget_set_root (widget, root, FALSE); - g_free (uri); g_object_unref (root); } @@ -2375,7 +2348,7 @@ bookmark_open (XedFileBrowserWidget *obj, GtkTreeModel *model, GtkTreeIter *iter) { - gchar *uri; + GFile *location; gint flags; gtk_tree_model_get (model, iter, @@ -2397,11 +2370,11 @@ bookmark_open (XedFileBrowserWidget *obj, return; } - uri = - xed_file_bookmarks_store_get_uri + location = + xed_file_bookmarks_store_get_location (XED_FILE_BOOKMARKS_STORE (model), iter); - if (uri) { + if (location) { /* here we check if the bookmark is a mount point, or if it is a remote bookmark. If that's the case, we will set the root to the uri of the bookmark and not try to set the @@ -2410,18 +2383,18 @@ bookmark_open (XedFileBrowserWidget *obj, if ((flags & XED_FILE_BOOKMARKS_STORE_IS_MOUNT) || (flags & XED_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK)) { xed_file_browser_widget_set_root (obj, - uri, + location, FALSE); } else { xed_file_browser_widget_set_root (obj, - uri, + location, TRUE); } + + g_object_unref (location); } else { g_warning ("No uri!"); } - - g_free (uri); } static void @@ -2429,19 +2402,17 @@ file_open (XedFileBrowserWidget *obj, GtkTreeModel *model, GtkTreeIter *iter) { - gchar *uri; + GFile *location; gint flags; gtk_tree_model_get (model, iter, XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, - XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, + XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1); if (!FILE_IS_DIR (flags) && !FILE_IS_DUMMY (flags)) { - g_signal_emit (obj, signals[URI_ACTIVATED], 0, uri); + g_signal_emit (obj, signals[LOCATION_ACTIVATED], 0, location); } - - g_free (uri); } static gboolean @@ -2451,17 +2422,20 @@ directory_open (XedFileBrowserWidget *obj, { gboolean result = FALSE; GError *error = NULL; - gchar *uri = NULL; + GFile *location; XedFileBrowserStoreFlag flags; gtk_tree_model_get (model, iter, XED_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags, - XED_FILE_BROWSER_STORE_COLUMN_URI, &uri, + XED_FILE_BROWSER_STORE_COLUMN_LOCATION, &location, -1); - if (FILE_IS_DIR (flags)) { + if (FILE_IS_DIR (flags) && location) { + gchar *uri; result = TRUE; + uri = g_file_get_uri (location); + if (!gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (obj)), uri, GDK_CURRENT_TIME, &error)) { g_signal_emit (obj, signals[ERROR], 0, XED_FILE_BROWSER_ERROR_OPEN_DIRECTORY, @@ -2470,9 +2444,9 @@ directory_open (XedFileBrowserWidget *obj, g_error_free (error); error = NULL; } - } - g_free (uri); + g_free (uri); + } return result; } @@ -2519,8 +2493,7 @@ on_virtual_root_changed (XedFileBrowserStore * model, XedFileBrowserWidget * obj) { GtkTreeIter iter; - gchar *uri; - gchar *root_uri; + GFile *location; GtkTreeIter root; GtkAction *action; Location *loc; @@ -2534,8 +2507,8 @@ on_virtual_root_changed (XedFileBrowserStore * model, if (xed_file_browser_store_get_iter_virtual_root (model, &iter)) { gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, - XED_FILE_BROWSER_STORE_COLUMN_URI, - &uri, -1); + XED_FILE_BROWSER_STORE_COLUMN_LOCATION, + &location, -1); if (xed_file_browser_store_get_iter_root (model, &root)) { if (!obj->priv->changing_location) { @@ -2543,14 +2516,9 @@ on_virtual_root_changed (XedFileBrowserStore * model, if (obj->priv->current_location) clear_next_locations (obj); - root_uri = - xed_file_browser_store_get_root - (model); - loc = g_new (Location, 1); - loc->root = g_file_new_for_uri (root_uri); - loc->virtual_root = g_file_new_for_uri (uri); - g_free (root_uri); + loc->root = xed_file_browser_store_get_root (model); + loc->virtual_root = g_object_ref (location); if (obj->priv->current_location) { /* Add current location to the menu so we can go back @@ -2619,7 +2587,6 @@ on_virtual_root_changed (XedFileBrowserStore * model, } check_current_item (obj, TRUE); - g_free (uri); } else { g_message ("NO!"); } @@ -2699,7 +2666,6 @@ on_combo_changed (GtkComboBox * combo, XedFileBrowserWidget * obj) { GtkTreeIter iter; guint id; - gchar * uri; GFile * file; if (!gtk_combo_box_get_active_iter (combo, &iter)) @@ -2718,11 +2684,8 @@ on_combo_changed (GtkComboBox * combo, XedFileBrowserWidget * obj) (obj->priv->combo_model), &iter, COLUMN_FILE, &file, -1); - uri = g_file_get_uri (file); - xed_file_browser_store_set_virtual_root_from_string - (obj->priv->file_store, uri); + xed_file_browser_store_set_virtual_root_from_location (obj->priv->file_store, file); - g_free (uri); g_object_unref (file); break; } @@ -2907,22 +2870,19 @@ on_bookmarks_row_deleted (GtkTreeModel * model, XedFileBrowserWidget *obj) { GtkTreeIter iter; - gchar * uri; - GFile * file; + GFile *location; if (!gtk_tree_model_get_iter (model, &iter, path)) return; - uri = xed_file_bookmarks_store_get_uri (obj->priv->bookmarks_store, &iter); + location = xed_file_bookmarks_store_get_location (obj->priv->bookmarks_store, &iter); - if (!uri) + if (!location) return; - file = g_file_new_for_uri (uri); - g_hash_table_remove (obj->priv->bookmarks_hash, file); + g_hash_table_remove (obj->priv->bookmarks_hash, location); - g_object_unref (file); - g_free (uri); + g_object_unref (location); } static void @@ -3146,4 +3106,10 @@ on_action_bookmark_open (GtkAction * action, XedFileBrowserWidget * obj) bookmark_open (obj, model, &iter); } +void +_xed_file_browser_widget_register_type (GTypeModule *type_module) +{ + xed_file_browser_widget_register_type (type_module); +} + // ex:ts=8:noet: diff --git a/plugins/filebrowser/xed-file-browser-widget.h b/plugins/filebrowser/xed-file-browser-widget.h index 486fbe4..73ae4ea 100644 --- a/plugins/filebrowser/xed-file-browser-widget.h +++ b/plugins/filebrowser/xed-file-browser-widget.h @@ -1,5 +1,5 @@ /* - * xed-file-browser-widget.h - Xed plugin providing easy file access + * xed-file-browser-widget.h - Xed plugin providing easy file access * from the sidepanel * * Copyright (C) 2006 - Jesse van den Kieboom @@ -28,13 +28,13 @@ #include "xed-file-browser-view.h" G_BEGIN_DECLS -#define XED_TYPE_FILE_BROWSER_WIDGET (xed_file_browser_widget_get_type ()) -#define XED_FILE_BROWSER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_WIDGET, XedFileBrowserWidget)) -#define XED_FILE_BROWSER_WIDGET_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_WIDGET, XedFileBrowserWidget const)) -#define XED_FILE_BROWSER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BROWSER_WIDGET, XedFileBrowserWidgetClass)) -#define XED_IS_FILE_BROWSER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BROWSER_WIDGET)) -#define XED_IS_FILE_BROWSER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BROWSER_WIDGET)) -#define XED_FILE_BROWSER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BROWSER_WIDGET, XedFileBrowserWidgetClass)) +#define XED_TYPE_FILE_BROWSER_WIDGET (xed_file_browser_widget_get_type ()) +#define XED_FILE_BROWSER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_WIDGET, XedFileBrowserWidget)) +#define XED_FILE_BROWSER_WIDGET_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_FILE_BROWSER_WIDGET, XedFileBrowserWidget const)) +#define XED_FILE_BROWSER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_FILE_BROWSER_WIDGET, XedFileBrowserWidgetClass)) +#define XED_IS_FILE_BROWSER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_FILE_BROWSER_WIDGET)) +#define XED_IS_FILE_BROWSER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_BROWSER_WIDGET)) +#define XED_FILE_BROWSER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_BROWSER_WIDGET, XedFileBrowserWidgetClass)) typedef struct _XedFileBrowserWidget XedFileBrowserWidget; typedef struct _XedFileBrowserWidgetClass XedFileBrowserWidgetClass; @@ -42,36 +42,36 @@ typedef struct _XedFileBrowserWidgetPrivate XedFileBrowserWidgetPrivate; typedef gboolean (*XedFileBrowserWidgetFilterFunc) (XedFileBrowserWidget * obj, - XedFileBrowserStore * - model, GtkTreeIter * iter, - gpointer user_data); + XedFileBrowserStore * + model, GtkTreeIter * iter, + gpointer user_data); -struct _XedFileBrowserWidget +struct _XedFileBrowserWidget { - GtkBox parent; + GtkBox parent; - XedFileBrowserWidgetPrivate *priv; + XedFileBrowserWidgetPrivate *priv; }; -struct _XedFileBrowserWidgetClass +struct _XedFileBrowserWidgetClass { - GtkBoxClass parent_class; + GtkBoxClass parent_class; - /* Signals */ - void (*uri_activated) (XedFileBrowserWidget * widget, - gchar const *uri); - void (*error) (XedFileBrowserWidget * widget, - guint code, - gchar const *message); - gboolean (*confirm_delete) (XedFileBrowserWidget * widget, - XedFileBrowserStore * model, - GList *list); - gboolean (*confirm_no_trash) (XedFileBrowserWidget * widget, - GList *list); + /* Signals */ + void (*location_activated) (XedFileBrowserWidget * widget, + GFile *location); + void (*error) (XedFileBrowserWidget * widget, + guint code, + gchar const *message); + gboolean (*confirm_delete) (XedFileBrowserWidget * widget, + XedFileBrowserStore * model, + GList *list); + gboolean (*confirm_no_trash) (XedFileBrowserWidget * widget, + GList *list); }; GType xed_file_browser_widget_get_type (void) G_GNUC_CONST; -GType xed_file_browser_widget_register_type (GTypeModule * module); +void _xed_file_browser_widget_register_type (GTypeModule *type_module); GtkWidget *xed_file_browser_widget_new (const gchar *data_dir); @@ -79,31 +79,31 @@ void xed_file_browser_widget_show_bookmarks (XedFileBrowserWidget * obj); void xed_file_browser_widget_show_files (XedFileBrowserWidget * obj); void xed_file_browser_widget_set_root (XedFileBrowserWidget * obj, - gchar const *root, + GFile *root, gboolean virtual_root); void xed_file_browser_widget_set_root_and_virtual_root (XedFileBrowserWidget * obj, - gchar const *root, - gchar const *virtual_root); + GFile *root, + GFile *virtual_root); gboolean -xed_file_browser_widget_get_selected_directory (XedFileBrowserWidget * obj, +xed_file_browser_widget_get_selected_directory (XedFileBrowserWidget * obj, GtkTreeIter * iter); -XedFileBrowserStore * +XedFileBrowserStore * xed_file_browser_widget_get_browser_store (XedFileBrowserWidget * obj); -XedFileBookmarksStore * +XedFileBookmarksStore * xed_file_browser_widget_get_bookmarks_store (XedFileBrowserWidget * obj); XedFileBrowserView * xed_file_browser_widget_get_browser_view (XedFileBrowserWidget * obj); GtkWidget * xed_file_browser_widget_get_filter_entry (XedFileBrowserWidget * obj); -GtkUIManager * +GtkUIManager * xed_file_browser_widget_get_ui_manager (XedFileBrowserWidget * obj); gulong xed_file_browser_widget_add_filter (XedFileBrowserWidget * obj, - XedFileBrowserWidgetFilterFunc func, + XedFileBrowserWidgetFilterFunc func, gpointer user_data, GDestroyNotify notify); void xed_file_browser_widget_remove_filter (XedFileBrowserWidget * obj, @@ -111,9 +111,9 @@ void xed_file_browser_widget_remove_filter (XedFileBrowserWidget * obj, void xed_file_browser_widget_set_filter_pattern (XedFileBrowserWidget * obj, gchar const *pattern); -void xed_file_browser_widget_refresh (XedFileBrowserWidget * obj); -void xed_file_browser_widget_history_back (XedFileBrowserWidget * obj); -void xed_file_browser_widget_history_forward (XedFileBrowserWidget * obj); +void xed_file_browser_widget_refresh (XedFileBrowserWidget * obj); +void xed_file_browser_widget_history_back (XedFileBrowserWidget * obj); +void xed_file_browser_widget_history_forward (XedFileBrowserWidget * obj); G_END_DECLS #endif /* __XED_FILE_BROWSER_WIDGET_H__ */ diff --git a/plugins/modelines/Makefile.am b/plugins/modelines/Makefile.am index 6485fe1..e3cdc0b 100644 --- a/plugins/modelines/Makefile.am +++ b/plugins/modelines/Makefile.am @@ -22,10 +22,10 @@ libmodelines_la_SOURCES = \ libmodelines_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) libmodelines_la_LIBADD = $(XED_LIBS) -plugin_in_files = modelines.xed-plugin.desktop.in -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache +plugin_in_files = modelines.plugin.desktop.in +%.plugin: %.plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) +plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin) EXTRA_DIST = \ $(plugin_in_files) \ diff --git a/plugins/modelines/modeline-parser.c b/plugins/modelines/modeline-parser.c index f0962ef..3b9133e 100644 --- a/plugins/modelines/modeline-parser.c +++ b/plugins/modelines/modeline-parser.c @@ -24,9 +24,9 @@ #include #include #include -#include -#include #include +#include +#include #include "modeline-parser.h" #define MODELINES_LANGUAGE_MAPPINGS_FILE "language-mappings" @@ -64,7 +64,7 @@ typedef struct _ModelineOptions GtkWrapMode wrap_mode; gboolean display_right_margin; guint right_margin_position; - + ModelineSet set; } ModelineOptions; @@ -80,7 +80,10 @@ has_option (ModelineOptions *options, void modeline_parser_init (const gchar *data_dir) { - modelines_data_dir = g_strdup (data_dir); + if (modelines_data_dir == NULL) + { + modelines_data_dir = g_strdup (data_dir); + } } void @@ -94,12 +97,13 @@ modeline_parser_shutdown () if (kate_languages != NULL) g_hash_table_destroy (kate_languages); - + vim_languages = NULL; emacs_languages = NULL; kate_languages = NULL; g_free (modelines_data_dir); + modelines_data_dir = NULL; } static GHashTable * @@ -224,7 +228,7 @@ skip_whitespaces (gchar **s) } /* Parse vi(m) modelines. - * Vi(m) modelines looks like this: + * Vi(m) modelines looks like this: * - first form: [text]{white}{vi:|vim:|ex:}[white]{options} * - second form: [text]{white}{vi:|vim:|ex:}[white]se[t] {options}:[text] * They can happen on the three first or last lines. @@ -289,7 +293,7 @@ parse_vim_modeline (gchar *s, { g_free (options->language_id); options->language_id = get_language_id_vim (value->str); - + options->set |= MODELINE_SET_LANGUAGE; } else if (strcmp (key->str, "et") == 0 || @@ -302,7 +306,7 @@ parse_vim_modeline (gchar *s, strcmp (key->str, "tabstop") == 0) { intval = atoi (value->str); - + if (intval) { options->tab_width = intval; @@ -313,7 +317,7 @@ parse_vim_modeline (gchar *s, strcmp (key->str, "shiftwidth") == 0) { intval = atoi (value->str); - + if (intval) { options->indent_width = intval; @@ -326,18 +330,18 @@ parse_vim_modeline (gchar *s, options->set |= MODELINE_SET_WRAP_MODE; } - else if (strcmp (key->str, "textwidth") == 0) + else if (strcmp (key->str, "textwidth") == 0 || strcmp (key->str, "tw") == 0) { intval = atoi (value->str); - + if (intval) { options->right_margin_position = intval; options->display_right_margin = TRUE; - + options->set |= MODELINE_SET_SHOW_RIGHT_MARGIN | MODELINE_SET_RIGHT_MARGIN_POSITION; - + } } } @@ -406,13 +410,13 @@ parse_emacs_modeline (gchar *s, { g_free (options->language_id); options->language_id = get_language_id_emacs (value->str); - + options->set |= MODELINE_SET_LANGUAGE; } else if (strcmp (key->str, "tab-width") == 0) { intval = atoi (value->str); - + if (intval) { options->tab_width = intval; @@ -422,7 +426,7 @@ parse_emacs_modeline (gchar *s, else if (strcmp (key->str, "indent-offset") == 0) { intval = atoi (value->str); - + if (intval) { options->indent_width = intval; @@ -433,14 +437,14 @@ parse_emacs_modeline (gchar *s, { intval = strcmp (value->str, "nil") == 0; options->insert_spaces = intval; - + options->set |= MODELINE_SET_INSERT_SPACES; } else if (strcmp (key->str, "autowrap") == 0) { intval = strcmp (value->str, "nil") != 0; options->wrap_mode = intval ? GTK_WRAP_WORD : GTK_WRAP_NONE; - + options->set |= MODELINE_SET_WRAP_MODE; } } @@ -504,13 +508,13 @@ parse_kate_modeline (gchar *s, { g_free (options->language_id); options->language_id = get_language_id_kate (value->str); - + options->set |= MODELINE_SET_LANGUAGE; } else if (strcmp (key->str, "tab-width") == 0) { intval = atoi (value->str); - + if (intval) { options->tab_width = intval; @@ -539,17 +543,17 @@ parse_kate_modeline (gchar *s, options->wrap_mode = intval ? GTK_WRAP_WORD : GTK_WRAP_NONE; - options->set |= MODELINE_SET_WRAP_MODE; + options->set |= MODELINE_SET_WRAP_MODE; } else if (strcmp (key->str, "word-wrap-column") == 0) { intval = atoi (value->str); - + if (intval) { options->right_margin_position = intval; options->display_right_margin = TRUE; - + options->set |= MODELINE_SET_RIGHT_MARGIN_POSITION | MODELINE_SET_SHOW_RIGHT_MARGIN; } @@ -611,7 +615,7 @@ check_previous (GtkSourceView *view, ModelineSet set) { GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - + /* Do not restore default when this is the first time */ if (!previous) return FALSE; @@ -648,7 +652,7 @@ check_previous (GtkSourceView *view, case MODELINE_SET_LANGUAGE: { GtkSourceLanguage *language = gtk_source_buffer_get_language (buffer); - + return (language == NULL && previous->language_id == NULL) || (language != NULL && g_strcmp0 (gtk_source_language_get_id (language), previous->language_id) == 0); @@ -674,7 +678,8 @@ modeline_parser_apply_modeline (GtkSourceView *view) GtkTextBuffer *buffer; GtkTextIter iter, liter; gint line_count; - + GSettings *settings; + options.language_id = NULL; options.set = MODELINE_SET_NONE; @@ -746,7 +751,7 @@ modeline_parser_apply_modeline (GtkSourceView *view) GtkSourceLanguageManager *manager; GtkSourceLanguage *language; - manager = xed_get_language_manager (); + manager = gtk_source_language_manager_get_default (); language = gtk_source_language_manager_get_language (manager, options.language_id); @@ -757,9 +762,11 @@ modeline_parser_apply_modeline (GtkSourceView *view) } } - ModelineOptions *previous = g_object_get_data (G_OBJECT (buffer), + ModelineOptions *previous = g_object_get_data (G_OBJECT (buffer), MODELINE_OPTIONS_DATA_KEY); + settings = g_settings_new ("org.x.editor.preferences.editor"); + /* Apply the options we got from modelines and restore defaults if we set them before */ if (has_option (&options, MODELINE_SET_INSERT_SPACES)) @@ -769,21 +776,24 @@ modeline_parser_apply_modeline (GtkSourceView *view) } else if (check_previous (view, previous, MODELINE_SET_INSERT_SPACES)) { - gtk_source_view_set_insert_spaces_instead_of_tabs - (view, - xed_prefs_manager_get_insert_spaces ()); + gboolean insert_spaces; + + insert_spaces = g_settings_get_boolean (settings, XED_SETTINGS_INSERT_SPACES); + gtk_source_view_set_insert_spaces_instead_of_tabs (view, insert_spaces); } - + if (has_option (&options, MODELINE_SET_TAB_WIDTH)) { gtk_source_view_set_tab_width (view, options.tab_width); } else if (check_previous (view, previous, MODELINE_SET_TAB_WIDTH)) { - gtk_source_view_set_tab_width (view, - xed_prefs_manager_get_tabs_size ()); + guint tab_width; + + tab_width = g_settings_get_uint (settings, XED_SETTINGS_TABS_SIZE); + gtk_source_view_set_tab_width (view, tab_width); } - + if (has_option (&options, MODELINE_SET_INDENT_WIDTH)) { gtk_source_view_set_indent_width (view, options.indent_width); @@ -792,39 +802,46 @@ modeline_parser_apply_modeline (GtkSourceView *view) { gtk_source_view_set_indent_width (view, -1); } - + if (has_option (&options, MODELINE_SET_WRAP_MODE)) { gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), options.wrap_mode); } else if (check_previous (view, previous, MODELINE_SET_WRAP_MODE)) { - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), - xed_prefs_manager_get_wrap_mode ()); + GtkWrapMode mode; + + mode = g_settings_get_enum (settings, XED_SETTINGS_WRAP_MODE); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), mode); } - + if (has_option (&options, MODELINE_SET_RIGHT_MARGIN_POSITION)) { gtk_source_view_set_right_margin_position (view, options.right_margin_position); } else if (check_previous (view, previous, MODELINE_SET_RIGHT_MARGIN_POSITION)) { - gtk_source_view_set_right_margin_position (view, - xed_prefs_manager_get_right_margin_position ()); + guint right_margin_pos; + + right_margin_pos = g_settings_get_uint (settings, XED_SETTINGS_RIGHT_MARGIN_POSITION); + gtk_source_view_set_right_margin_position (view, right_margin_pos); } - + if (has_option (&options, MODELINE_SET_SHOW_RIGHT_MARGIN)) { gtk_source_view_set_show_right_margin (view, options.display_right_margin); } else if (check_previous (view, previous, MODELINE_SET_SHOW_RIGHT_MARGIN)) { - gtk_source_view_set_show_right_margin (view, - xed_prefs_manager_get_display_right_margin ()); + gboolean display_right_margin; + + display_right_margin = g_settings_get_boolean (settings, XED_SETTINGS_DISPLAY_RIGHT_MARGIN); + gtk_source_view_set_show_right_margin (view, display_right_margin); } - + if (previous) { + g_free (previous->language_id); *previous = options; previous->language_id = g_strdup (options.language_id); } @@ -833,13 +850,13 @@ modeline_parser_apply_modeline (GtkSourceView *view) previous = g_slice_new (ModelineOptions); *previous = options; previous->language_id = g_strdup (options.language_id); - - g_object_set_data_full (G_OBJECT (buffer), - MODELINE_OPTIONS_DATA_KEY, + + g_object_set_data_full (G_OBJECT (buffer), + MODELINE_OPTIONS_DATA_KEY, previous, (GDestroyNotify)free_modeline_options); } - + g_free (options.language_id); } diff --git a/plugins/modelines/modeline-parser.h b/plugins/modelines/modeline-parser.h index 5c97b00..470d7ef 100644 --- a/plugins/modelines/modeline-parser.h +++ b/plugins/modelines/modeline-parser.h @@ -1,14 +1,14 @@ /* * modelie-parser.h * Emacs, Kate and Vim-style modelines support for xed. - * + * * Copyright (C) 2005-2007 - Steve Frécinaux * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -23,14 +23,14 @@ #define __MODELINE_PARSER_H__ #include -#include +#include G_BEGIN_DECLS -void modeline_parser_init (const gchar *data_dir); -void modeline_parser_shutdown (void); -void modeline_parser_apply_modeline (GtkSourceView *view); -void modeline_parser_deactivate (GtkSourceView *view); +void modeline_parser_init (const gchar *data_dir); +void modeline_parser_shutdown (void); +void modeline_parser_apply_modeline (GtkSourceView *view); +void modeline_parser_deactivate (GtkSourceView *view); G_END_DECLS diff --git a/plugins/modelines/modelines.xed-plugin.desktop.in b/plugins/modelines/modelines.plugin.desktop.in similarity index 94% rename from plugins/modelines/modelines.xed-plugin.desktop.in rename to plugins/modelines/modelines.plugin.desktop.in index 70f7521..cfd5b42 100644 --- a/plugins/modelines/modelines.xed-plugin.desktop.in +++ b/plugins/modelines/modelines.plugin.desktop.in @@ -1,4 +1,4 @@ -[Xed Plugin] +[Plugin] Module=modelines IAge=2 _Name=Modelines diff --git a/plugins/modelines/xed-modeline-plugin.c b/plugins/modelines/xed-modeline-plugin.c index b8921bb..b75ab3f 100644 --- a/plugins/modelines/xed-modeline-plugin.c +++ b/plugins/modelines/xed-modeline-plugin.c @@ -1,14 +1,14 @@ /* * xed-modeline-plugin.c * Emacs, Kate and Vim-style modelines support for xed. - * + * * Copyright (C) 2005-2007 - Steve Frécinaux * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -18,9 +18,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ - + #ifdef HAVE_CONFIG_H -# include +# include #endif #include @@ -29,220 +29,196 @@ #include "modeline-parser.h" #include -#include +#include +#include -#define WINDOW_DATA_KEY "XedModelinePluginWindowData" -#define DOCUMENT_DATA_KEY "XedModelinePluginDocumentData" - -typedef struct +struct _XedModelinePluginPrivate { - gulong tab_added_handler_id; - gulong tab_removed_handler_id; -} WindowData; + XedView *view; -typedef struct + gulong document_loaded_handler_id; + gulong document_saved_handler_id; +}; + +enum { - gulong document_loaded_handler_id; - gulong document_saved_handler_id; -} DocumentData; + PROP_0, + PROP_VIEW +}; -static void xed_modeline_plugin_activate (XedPlugin *plugin, XedWindow *window); -static void xed_modeline_plugin_deactivate (XedPlugin *plugin, XedWindow *window); -static GObject *xed_modeline_plugin_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_param); -static void xed_modeline_plugin_finalize (GObject *object); +static void xed_view_activatable_iface_init (XedViewActivatableInterface *iface); -XED_PLUGIN_REGISTER_TYPE(XedModelinePlugin, xed_modeline_plugin) +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedModelinePlugin, + xed_modeline_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_VIEW_ACTIVATABLE, + xed_view_activatable_iface_init)) static void -window_data_free (WindowData *wdata) +xed_modeline_plugin_constructed (GObject *object) { - g_slice_free (WindowData, wdata); -} + gchar *data_dir; -static void -document_data_free (DocumentData *ddata) -{ - g_slice_free (DocumentData, ddata); -} + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (object)); -static void -xed_modeline_plugin_class_init (XedModelinePluginClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); + modeline_parser_init (data_dir); - object_class->constructor = xed_modeline_plugin_constructor; - object_class->finalize = xed_modeline_plugin_finalize; + g_free (data_dir); - plugin_class->activate = xed_modeline_plugin_activate; - plugin_class->deactivate = xed_modeline_plugin_deactivate; -} - -static GObject * -xed_modeline_plugin_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_param) -{ - GObject *object; - gchar *data_dir; - - object = G_OBJECT_CLASS (xed_modeline_plugin_parent_class)->constructor (type, - n_construct_properties, - construct_param); - - data_dir = xed_plugin_get_data_dir (XED_PLUGIN (object)); - - modeline_parser_init (data_dir); - - g_free (data_dir); - - return object; + G_OBJECT_CLASS (xed_modeline_plugin_parent_class)->constructed (object); } static void xed_modeline_plugin_init (XedModelinePlugin *plugin) { - xed_debug_message (DEBUG_PLUGINS, "XedModelinePlugin initializing"); + xed_debug_message (DEBUG_PLUGINS, "XedModelinePlugin initializing"); + + plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin, + XED_TYPE_MODELINE_PLUGIN, + XedModelinePluginPrivate); +} + +static void +xed_modeline_plugin_dispose (GObject *object) +{ + XedModelinePlugin *plugin = XED_MODELINE_PLUGIN (object); + + xed_debug_message (DEBUG_PLUGINS, "XedModelinePlugin disposing"); + + g_clear_object (&plugin->priv->view); + + G_OBJECT_CLASS (xed_modeline_plugin_parent_class)->dispose (object); } static void xed_modeline_plugin_finalize (GObject *object) { - xed_debug_message (DEBUG_PLUGINS, "XedModelinePlugin finalizing"); + xed_debug_message (DEBUG_PLUGINS, "XedModelinePlugin finalizing"); - modeline_parser_shutdown (); + modeline_parser_shutdown (); - G_OBJECT_CLASS (xed_modeline_plugin_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_modeline_plugin_parent_class)->finalize (object); } static void -on_document_loaded_or_saved (XedDocument *document, - const GError *error, - GtkSourceView *view) +xed_modeline_plugin_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - modeline_parser_apply_modeline (view); + XedModelinePlugin *plugin = XED_MODELINE_PLUGIN (object); + + switch (prop_id) + { + case PROP_VIEW: + plugin->priv->view = XED_VIEW (g_value_dup_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -connect_handlers (XedView *view) +xed_modeline_plugin_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - DocumentData *data; - GtkTextBuffer *doc; + XedModelinePlugin *plugin = XED_MODELINE_PLUGIN (object); - doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); - - data = g_slice_new (DocumentData); - - data->document_loaded_handler_id = - g_signal_connect (doc, "loaded", - G_CALLBACK (on_document_loaded_or_saved), - view); - data->document_saved_handler_id = - g_signal_connect (doc, "saved", - G_CALLBACK (on_document_loaded_or_saved), - view); - - g_object_set_data_full (G_OBJECT (doc), DOCUMENT_DATA_KEY, - data, (GDestroyNotify) document_data_free); + switch (prop_id) + { + case PROP_VIEW: + g_value_set_object (value, plugin->priv->view); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -disconnect_handlers (XedView *view) +on_document_loaded_or_saved (XedDocument *document, + GtkSourceView *view) { - DocumentData *data; - GtkTextBuffer *doc; - - doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); - - data = g_object_steal_data (G_OBJECT (doc), DOCUMENT_DATA_KEY); - - if (data) - { - g_signal_handler_disconnect (doc, data->document_loaded_handler_id); - g_signal_handler_disconnect (doc, data->document_saved_handler_id); - - document_data_free (data); - } - else - { - g_warning ("Modeline handlers not found"); - } + modeline_parser_apply_modeline (view); } static void -on_window_tab_added (XedWindow *window, - XedTab *tab, - gpointer user_data) +xed_modeline_plugin_activate (XedViewActivatable *activatable) { - connect_handlers (xed_tab_get_view (tab)); + XedModelinePlugin *plugin; + GtkTextBuffer *doc; + + xed_debug (DEBUG_PLUGINS); + + plugin = XED_MODELINE_PLUGIN (activatable); + + modeline_parser_apply_modeline (GTK_SOURCE_VIEW (plugin->priv->view)); + + doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plugin->priv->view)); + + plugin->priv->document_loaded_handler_id = + g_signal_connect (doc, "loaded", + G_CALLBACK (on_document_loaded_or_saved), plugin->priv->view); + plugin->priv->document_saved_handler_id = + g_signal_connect (doc, "saved", + G_CALLBACK (on_document_loaded_or_saved), plugin->priv->view); } static void -on_window_tab_removed (XedWindow *window, - XedTab *tab, - gpointer user_data) +xed_modeline_plugin_deactivate (XedViewActivatable *activatable) { - disconnect_handlers (xed_tab_get_view (tab)); + XedModelinePlugin *plugin; + GtkTextBuffer *doc; + + xed_debug (DEBUG_PLUGINS); + + plugin = XED_MODELINE_PLUGIN (activatable); + + doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plugin->priv->view)); + + g_signal_handler_disconnect (doc, plugin->priv->document_loaded_handler_id); + g_signal_handler_disconnect (doc, plugin->priv->document_saved_handler_id); } static void -xed_modeline_plugin_activate (XedPlugin *plugin, - XedWindow *window) +xed_modeline_plugin_class_init (XedModelinePluginClass *klass) { - WindowData *wdata; - GList *views; - GList *l; + GObjectClass *object_class = G_OBJECT_CLASS (klass); - xed_debug (DEBUG_PLUGINS); + object_class->constructed = xed_modeline_plugin_constructed; + object_class->dispose = xed_modeline_plugin_dispose; + object_class->finalize = xed_modeline_plugin_finalize; + object_class->set_property = xed_modeline_plugin_set_property; + object_class->get_property = xed_modeline_plugin_get_property; - views = xed_window_get_views (window); - for (l = views; l != NULL; l = l->next) - { - connect_handlers (XED_VIEW (l->data)); - modeline_parser_apply_modeline (GTK_SOURCE_VIEW (l->data)); - } - g_list_free (views); + g_object_class_override_property (object_class, PROP_VIEW, "view"); - wdata = g_slice_new (WindowData); - - wdata->tab_added_handler_id = - g_signal_connect (window, "tab-added", - G_CALLBACK (on_window_tab_added), NULL); - - wdata->tab_removed_handler_id = - g_signal_connect (window, "tab-removed", - G_CALLBACK (on_window_tab_removed), NULL); - - g_object_set_data_full (G_OBJECT (window), WINDOW_DATA_KEY, - wdata, (GDestroyNotify) window_data_free); + g_type_class_add_private (klass, sizeof (XedModelinePluginPrivate)); } static void -xed_modeline_plugin_deactivate (XedPlugin *plugin, - XedWindow *window) +xed_view_activatable_iface_init (XedViewActivatableInterface *iface) { - WindowData *wdata; - GList *views; - GList *l; - - xed_debug (DEBUG_PLUGINS); - - wdata = g_object_steal_data (G_OBJECT (window), WINDOW_DATA_KEY); - - g_signal_handler_disconnect (window, wdata->tab_added_handler_id); - g_signal_handler_disconnect (window, wdata->tab_removed_handler_id); - - window_data_free (wdata); - - views = xed_window_get_views (window); - - for (l = views; l != NULL; l = l->next) - { - disconnect_handlers (XED_VIEW (l->data)); - - modeline_parser_deactivate (GTK_SOURCE_VIEW (l->data)); - } - - g_list_free (views); + iface->activate = xed_modeline_plugin_activate; + iface->deactivate = xed_modeline_plugin_deactivate; } +static void +xed_modeline_plugin_class_finalize (XedModelinePluginClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE_EXTENDED */ +} + +G_MODULE_EXPORT void +peas_register_types (PeasObjectModule *module) +{ + xed_modeline_plugin_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + XED_TYPE_VIEW_ACTIVATABLE, + XED_TYPE_MODELINE_PLUGIN); +} diff --git a/plugins/modelines/xed-modeline-plugin.h b/plugins/modelines/xed-modeline-plugin.h index 726ce8a..8c16507 100644 --- a/plugins/modelines/xed-modeline-plugin.h +++ b/plugins/modelines/xed-modeline-plugin.h @@ -1,7 +1,7 @@ /* * xed-modeline-plugin.h * Emacs, Kate and Vim-style modelines support for xed. - * + * * Copyright (C) 2005-2007 - Steve Frécinaux * * This program is free software; you can redistribute it and/or modify @@ -24,24 +24,41 @@ #include #include -#include +#include +#include G_BEGIN_DECLS -#define XED_TYPE_MODELINE_PLUGIN (xed_modeline_plugin_get_type ()) -#define XED_MODELINE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_MODELINE_PLUGIN, XedModelinePlugin)) -#define XED_MODELINE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_MODELINE_PLUGIN, XedModelinePluginClass)) -#define XED_IS_MODELINE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_MODELINE_PLUGIN)) -#define XED_IS_MODELINE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_MODELINE_PLUGIN)) -#define XED_MODELINE_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_MODELINE_PLUGIN, XedModelinePluginClass)) +#define XED_TYPE_MODELINE_PLUGIN (xed_modeline_plugin_get_type ()) +#define XED_MODELINE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_MODELINE_PLUGIN, XedModelinePlugin)) +#define XED_MODELINE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_MODELINE_PLUGIN, XedModelinePluginClass)) +#define XED_IS_MODELINE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_MODELINE_PLUGIN)) +#define XED_IS_MODELINE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_MODELINE_PLUGIN)) +#define XED_MODELINE_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_MODELINE_PLUGIN, XedModelinePluginClass)) /* Private structure type */ -typedef XedPluginClass XedModelinePluginClass; -typedef XedPlugin XedModelinePlugin; +typedef struct _XedModelinePlugin XedModelinePlugin; +typedef struct _XedModelinePluginPrivate XedModelinePluginPrivate; +typedef struct _XedModelinePluginClass XedModelinePluginClass; -GType xed_modeline_plugin_get_type (void) G_GNUC_CONST; +struct _XedModelinePlugin +{ + PeasExtensionBase parent; -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule *module); + /*< private >*/ + XedModelinePluginPrivate *priv; +}; + +typedef struct _XedModelinePluginClass XedModelinePluginClass; + +struct _XedModelinePluginClass +{ + PeasExtensionBaseClass parent_class; +}; + +GType xed_modeline_plugin_get_type (void) G_GNUC_CONST; + +G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); G_END_DECLS diff --git a/plugins/sort/Makefile.am b/plugins/sort/Makefile.am index 1738e80..13e65f8 100644 --- a/plugins/sort/Makefile.am +++ b/plugins/sort/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir) \ $(XED_CFLAGS) \ $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) + $(DISABLE_DEPRECATED_CFLAGS) plugin_LTLIBRARIES = libsort.la @@ -19,11 +19,11 @@ libsort_la_LIBADD = $(XED_LIBS) uidir = $(XED_PLUGINS_DATA_DIR)/sort ui_DATA = sort.ui -plugin_in_files = sort.xed-plugin.desktop.in +plugin_in_files = sort.plugin.desktop.in -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache +%.plugin: %.plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) +plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin) EXTRA_DIST = $(ui_DATA) $(plugin_in_files) diff --git a/plugins/sort/sort.xed-plugin.desktop.in b/plugins/sort/sort.plugin.desktop.in similarity index 97% rename from plugins/sort/sort.xed-plugin.desktop.in rename to plugins/sort/sort.plugin.desktop.in index 8cc189c..4b56701 100644 --- a/plugins/sort/sort.xed-plugin.desktop.in +++ b/plugins/sort/sort.plugin.desktop.in @@ -1,4 +1,4 @@ -[Xed Plugin] +[Plugin] Module=sort IAge=2 _Name=Sort diff --git a/plugins/sort/xed-sort-plugin.c b/plugins/sort/xed-sort-plugin.c index b64bd98..80f33b0 100644 --- a/plugins/sort/xed-sort-plugin.c +++ b/plugins/sort/xed-sort-plugin.c @@ -28,561 +28,550 @@ #include "xed-sort-plugin.h" #include -#include -#include +#include +#include +#include #include #include -#include +#include #define XED_SORT_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_SORT_PLUGIN, XedSortPluginPrivate)) -/* Key in case the plugin ever needs any settings. */ -#define SORT_BASE_KEY "/apps/xed/plugins/sort" - -#define WINDOW_DATA_KEY "XedSortPluginWindowData" #define MENU_PATH "/MenuBar/EditMenu/EditOps_6" -XED_PLUGIN_REGISTER_TYPE(XedSortPlugin, xed_sort_plugin) +static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedSortPlugin, + xed_sort_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, + xed_window_activatable_iface_init)) + +struct _XedSortPluginPrivate +{ + XedWindow *window; + + GtkActionGroup *ui_action_group; + guint ui_id; + + GtkWidget *dialog; + GtkWidget *col_num_spinbutton; + GtkWidget *reverse_order_checkbutton; + GtkWidget *ignore_case_checkbutton; + GtkWidget *remove_dups_checkbutton; + + GtkTextIter start, end; /* selection */ +}; typedef struct { - GtkWidget *dialog; - GtkWidget *col_num_spinbutton; - GtkWidget *reverse_order_checkbutton; - GtkWidget *ignore_case_checkbutton; - GtkWidget *remove_dups_checkbutton; + gint starting_column; - XedDocument *doc; - - GtkTextIter start, end; /* selection */ -} SortDialog; - -typedef struct -{ - GtkActionGroup *ui_action_group; - guint ui_id; -} WindowData; - -typedef struct -{ - XedPlugin *plugin; - XedWindow *window; -} ActionData; - -typedef struct -{ - gboolean ignore_case; - gboolean reverse_order; - gboolean remove_duplicates; - gint starting_column; + guint ignore_case : 1; + guint reverse_order : 1; + guint remove_duplicates : 1; } SortInfo; -static void sort_cb (GtkAction *action, ActionData *action_data); -static void sort_real (SortDialog *dialog); +enum +{ + PROP_0, + PROP_WINDOW +}; + +static void sort_cb (GtkAction *action, + XedSortPlugin *plugin); +static void sort_real (XedSortPlugin *plugin); static const GtkActionEntry action_entries[] = { - { "Sort", - "view-sort-ascending-symbolic", - N_("S_ort..."), - NULL, - N_("Sort the current document or selection"), - G_CALLBACK (sort_cb) } + { "Sort", + "view-sort-ascending-symbolic", + N_("S_ort..."), + NULL, + N_("Sort the current document or selection"), + G_CALLBACK (sort_cb) + } }; static void -sort_dialog_dispose (GObject *obj, - gpointer dialog_pointer) +sort_dialog_response_handler (GtkDialog *dlg, + gint res_id, + XedSortPlugin *plugin) { - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_slice_free (SortDialog, dialog_pointer); -} + switch (res_id) + { + case GTK_RESPONSE_OK: + sort_real (plugin); + gtk_widget_destroy (GTK_WIDGET (dlg)); + break; -static void -sort_dialog_response_handler (GtkDialog *widget, - gint res_id, - SortDialog *dialog) -{ - xed_debug (DEBUG_PLUGINS); + case GTK_RESPONSE_HELP: + xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-sort-plugin"); + break; - switch (res_id) - { - case GTK_RESPONSE_OK: - sort_real (dialog); - gtk_widget_destroy (dialog->dialog); - break; - - case GTK_RESPONSE_HELP: - xed_help_display (GTK_WINDOW (widget), - NULL, - "xed-sort-plugin"); - break; - - case GTK_RESPONSE_CANCEL: - gtk_widget_destroy (dialog->dialog); - break; - } + case GTK_RESPONSE_CANCEL: + gtk_widget_destroy (GTK_WIDGET (dlg)); + break; + } } /* NOTE: we store the current selection in the dialog since focusing * the text field (like the combo box) looses the documnent selection. * Storing the selection ONLY works because the dialog is modal */ static void -get_current_selection (XedWindow *window, SortDialog *dialog) +get_current_selection (XedSortPlugin *plugin) { - XedDocument *doc; + XedSortPluginPrivate *priv; + XedDocument *doc; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - doc = xed_window_get_active_document (window); + priv = plugin->priv; - if (!gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), - &dialog->start, - &dialog->end)) - { - /* No selection, get the whole document. */ - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), - &dialog->start, - &dialog->end); - } -} + doc = xed_window_get_active_document (priv->window); -static SortDialog * -get_sort_dialog (ActionData *action_data) -{ - SortDialog *dialog; - GtkWidget *error_widget; - gboolean ret; - gchar *data_dir; - gchar *ui_file; - - xed_debug (DEBUG_PLUGINS); - - dialog = g_slice_new (SortDialog); - - data_dir = xed_plugin_get_data_dir (action_data->plugin); - ui_file = g_build_filename (data_dir, "sort.ui", NULL); - g_free (data_dir); - ret = xed_utils_get_ui_objects (ui_file, - NULL, - &error_widget, - "sort_dialog", &dialog->dialog, - "reverse_order_checkbutton", &dialog->reverse_order_checkbutton, - "col_num_spinbutton", &dialog->col_num_spinbutton, - "ignore_case_checkbutton", &dialog->ignore_case_checkbutton, - "remove_dups_checkbutton", &dialog->remove_dups_checkbutton, - NULL); - g_free (ui_file); - - if (!ret) - { - const gchar *err_message; - - err_message = gtk_label_get_label (GTK_LABEL (error_widget)); - xed_warning (GTK_WINDOW (action_data->window), - "%s", err_message); - - g_slice_free (SortDialog, dialog); - gtk_widget_destroy (error_widget); - - return NULL; - } - - gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog), - GTK_RESPONSE_OK); - - g_signal_connect (dialog->dialog, - "dispose", - G_CALLBACK (sort_dialog_dispose), - dialog); - - g_signal_connect (dialog->dialog, - "response", - G_CALLBACK (sort_dialog_response_handler), - dialog); - - get_current_selection (action_data->window, dialog); - - return dialog; + if (!gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), &priv->start, &priv->end)) + { + /* No selection, get the whole document. */ + gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), &priv->start, &priv->end); + } } static void -sort_cb (GtkAction *action, - ActionData *action_data) +create_sort_dialog (XedSortPlugin *plugin) { - XedDocument *doc; - GtkWindowGroup *wg; - SortDialog *dialog; + XedSortPluginPrivate *priv; + GtkWidget *error_widget; + gboolean ret; + gchar *data_dir; + gchar *ui_file; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - doc = xed_window_get_active_document (action_data->window); - g_return_if_fail (doc != NULL); + priv = plugin->priv; - dialog = get_sort_dialog (action_data); - g_return_if_fail (dialog != NULL); + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); + ui_file = g_build_filename (data_dir, "sort.ui", NULL); + ret = xed_utils_get_ui_objects (ui_file, + NULL, + &error_widget, + "sort_dialog", &priv->dialog, + "reverse_order_checkbutton", &priv->reverse_order_checkbutton, + "col_num_spinbutton", &priv->col_num_spinbutton, + "ignore_case_checkbutton", &priv->ignore_case_checkbutton, + "remove_dups_checkbutton", &priv->remove_dups_checkbutton, + NULL); + g_free (data_dir); + g_free (ui_file); - wg = xed_window_get_group (action_data->window); - gtk_window_group_add_window (wg, - GTK_WINDOW (dialog->dialog)); + if (!ret) + { + const gchar *err_message; - dialog->doc = doc; + err_message = gtk_label_get_label (GTK_LABEL (error_widget)); + xed_warning (GTK_WINDOW (priv->window), "%s", err_message); - gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog), - GTK_WINDOW (action_data->window)); + gtk_widget_destroy (error_widget); - gtk_window_set_modal (GTK_WINDOW (dialog->dialog), - TRUE); + return; + } - gtk_widget_show (GTK_WIDGET (dialog->dialog)); + gtk_dialog_set_default_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_OK); + + g_signal_connect (priv->dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &priv->dialog); + g_signal_connect (priv->dialog, "response", G_CALLBACK (sort_dialog_response_handler), plugin); + + get_current_selection (plugin); +} + +static void +sort_cb (GtkAction *action, + XedSortPlugin *plugin) +{ + XedSortPluginPrivate *priv; + GtkWindowGroup *wg; + + xed_debug (DEBUG_PLUGINS); + + priv = plugin->priv; + + create_sort_dialog (plugin); + + wg = xed_window_get_group (priv->window); + gtk_window_group_add_window (wg, GTK_WINDOW (priv->dialog)); + + gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (priv->window)); + gtk_window_set_modal (GTK_WINDOW (priv->dialog), TRUE); + + gtk_widget_show (GTK_WIDGET (priv->dialog)); } /* Compares two strings for the sorting algorithm. Uses the UTF-8 processing * functions in GLib to be as correct as possible.*/ static gint compare_algorithm (gconstpointer s1, - gconstpointer s2, - gpointer data) + gconstpointer s2, + gpointer data) { - gint length1, length2; - gint ret; - gchar *string1, *string2; - gchar *substring1, *substring2; - gchar *key1, *key2; - SortInfo *sort_info; + gint length1, length2; + gint ret; + gchar *string1, *string2; + gchar *substring1, *substring2; + gchar *key1, *key2; + SortInfo *sort_info; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - sort_info = (SortInfo *) data; - g_return_val_if_fail (sort_info != NULL, -1); + sort_info = (SortInfo *) data; + g_return_val_if_fail (sort_info != NULL, -1); - if (!sort_info->ignore_case) - { - string1 = *((gchar **) s1); - string2 = *((gchar **) s2); - } - else - { - string1 = g_utf8_casefold (*((gchar **) s1), -1); - string2 = g_utf8_casefold (*((gchar **) s2), -1); - } + if (!sort_info->ignore_case) + { + string1 = *((gchar **) s1); + string2 = *((gchar **) s2); + } + else + { + string1 = g_utf8_casefold (*((gchar **) s1), -1); + string2 = g_utf8_casefold (*((gchar **) s2), -1); + } - length1 = g_utf8_strlen (string1, -1); - length2 = g_utf8_strlen (string2, -1); + length1 = g_utf8_strlen (string1, -1); + length2 = g_utf8_strlen (string2, -1); - if ((length1 < sort_info->starting_column) && - (length2 < sort_info->starting_column)) - { - ret = 0; - } - else if (length1 < sort_info->starting_column) - { - ret = -1; - } - else if (length2 < sort_info->starting_column) - { - ret = 1; - } - else if (sort_info->starting_column < 1) - { - key1 = g_utf8_collate_key (string1, -1); - key2 = g_utf8_collate_key (string2, -1); - ret = strcmp (key1, key2); + if ((length1 < sort_info->starting_column) && + (length2 < sort_info->starting_column)) + { + ret = 0; + } + else if (length1 < sort_info->starting_column) + { + ret = -1; + } + else if (length2 < sort_info->starting_column) + { + ret = 1; + } + else if (sort_info->starting_column < 1) + { + key1 = g_utf8_collate_key (string1, -1); + key2 = g_utf8_collate_key (string2, -1); + ret = strcmp (key1, key2); - g_free (key1); - g_free (key2); - } - else - { - /* A character column offset is required, so figure out - * the correct offset into the UTF-8 string. */ - substring1 = g_utf8_offset_to_pointer (string1, sort_info->starting_column); - substring2 = g_utf8_offset_to_pointer (string2, sort_info->starting_column); + g_free (key1); + g_free (key2); + } + else + { + /* A character column offset is required, so figure out + * the correct offset into the UTF-8 string. */ + substring1 = g_utf8_offset_to_pointer (string1, sort_info->starting_column); + substring2 = g_utf8_offset_to_pointer (string2, sort_info->starting_column); - key1 = g_utf8_collate_key (substring1, -1); - key2 = g_utf8_collate_key (substring2, -1); - ret = strcmp (key1, key2); + key1 = g_utf8_collate_key (substring1, -1); + key2 = g_utf8_collate_key (substring2, -1); + ret = strcmp (key1, key2); - g_free (key1); - g_free (key2); - } + g_free (key1); + g_free (key2); + } - /* Do the necessary cleanup. */ - if (sort_info->ignore_case) - { - g_free (string1); - g_free (string2); - } + /* Do the necessary cleanup. */ + if (sort_info->ignore_case) + { + g_free (string1); + g_free (string2); + } - if (sort_info->reverse_order) - { - ret = -1 * ret; - } + if (sort_info->reverse_order) + { + ret = -1 * ret; + } - return ret; + return ret; } static gchar * get_line_slice (GtkTextBuffer *buf, - gint line) + gint line) { - GtkTextIter start, end; - char *ret; + GtkTextIter start, end; + char *ret; - gtk_text_buffer_get_iter_at_line (buf, &start, line); - end = start; + gtk_text_buffer_get_iter_at_line (buf, &start, line); + end = start; - if (!gtk_text_iter_ends_line (&start)) - gtk_text_iter_forward_to_line_end (&end); + if (!gtk_text_iter_ends_line (&start)) + { + gtk_text_iter_forward_to_line_end (&end); + } - ret= gtk_text_buffer_get_slice (buf, - &start, - &end, - TRUE); + ret= gtk_text_buffer_get_slice (buf, &start, &end, TRUE); - g_assert (ret != NULL); + g_assert (ret != NULL); - return ret; + return ret; } static void -sort_real (SortDialog *dialog) +sort_real (XedSortPlugin *plugin) { - XedDocument *doc; - GtkTextIter start, end; - gint start_line, end_line; - gint i; - gchar *last_row = NULL; - gint num_lines; - gchar **lines; - SortInfo *sort_info; + XedSortPluginPrivate *priv; + XedDocument *doc; + GtkTextIter start, end; + gint start_line, end_line; + gint i; + gchar *last_row = NULL; + gint num_lines; + gchar **lines; + SortInfo *sort_info; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - doc = dialog->doc; - g_return_if_fail (doc != NULL); + priv = plugin->priv; - sort_info = g_new0 (SortInfo, 1); - sort_info->ignore_case = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->ignore_case_checkbutton)); - sort_info->reverse_order = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->reverse_order_checkbutton)); - sort_info->remove_duplicates = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->remove_dups_checkbutton)); - sort_info->starting_column = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (dialog->col_num_spinbutton)) - 1; + doc = xed_window_get_active_document (priv->window); + g_return_if_fail (doc != NULL); - start = dialog->start; - end = dialog->end; - start_line = gtk_text_iter_get_line (&start); - end_line = gtk_text_iter_get_line (&end); + sort_info = g_slice_new (SortInfo); + sort_info->ignore_case = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->ignore_case_checkbutton)); + sort_info->reverse_order = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->reverse_order_checkbutton)); + sort_info->remove_duplicates = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->remove_dups_checkbutton)); + sort_info->starting_column = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->col_num_spinbutton)) - 1; - /* if we are at line start our last line is the previus one. - * Otherwise the last line is the current one but we try to - * move the iter after the line terminator */ - if (gtk_text_iter_get_line_offset (&end) == 0) - end_line = MAX (start_line, end_line - 1); - else - gtk_text_iter_forward_line (&end); + start = priv->start; + end = priv->end; + start_line = gtk_text_iter_get_line (&start); + end_line = gtk_text_iter_get_line (&end); - num_lines = end_line - start_line + 1; - lines = g_new0 (gchar *, num_lines + 1); + /* if we are at line start our last line is the previus one. + * Otherwise the last line is the current one but we try to + * move the iter after the line terminator */ + if (gtk_text_iter_get_line_offset (&end) == 0) + { + end_line = MAX (start_line, end_line - 1); + } + else + { + gtk_text_iter_forward_line (&end); + } - xed_debug_message (DEBUG_PLUGINS, "Building list..."); + num_lines = end_line - start_line + 1; + lines = g_new0 (gchar *, num_lines + 1); - for (i = 0; i < num_lines; i++) - { - lines[i] = get_line_slice (GTK_TEXT_BUFFER (doc), start_line + i); - } + xed_debug_message (DEBUG_PLUGINS, "Building list..."); - lines[num_lines] = NULL; + for (i = 0; i < num_lines; i++) + { + lines[i] = get_line_slice (GTK_TEXT_BUFFER (doc), start_line + i); + } - xed_debug_message (DEBUG_PLUGINS, "Sort list..."); + lines[num_lines] = NULL; - g_qsort_with_data (lines, - num_lines, - sizeof (gpointer), - compare_algorithm, - sort_info); + xed_debug_message (DEBUG_PLUGINS, "Sort list..."); - xed_debug_message (DEBUG_PLUGINS, "Rebuilding document..."); + g_qsort_with_data (lines, num_lines, sizeof (gpointer), compare_algorithm, sort_info); - gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (doc)); + xed_debug_message (DEBUG_PLUGINS, "Rebuilding document..."); - gtk_text_buffer_delete (GTK_TEXT_BUFFER (doc), - &start, - &end); + gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (doc)); - for (i = 0; i < num_lines; i++) - { - if (sort_info->remove_duplicates && - last_row != NULL && - (strcmp (last_row, lines[i]) == 0)) - continue; + gtk_text_buffer_delete (GTK_TEXT_BUFFER (doc), &start, &end); - gtk_text_buffer_insert (GTK_TEXT_BUFFER (doc), - &start, - lines[i], - -1); - gtk_text_buffer_insert (GTK_TEXT_BUFFER (doc), - &start, - "\n", - -1); + for (i = 0; i < num_lines; i++) + { + if (sort_info->remove_duplicates && last_row != NULL && (strcmp (last_row, lines[i]) == 0)) + { + continue; + } - last_row = lines[i]; - } + gtk_text_buffer_insert (GTK_TEXT_BUFFER (doc), &start, lines[i], -1); + gtk_text_buffer_insert (GTK_TEXT_BUFFER (doc), &start, "\n", -1); - gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (doc)); + last_row = lines[i]; + } - g_strfreev (lines); - g_free (sort_info); + gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (doc)); - xed_debug_message (DEBUG_PLUGINS, "Done."); + g_strfreev (lines); + g_slice_free (SortInfo, sort_info); + + xed_debug_message (DEBUG_PLUGINS, "Done."); } static void -free_window_data (WindowData *data) +update_ui (XedSortPlugin *plugin) { - g_return_if_fail (data != NULL); + XedView *view; - g_object_unref (data->ui_action_group); - g_slice_free (WindowData, data); + xed_debug (DEBUG_PLUGINS); + + view = xed_window_get_active_view (plugin->priv->window); + + gtk_action_group_set_sensitive (plugin->priv->ui_action_group, + (view != NULL) && + gtk_text_view_get_editable (GTK_TEXT_VIEW (view))); } static void -free_action_data (ActionData *data) +xed_sort_plugin_activate (XedWindowActivatable *activatable) { - g_return_if_fail (data != NULL); + XedSortPluginPrivate *priv; + GtkUIManager *manager; - g_slice_free (ActionData, data); + xed_debug (DEBUG_PLUGINS); + + priv = XED_SORT_PLUGIN (activatable)->priv; + manager = xed_window_get_ui_manager (priv->window); + + priv->ui_action_group = gtk_action_group_new ("XedSortPluginActions"); + gtk_action_group_set_translation_domain (priv->ui_action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions (priv->ui_action_group, action_entries, G_N_ELEMENTS (action_entries), activatable); + + gtk_ui_manager_insert_action_group (manager, priv->ui_action_group, -1); + + priv->ui_id = gtk_ui_manager_new_merge_id (manager); + + gtk_ui_manager_add_ui (manager, + priv->ui_id, + MENU_PATH, + "Sort", + "Sort", + GTK_UI_MANAGER_MENUITEM, + FALSE); + + update_ui (XED_SORT_PLUGIN (activatable)); } static void -update_ui_real (XedWindow *window, - WindowData *data) +xed_sort_plugin_deactivate (XedWindowActivatable *activatable) { - XedView *view; + XedSortPluginPrivate *priv; + GtkUIManager *manager; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - view = xed_window_get_active_view (window); + priv = XED_SORT_PLUGIN (activatable)->priv; + manager = xed_window_get_ui_manager (priv->window); - gtk_action_group_set_sensitive (data->ui_action_group, - (view != NULL) && - gtk_text_view_get_editable (GTK_TEXT_VIEW (view))); + gtk_ui_manager_remove_ui (manager, priv->ui_id); + gtk_ui_manager_remove_action_group (manager, priv->ui_action_group); } static void -impl_activate (XedPlugin *plugin, - XedWindow *window) +xed_sort_plugin_update_state (XedWindowActivatable *activatable) { - GtkUIManager *manager; - WindowData *data; - ActionData *action_data; + xed_debug (DEBUG_PLUGINS); - xed_debug (DEBUG_PLUGINS); - - data = g_slice_new (WindowData); - action_data = g_slice_new (ActionData); - action_data->window = window; - action_data->plugin = plugin; - - manager = xed_window_get_ui_manager (window); - - data->ui_action_group = gtk_action_group_new ("XedSortPluginActions"); - gtk_action_group_set_translation_domain (data->ui_action_group, - GETTEXT_PACKAGE); - gtk_action_group_add_actions_full (data->ui_action_group, - action_entries, - G_N_ELEMENTS (action_entries), - action_data, - (GDestroyNotify) free_action_data); - - gtk_ui_manager_insert_action_group (manager, - data->ui_action_group, - -1); - - data->ui_id = gtk_ui_manager_new_merge_id (manager); - - g_object_set_data_full (G_OBJECT (window), - WINDOW_DATA_KEY, - data, - (GDestroyNotify) free_window_data); - - gtk_ui_manager_add_ui (manager, - data->ui_id, - MENU_PATH, - "Sort", - "Sort", - GTK_UI_MANAGER_MENUITEM, - FALSE); - - update_ui_real (window, - data); -} - -static void -impl_deactivate (XedPlugin *plugin, - XedWindow *window) -{ - GtkUIManager *manager; - WindowData *data; - - xed_debug (DEBUG_PLUGINS); - - manager = xed_window_get_ui_manager (window); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - gtk_ui_manager_remove_ui (manager, - data->ui_id); - gtk_ui_manager_remove_action_group (manager, - data->ui_action_group); - - g_object_set_data (G_OBJECT (window), - WINDOW_DATA_KEY, - NULL); -} - -static void -impl_update_ui (XedPlugin *plugin, - XedWindow *window) -{ - WindowData *data; - - xed_debug (DEBUG_PLUGINS); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - update_ui_real (window, - data); + update_ui (XED_SORT_PLUGIN (activatable)); } static void xed_sort_plugin_init (XedSortPlugin *plugin) { - xed_debug_message (DEBUG_PLUGINS, "XedSortPlugin initializing"); + xed_debug_message (DEBUG_PLUGINS, "XedSortPlugin initializing"); + + plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin, XED_TYPE_SORT_PLUGIN, XedSortPluginPrivate); +} + +static void +xed_sort_plugin_dispose (GObject *object) +{ + XedSortPlugin *plugin = XED_SORT_PLUGIN (object); + + xed_debug_message (DEBUG_PLUGINS, "XedSortPlugin disposing"); + + g_clear_object (&plugin->priv->ui_action_group); + g_clear_object (&plugin->priv->window); + + G_OBJECT_CLASS (xed_sort_plugin_parent_class)->dispose (object); } static void xed_sort_plugin_finalize (GObject *object) { - xed_debug_message (DEBUG_PLUGINS, "XedSortPlugin finalizing"); + xed_debug_message (DEBUG_PLUGINS, "XedSortPlugin finalizing"); - G_OBJECT_CLASS (xed_sort_plugin_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_sort_plugin_parent_class)->finalize (object); +} + +static void +xed_sort_plugin_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XedSortPlugin *plugin = XED_SORT_PLUGIN (object); + + switch (prop_id) + { + case PROP_WINDOW: + plugin->priv->window = XED_WINDOW (g_value_dup_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_sort_plugin_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XedSortPlugin *plugin = XED_SORT_PLUGIN (object); + + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, plugin->priv->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_sort_plugin_class_init (XedSortPluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_sort_plugin_finalize; + object_class->dispose = xed_sort_plugin_dispose; + object_class->finalize = xed_sort_plugin_finalize; + object_class->set_property = xed_sort_plugin_set_property; + object_class->get_property = xed_sort_plugin_get_property; - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - plugin_class->update_ui = impl_update_ui; + g_object_class_override_property (object_class, PROP_WINDOW, "window"); + + g_type_class_add_private (klass, sizeof (XedSortPluginPrivate)); +} + +static void +xed_sort_plugin_class_finalize (XedSortPluginClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE_EXTENDED */ +} + +static void +xed_window_activatable_iface_init (XedWindowActivatableInterface *iface) +{ + iface->activate = xed_sort_plugin_activate; + iface->deactivate = xed_sort_plugin_deactivate; + iface->update_state = xed_sort_plugin_update_state; +} + +G_MODULE_EXPORT void +peas_register_types (PeasObjectModule *module) +{ + xed_sort_plugin_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + XED_TYPE_WINDOW_ACTIVATABLE, + XED_TYPE_SORT_PLUGIN); } diff --git a/plugins/sort/xed-sort-plugin.h b/plugins/sort/xed-sort-plugin.h index d35c2c8..945e6a1 100644 --- a/plugins/sort/xed-sort-plugin.h +++ b/plugins/sort/xed-sort-plugin.h @@ -1,6 +1,6 @@ /* * xed-sort-plugin.h - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -14,8 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $Id$ */ #ifndef __XED_SORT_PLUGIN_H__ @@ -23,50 +21,38 @@ #include #include -#include +#include +#include G_BEGIN_DECLS -/* - * Type checking and casting macros - */ -#define XED_TYPE_SORT_PLUGIN (xed_sort_plugin_get_type ()) -#define XED_SORT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_SORT_PLUGIN, XedSortPlugin)) -#define XED_SORT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_SORT_PLUGIN, XedSortPluginClass)) -#define XED_IS_SORT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_SORT_PLUGIN)) -#define XED_IS_SORT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_SORT_PLUGIN)) -#define XED_SORT_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_SORT_PLUGIN, XedSortPluginClass)) +#define XED_TYPE_SORT_PLUGIN (xed_sort_plugin_get_type ()) +#define XED_SORT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_SORT_PLUGIN, XedSortPlugin)) +#define XED_SORT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_SORT_PLUGIN, XedSortPluginClass)) +#define XED_IS_SORT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_SORT_PLUGIN)) +#define XED_IS_SORT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_SORT_PLUGIN)) +#define XED_SORT_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_SORT_PLUGIN, XedSortPluginClass)) -/* Private structure type */ -typedef struct _XedSortPluginPrivate XedSortPluginPrivate; - -/* - * Main object structure - */ -typedef struct _XedSortPlugin XedSortPlugin; +typedef struct _XedSortPlugin XedSortPlugin; +typedef struct _XedSortPluginPrivate XedSortPluginPrivate; +typedef struct _XedSortPluginClass XedSortPluginClass; struct _XedSortPlugin { - XedPlugin parent_instance; -}; + PeasExtensionBase parent; -/* - * Class definition - */ -typedef struct _XedSortPluginClass XedSortPluginClass; + /*< private >*/ + XedSortPluginPrivate *priv; +}; struct _XedSortPluginClass { - XedPluginClass parent_class; + PeasExtensionBaseClass parent_class; }; -/* - * Public methods - */ -GType xed_sort_plugin_get_type (void) G_GNUC_CONST; +GType xed_sort_plugin_get_type (void) G_GNUC_CONST; -/* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule *module); +G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); G_END_DECLS diff --git a/plugins/spell/Makefile.am b/plugins/spell/Makefile.am index e9a9156..1afd0d3 100644 --- a/plugins/spell/Makefile.am +++ b/plugins/spell/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = \ $(XED_CFLAGS) \ $(ENCHANT_CFLAGS) \ $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) + $(DISABLE_DEPRECATED_CFLAGS) BUILT_SOURCES = \ xed-spell-marshal.c \ @@ -29,9 +29,9 @@ libspell_la_SOURCES = \ xed-automatic-spell-checker.h \ xed-spell-utils.c \ xed-spell-utils.h \ - $(BUILT_SOURCES) + $(BUILT_SOURCES) -libspell_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) +libspell_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) libspell_la_LIBADD = $(XED_LIBS) $(ENCHANT_LIBS) uidir = $(XED_PLUGINS_DATA_DIR)/spell @@ -44,11 +44,11 @@ xed-spell-marshal.c: xed-spell-marshal.list $(GLIB_GENMARSHAL) $(AM_V_GEN) echo "#include \"xed-spell-marshal.h\"" > $@ && \ $(GLIB_GENMARSHAL) $< --body --prefix=xed_marshal >> $@ -plugin_in_files = spell.xed-plugin.desktop.in +plugin_in_files = spell.plugin.desktop.in -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache +%.plugin: %.plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) +plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin) @INTLTOOL_XML_NOMERGE_RULE@ spell_gschema_in = org.x.editor.plugins.spell.gschema.xml.in diff --git a/plugins/spell/languages-dialog.ui b/plugins/spell/languages-dialog.ui index 1bc8603..28ec4fb 100644 --- a/plugins/spell/languages-dialog.ui +++ b/plugins/spell/languages-dialog.ui @@ -1,136 +1,132 @@ - + + + + False 5 Set language - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE True - True True - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False + dialog - + True - False + False 2 - + True - GTK_BUTTONBOX_END + False + end - True - True - True gtk-help + True + True + True + False True - GTK_RELIEF_NORMAL - True + + True + True + 0 + - True - True - True gtk-cancel + True + True + True + False True - GTK_RELIEF_NORMAL - True + + True + True + 1 + - True - True - True gtk-ok + True + True + True + False True - GTK_RELIEF_NORMAL - True + + True + True + 2 + - 0 False True - GTK_PACK_END + end + 0 - - 5 + True - False + False + True + True + 5 + vertical 11 True + False Select the _language of the current document. True - False - GTK_JUSTIFY_LEFT True - False - 0 - 0.5 - 0 - 0 languages_treeview - PANGO_ELLIPSIZE_NONE - -1 - False - 0 + 0 - 0 False False + 0 + 180 True True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_ETCHED_IN - GTK_CORNER_TOP_LEFT + etched-in 180 True True False - False - False - True - False - False - False + + + - 0 True True + 1 - 0 - True + False True + 0 diff --git a/plugins/spell/spell-checker.ui b/plugins/spell/spell-checker.ui index ea84290..f5f8a30 100644 --- a/plugins/spell/spell-checker.ui +++ b/plugins/spell/spell-checker.ui @@ -1,479 +1,366 @@ - - + + - - gtk-spell-check - 4 - - - gtk-add - 4 - - - gtk-go-down - 4 - - - gtk-convert - 4 - - - gtk-goto-bottom - 4 - - - gtk-convert - 4 - + - True - Check spelling - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False + False False - False + True + dialog + True + Check spelling - - 12 + True - False + False + 12 + vertical 6 - + True - 2 - 2 - False + False + True 6 12 True + False Misspelled word: - False - False - GTK_JUSTIFY_CENTER - False - False 0 - 0.5 - 0 - 0 0 - 1 0 - 1 - fill - True + False word - False True - GTK_JUSTIFY_CENTER - False - False + center 0 - 0.5 - 0 - 0 - - - 1 - 2 0 - 1 - fill - - + True + False Change _to: True - False - GTK_JUSTIFY_CENTER - False - False 0 - 0.5 - 0 - 0 - word_entry 0 - 1 1 - 2 - fill - - + True - False + False + True 12 True True - True - True - 0 - - True - False + True - 0 - True + False True + 0 + Check _Word True True - GTK_RELIEF_NORMAL - check_word_image - Check _Word + True True - 0 False - False + True + 1 1 - 2 1 - 2 - fill - 0 False True + 0 - + True - 3 - 2 - False + False 6 12 - + True + False _Suggestions: True - False - GTK_JUSTIFY_CENTER - False - False 0 - 0.5 - 0 - 0 - suggestions_list 0 - 1 0 - 1 - fill - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_ETCHED_IN - GTK_CORNER_TOP_LEFT + True + True + True + in - 200 True True False - False - False - True + + + 0 - 1 1 - 2 - + True - True + False + 6 + vertical 12 - + True - 2 - 2 - True + False 12 12 - True - True - GTK_RELIEF_NORMAL - ignore_image _Ignore - True - - - 0 - 1 - 0 - 1 - expand - - - - True True - GTK_RELIEF_NORMAL - change_image - Cha_nge + True True 0 - 1 - 1 - 2 - expand + 0 + Ignore _All True True - GTK_RELIEF_NORMAL - ignore_all_image - Ignore _All + True True 1 - 2 0 - 1 - expand + + + + + Cha_nge + True + True + True + True + + + 0 + 1 + Change A_ll True True - GTK_RELIEF_NORMAL - change_all_image - Change A_ll + True True 1 - 2 1 - 2 - expand - 0 - True + False True + 0 - + True - False + False + vertical 11 - + True + False User dictionary: - False True - GTK_JUSTIFY_LEFT - False - False - 7.45058e-09 - 0.5 - 0 - 0 + 0 - 0 False True + 0 - + True - True + False 6 + True + Add w_ord True True - GTK_RELIEF_NORMAL - add_word_image - Add w_ord + True True - 0 - True + False True + 0 - 0 False - False + True + 2 - 0 - True - False + False + True + 1 1 - 2 1 - 2 - + True - False + False 12 - + True + False Language: - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - 0 False - False + True + 0 True + False Language - False True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - - - - 0 False - False + True + 1 0 - 1 2 - 3 - fill - fill - + True - GTK_BUTTONBOX_END - 0 + False + True + end + _Close True - True True - gtk-close - True - GTK_RELIEF_NORMAL + True + end + True + + + True + True + 0 + 1 - 2 - 2 - 3 - fill - fill + 3 + + + + + + + + + - 0 True True + 1 diff --git a/plugins/spell/spell.xed-plugin.desktop.in b/plugins/spell/spell.plugin.desktop.in similarity index 94% rename from plugins/spell/spell.xed-plugin.desktop.in rename to plugins/spell/spell.plugin.desktop.in index d418daa..9ddb813 100644 --- a/plugins/spell/spell.xed-plugin.desktop.in +++ b/plugins/spell/spell.plugin.desktop.in @@ -1,4 +1,4 @@ -[Xed Plugin] +[Plugin] Module=spell IAge=2 _Name=Spell Checker diff --git a/plugins/spell/xed-automatic-spell-checker.c b/plugins/spell/xed-automatic-spell-checker.c index 35feec0..1202920 100644 --- a/plugins/spell/xed-automatic-spell-checker.c +++ b/plugins/spell/xed-automatic-spell-checker.c @@ -3,7 +3,7 @@ * xed-automatic-spell-checker.c * This file is part of xed * - * Copyright (C) 2002 Paolo Maggi + * Copyright (C) 2002 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,14 +17,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ /* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2002. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ /* This is a modified version of gtkspell 2.0.5 (gtkspell.sf.net) */ @@ -43,18 +43,19 @@ #include "xed-automatic-spell-checker.h" #include "xed-spell-utils.h" -struct _XedAutomaticSpellChecker { - XedDocument *doc; - GSList *views; - - GtkTextMark *mark_insert_start; - GtkTextMark *mark_insert_end; - gboolean deferred_check; +struct _XedAutomaticSpellChecker +{ + XedDocument *doc; + GSList *views; - GtkTextTag *tag_highlight; - GtkTextMark *mark_click; + GtkTextMark *mark_insert_start; + GtkTextMark *mark_insert_end; + gboolean deferred_check; - XedSpellChecker *spell_checker; + GtkTextTag *tag_highlight; + GtkTextMark *mark_click; + + XedSpellChecker *spell_checker; }; static GQuark automatic_spell_checker_id = 0; @@ -63,164 +64,164 @@ static GQuark suggestion_id = 0; static void xed_automatic_spell_checker_free_internal (XedAutomaticSpellChecker *spell); static void -view_destroy (XedView *view, XedAutomaticSpellChecker *spell) +view_destroy (XedView *view, + XedAutomaticSpellChecker *spell) { - xed_automatic_spell_checker_detach_view (spell, view); + xed_automatic_spell_checker_detach_view (spell, view); } static void -check_word (XedAutomaticSpellChecker *spell, GtkTextIter *start, GtkTextIter *end) +check_word (XedAutomaticSpellChecker *spell, + GtkTextIter *start, + GtkTextIter *end) { - gchar *word; + gchar *word; - word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), start, end, FALSE); + word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), start, end, FALSE); - /* - g_print ("Check word: %s [%d - %d]\n", word, gtk_text_iter_get_offset (start), - gtk_text_iter_get_offset (end)); - */ + /* + g_print ("Check word: %s [%d - %d]\n", word, gtk_text_iter_get_offset (start), + gtk_text_iter_get_offset (end)); + */ - if (!xed_spell_checker_check_word (spell->spell_checker, word, -1)) - { - /* - g_print ("Apply tag: [%d - %d]\n", gtk_text_iter_get_offset (start), - gtk_text_iter_get_offset (end)); - */ - gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (spell->doc), - spell->tag_highlight, - start, - end); - } - - g_free (word); + if (!xed_spell_checker_check_word (spell->spell_checker, word, -1)) + { + /* + g_print ("Apply tag: [%d - %d]\n", gtk_text_iter_get_offset (start), + gtk_text_iter_get_offset (end)); + */ + gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (spell->doc), spell->tag_highlight, start, end); + } + + g_free (word); } static void -check_range (XedAutomaticSpellChecker *spell, - GtkTextIter start, - GtkTextIter end, - gboolean force_all) +check_range (XedAutomaticSpellChecker *spell, + GtkTextIter start, + GtkTextIter end, + gboolean force_all) { - /* we need to "split" on word boundaries. - * luckily, Pango knows what "words" are - * so we don't have to figure it out. */ + /* we need to "split" on word boundaries. + * luckily, Pango knows what "words" are + * so we don't have to figure it out. */ - GtkTextIter wstart; - GtkTextIter wend; - GtkTextIter cursor; - GtkTextIter precursor; - gboolean highlight; + GtkTextIter wstart; + GtkTextIter wend; + GtkTextIter cursor; + GtkTextIter precursor; + gboolean highlight; - /* - g_print ("Check range: [%d - %d]\n", gtk_text_iter_get_offset (&start), - gtk_text_iter_get_offset (&end)); - */ + /* + g_print ("Check range: [%d - %d]\n", gtk_text_iter_get_offset (&start), + gtk_text_iter_get_offset (&end)); + */ - if (gtk_text_iter_inside_word (&end)) - gtk_text_iter_forward_word_end (&end); - - if (!gtk_text_iter_starts_word (&start)) - { - if (gtk_text_iter_inside_word (&start) || - gtk_text_iter_ends_word (&start)) - { - gtk_text_iter_backward_word_start (&start); - } - else - { - /* if we're neither at the beginning nor inside a word, - * me must be in some spaces. - * skip forward to the beginning of the next word. */ - - if (gtk_text_iter_forward_word_end (&start)) - gtk_text_iter_backward_word_start (&start); - } - } + if (gtk_text_iter_inside_word (&end)) + { + gtk_text_iter_forward_word_end (&end); + } - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), - &cursor, - gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (spell->doc))); - - precursor = cursor; - gtk_text_iter_backward_char (&precursor); - - highlight = gtk_text_iter_has_tag (&cursor, spell->tag_highlight) || - gtk_text_iter_has_tag (&precursor, spell->tag_highlight); - - gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), - spell->tag_highlight, - &start, - &end); + if (!gtk_text_iter_starts_word (&start)) + { + if (gtk_text_iter_inside_word (&start) || gtk_text_iter_ends_word (&start)) + { + gtk_text_iter_backward_word_start (&start); + } + else + { + /* if we're neither at the beginning nor inside a word, + * me must be in some spaces. + * skip forward to the beginning of the next word. */ - /* Fix a corner case when replacement occurs at beginning of buffer: - * An iter at offset 0 seems to always be inside a word, - * even if it's not. Possibly a pango bug. - */ - if (gtk_text_iter_get_offset (&start) == 0) - { - gtk_text_iter_forward_word_end(&start); - gtk_text_iter_backward_word_start(&start); - } + if (gtk_text_iter_forward_word_end (&start)) + { + gtk_text_iter_backward_word_start (&start); + } + } + } - wstart = start; - - while (xed_spell_utils_skip_no_spell_check (&wstart, &end) && - gtk_text_iter_compare (&wstart, &end) < 0) - { - gboolean inword; + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), + &cursor, + gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (spell->doc))); - /* move wend to the end of the current word. */ - wend = wstart; - - gtk_text_iter_forward_word_end (&wend); + precursor = cursor; + gtk_text_iter_backward_char (&precursor); - inword = (gtk_text_iter_compare (&wstart, &cursor) < 0) && - (gtk_text_iter_compare (&cursor, &wend) <= 0); - - if (inword && !force_all) - { - /* this word is being actively edited, - * only check if it's already highligted, - * otherwise defer this check until later. */ - if (highlight) - check_word (spell, &wstart, &wend); - else - spell->deferred_check = TRUE; - } - else - { - check_word (spell, &wstart, &wend); - spell->deferred_check = FALSE; - } + highlight = gtk_text_iter_has_tag (&cursor, spell->tag_highlight) || + gtk_text_iter_has_tag (&precursor, spell->tag_highlight); - /* now move wend to the beginning of the next word, */ - gtk_text_iter_forward_word_end (&wend); - gtk_text_iter_backward_word_start (&wend); - - /* make sure we've actually advanced - * (we don't advance in some corner cases), */ - if (gtk_text_iter_equal (&wstart, &wend)) - break; /* we're done in these cases.. */ + gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), spell->tag_highlight, &start, &end); - /* and then pick this as the new next word beginning. */ - wstart = wend; - } + /* Fix a corner case when replacement occurs at beginning of buffer: + * An iter at offset 0 seems to always be inside a word, + * even if it's not. Possibly a pango bug. + */ + if (gtk_text_iter_get_offset (&start) == 0) + { + gtk_text_iter_forward_word_end(&start); + gtk_text_iter_backward_word_start(&start); + } + + wstart = start; + + while (xed_spell_utils_skip_no_spell_check (&wstart, &end) && gtk_text_iter_compare (&wstart, &end) < 0) + { + gboolean inword; + + /* move wend to the end of the current word. */ + wend = wstart; + + gtk_text_iter_forward_word_end (&wend); + + inword = (gtk_text_iter_compare (&wstart, &cursor) < 0) && (gtk_text_iter_compare (&cursor, &wend) <= 0); + + if (inword && !force_all) + { + /* this word is being actively edited, + * only check if it's already highligted, + * otherwise defer this check until later. */ + if (highlight) + { + check_word (spell, &wstart, &wend); + } + else + { + spell->deferred_check = TRUE; + } + } + else + { + check_word (spell, &wstart, &wend); + spell->deferred_check = FALSE; + } + + /* now move wend to the beginning of the next word, */ + gtk_text_iter_forward_word_end (&wend); + gtk_text_iter_backward_word_start (&wend); + + /* make sure we've actually advanced + * (we don't advance in some corner cases), */ + if (gtk_text_iter_equal (&wstart, &wend)) + { + break; /* we're done in these cases.. */ + } + + /* and then pick this as the new next word beginning. */ + wstart = wend; + } } static void -check_deferred_range (XedAutomaticSpellChecker *spell, - gboolean force_all) +check_deferred_range (XedAutomaticSpellChecker *spell, + gboolean force_all) { - GtkTextIter start, end; + GtkTextIter start, end; - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), - &start, - spell->mark_insert_start); - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), - &end, - spell->mark_insert_end); + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), &start, spell->mark_insert_start); + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), &end, spell->mark_insert_end); - check_range (spell, start, end, force_all); + check_range (spell, start, end, force_all); } /* insertion works like this: @@ -231,24 +232,30 @@ check_deferred_range (XedAutomaticSpellChecker *spell, * this may be overkill for the common case (inserting one character). */ static void -insert_text_before (GtkTextBuffer *buffer, GtkTextIter *iter, - gchar *text, gint len, XedAutomaticSpellChecker *spell) +insert_text_before (GtkTextBuffer *buffer, + GtkTextIter *iter, + gchar *text, + gint len, + XedAutomaticSpellChecker *spell) { - gtk_text_buffer_move_mark (buffer, spell->mark_insert_start, iter); + gtk_text_buffer_move_mark (buffer, spell->mark_insert_start, iter); } static void -insert_text_after (GtkTextBuffer *buffer, GtkTextIter *iter, - gchar *text, gint len, XedAutomaticSpellChecker *spell) +insert_text_after (GtkTextBuffer *buffer, + GtkTextIter *iter, + gchar *text, + gint len, + XedAutomaticSpellChecker *spell) { - GtkTextIter start; + GtkTextIter start; - /* we need to check a range of text. */ - gtk_text_buffer_get_iter_at_mark (buffer, &start, spell->mark_insert_start); - - check_range (spell, start, *iter, FALSE); + /* we need to check a range of text. */ + gtk_text_buffer_get_iter_at_mark (buffer, &start, spell->mark_insert_start); - gtk_text_buffer_move_mark (buffer, spell->mark_insert_end, iter); + check_range (spell, start, *iter, FALSE); + + gtk_text_buffer_move_mark (buffer, spell->mark_insert_end, iter); } /* deleting is more simple: we're given the range of deleted text. @@ -259,757 +266,702 @@ insert_text_after (GtkTextBuffer *buffer, GtkTextIter *iter, */ static void -delete_range_after (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, - XedAutomaticSpellChecker *spell) +delete_range_after (GtkTextBuffer *buffer, + GtkTextIter *start, + GtkTextIter *end, + XedAutomaticSpellChecker *spell) { - check_range (spell, *start, *end, FALSE); + check_range (spell, *start, *end, FALSE); } static void -mark_set (GtkTextBuffer *buffer, - GtkTextIter *iter, - GtkTextMark *mark, - XedAutomaticSpellChecker *spell) +mark_set (GtkTextBuffer *buffer, + GtkTextIter *iter, + GtkTextMark *mark, + XedAutomaticSpellChecker *spell) { - /* if the cursor has moved and there is a deferred check so handle it now */ - if ((mark == gtk_text_buffer_get_insert (buffer)) && spell->deferred_check) - check_deferred_range (spell, FALSE); + /* if the cursor has moved and there is a deferred check so handle it now */ + if ((mark == gtk_text_buffer_get_insert (buffer)) && spell->deferred_check) + { + check_deferred_range (spell, FALSE); + } } static void -get_word_extents_from_mark (GtkTextBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end, - GtkTextMark *mark) +get_word_extents_from_mark (GtkTextBuffer *buffer, + GtkTextIter *start, + GtkTextIter *end, + GtkTextMark *mark) { - gtk_text_buffer_get_iter_at_mark(buffer, start, mark); - - if (!gtk_text_iter_starts_word (start)) - gtk_text_iter_backward_word_start (start); - - *end = *start; - - if (gtk_text_iter_inside_word (end)) - gtk_text_iter_forward_word_end (end); + gtk_text_buffer_get_iter_at_mark(buffer, start, mark); + + if (!gtk_text_iter_starts_word (start)) + { + gtk_text_iter_backward_word_start (start); + } + + *end = *start; + + if (gtk_text_iter_inside_word (end)) + { + gtk_text_iter_forward_word_end (end); + } } static void -remove_tag_to_word (XedAutomaticSpellChecker *spell, const gchar *word) +remove_tag_to_word (XedAutomaticSpellChecker *spell, + const gchar *word) { - GtkTextIter iter; - GtkTextIter match_start, match_end; + GtkTextIter iter; + GtkTextIter match_start, match_end; - gboolean found; + gboolean found; - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (spell->doc), &iter, 0); - - found = TRUE; + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (spell->doc), &iter, 0); - while (found) - { - found = gtk_text_iter_forward_search (&iter, - word, - GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, - &match_start, - &match_end, - NULL); + found = TRUE; - if (found) - { - if (gtk_text_iter_starts_word (&match_start) && - gtk_text_iter_ends_word (&match_end)) - { - gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), - spell->tag_highlight, - &match_start, - &match_end); - } + while (found) + { + found = gtk_text_iter_forward_search (&iter, + word, + GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, + &match_start, + &match_end, + NULL); - iter = match_end; - } - } + if (found) + { + if (gtk_text_iter_starts_word (&match_start) && gtk_text_iter_ends_word (&match_end)) + { + gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), + spell->tag_highlight, + &match_start, + &match_end); + } + + iter = match_end; + } + } } static void -add_to_dictionary (GtkWidget *menuitem, XedAutomaticSpellChecker *spell) +add_to_dictionary (GtkWidget *menuitem, + XedAutomaticSpellChecker *spell) { - gchar *word; - - GtkTextIter start, end; - - get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); + gchar *word; - word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), - &start, - &end, - FALSE); - - xed_spell_checker_add_word_to_personal (spell->spell_checker, word, -1); + GtkTextIter start, end; - g_free (word); + get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); + + word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); + + xed_spell_checker_add_word_to_personal (spell->spell_checker, word, -1); + + g_free (word); } static void -ignore_all (GtkWidget *menuitem, XedAutomaticSpellChecker *spell) +ignore_all (GtkWidget *menuitem, + XedAutomaticSpellChecker *spell) { - gchar *word; - - GtkTextIter start, end; - - get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); + gchar *word; - word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), - &start, - &end, - FALSE); - - xed_spell_checker_add_word_to_session (spell->spell_checker, word, -1); + GtkTextIter start, end; - g_free (word); + get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); + + word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); + + xed_spell_checker_add_word_to_session (spell->spell_checker, word, -1); + + g_free (word); } static void -replace_word (GtkWidget *menuitem, XedAutomaticSpellChecker *spell) +replace_word (GtkWidget *menuitem, + XedAutomaticSpellChecker *spell) { - gchar *oldword; - const gchar *newword; - - GtkTextIter start, end; + gchar *oldword; + const gchar *newword; - get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); + GtkTextIter start, end; - oldword = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); - - newword = g_object_get_qdata (G_OBJECT (menuitem), suggestion_id); - g_return_if_fail (newword != NULL); + get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); - gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (spell->doc)); + oldword = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); - gtk_text_buffer_delete (GTK_TEXT_BUFFER (spell->doc), &start, &end); - gtk_text_buffer_insert (GTK_TEXT_BUFFER (spell->doc), &start, newword, -1); + newword = g_object_get_qdata (G_OBJECT (menuitem), suggestion_id); + g_return_if_fail (newword != NULL); - gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (spell->doc)); + gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (spell->doc)); - xed_spell_checker_set_correction (spell->spell_checker, - oldword, strlen (oldword), - newword, strlen (newword)); + gtk_text_buffer_delete (GTK_TEXT_BUFFER (spell->doc), &start, &end); + gtk_text_buffer_insert (GTK_TEXT_BUFFER (spell->doc), &start, newword, -1); - g_free (oldword); + gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (spell->doc)); + + xed_spell_checker_set_correction (spell->spell_checker, + oldword, strlen (oldword), + newword, strlen (newword)); + + g_free (oldword); } static GtkWidget * -build_suggestion_menu (XedAutomaticSpellChecker *spell, const gchar *word) +build_suggestion_menu (XedAutomaticSpellChecker *spell, + const gchar *word) { - GtkWidget *topmenu, *menu; - GtkWidget *mi; - GSList *suggestions; - GSList *list; - gchar *label_text; - - topmenu = menu = gtk_menu_new(); + GtkWidget *topmenu, *menu; + GtkWidget *mi; + GSList *suggestions; + GSList *list; + gchar *label_text; - suggestions = xed_spell_checker_get_suggestions (spell->spell_checker, word, -1); + topmenu = menu = gtk_menu_new(); - list = suggestions; + suggestions = xed_spell_checker_get_suggestions (spell->spell_checker, word, -1); - if (suggestions == NULL) - { - /* no suggestions. put something in the menu anyway... */ - GtkWidget *label; - /* Translators: Displayed in the "Check Spelling" dialog if there are no suggestions for the current misspelled word */ - label = gtk_label_new (_("(no suggested words)")); - - mi = gtk_menu_item_new (); - gtk_widget_set_sensitive (mi, FALSE); - gtk_container_add (GTK_CONTAINER(mi), label); - gtk_widget_show_all (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); - } - else - { - gint count = 0; - - /* build a set of menus with suggestions. */ - while (suggestions != NULL) - { - GtkWidget *label; + list = suggestions; - if (count == 10) - { - /* Separator */ - mi = gtk_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - - mi = gtk_menu_item_new_with_mnemonic (_("_More...")); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); + if (suggestions == NULL) + { + /* no suggestions. put something in the menu anyway... */ + GtkWidget *label; + /* Translators: Displayed in the "Check Spelling" dialog if there are no suggestions for the current misspelled word */ + label = gtk_label_new (_("(no suggested words)")); - menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu); - count = 0; - } - - label_text = g_strdup_printf ("%s", (gchar*) suggestions->data); - - label = gtk_label_new (label_text); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + mi = gtk_menu_item_new (); + gtk_widget_set_sensitive (mi, FALSE); + gtk_container_add (GTK_CONTAINER(mi), label); + gtk_widget_show_all (mi); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); + } + else + { + gint count = 0; - mi = gtk_menu_item_new (); - gtk_container_add (GTK_CONTAINER(mi), label); - - gtk_widget_show_all (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); + /* build a set of menus with suggestions. */ + while (suggestions != NULL) + { + GtkWidget *label; - g_object_set_qdata_full (G_OBJECT (mi), - suggestion_id, - g_strdup (suggestions->data), - (GDestroyNotify)g_free); + if (count == 10) + { + /* Separator */ + mi = gtk_menu_item_new (); + gtk_widget_show (mi); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - g_free (label_text); - g_signal_connect (mi, - "activate", - G_CALLBACK (replace_word), - spell); + mi = gtk_menu_item_new_with_mnemonic (_("_More...")); + gtk_widget_show (mi); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - count++; + menu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu); + count = 0; + } - suggestions = g_slist_next (suggestions); - } - } + label_text = g_strdup_printf ("%s", (gchar*) suggestions->data); - /* free the suggestion list */ - suggestions = list; + label = gtk_label_new (label_text); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_widget_set_halign (label, GTK_ALIGN_START); - while (list) - { - g_free (list->data); - list = g_slist_next (list); - } + mi = gtk_menu_item_new (); + gtk_container_add (GTK_CONTAINER (mi), label); - g_slist_free (suggestions); + gtk_widget_show_all (mi); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - /* Separator */ - mi = gtk_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); + g_object_set_qdata_full (G_OBJECT (mi), + suggestion_id, + g_strdup (suggestions->data), + (GDestroyNotify)g_free); - /* Ignore all */ - mi = gtk_image_menu_item_new_with_mnemonic (_("_Ignore All")); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), - gtk_image_new_from_stock (GTK_STOCK_GOTO_BOTTOM, - GTK_ICON_SIZE_MENU)); - - g_signal_connect (mi, - "activate", - G_CALLBACK(ignore_all), - spell); + g_free (label_text); + g_signal_connect (mi, "activate", + G_CALLBACK (replace_word), spell); - gtk_widget_show_all (mi); + count++; - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); + suggestions = g_slist_next (suggestions); + } + } - /* + Add to Dictionary */ - mi = gtk_image_menu_item_new_with_mnemonic (_("_Add")); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), - gtk_image_new_from_stock (GTK_STOCK_ADD, - GTK_ICON_SIZE_MENU)); + /* free the suggestion list */ + suggestions = list; - g_signal_connect (mi, - "activate", - G_CALLBACK (add_to_dictionary), - spell); + while (list) + { + g_free (list->data); + list = g_slist_next (list); + } - gtk_widget_show_all (mi); - - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); + g_slist_free (suggestions); - return topmenu; + /* Separator */ + mi = gtk_menu_item_new (); + gtk_widget_show (mi); + gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); + + /* Ignore all */ + mi = gtk_menu_item_new_with_mnemonic (_("_Ignore All")); + + g_signal_connect (mi, "activate", + G_CALLBACK(ignore_all), spell); + + gtk_widget_show_all (mi); + + gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); + + /* + Add to Dictionary */ + mi = gtk_menu_item_new_with_mnemonic (_("_Add")); + + g_signal_connect (mi, "activate", + G_CALLBACK (add_to_dictionary), spell); + + gtk_widget_show_all (mi); + + gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); + + return topmenu; } static void -populate_popup (GtkTextView *textview, GtkMenu *menu, XedAutomaticSpellChecker *spell) +populate_popup (GtkTextView *textview, + GtkMenu *menu, + XedAutomaticSpellChecker *spell) { - GtkWidget *img, *mi; - GtkTextIter start, end; - char *word; + GtkWidget *mi; + GtkTextIter start, end; + char *word; - /* we need to figure out if they picked a misspelled word. */ - get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); + /* we need to figure out if they picked a misspelled word. */ + get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); - /* if our highlight algorithm ever messes up, - * this isn't correct, either. */ - if (!gtk_text_iter_has_tag (&start, spell->tag_highlight)) - return; /* word wasn't misspelled. */ + /* if our highlight algorithm ever messes up, + * this isn't correct, either. */ + if (!gtk_text_iter_has_tag (&start, spell->tag_highlight)) + { + return; /* word wasn't misspelled. */ + } - /* menu separator comes first. */ - mi = gtk_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); + /* menu separator comes first. */ + mi = gtk_menu_item_new (); + gtk_widget_show (mi); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); - /* then, on top of it, the suggestions menu. */ - img = gtk_image_new_from_stock (GTK_STOCK_SPELL_CHECK, GTK_ICON_SIZE_MENU); - mi = gtk_image_menu_item_new_with_mnemonic (_("_Spelling Suggestions...")); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img); + /* then, on top of it, the suggestions menu. */ + mi = gtk_menu_item_new_with_mnemonic (_("_Spelling Suggestions...")); - word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), - build_suggestion_menu (spell, word)); - g_free(word); + word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), build_suggestion_menu (spell, word)); + g_free(word); - gtk_widget_show_all (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); + gtk_widget_show_all (mi); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); } void xed_automatic_spell_checker_recheck_all (XedAutomaticSpellChecker *spell) { - GtkTextIter start, end; + GtkTextIter start, end; - g_return_if_fail (spell != NULL); + g_return_if_fail (spell != NULL); - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (spell->doc), &start, &end); + gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (spell->doc), &start, &end); - check_range (spell, start, end, TRUE); + check_range (spell, start, end, TRUE); } -static void -add_word_signal_cb (XedSpellChecker *checker, - const gchar *word, - gint len, - XedAutomaticSpellChecker *spell) +static void +add_word_signal_cb (XedSpellChecker *checker, + const gchar *word, + gint len, + XedAutomaticSpellChecker *spell) { - gchar *w; + gchar *w; - if (len < 0) - w = g_strdup (word); - else - w = g_strndup (word, len); + if (len < 0) + { + w = g_strdup (word); + } + else + { + w = g_strndup (word, len); + } - remove_tag_to_word (spell, w); + remove_tag_to_word (spell, w); - g_free (w); + g_free (w); } -static void +static void set_language_cb (XedSpellChecker *checker, - const XedSpellCheckerLanguage *lang, - XedAutomaticSpellChecker *spell) + const XedSpellCheckerLanguage *lang, + XedAutomaticSpellChecker *spell) { - xed_automatic_spell_checker_recheck_all (spell); + xed_automatic_spell_checker_recheck_all (spell); } -static void +static void clear_session_cb (XedSpellChecker *checker, - XedAutomaticSpellChecker *spell) + XedAutomaticSpellChecker *spell) { - xed_automatic_spell_checker_recheck_all (spell); + xed_automatic_spell_checker_recheck_all (spell); } /* When the user right-clicks on a word, they want to check that word. * Here, we do NOT move the cursor to the location of the clicked-upon word - * since that prevents the use of edit functions on the context menu. + * since that prevents the use of edit functions on the context menu. */ static gboolean -button_press_event (GtkTextView *view, - GdkEventButton *event, - XedAutomaticSpellChecker *spell) +button_press_event (GtkTextView *view, + GdkEventButton *event, + XedAutomaticSpellChecker *spell) { - if (event->button == 3) - { - gint x, y; - GtkTextIter iter; + if (event->button == 3) + { + gint x, y; + GtkTextIter iter; - GtkTextBuffer *buffer = gtk_text_view_get_buffer (view); + GtkTextBuffer *buffer = gtk_text_view_get_buffer (view); - /* handle deferred check if it exists */ - if (spell->deferred_check) - check_deferred_range (spell, TRUE); + /* handle deferred check if it exists */ + if (spell->deferred_check) + { + check_deferred_range (spell, TRUE); + } - gtk_text_view_window_to_buffer_coords (view, - GTK_TEXT_WINDOW_TEXT, - event->x, event->y, - &x, &y); - - gtk_text_view_get_iter_at_location (view, &iter, x, y); + gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_TEXT, event->x, event->y, &x, &y); - gtk_text_buffer_move_mark (buffer, spell->mark_click, &iter); - } + gtk_text_view_get_iter_at_location (view, &iter, x, y); - return FALSE; /* false: let gtk process this event, too. - we don't want to eat any events. */ + gtk_text_buffer_move_mark (buffer, spell->mark_click, &iter); + } + + return FALSE; /* false: let gtk process this event, too. + we don't want to eat any events. */ } /* Move the insert mark before popping up the menu, otherwise it * will contain the wrong set of suggestions. */ static gboolean -popup_menu_event (GtkTextView *view, XedAutomaticSpellChecker *spell) +popup_menu_event (GtkTextView *view, + XedAutomaticSpellChecker *spell) { - GtkTextIter iter; - GtkTextBuffer *buffer; + GtkTextIter iter; + GtkTextBuffer *buffer; - buffer = gtk_text_view_get_buffer (view); + buffer = gtk_text_view_get_buffer (view); - /* handle deferred check if it exists */ - if (spell->deferred_check) - check_deferred_range (spell, TRUE); + /* handle deferred check if it exists */ + if (spell->deferred_check) + { + check_deferred_range (spell, TRUE); + } - gtk_text_buffer_get_iter_at_mark (buffer, &iter, - gtk_text_buffer_get_insert (buffer)); - gtk_text_buffer_move_mark (buffer, spell->mark_click, &iter); + gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer)); + gtk_text_buffer_move_mark (buffer, spell->mark_click, &iter); - return FALSE; + return FALSE; } static void -tag_table_changed (GtkTextTagTable *table, - XedAutomaticSpellChecker *spell) -{ - g_return_if_fail (spell->tag_highlight != NULL); - - gtk_text_tag_set_priority (spell->tag_highlight, - gtk_text_tag_table_get_size (table) - 1); -} - -static void -tag_added_or_removed (GtkTextTagTable *table, - GtkTextTag *tag, - XedAutomaticSpellChecker *spell) -{ - tag_table_changed (table, spell); -} - -static void -tag_changed (GtkTextTagTable *table, - GtkTextTag *tag, - gboolean size_changed, - XedAutomaticSpellChecker *spell) -{ - tag_table_changed (table, spell); -} - -static void -highlight_updated (GtkSourceBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end, +tag_table_changed (GtkTextTagTable *table, XedAutomaticSpellChecker *spell) { - check_range (spell, *start, *end, FALSE); + g_return_if_fail (spell->tag_highlight != NULL); + + gtk_text_tag_set_priority (spell->tag_highlight, gtk_text_tag_table_get_size (table) - 1); +} + +static void +tag_added_or_removed (GtkTextTagTable *table, + GtkTextTag *tag, + XedAutomaticSpellChecker *spell) +{ + tag_table_changed (table, spell); +} + +static void +tag_changed (GtkTextTagTable *table, + GtkTextTag *tag, + gboolean size_changed, + XedAutomaticSpellChecker *spell) +{ + tag_table_changed (table, spell); +} + +static void +highlight_updated (GtkSourceBuffer *buffer, + GtkTextIter *start, + GtkTextIter *end, + XedAutomaticSpellChecker *spell) +{ + check_range (spell, *start, *end, FALSE); } static void spell_tag_destroyed (XedAutomaticSpellChecker *spell, - GObject *where_the_object_was) + GObject *where_the_object_was) { - spell->tag_highlight = NULL; + spell->tag_highlight = NULL; } XedAutomaticSpellChecker * xed_automatic_spell_checker_new (XedDocument *doc, - XedSpellChecker *checker) + XedSpellChecker *checker) { - XedAutomaticSpellChecker *spell; - GtkTextTagTable *tag_table; - GtkTextIter start, end; + XedAutomaticSpellChecker *spell; + GtkTextTagTable *tag_table; + GtkTextIter start, end; - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - g_return_val_if_fail (XED_IS_SPELL_CHECKER (checker), NULL); - g_return_val_if_fail ((spell = xed_automatic_spell_checker_get_from_document (doc)) == NULL, - spell); - - /* attach to the widget */ - spell = g_new0 (XedAutomaticSpellChecker, 1); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + g_return_val_if_fail (XED_IS_SPELL_CHECKER (checker), NULL); + g_return_val_if_fail ((spell = xed_automatic_spell_checker_get_from_document (doc)) == NULL, spell); - spell->doc = doc; - spell->spell_checker = g_object_ref (checker); + /* attach to the widget */ + spell = g_new0 (XedAutomaticSpellChecker, 1); - if (automatic_spell_checker_id == 0) - { - automatic_spell_checker_id = - g_quark_from_string ("XedAutomaticSpellCheckerID"); - } - if (suggestion_id == 0) - { - suggestion_id = g_quark_from_string ("XedAutoSuggestionID"); - } + spell->doc = doc; + spell->spell_checker = g_object_ref (checker); - g_object_set_qdata_full (G_OBJECT (doc), - automatic_spell_checker_id, - spell, - (GDestroyNotify)xed_automatic_spell_checker_free_internal); + if (automatic_spell_checker_id == 0) + { + automatic_spell_checker_id = g_quark_from_string ("XedAutomaticSpellCheckerID"); + } + if (suggestion_id == 0) + { + suggestion_id = g_quark_from_string ("XedAutoSuggestionID"); + } - g_signal_connect (doc, - "insert-text", - G_CALLBACK (insert_text_before), - spell); - g_signal_connect_after (doc, - "insert-text", - G_CALLBACK (insert_text_after), - spell); - g_signal_connect_after (doc, - "delete-range", - G_CALLBACK (delete_range_after), - spell); - g_signal_connect (doc, - "mark-set", - G_CALLBACK (mark_set), - spell); + g_object_set_qdata_full (G_OBJECT (doc), automatic_spell_checker_id, + spell, (GDestroyNotify)xed_automatic_spell_checker_free_internal); - g_signal_connect (doc, - "highlight-updated", - G_CALLBACK (highlight_updated), - spell); + g_signal_connect (doc, "insert-text", + G_CALLBACK (insert_text_before), spell); + g_signal_connect_after (doc, "insert-text", + G_CALLBACK (insert_text_after), spell); + g_signal_connect_after (doc, "delete-range", + G_CALLBACK (delete_range_after), spell); + g_signal_connect (doc, "mark-set", + G_CALLBACK (mark_set), spell); - g_signal_connect (spell->spell_checker, - "add_word_to_session", - G_CALLBACK (add_word_signal_cb), - spell); - g_signal_connect (spell->spell_checker, - "add_word_to_personal", - G_CALLBACK (add_word_signal_cb), - spell); - g_signal_connect (spell->spell_checker, - "clear_session", - G_CALLBACK (clear_session_cb), - spell); - g_signal_connect (spell->spell_checker, - "set_language", - G_CALLBACK (set_language_cb), - spell); + g_signal_connect (doc, "highlight-updated", + G_CALLBACK (highlight_updated), spell); - spell->tag_highlight = gtk_text_buffer_create_tag ( - GTK_TEXT_BUFFER (doc), - "gtkspell-misspelled", - "underline", PANGO_UNDERLINE_ERROR, - NULL); + g_signal_connect (spell->spell_checker, "add_word_to_session", + G_CALLBACK (add_word_signal_cb), spell); + g_signal_connect (spell->spell_checker, "add_word_to_personal", + G_CALLBACK (add_word_signal_cb), spell); + g_signal_connect (spell->spell_checker, "clear_session", + G_CALLBACK (clear_session_cb), spell); + g_signal_connect (spell->spell_checker, "set_language", + G_CALLBACK (set_language_cb), spell); - g_object_weak_ref (G_OBJECT (spell->tag_highlight), - (GWeakNotify)spell_tag_destroyed, - spell); + spell->tag_highlight = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (doc), + "gtkspell-misspelled", + "underline", PANGO_UNDERLINE_ERROR, + NULL); - tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (doc)); + g_object_weak_ref (G_OBJECT (spell->tag_highlight), (GWeakNotify)spell_tag_destroyed, spell); - gtk_text_tag_set_priority (spell->tag_highlight, - gtk_text_tag_table_get_size (tag_table) - 1); + tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (doc)); - g_signal_connect (tag_table, - "tag-added", - G_CALLBACK (tag_added_or_removed), - spell); - g_signal_connect (tag_table, - "tag-removed", - G_CALLBACK (tag_added_or_removed), - spell); - g_signal_connect (tag_table, - "tag-changed", - G_CALLBACK (tag_changed), - spell); + gtk_text_tag_set_priority (spell->tag_highlight, gtk_text_tag_table_get_size (tag_table) - 1); - /* we create the mark here, but we don't use it until text is - * inserted, so we don't really care where iter points. */ - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), &start, &end); - - spell->mark_insert_start = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-insert-start"); + g_signal_connect (tag_table, "tag-added", + G_CALLBACK (tag_added_or_removed), spell); + g_signal_connect (tag_table, "tag-removed", + G_CALLBACK (tag_added_or_removed), spell); + g_signal_connect (tag_table, "tag-changed", + G_CALLBACK (tag_changed), spell); - if (spell->mark_insert_start == NULL) - { - spell->mark_insert_start = - gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-insert-start", - &start, - TRUE); - } - else - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), - spell->mark_insert_start, - &start); - } + /* we create the mark here, but we don't use it until text is + * inserted, so we don't really care where iter points. */ + gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), &start, &end); - spell->mark_insert_end = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-insert-end"); + spell->mark_insert_start = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), + "xed-automatic-spell-checker-insert-start"); - if (spell->mark_insert_end == NULL) - { - spell->mark_insert_end = - gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-insert-end", - &start, - TRUE); - } - else - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), - spell->mark_insert_end, - &start); - } + if (spell->mark_insert_start == NULL) + { + spell->mark_insert_start = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), + "xed-automatic-spell-checker-insert-start", + &start, + TRUE); + } + else + { + gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), spell->mark_insert_start, &start); + } - spell->mark_click = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-click"); + spell->mark_insert_end = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), + "xed-automatic-spell-checker-insert-end"); - if (spell->mark_click == NULL) - { - spell->mark_click = - gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-click", - &start, - TRUE); - } - else - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), - spell->mark_click, - &start); - } + if (spell->mark_insert_end == NULL) + { + spell->mark_insert_end = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), + "xed-automatic-spell-checker-insert-end", + &start, + TRUE); + } + else + { + gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), spell->mark_insert_end, &start); + } - spell->deferred_check = FALSE; + spell->mark_click = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), + "xed-automatic-spell-checker-click"); - return spell; + if (spell->mark_click == NULL) + { + spell->mark_click = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), + "xed-automatic-spell-checker-click", + &start, + TRUE); + } + else + { + gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), spell->mark_click, &start); + } + + spell->deferred_check = FALSE; + + return spell; } XedAutomaticSpellChecker * xed_automatic_spell_checker_get_from_document (const XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - if (automatic_spell_checker_id == 0) - return NULL; + if (automatic_spell_checker_id == 0) + { + return NULL; + } - return g_object_get_qdata (G_OBJECT (doc), automatic_spell_checker_id); -} + return g_object_get_qdata (G_OBJECT (doc), automatic_spell_checker_id); +} void xed_automatic_spell_checker_free (XedAutomaticSpellChecker *spell) { - g_return_if_fail (spell != NULL); - g_return_if_fail (xed_automatic_spell_checker_get_from_document (spell->doc) == spell); - - if (automatic_spell_checker_id == 0) - return; + g_return_if_fail (spell != NULL); + g_return_if_fail (xed_automatic_spell_checker_get_from_document (spell->doc) == spell); - g_object_set_qdata (G_OBJECT (spell->doc), automatic_spell_checker_id, NULL); + if (automatic_spell_checker_id == 0) + { + return; + } + + g_object_set_qdata (G_OBJECT (spell->doc), automatic_spell_checker_id, NULL); } static void xed_automatic_spell_checker_free_internal (XedAutomaticSpellChecker *spell) { - GtkTextTagTable *table; - GtkTextIter start, end; - GSList *list; - - g_return_if_fail (spell != NULL); + GtkTextTagTable *table; + GtkTextIter start, end; + GSList *list; - table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (spell->doc)); + g_return_if_fail (spell != NULL); - if (table != NULL && spell->tag_highlight != NULL) - { - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (spell->doc), - &start, - &end); - gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), - spell->tag_highlight, - &start, - &end); + table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (spell->doc)); - g_signal_handlers_disconnect_matched (G_OBJECT (table), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); + if (table != NULL && spell->tag_highlight != NULL) + { + gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (spell->doc), &start, &end); + gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), spell->tag_highlight, &start, &end); - gtk_text_tag_table_remove (table, spell->tag_highlight); - } - - g_signal_handlers_disconnect_matched (G_OBJECT (spell->doc), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); + g_signal_handlers_disconnect_matched (G_OBJECT (table), + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, + spell); - g_signal_handlers_disconnect_matched (G_OBJECT (spell->spell_checker), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); + gtk_text_tag_table_remove (table, spell->tag_highlight); + } - g_object_unref (spell->spell_checker); + g_signal_handlers_disconnect_matched (G_OBJECT (spell->doc), + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, + spell); - list = spell->views; - while (list != NULL) - { - XedView *view = XED_VIEW (list->data); - - g_signal_handlers_disconnect_matched (G_OBJECT (view), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); + g_signal_handlers_disconnect_matched (G_OBJECT (spell->spell_checker), + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, + spell); - g_signal_handlers_disconnect_matched (G_OBJECT (view), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); + g_object_unref (spell->spell_checker); - list = g_slist_next (list); - } + list = spell->views; + while (list != NULL) + { + XedView *view = XED_VIEW (list->data); - g_slist_free (spell->views); - - g_free (spell); + g_signal_handlers_disconnect_matched (G_OBJECT (view), + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, + spell); + + g_signal_handlers_disconnect_matched (G_OBJECT (view), + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, + spell); + + list = g_slist_next (list); + } + + g_slist_free (spell->views); + + g_free (spell); } void -xed_automatic_spell_checker_attach_view ( - XedAutomaticSpellChecker *spell, - XedView *view) +xed_automatic_spell_checker_attach_view (XedAutomaticSpellChecker *spell, + XedView *view) { - g_return_if_fail (spell != NULL); - g_return_if_fail (XED_IS_VIEW (view)); + g_return_if_fail (spell != NULL); + g_return_if_fail (XED_IS_VIEW (view)); - g_return_if_fail (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)) == - GTK_TEXT_BUFFER (spell->doc)); + g_return_if_fail (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)) == GTK_TEXT_BUFFER (spell->doc)); - g_signal_connect (view, - "button-press-event", - G_CALLBACK (button_press_event), - spell); - g_signal_connect (view, - "popup-menu", - G_CALLBACK (popup_menu_event), - spell); - g_signal_connect (view, - "populate-popup", - G_CALLBACK (populate_popup), - spell); - g_signal_connect (view, - "destroy", - G_CALLBACK (view_destroy), - spell); + g_signal_connect (view, "button-press-event", + G_CALLBACK (button_press_event), spell); + g_signal_connect (view, "popup-menu", + G_CALLBACK (popup_menu_event), spell); + g_signal_connect (view, "populate-popup", + G_CALLBACK (populate_popup), spell); + g_signal_connect (view, "destroy", + G_CALLBACK (view_destroy), spell); - spell->views = g_slist_prepend (spell->views, view); + spell->views = g_slist_prepend (spell->views, view); } -void -xed_automatic_spell_checker_detach_view ( - XedAutomaticSpellChecker *spell, - XedView *view) +void +xed_automatic_spell_checker_detach_view (XedAutomaticSpellChecker *spell, + XedView *view) { - g_return_if_fail (spell != NULL); - g_return_if_fail (XED_IS_VIEW (view)); + g_return_if_fail (spell != NULL); + g_return_if_fail (XED_IS_VIEW (view)); - g_return_if_fail (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)) == - GTK_TEXT_BUFFER (spell->doc)); - g_return_if_fail (spell->views != NULL); + g_return_if_fail (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)) == GTK_TEXT_BUFFER (spell->doc)); + g_return_if_fail (spell->views != NULL); - g_signal_handlers_disconnect_matched (G_OBJECT (view), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); + g_signal_handlers_disconnect_matched (G_OBJECT (view), + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, + spell); - g_signal_handlers_disconnect_matched (G_OBJECT (view), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); + g_signal_handlers_disconnect_matched (G_OBJECT (view), + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, + spell); - spell->views = g_slist_remove (spell->views, view); + spell->views = g_slist_remove (spell->views, view); } diff --git a/plugins/spell/xed-spell-language-dialog.c b/plugins/spell/xed-spell-language-dialog.c index b0d9029..452447a 100644 --- a/plugins/spell/xed-spell-language-dialog.c +++ b/plugins/spell/xed-spell-language-dialog.c @@ -3,7 +3,7 @@ * xed-spell-language-dialog.c * This file is part of xed * - * Copyright (C) 2002 Paolo Maggi + * Copyright (C) 2002 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,14 +17,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2002. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ #ifdef HAVE_CONFIG_H @@ -34,275 +34,251 @@ #include #include #include -#include +#include #include "xed-spell-language-dialog.h" #include "xed-spell-checker-language.h" enum { - COLUMN_LANGUAGE_NAME = 0, - COLUMN_LANGUAGE_POINTER, - ENCODING_NUM_COLS + COLUMN_LANGUAGE_NAME = 0, + COLUMN_LANGUAGE_POINTER, + ENCODING_NUM_COLS }; -struct _XedSpellLanguageDialog +struct _XedSpellLanguageDialog { - GtkDialog dialog; + GtkDialog dialog; - GtkWidget *languages_treeview; - GtkTreeModel *model; + GtkWidget *languages_treeview; + GtkTreeModel *model; }; -G_DEFINE_TYPE(XedSpellLanguageDialog, xed_spell_language_dialog, GTK_TYPE_DIALOG) +G_DEFINE_TYPE (XedSpellLanguageDialog, xed_spell_language_dialog, GTK_TYPE_DIALOG) -static void +static void xed_spell_language_dialog_class_init (XedSpellLanguageDialogClass *klass) { - /* GObjectClass *object_class = G_OBJECT_CLASS (klass); */ + /* GObjectClass *object_class = G_OBJECT_CLASS (klass); */ } static void dialog_response_handler (GtkDialog *dlg, - gint res_id) + gint res_id) { - if (res_id == GTK_RESPONSE_HELP) - { - xed_help_display (GTK_WINDOW (dlg), - NULL, - "xed-spell-checker-plugin"); + if (res_id == GTK_RESPONSE_HELP) + { + xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-spell-checker-plugin"); - g_signal_stop_emission_by_name (dlg, "response"); - } -} - -static void -scroll_to_selected (GtkTreeView *tree_view) -{ - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - - model = gtk_tree_view_get_model (tree_view); - g_return_if_fail (model != NULL); - - /* Scroll to selected */ - selection = gtk_tree_view_get_selection (tree_view); - g_return_if_fail (selection != NULL); - - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - GtkTreePath* path; - - path = gtk_tree_model_get_path (model, &iter); - g_return_if_fail (path != NULL); - - gtk_tree_view_scroll_to_cell (tree_view, - path, NULL, TRUE, 1.0, 0.0); - gtk_tree_path_free (path); - } + g_signal_stop_emission_by_name (dlg, "response"); + } } static void -language_row_activated (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - XedSpellLanguageDialog *dialog) +scroll_to_selected (GtkTreeView *tree_view) { - gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + + model = gtk_tree_view_get_model (tree_view); + g_return_if_fail (model != NULL); + + /* Scroll to selected */ + selection = gtk_tree_view_get_selection (tree_view); + g_return_if_fail (selection != NULL); + + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + GtkTreePath* path; + + path = gtk_tree_model_get_path (model, &iter); + g_return_if_fail (path != NULL); + + gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 1.0, 0.0); + gtk_tree_path_free (path); + } +} + +static void +language_row_activated (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + XedSpellLanguageDialog *dialog) +{ + gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); } static void create_dialog (XedSpellLanguageDialog *dlg, - const gchar *data_dir) + const gchar *data_dir) { - GtkWidget *error_widget; - GtkWidget *content; - gboolean ret; - GtkCellRenderer *cell; - GtkTreeViewColumn *column; - gchar *ui_file; - gchar *root_objects[] = { - "content", - NULL - }; - - gtk_dialog_add_buttons (GTK_DIALOG (dlg), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, - GTK_RESPONSE_OK, - GTK_STOCK_HELP, - GTK_RESPONSE_HELP, - NULL); + GtkWidget *error_widget; + GtkWidget *content; + gboolean ret; + GtkCellRenderer *cell; + GtkTreeViewColumn *column; + gchar *ui_file; + gchar *root_objects[] = { + "content", + NULL + }; - gtk_window_set_title (GTK_WINDOW (dlg), _("Set language")); - gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); - gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE); + gtk_dialog_add_buttons (GTK_DIALOG (dlg), + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_OK"), GTK_RESPONSE_OK, + _("_Help"), GTK_RESPONSE_HELP, + NULL); - /* HIG defaults */ - gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - 2); /* 2 * 5 + 2 = 12 */ - gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), - 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), - 6); + gtk_window_set_title (GTK_WINDOW (dlg), _("Set language")); + gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); + gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE); - g_signal_connect (dlg, - "response", - G_CALLBACK (dialog_response_handler), - NULL); + /* HIG defaults */ + gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), 2); + gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 5); + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 6); - ui_file = g_build_filename (data_dir, "languages-dialog.ui", NULL); - ret = xed_utils_get_ui_objects (ui_file, - root_objects, - &error_widget, - "content", &content, - "languages_treeview", &dlg->languages_treeview, - NULL); - g_free (ui_file); - - if (!ret) - { - gtk_widget_show (error_widget); + g_signal_connect (dlg, "response", + G_CALLBACK (dialog_response_handler), NULL); - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - error_widget, - TRUE, TRUE, 0); + ui_file = g_build_filename (data_dir, "languages-dialog.ui", NULL); + ret = xed_utils_get_ui_objects (ui_file, + root_objects, + &error_widget, + "content", &content, + "languages_treeview", &dlg->languages_treeview, + NULL); + g_free (ui_file); - return; - } + if (!ret) + { + gtk_widget_show (error_widget); - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - content, TRUE, TRUE, 0); - g_object_unref (content); - gtk_container_set_border_width (GTK_CONTAINER (content), 5); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), error_widget, TRUE, TRUE, 0); - dlg->model = GTK_TREE_MODEL (gtk_list_store_new (ENCODING_NUM_COLS, - G_TYPE_STRING, - G_TYPE_POINTER)); + return; + } - gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->languages_treeview), - dlg->model); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), content, TRUE, TRUE, 0); + g_object_unref (content); + gtk_container_set_border_width (GTK_CONTAINER (content), 5); - g_object_unref (dlg->model); + dlg->model = GTK_TREE_MODEL (gtk_list_store_new (ENCODING_NUM_COLS, G_TYPE_STRING, G_TYPE_POINTER)); - /* Add the encoding column */ - cell = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("Languages"), - cell, - "text", - COLUMN_LANGUAGE_NAME, - NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->languages_treeview), - column); + gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->languages_treeview), dlg->model); - gtk_tree_view_set_search_column (GTK_TREE_VIEW (dlg->languages_treeview), - COLUMN_LANGUAGE_NAME); + g_object_unref (dlg->model); - g_signal_connect (dlg->languages_treeview, - "realize", - G_CALLBACK (scroll_to_selected), - dlg); - g_signal_connect (dlg->languages_treeview, - "row-activated", - G_CALLBACK (language_row_activated), - dlg); + /* Add the encoding column */ + cell = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Languages"), + cell, + "text", + COLUMN_LANGUAGE_NAME, + NULL); + + gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->languages_treeview), column); + + gtk_tree_view_set_search_column (GTK_TREE_VIEW (dlg->languages_treeview), COLUMN_LANGUAGE_NAME); + + g_signal_connect (dlg->languages_treeview, "realize", + G_CALLBACK (scroll_to_selected), dlg); + g_signal_connect (dlg->languages_treeview, "row-activated", + G_CALLBACK (language_row_activated), dlg); } static void xed_spell_language_dialog_init (XedSpellLanguageDialog *dlg) { - + } static void populate_language_list (XedSpellLanguageDialog *dlg, - const XedSpellCheckerLanguage *cur_lang) + const XedSpellCheckerLanguage *cur_lang) { - GtkListStore *store; - GtkTreeIter iter; + GtkListStore *store; + GtkTreeIter iter; - const GSList* langs; + const GSList* langs; - /* create list store */ - store = GTK_LIST_STORE (dlg->model); + /* create list store */ + store = GTK_LIST_STORE (dlg->model); - langs = xed_spell_checker_get_available_languages (); + langs = xed_spell_checker_get_available_languages (); - while (langs) - { - const gchar *name; + while (langs) + { + const gchar *name; - name = xed_spell_checker_language_to_string ((const XedSpellCheckerLanguage*)langs->data); + name = xed_spell_checker_language_to_string ((const XedSpellCheckerLanguage*)langs->data); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COLUMN_LANGUAGE_NAME, name, - COLUMN_LANGUAGE_POINTER, langs->data, - -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + COLUMN_LANGUAGE_NAME, name, + COLUMN_LANGUAGE_POINTER, langs->data, + -1); - if (langs->data == cur_lang) - { - GtkTreeSelection *selection; + if (langs->data == cur_lang) + { + GtkTreeSelection *selection; - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->languages_treeview)); - g_return_if_fail (selection != NULL); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->languages_treeview)); + g_return_if_fail (selection != NULL); - gtk_tree_selection_select_iter (selection, &iter); - } + gtk_tree_selection_select_iter (selection, &iter); + } - langs = g_slist_next (langs); - } + langs = g_slist_next (langs); + } } GtkWidget * -xed_spell_language_dialog_new (GtkWindow *parent, - const XedSpellCheckerLanguage *cur_lang, - const gchar *data_dir) +xed_spell_language_dialog_new (GtkWindow *parent, + const XedSpellCheckerLanguage *cur_lang, + const gchar *data_dir) { - XedSpellLanguageDialog *dlg; + XedSpellLanguageDialog *dlg; - g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL); + g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL); - dlg = g_object_new (XED_TYPE_SPELL_LANGUAGE_DIALOG, NULL); + dlg = g_object_new (XED_TYPE_SPELL_LANGUAGE_DIALOG, NULL); - create_dialog (dlg, data_dir); + create_dialog (dlg, data_dir); - populate_language_list (dlg, cur_lang); + populate_language_list (dlg, cur_lang); - gtk_window_set_transient_for (GTK_WINDOW (dlg), parent); - gtk_widget_grab_focus (dlg->languages_treeview); + gtk_window_set_transient_for (GTK_WINDOW (dlg), parent); + gtk_widget_grab_focus (dlg->languages_treeview); - return GTK_WIDGET (dlg); + return GTK_WIDGET (dlg); } const XedSpellCheckerLanguage * xed_spell_language_get_selected_language (XedSpellLanguageDialog *dlg) { - GValue value = {0, }; - const XedSpellCheckerLanguage* lang; + GValue value = {0, }; + const XedSpellCheckerLanguage* lang; - GtkTreeIter iter; - GtkTreeSelection *selection; + GtkTreeIter iter; + GtkTreeSelection *selection; - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->languages_treeview)); - g_return_val_if_fail (selection != NULL, NULL); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->languages_treeview)); + g_return_val_if_fail (selection != NULL, NULL); - if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) - return NULL; + if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + return NULL; + } - gtk_tree_model_get_value (dlg->model, - &iter, - COLUMN_LANGUAGE_POINTER, - &value); + gtk_tree_model_get_value (dlg->model, &iter, COLUMN_LANGUAGE_POINTER, &value); - lang = (const XedSpellCheckerLanguage* ) g_value_get_pointer (&value); + lang = (const XedSpellCheckerLanguage* ) g_value_get_pointer (&value); - return lang; + return lang; } diff --git a/plugins/spell/xed-spell-language-dialog.h b/plugins/spell/xed-spell-language-dialog.h index 488040c..b11c454 100644 --- a/plugins/spell/xed-spell-language-dialog.h +++ b/plugins/spell/xed-spell-language-dialog.h @@ -3,7 +3,7 @@ * xed-spell-language-dialog.h * This file is part of xed * - * Copyright (C) 2002 Paolo Maggi + * Copyright (C) 2002 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,14 +17,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2002. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ #ifndef __XED_SPELL_LANGUAGE_DIALOG_H__ @@ -44,22 +44,20 @@ G_BEGIN_DECLS typedef struct _XedSpellLanguageDialog XedSpellLanguageDialog; - typedef struct _XedSpellLanguageDialogClass XedSpellLanguageDialogClass; -struct _XedSpellLanguageDialogClass +struct _XedSpellLanguageDialogClass { - GtkDialogClass parent_class; + GtkDialogClass parent_class; }; -GType xed_spell_language_dialog_get_type (void) G_GNUC_CONST; +GType xed_spell_language_dialog_get_type (void) G_GNUC_CONST; -GtkWidget *xed_spell_language_dialog_new (GtkWindow *parent, - const XedSpellCheckerLanguage *cur_lang, - const gchar *data_dir); +GtkWidget *xed_spell_language_dialog_new (GtkWindow *parent, + const XedSpellCheckerLanguage *cur_lang, + const gchar *data_dir); -const XedSpellCheckerLanguage * - xed_spell_language_get_selected_language (XedSpellLanguageDialog *dlg); +const XedSpellCheckerLanguage *xed_spell_language_get_selected_language (XedSpellLanguageDialog *dlg); G_END_DECLS diff --git a/plugins/spell/xed-spell-plugin.c b/plugins/spell/xed-spell-plugin.c index 32ac6eb..5dd72f9 100644 --- a/plugins/spell/xed-spell-plugin.c +++ b/plugins/spell/xed-spell-plugin.c @@ -1,13 +1,13 @@ /* * xed-spell-plugin.c - * - * Copyright (C) 2002-2005 Paolo Maggi + * + * Copyright (C) 2002-2005 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -16,8 +16,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -29,14 +27,15 @@ #include /* For strlen */ -#include -#include +#include +#include +#include +#include #include -#include -#include #include #include +#include #include "xed-spell-checker.h" #include "xed-spell-checker-dialog.h" @@ -46,1446 +45,1391 @@ #define XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE "metadata::xed-spell-language" #define XED_METADATA_ATTRIBUTE_SPELL_ENABLED "metadata::xed-spell-enabled" -#define WINDOW_DATA_KEY "XedSpellPluginWindowData" +#define XED_AUTOMATIC_SPELL_VIEW "XedAutomaticSpellView" + #define MENU_PATH "/MenuBar/ToolsMenu/ToolsOps_1" #define XED_SPELL_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_SPELL_PLUGIN, \ - XedSpellPluginPrivate)) + XED_TYPE_SPELL_PLUGIN, \ + XedSpellPluginPrivate)) /* GSettings keys */ -#define SPELL_SCHEMA "org.x.editor.plugins.spell" -#define AUTOCHECK_TYPE_KEY "autocheck-type" +#define SPELL_SCHEMA "org.x.editor.plugins.spell" +#define AUTOCHECK_TYPE_KEY "autocheck-type" -XED_PLUGIN_REGISTER_TYPE(XedSpellPlugin, xed_spell_plugin) +static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface); +static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface); -typedef struct -{ - GtkActionGroup *action_group; - guint ui_id; - guint message_cid; - gulong tab_added_id; - gulong tab_removed_id; - XedSpellPlugin *plugin; -} WindowData; - -typedef struct -{ - XedPlugin *plugin; - XedWindow *window; -} ActionData; +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedSpellPlugin, + xed_spell_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, + xed_window_activatable_iface_init) + G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE, + peas_gtk_configurable_iface_init)) struct _XedSpellPluginPrivate { - GSettings *settings; + XedWindow *window; + + GtkActionGroup *action_group; + guint ui_id; + guint message_cid; + gulong tab_added_id; + gulong tab_removed_id; + + GSettings *settings; }; -static void spell_cb (GtkAction *action, ActionData *action_data); -static void set_language_cb (GtkAction *action, ActionData *action_data); -static void auto_spell_cb (GtkAction *action, XedWindow *window); - -/* UI actions. */ -static const GtkActionEntry action_entries[] = -{ - { "CheckSpell", - "tools-check-spelling-symbolic", - N_("_Check Spelling..."), - "F7", - N_("Check the current document for incorrect spelling"), - G_CALLBACK (spell_cb) - }, - - { "ConfigSpell", - NULL, - N_("Set _Language..."), - NULL, - N_("Set the language of the current document"), - G_CALLBACK (set_language_cb) - } -}; - -static const GtkToggleActionEntry toggle_action_entries[] = -{ - { "AutoSpell", - NULL, - N_("_Autocheck Spelling"), - NULL, - N_("Automatically spell-check the current document"), - G_CALLBACK (auto_spell_cb), - FALSE - } -}; - -typedef struct _SpellConfigureDialog SpellConfigureDialog; - -struct _SpellConfigureDialog -{ - GtkWidget *dialog; - - GtkWidget *never; - GtkWidget *always; - GtkWidget *document; - - XedSpellPlugin *plugin; -}; - -typedef enum -{ - AUTOCHECK_NEVER = 0, - AUTOCHECK_DOCUMENT, - AUTOCHECK_ALWAYS -} XedSpellPluginAutocheckType; - typedef struct _CheckRange CheckRange; struct _CheckRange { - GtkTextMark *start_mark; - GtkTextMark *end_mark; + GtkTextMark *start_mark; + GtkTextMark *end_mark; - gint mw_start; /* misspelled word start */ - gint mw_end; /* end */ + gint mw_start; /* misspelled word start */ + gint mw_end; /* end */ - GtkTextMark *current_mark; + GtkTextMark *current_mark; }; +enum +{ + PROP_0, + PROP_WINDOW +}; + +static void spell_cb (GtkAction *action, + XedSpellPlugin *plugin); +static void set_language_cb (GtkAction *action, + XedSpellPlugin *plugin); +static void auto_spell_cb (GtkAction *action, + XedSpellPlugin *plugin); + +/* UI actions. */ +static const GtkActionEntry action_entries[] = +{ + { "CheckSpell", + "tools-check-spelling-symbolic", + N_("_Check Spelling..."), + "F7", + N_("Check the current document for incorrect spelling"), + G_CALLBACK (spell_cb) + }, + + { "ConfigSpell", + NULL, + N_("Set _Language..."), + NULL, + N_("Set the language of the current document"), + G_CALLBACK (set_language_cb) + } +}; + +static const GtkToggleActionEntry toggle_action_entries[] = +{ + { "AutoSpell", + NULL, + N_("_Autocheck Spelling"), + NULL, + N_("Automatically spell-check the current document"), + G_CALLBACK (auto_spell_cb), + FALSE + } +}; + +typedef struct _SpellConfigureWidget SpellConfigureWidget; + +struct _SpellConfigureWidget +{ + GtkWidget *content; + + GtkWidget *never; + GtkWidget *always; + GtkWidget *document; + + GSettings *settings; +}; + +typedef enum +{ + AUTOCHECK_NEVER = 0, + AUTOCHECK_DOCUMENT, + AUTOCHECK_ALWAYS +} XedSpellPluginAutocheckType; + + + static GQuark spell_checker_id = 0; static GQuark check_range_id = 0; static void xed_spell_plugin_init (XedSpellPlugin *plugin) { - xed_debug_message (DEBUG_PLUGINS, "XedSpellPlugin initializing"); + xed_debug_message (DEBUG_PLUGINS, "XedSpellPlugin initializing"); - plugin->priv = XED_SPELL_PLUGIN_GET_PRIVATE (plugin); + plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin, XED_TYPE_SPELL_PLUGIN, XedSpellPluginPrivate); - plugin->priv->settings = g_settings_new (SPELL_SCHEMA); + plugin->priv->settings = g_settings_new (SPELL_SCHEMA); } static void -xed_spell_plugin_finalize (GObject *object) +xed_spell_plugin_dispose (GObject *object) { - XedSpellPlugin *plugin = XED_SPELL_PLUGIN (object); + XedSpellPlugin *plugin = XED_SPELL_PLUGIN (object); - xed_debug_message (DEBUG_PLUGINS, "XedSpellPlugin finalizing"); + xed_debug_message (DEBUG_PLUGINS, "XedSpellPlugin disposing"); - g_object_unref (G_OBJECT (plugin->priv->settings)); + g_clear_object (&plugin->priv->settings); + g_clear_object (&plugin->priv->window); + g_clear_object (&plugin->priv->action_group); + g_clear_object (&plugin->priv->settings); - G_OBJECT_CLASS (xed_spell_plugin_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_spell_plugin_parent_class)->dispose (object); } -static void -set_spell_language_cb (XedSpellChecker *spell, - const XedSpellCheckerLanguage *lang, - XedDocument *doc) + +static void +xed_spell_plugin_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - const gchar *key; + XedSpellPlugin *plugin = XED_SPELL_PLUGIN (object); - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (lang != NULL); + switch (prop_id) + { + case PROP_WINDOW: + plugin->priv->window = XED_WINDOW (g_value_dup_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} - key = xed_spell_checker_language_to_key (lang); - g_return_if_fail (key != NULL); +static void +xed_spell_plugin_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XedSpellPlugin *plugin = XED_SPELL_PLUGIN (object); - xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, - key, NULL); + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, plugin->priv->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +set_spell_language_cb (XedSpellChecker *spell, + const XedSpellCheckerLanguage *lang, + XedDocument *doc) +{ + const gchar *key; + + g_return_if_fail (XED_IS_DOCUMENT (doc)); + g_return_if_fail (lang != NULL); + + key = xed_spell_checker_language_to_key (lang); + g_return_if_fail (key != NULL); + + xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, key, NULL); } static void set_language_from_metadata (XedSpellChecker *spell, - XedDocument *doc) + XedDocument *doc) { - const XedSpellCheckerLanguage *lang = NULL; - gchar *value = NULL; + const XedSpellCheckerLanguage *lang = NULL; + gchar *value = NULL; - value = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE); + value = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE); - if (value != NULL) - { - lang = xed_spell_checker_language_from_key (value); - g_free (value); - } + if (value != NULL) + { + lang = xed_spell_checker_language_from_key (value); + g_free (value); + } - if (lang != NULL) - { - g_signal_handlers_block_by_func (spell, set_spell_language_cb, doc); - xed_spell_checker_set_language (spell, lang); - g_signal_handlers_unblock_by_func (spell, set_spell_language_cb, doc); - } + if (lang != NULL) + { + g_signal_handlers_block_by_func (spell, set_spell_language_cb, doc); + xed_spell_checker_set_language (spell, lang); + g_signal_handlers_unblock_by_func (spell, set_spell_language_cb, doc); + } } static XedSpellPluginAutocheckType get_autocheck_type (XedSpellPlugin *plugin) { - XedSpellPluginAutocheckType autocheck_type; + XedSpellPluginAutocheckType autocheck_type; - autocheck_type = g_settings_get_enum (plugin->priv->settings, - AUTOCHECK_TYPE_KEY); + autocheck_type = g_settings_get_enum (plugin->priv->settings, AUTOCHECK_TYPE_KEY); - return autocheck_type; + return autocheck_type; } static void -set_autocheck_type (XedSpellPlugin *plugin, - XedSpellPluginAutocheckType autocheck_type) +set_autocheck_type (GSettings *settings, + XedSpellPluginAutocheckType autocheck_type) { - if (!g_settings_is_writable (plugin->priv->settings, - AUTOCHECK_TYPE_KEY)) - { - return; - } + if (!g_settings_is_writable (settings, AUTOCHECK_TYPE_KEY)) + { + return; + } - g_settings_set_enum (plugin->priv->settings, - AUTOCHECK_TYPE_KEY, - autocheck_type); + g_settings_set_enum (settings, AUTOCHECK_TYPE_KEY, autocheck_type); } static XedSpellChecker * get_spell_checker_from_document (XedDocument *doc) { - XedSpellChecker *spell; - gpointer data; + XedSpellChecker *spell; + gpointer data; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_val_if_fail (doc != NULL, NULL); + g_return_val_if_fail (doc != NULL, NULL); - data = g_object_get_qdata (G_OBJECT (doc), spell_checker_id); + data = g_object_get_qdata (G_OBJECT (doc), spell_checker_id); - if (data == NULL) - { - spell = xed_spell_checker_new (); + if (data == NULL) + { + spell = xed_spell_checker_new (); - set_language_from_metadata (spell, doc); + set_language_from_metadata (spell, doc); - g_object_set_qdata_full (G_OBJECT (doc), - spell_checker_id, - spell, - (GDestroyNotify) g_object_unref); + g_object_set_qdata_full (G_OBJECT (doc), + spell_checker_id, + spell, + (GDestroyNotify) g_object_unref); - g_signal_connect (spell, - "set_language", - G_CALLBACK (set_spell_language_cb), - doc); - } - else - { - g_return_val_if_fail (XED_IS_SPELL_CHECKER (data), NULL); - spell = XED_SPELL_CHECKER (data); - } + g_signal_connect (spell, "set_language", + G_CALLBACK (set_spell_language_cb), doc); + } + else + { + g_return_val_if_fail (XED_IS_SPELL_CHECKER (data), NULL); + spell = XED_SPELL_CHECKER (data); + } - return spell; + return spell; } static CheckRange * get_check_range (XedDocument *doc) { - CheckRange *range; + CheckRange *range; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_val_if_fail (doc != NULL, NULL); + g_return_val_if_fail (doc != NULL, NULL); - range = (CheckRange *) g_object_get_qdata (G_OBJECT (doc), check_range_id); + range = (CheckRange *) g_object_get_qdata (G_OBJECT (doc), check_range_id); - return range; + return range; } static void update_current (XedDocument *doc, - gint current) + gint current) { - CheckRange *range; - GtkTextIter iter; - GtkTextIter end_iter; + CheckRange *range; + GtkTextIter iter; + GtkTextIter end_iter; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_if_fail (doc != NULL); - g_return_if_fail (current >= 0); + g_return_if_fail (doc != NULL); + g_return_if_fail (current >= 0); - range = get_check_range (doc); - g_return_if_fail (range != NULL); + range = get_check_range (doc); + g_return_if_fail (range != NULL); - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), - &iter, current); + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &iter, current); - if (!gtk_text_iter_inside_word (&iter)) - { - /* if we're not inside a word, - * we must be in some spaces. - * skip forward to the beginning of the next word. */ - if (!gtk_text_iter_is_end (&iter)) - { - gtk_text_iter_forward_word_end (&iter); - gtk_text_iter_backward_word_start (&iter); - } - } - else - { - if (!gtk_text_iter_starts_word (&iter)) - gtk_text_iter_backward_word_start (&iter); - } + if (!gtk_text_iter_inside_word (&iter)) + { + /* if we're not inside a word, + * we must be in some spaces. + * skip forward to the beginning of the next word. */ + if (!gtk_text_iter_is_end (&iter)) + { + gtk_text_iter_forward_word_end (&iter); + gtk_text_iter_backward_word_start (&iter); + } + } + else + { + if (!gtk_text_iter_starts_word (&iter)) + { + gtk_text_iter_backward_word_start (&iter); + } + } - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), - &end_iter, - range->end_mark); + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &end_iter, range->end_mark); - if (gtk_text_iter_compare (&end_iter, &iter) < 0) - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), - range->current_mark, - &end_iter); - } - else - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), - range->current_mark, - &iter); - } + if (gtk_text_iter_compare (&end_iter, &iter) < 0) + { + gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->current_mark, &end_iter); + } + else + { + gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->current_mark, &iter); + } } static void set_check_range (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end) + GtkTextIter *start, + GtkTextIter *end) { - CheckRange *range; - GtkTextIter iter; + CheckRange *range; + GtkTextIter iter; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - range = get_check_range (doc); + range = get_check_range (doc); - if (range == NULL) - { - xed_debug_message (DEBUG_PLUGINS, "There was not a previous check range"); + if (range == NULL) + { + xed_debug_message (DEBUG_PLUGINS, "There was not a previous check range"); - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter); + gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter); - range = g_new0 (CheckRange, 1); + range = g_new0 (CheckRange, 1); - range->start_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "check_range_start_mark", &iter, TRUE); + range->start_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), + "check_range_start_mark", &iter, TRUE); - range->end_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "check_range_end_mark", &iter, FALSE); + range->end_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), + "check_range_end_mark", &iter, FALSE); - range->current_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "check_range_current_mark", &iter, TRUE); + range->current_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), + "check_range_current_mark", &iter, TRUE); - g_object_set_qdata_full (G_OBJECT (doc), - check_range_id, - range, - (GDestroyNotify)g_free); - } + g_object_set_qdata_full (G_OBJECT (doc), check_range_id, range, (GDestroyNotify)g_free); + } - if (xed_spell_utils_skip_no_spell_check (start, end)) - { - if (!gtk_text_iter_inside_word (end)) - { - /* if we're neither inside a word, - * we must be in some spaces. - * skip backward to the end of the previous word. */ - if (!gtk_text_iter_is_end (end)) - { - gtk_text_iter_backward_word_start (end); - gtk_text_iter_forward_word_end (end); - } - } - else - { - if (!gtk_text_iter_ends_word (end)) - gtk_text_iter_forward_word_end (end); - } - } - else - { - /* no spell checking in the specified range */ - start = end; - } + if (xed_spell_utils_skip_no_spell_check (start, end)) + { + if (!gtk_text_iter_inside_word (end)) + { + /* if we're neither inside a word, + * we must be in some spaces. + * skip backward to the end of the previous word. */ + if (!gtk_text_iter_is_end (end)) + { + gtk_text_iter_backward_word_start (end); + gtk_text_iter_forward_word_end (end); + } + } + else + { + if (!gtk_text_iter_ends_word (end)) + { + gtk_text_iter_forward_word_end (end); + } + } + } + else + { + /* no spell checking in the specified range */ + start = end; + } - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), - range->start_mark, - start); - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), - range->end_mark, - end); + gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->start_mark, start); + gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->end_mark, end); - range->mw_start = -1; - range->mw_end = -1; + range->mw_start = -1; + range->mw_end = -1; - update_current (doc, gtk_text_iter_get_offset (start)); + update_current (doc, gtk_text_iter_get_offset (start)); } static gchar * -get_current_word (XedDocument *doc, gint *start, gint *end) +get_current_word (XedDocument *doc, + gint *start, + gint *end) { - const CheckRange *range; - GtkTextIter end_iter; - GtkTextIter current_iter; - gint range_end; + const CheckRange *range; + GtkTextIter end_iter; + GtkTextIter current_iter; + gint range_end; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_val_if_fail (doc != NULL, NULL); - g_return_val_if_fail (start != NULL, NULL); - g_return_val_if_fail (end != NULL, NULL); + g_return_val_if_fail (doc != NULL, NULL); + g_return_val_if_fail (start != NULL, NULL); + g_return_val_if_fail (end != NULL, NULL); - range = get_check_range (doc); - g_return_val_if_fail (range != NULL, NULL); + range = get_check_range (doc); + g_return_val_if_fail (range != NULL, NULL); - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), - &end_iter, range->end_mark); + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &end_iter, range->end_mark); - range_end = gtk_text_iter_get_offset (&end_iter); + range_end = gtk_text_iter_get_offset (&end_iter); - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), - ¤t_iter, range->current_mark); + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), ¤t_iter, range->current_mark); - end_iter = current_iter; + end_iter = current_iter; - if (!gtk_text_iter_is_end (&end_iter)) - { - xed_debug_message (DEBUG_PLUGINS, "Current is not end"); + if (!gtk_text_iter_is_end (&end_iter)) + { + xed_debug_message (DEBUG_PLUGINS, "Current is not end"); - gtk_text_iter_forward_word_end (&end_iter); - } + gtk_text_iter_forward_word_end (&end_iter); + } - *start = gtk_text_iter_get_offset (¤t_iter); - *end = MIN (gtk_text_iter_get_offset (&end_iter), range_end); + *start = gtk_text_iter_get_offset (¤t_iter); + *end = MIN (gtk_text_iter_get_offset (&end_iter), range_end); - xed_debug_message (DEBUG_PLUGINS, "Current word extends [%d, %d]", *start, *end); + xed_debug_message (DEBUG_PLUGINS, "Current word extends [%d, %d]", *start, *end); - if (!(*start < *end)) - return NULL; + if (!(*start < *end)) + { + return NULL; + } - return gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), - ¤t_iter, - &end_iter, - TRUE); + return gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), ¤t_iter, &end_iter, TRUE); } static gboolean goto_next_word (XedDocument *doc) { - CheckRange *range; - GtkTextIter current_iter; - GtkTextIter old_current_iter; - GtkTextIter end_iter; + CheckRange *range; + GtkTextIter current_iter; + GtkTextIter old_current_iter; + GtkTextIter end_iter; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_val_if_fail (doc != NULL, FALSE); + g_return_val_if_fail (doc != NULL, FALSE); - range = get_check_range (doc); - g_return_val_if_fail (range != NULL, FALSE); + range = get_check_range (doc); + g_return_val_if_fail (range != NULL, FALSE); - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), - ¤t_iter, - range->current_mark); - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end_iter); + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), ¤t_iter, range->current_mark); + gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end_iter); - old_current_iter = current_iter; + old_current_iter = current_iter; - gtk_text_iter_forward_word_ends (¤t_iter, 2); - gtk_text_iter_backward_word_start (¤t_iter); + gtk_text_iter_forward_word_ends (¤t_iter, 2); + gtk_text_iter_backward_word_start (¤t_iter); - if (xed_spell_utils_skip_no_spell_check (¤t_iter, &end_iter) && - (gtk_text_iter_compare (&old_current_iter, ¤t_iter) < 0) && - (gtk_text_iter_compare (¤t_iter, &end_iter) < 0)) - { - update_current (doc, gtk_text_iter_get_offset (¤t_iter)); - return TRUE; - } + if (xed_spell_utils_skip_no_spell_check (¤t_iter, &end_iter) && + (gtk_text_iter_compare (&old_current_iter, ¤t_iter) < 0) && + (gtk_text_iter_compare (¤t_iter, &end_iter) < 0)) + { + update_current (doc, gtk_text_iter_get_offset (¤t_iter)); + return TRUE; + } - return FALSE; + return FALSE; } static gchar * get_next_misspelled_word (XedView *view) { - XedDocument *doc; - CheckRange *range; - gint start, end; - gchar *word; - XedSpellChecker *spell; + XedDocument *doc; + CheckRange *range; + gint start, end; + gchar *word; + XedSpellChecker *spell; - g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (view != NULL, NULL); - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - g_return_val_if_fail (doc != NULL, NULL); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + g_return_val_if_fail (doc != NULL, NULL); - range = get_check_range (doc); - g_return_val_if_fail (range != NULL, NULL); + range = get_check_range (doc); + g_return_val_if_fail (range != NULL, NULL); - spell = get_spell_checker_from_document (doc); - g_return_val_if_fail (spell != NULL, NULL); + spell = get_spell_checker_from_document (doc); + g_return_val_if_fail (spell != NULL, NULL); - word = get_current_word (doc, &start, &end); - if (word == NULL) - return NULL; + word = get_current_word (doc, &start, &end); + if (word == NULL) + { + return NULL; + } - xed_debug_message (DEBUG_PLUGINS, "Word to check: %s", word); + xed_debug_message (DEBUG_PLUGINS, "Word to check: %s", word); - while (xed_spell_checker_check_word (spell, word, -1)) - { - g_free (word); + while (xed_spell_checker_check_word (spell, word, -1)) + { + g_free (word); - if (!goto_next_word (doc)) - return NULL; + if (!goto_next_word (doc)) + { + return NULL; + } - /* may return null if we reached the end of the selection */ - word = get_current_word (doc, &start, &end); - if (word == NULL) - return NULL; + /* may return null if we reached the end of the selection */ + word = get_current_word (doc, &start, &end); + if (word == NULL) + { + return NULL; + } - xed_debug_message (DEBUG_PLUGINS, "Word to check: %s", word); - } + xed_debug_message (DEBUG_PLUGINS, "Word to check: %s", word); + } - if (!goto_next_word (doc)) - update_current (doc, gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc))); + if (!goto_next_word (doc)) + { + update_current (doc, gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc))); + } - if (word != NULL) - { - GtkTextIter s, e; + if (word != NULL) + { + GtkTextIter s, e; - range->mw_start = start; - range->mw_end = end; + range->mw_start = start; + range->mw_end = end; - xed_debug_message (DEBUG_PLUGINS, "Select [%d, %d]", start, end); + xed_debug_message (DEBUG_PLUGINS, "Select [%d, %d]", start, end); - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &s, start); - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &e, end); + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &s, start); + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &e, end); - gtk_text_buffer_select_range (GTK_TEXT_BUFFER (doc), &s, &e); + gtk_text_buffer_select_range (GTK_TEXT_BUFFER (doc), &s, &e); - xed_view_scroll_to_cursor (view); - } - else - { - range->mw_start = -1; - range->mw_end = -1; - } + xed_view_scroll_to_cursor (view); + } + else + { + range->mw_start = -1; + range->mw_end = -1; + } - return word; + return word; } static void ignore_cb (XedSpellCheckerDialog *dlg, - const gchar *w, - XedView *view) + const gchar *w, + XedView *view) { - gchar *word = NULL; + gchar *word = NULL; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_if_fail (w != NULL); - g_return_if_fail (view != NULL); + g_return_if_fail (w != NULL); + g_return_if_fail (view != NULL); - word = get_next_misspelled_word (view); - if (word == NULL) - { - xed_spell_checker_dialog_set_completed (dlg); - - return; - } + word = get_next_misspelled_word (view); + if (word == NULL) + { + xed_spell_checker_dialog_set_completed (dlg); - xed_spell_checker_dialog_set_misspelled_word (XED_SPELL_CHECKER_DIALOG (dlg), - word, - -1); + return; + } - g_free (word); + xed_spell_checker_dialog_set_misspelled_word (XED_SPELL_CHECKER_DIALOG (dlg), word, -1); + + g_free (word); } static void change_cb (XedSpellCheckerDialog *dlg, - const gchar *word, - const gchar *change, - XedView *view) + const gchar *word, + const gchar *change, + XedView *view) { - XedDocument *doc; - CheckRange *range; - gchar *w = NULL; - GtkTextIter start, end; + XedDocument *doc; + CheckRange *range; + gchar *w = NULL; + GtkTextIter start, end; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_if_fail (view != NULL); - g_return_if_fail (word != NULL); - g_return_if_fail (change != NULL); + g_return_if_fail (view != NULL); + g_return_if_fail (word != NULL); + g_return_if_fail (change != NULL); - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - g_return_if_fail (doc != NULL); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + g_return_if_fail (doc != NULL); - range = get_check_range (doc); - g_return_if_fail (range != NULL); + range = get_check_range (doc); + g_return_if_fail (range != NULL); - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &start, range->mw_start); - if (range->mw_end < 0) - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end); - else - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &end, range->mw_end); + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &start, range->mw_start); + if (range->mw_end < 0) + { + gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end); + } + else + { + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &end, range->mw_end); + } - w = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), &start, &end, TRUE); - g_return_if_fail (w != NULL); + w = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), &start, &end, TRUE); + g_return_if_fail (w != NULL); - if (strcmp (w, word) != 0) - { - g_free (w); - return; - } + if (strcmp (w, word) != 0) + { + g_free (w); + return; + } - g_free (w); + g_free (w); - gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER(doc)); + gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER(doc)); - gtk_text_buffer_delete (GTK_TEXT_BUFFER (doc), &start, &end); - gtk_text_buffer_insert (GTK_TEXT_BUFFER (doc), &start, change, -1); + gtk_text_buffer_delete (GTK_TEXT_BUFFER (doc), &start, &end); + gtk_text_buffer_insert (GTK_TEXT_BUFFER (doc), &start, change, -1); - gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER(doc)); + gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER(doc)); - update_current (doc, range->mw_start + g_utf8_strlen (change, -1)); + update_current (doc, range->mw_start + g_utf8_strlen (change, -1)); - /* go to next misspelled word */ - ignore_cb (dlg, word, view); + /* go to next misspelled word */ + ignore_cb (dlg, word, view); } static void change_all_cb (XedSpellCheckerDialog *dlg, - const gchar *word, - const gchar *change, - XedView *view) + const gchar *word, + const gchar *change, + XedView *view) { - XedDocument *doc; - CheckRange *range; - gchar *w = NULL; - GtkTextIter start, end; - gint flags = 0; + XedDocument *doc; + CheckRange *range; + gchar *w = NULL; + GtkTextIter start, end; + GtkSourceSearchSettings *search_settings; + GtkSourceSearchContext *search_context; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_if_fail (view != NULL); - g_return_if_fail (word != NULL); - g_return_if_fail (change != NULL); + g_return_if_fail (view != NULL); + g_return_if_fail (word != NULL); + g_return_if_fail (change != NULL); - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - g_return_if_fail (doc != NULL); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + g_return_if_fail (doc != NULL); - range = get_check_range (doc); - g_return_if_fail (range != NULL); + range = get_check_range (doc); + g_return_if_fail (range != NULL); - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &start, range->mw_start); - if (range->mw_end < 0) - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end); - else - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &end, range->mw_end); + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &start, range->mw_start); + if (range->mw_end < 0) + { + gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end); + } + else + { + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &end, range->mw_end); + } - w = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), &start, &end, TRUE); - g_return_if_fail (w != NULL); + w = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), &start, &end, TRUE); + g_return_if_fail (w != NULL); - if (strcmp (w, word) != 0) - { - g_free (w); - return; - } + if (strcmp (w, word) != 0) + { + g_free (w); + return; + } - g_free (w); + g_free (w); - XED_SEARCH_SET_CASE_SENSITIVE (flags, TRUE); - XED_SEARCH_SET_ENTIRE_WORD (flags, TRUE); + search_settings = gtk_source_search_settings_new (); + gtk_source_search_settings_set_case_sensitive (search_settings, TRUE); + gtk_source_search_settings_set_at_word_boundaries (search_settings, TRUE); + gtk_source_search_settings_set_search_text (search_settings, word); - /* CHECK: currently this function does escaping etc */ - xed_document_replace_all (doc, word, change, flags); + search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (doc), search_settings); - update_current (doc, range->mw_start + g_utf8_strlen (change, -1)); + gtk_source_search_context_set_highlight (search_context, FALSE); - /* go to next misspelled word */ - ignore_cb (dlg, word, view); + gtk_source_search_context_replace_all (search_context, change, -1, NULL); + + update_current (doc, range->mw_start + g_utf8_strlen (change, -1)); + + /* go to next misspelled word */ + ignore_cb (dlg, word, view); + + g_object_unref (search_settings); + g_object_unref (search_context); } static void add_word_cb (XedSpellCheckerDialog *dlg, - const gchar *word, - XedView *view) + const gchar *word, + XedView *view) { - g_return_if_fail (view != NULL); - g_return_if_fail (word != NULL); + g_return_if_fail (view != NULL); + g_return_if_fail (word != NULL); - /* go to next misspelled word */ - ignore_cb (dlg, word, view); + /* go to next misspelled word */ + ignore_cb (dlg, word, view); } static void -language_dialog_response (GtkDialog *dlg, - gint res_id, - XedSpellChecker *spell) +language_dialog_response (GtkDialog *dlg, + gint res_id, + XedSpellChecker *spell) { - if (res_id == GTK_RESPONSE_OK) - { - const XedSpellCheckerLanguage *lang; + if (res_id == GTK_RESPONSE_OK) + { + const XedSpellCheckerLanguage *lang; - lang = xed_spell_language_get_selected_language (XED_SPELL_LANGUAGE_DIALOG (dlg)); - if (lang != NULL) - xed_spell_checker_set_language (spell, lang); - } + lang = xed_spell_language_get_selected_language (XED_SPELL_LANGUAGE_DIALOG (dlg)); + if (lang != NULL) + { + xed_spell_checker_set_language (spell, lang); + } + } - gtk_widget_destroy (GTK_WIDGET (dlg)); -} - -static SpellConfigureDialog * -get_configure_dialog (XedSpellPlugin *plugin) -{ - SpellConfigureDialog *dialog = NULL; - gchar *data_dir; - gchar *ui_file; - GtkWidget *content; - XedSpellPluginAutocheckType autocheck_type; - GtkWidget *error_widget; - gboolean ret; - gchar *root_objects[] = { - "spell_dialog_content", - NULL - }; - - xed_debug (DEBUG_PLUGINS); - - GtkWidget *dlg = gtk_dialog_new_with_buttons (_("Configure Spell Checker plugin..."), - NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, - GTK_RESPONSE_OK, - GTK_STOCK_HELP, - GTK_RESPONSE_HELP, - NULL); - - g_return_val_if_fail (dlg != NULL, NULL); - - dialog = g_new0 (SpellConfigureDialog, 1); - dialog->dialog = dlg; - - - /* HIG defaults */ - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog->dialog)), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))), - 2); /* 2 * 5 + 2 = 12 */ - gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dialog->dialog))), - 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dialog->dialog))), 6); - - data_dir = xed_plugin_get_data_dir (XED_PLUGIN (plugin)); - ui_file = g_build_filename (data_dir, "xed-spell-setup-dialog.ui", NULL); - ret = xed_utils_get_ui_objects (ui_file, - root_objects, - &error_widget, - "spell_dialog_content", &content, - "autocheck_never", &dialog->never, - "autocheck_document", &dialog->document, - "autocheck_always", &dialog->always, - NULL); - - g_free (data_dir); - g_free (ui_file); - - if (!ret) - { - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))), - error_widget, TRUE, TRUE, 0); - - gtk_container_set_border_width (GTK_CONTAINER (error_widget), 5); - - gtk_widget_show (error_widget); - - return dialog; - } - - gtk_window_set_resizable (GTK_WINDOW (dialog->dialog), FALSE); - - autocheck_type = get_autocheck_type (plugin); - - if (autocheck_type == AUTOCHECK_ALWAYS) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->always), TRUE); - } - else if (autocheck_type == AUTOCHECK_DOCUMENT) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->document), TRUE); - } - else - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->never), TRUE); - } - - gtk_window_set_default_size (GTK_WIDGET (content), 15, 120); - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))), - content, FALSE, FALSE, 0); - g_object_unref (content); - gtk_container_set_border_width (GTK_CONTAINER (content), 5); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog), - GTK_RESPONSE_OK); - - return dialog; + gtk_widget_destroy (GTK_WIDGET (dlg)); } static void -ok_button_pressed (SpellConfigureDialog *dialog) +configure_widget_button_toggled (GtkToggleButton *button, + SpellConfigureWidget *conf_widget) { - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->always))) - { - set_autocheck_type (dialog->plugin, AUTOCHECK_ALWAYS); - } - else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->document))) - { - set_autocheck_type (dialog->plugin, AUTOCHECK_DOCUMENT); - } - else - { - set_autocheck_type (dialog->plugin, AUTOCHECK_NEVER); - } + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (conf_widget->always))) + { + set_autocheck_type (conf_widget->settings, AUTOCHECK_ALWAYS); + } + else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (conf_widget->document))) + { + set_autocheck_type (conf_widget->settings, AUTOCHECK_DOCUMENT); + } + else + { + set_autocheck_type (conf_widget->settings, AUTOCHECK_NEVER); + } } static void -configure_dialog_response_cb (GtkWidget *widget, - gint response, - SpellConfigureDialog *dialog) +configure_widget_destroyed (GtkWidget *widget, + gpointer data) { - switch (response) - { - case GTK_RESPONSE_HELP: - { - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_HELP"); + SpellConfigureWidget *conf_widget = (SpellConfigureWidget *)data; - xed_help_display (GTK_WINDOW (widget), - NULL, - "xed-spell-checker-plugin"); - break; - } - case GTK_RESPONSE_OK: - { - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_OK"); + xed_debug (DEBUG_PLUGINS); - ok_button_pressed (dialog); + g_object_unref (conf_widget->settings); + g_slice_free (SpellConfigureWidget, data); - gtk_widget_destroy (dialog->dialog); - break; - } - case GTK_RESPONSE_CANCEL: - { - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_CANCEL"); - gtk_widget_destroy (dialog->dialog); - } - } + xed_debug_message (DEBUG_PLUGINS, "END"); +} + +static SpellConfigureWidget * +get_configure_widget (XedSpellPlugin *plugin) +{ + SpellConfigureWidget *widget; + gchar *data_dir; + gchar *ui_file; + XedSpellPluginAutocheckType autocheck_type; + GtkWidget *error_widget; + gboolean ret; + gchar *root_objects[] = { + "spell_dialog_content", + NULL + }; + + xed_debug (DEBUG_PLUGINS); + + widget = g_slice_new (SpellConfigureWidget); + widget->settings = g_object_ref (plugin->priv->settings); + + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); + ui_file = g_build_filename (data_dir, "xed-spell-setup-dialog.ui", NULL); + ret = xed_utils_get_ui_objects (ui_file, + root_objects, + &error_widget, + "spell_dialog_content", &widget->content, + "autocheck_never", &widget->never, + "autocheck_document", &widget->document, + "autocheck_always", &widget->always, + NULL); + + g_free (data_dir); + g_free (ui_file); + + if (!ret) + { + return NULL; + } + + autocheck_type = get_autocheck_type (plugin); + + if (autocheck_type == AUTOCHECK_ALWAYS) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->always), TRUE); + } + else if (autocheck_type == AUTOCHECK_DOCUMENT) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->document), TRUE); + } + else + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->never), TRUE); + } + + g_signal_connect (widget->always, "toggled", + G_CALLBACK (configure_widget_button_toggled), widget); + g_signal_connect (widget->document, "toggled", + G_CALLBACK (configure_widget_button_toggled), widget); + g_signal_connect (widget->never, "toggled", + G_CALLBACK (configure_widget_button_toggled), widget); + g_signal_connect (widget->content, "destroy", + G_CALLBACK (configure_widget_destroyed), widget); + + return widget; } static void -set_language_cb (GtkAction *action, - ActionData *action_data) +set_language_cb (GtkAction *action, + XedSpellPlugin *plugin) { - XedDocument *doc; - XedSpellChecker *spell; - const XedSpellCheckerLanguage *lang; - GtkWidget *dlg; - GtkWindowGroup *wg; - gchar *data_dir; + XedSpellPluginPrivate *priv; + XedDocument *doc; + XedSpellChecker *spell; + const XedSpellCheckerLanguage *lang; + GtkWidget *dlg; + GtkWindowGroup *wg; + gchar *data_dir; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - doc = xed_window_get_active_document (action_data->window); - g_return_if_fail (doc != NULL); + priv = plugin->priv; - spell = get_spell_checker_from_document (doc); - g_return_if_fail (spell != NULL); + doc = xed_window_get_active_document (priv->window); + g_return_if_fail (doc != NULL); - lang = xed_spell_checker_get_language (spell); + spell = get_spell_checker_from_document (doc); + g_return_if_fail (spell != NULL); - data_dir = xed_plugin_get_data_dir (action_data->plugin); - dlg = xed_spell_language_dialog_new (GTK_WINDOW (action_data->window), - lang, - data_dir); - g_free (data_dir); + lang = xed_spell_checker_get_language (spell); - wg = xed_window_get_group (action_data->window); + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); + dlg = xed_spell_language_dialog_new (GTK_WINDOW (priv->window), lang, data_dir); + g_free (data_dir); - gtk_window_group_add_window (wg, GTK_WINDOW (dlg)); + wg = xed_window_get_group (priv->window); - gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); + gtk_window_group_add_window (wg, GTK_WINDOW (dlg)); - g_signal_connect (dlg, - "response", - G_CALLBACK (language_dialog_response), - spell); + gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); - gtk_widget_show (dlg); + g_signal_connect (dlg, "response", + G_CALLBACK (language_dialog_response), spell); + + gtk_widget_show (dlg); } static void -spell_cb (GtkAction *action, - ActionData *action_data) +spell_cb (GtkAction *action, + XedSpellPlugin *plugin) { - XedView *view; - XedDocument *doc; - XedSpellChecker *spell; - GtkWidget *dlg; - GtkTextIter start, end; - gchar *word; - gchar *data_dir; + XedSpellPluginPrivate *priv; + XedView *view; + XedDocument *doc; + XedSpellChecker *spell; + GtkWidget *dlg; + GtkTextIter start, end; + gchar *word; + gchar *data_dir; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - view = xed_window_get_active_view (action_data->window); - g_return_if_fail (view != NULL); + priv = plugin->priv; - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - g_return_if_fail (doc != NULL); + view = xed_window_get_active_view (priv->window); + g_return_if_fail (view != NULL); - spell = get_spell_checker_from_document (doc); - g_return_if_fail (spell != NULL); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + g_return_if_fail (doc != NULL); - if (gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc)) <= 0) - { - WindowData *data; - GtkWidget *statusbar; + spell = get_spell_checker_from_document (doc); + g_return_if_fail (spell != NULL); - data = (WindowData *) g_object_get_data (G_OBJECT (action_data->window), - WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); + if (gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc)) <= 0) + { + GtkWidget *statusbar; - statusbar = xed_window_get_statusbar (action_data->window); - xed_statusbar_flash_message (XED_STATUSBAR (statusbar), - data->message_cid, - _("The document is empty.")); + statusbar = xed_window_get_statusbar (priv->window); + xed_statusbar_flash_message (XED_STATUSBAR (statusbar), priv->message_cid, _("The document is empty.")); - return; - } + return; + } - if (!gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), - &start, - &end)) - { - /* no selection, get the whole doc */ - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), - &start, - &end); - } + if (!gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), &start, &end)) + { + /* no selection, get the whole doc */ + gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), &start, &end); + } - set_check_range (doc, &start, &end); + set_check_range (doc, &start, &end); - word = get_next_misspelled_word (view); - if (word == NULL) - { - WindowData *data; - GtkWidget *statusbar; + word = get_next_misspelled_word (view); + if (word == NULL) + { + GtkWidget *statusbar; - data = (WindowData *) g_object_get_data (G_OBJECT (action_data->window), - WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); + statusbar = xed_window_get_statusbar (priv->window); + xed_statusbar_flash_message (XED_STATUSBAR (statusbar), priv->message_cid, _("No misspelled words")); - statusbar = xed_window_get_statusbar (action_data->window); - xed_statusbar_flash_message (XED_STATUSBAR (statusbar), - data->message_cid, - _("No misspelled words")); + return; + } - return; - } + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); + dlg = xed_spell_checker_dialog_new_from_spell_checker (spell, data_dir); + g_free (data_dir); - data_dir = xed_plugin_get_data_dir (action_data->plugin); - dlg = xed_spell_checker_dialog_new_from_spell_checker (spell, data_dir); - g_free (data_dir); - gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); - gtk_window_set_transient_for (GTK_WINDOW (dlg), - GTK_WINDOW (action_data->window)); + gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); + gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (priv->window)); - g_signal_connect (dlg, "ignore", G_CALLBACK (ignore_cb), view); - g_signal_connect (dlg, "ignore_all", G_CALLBACK (ignore_cb), view); + g_signal_connect (dlg, "ignore", G_CALLBACK (ignore_cb), view); + g_signal_connect (dlg, "ignore_all", G_CALLBACK (ignore_cb), view); - g_signal_connect (dlg, "change", G_CALLBACK (change_cb), view); - g_signal_connect (dlg, "change_all", G_CALLBACK (change_all_cb), view); + g_signal_connect (dlg, "change", G_CALLBACK (change_cb), view); + g_signal_connect (dlg, "change_all", G_CALLBACK (change_all_cb), view); - g_signal_connect (dlg, "add_word_to_personal", G_CALLBACK (add_word_cb), view); + g_signal_connect (dlg, "add_word_to_personal", G_CALLBACK (add_word_cb), view); - xed_spell_checker_dialog_set_misspelled_word (XED_SPELL_CHECKER_DIALOG (dlg), - word, - -1); + xed_spell_checker_dialog_set_misspelled_word (XED_SPELL_CHECKER_DIALOG (dlg), word, -1); - g_free (word); + g_free (word); - gtk_widget_show (dlg); + gtk_widget_show (dlg); } static void -set_auto_spell (XedWindow *window, - XedDocument *doc, - gboolean active) +set_auto_spell (XedWindow *window, + XedView *view, + gboolean active) { - XedAutomaticSpellChecker *autospell; - XedSpellChecker *spell; + XedAutomaticSpellChecker *autospell; + XedSpellChecker *spell; + XedDocument *doc; - spell = get_spell_checker_from_document (doc); - g_return_if_fail (spell != NULL); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - autospell = xed_automatic_spell_checker_get_from_document (doc); + spell = get_spell_checker_from_document (doc); + g_return_if_fail (spell != NULL); - if (active) - { - if (autospell == NULL) - { - XedView *active_view; + autospell = xed_automatic_spell_checker_get_from_document (doc); - active_view = xed_window_get_active_view (window); - g_return_if_fail (active_view != NULL); - - autospell = xed_automatic_spell_checker_new (doc, spell); - xed_automatic_spell_checker_attach_view (autospell, active_view); - xed_automatic_spell_checker_recheck_all (autospell); - } - } - else - { - if (autospell != NULL) - xed_automatic_spell_checker_free (autospell); - } + if (active) + { + if (autospell == NULL) + { + autospell = xed_automatic_spell_checker_new (doc, spell); + xed_automatic_spell_checker_attach_view (autospell, view); + xed_automatic_spell_checker_recheck_all (autospell); + } + } + else + { + if (autospell != NULL) + { + xed_automatic_spell_checker_free (autospell); + } + } } static void -auto_spell_cb (GtkAction *action, - XedWindow *window) +auto_spell_cb (GtkAction *action, + XedSpellPlugin *plugin) { - - XedDocument *doc; - gboolean active; - WindowData *data; + XedSpellPluginPrivate *priv; + XedDocument *doc; + XedView *view; + gboolean active; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + priv = plugin->priv; + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - xed_debug_message (DEBUG_PLUGINS, active ? "Auto Spell activated" : "Auto Spell deactivated"); + xed_debug_message (DEBUG_PLUGINS, active ? "Auto Spell activated" : "Auto Spell deactivated"); - doc = xed_window_get_active_document (window); - if (doc == NULL) - return; + view = xed_window_get_active_view (priv->window); + if (view == NULL) + { + return; + } - data = g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - if (get_autocheck_type(data->plugin) == AUTOCHECK_DOCUMENT) - { + if (get_autocheck_type (plugin) == AUTOCHECK_DOCUMENT) + { + xed_document_set_metadata (doc, + XED_METADATA_ATTRIBUTE_SPELL_ENABLED, + active ? "1" : NULL, NULL); + } - xed_document_set_metadata (doc, - XED_METADATA_ATTRIBUTE_SPELL_ENABLED, - active ? "1" : NULL, NULL); - } - - set_auto_spell (window, doc, active); + set_auto_spell (priv->window, view, active); } static void -free_window_data (WindowData *data) +update_ui (XedSpellPlugin *plugin) { - g_return_if_fail (data != NULL); + XedSpellPluginPrivate *priv; + XedView *view; + GtkAction *action; - g_object_unref (data->action_group); - g_slice_free (WindowData, data); + xed_debug (DEBUG_PLUGINS); + + priv = plugin->priv; + view = xed_window_get_active_view (priv->window); + + if (view != NULL) + { + XedDocument *doc; + XedTab *tab; + XedTabState state; + gboolean autospell; + + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + tab = xed_window_get_active_tab (priv->window); + state = xed_tab_get_state (tab); + autospell = (doc != NULL && xed_automatic_spell_checker_get_from_document (doc) != NULL); + + /* If the document is loading we can't get the metadata so we + endup with an useless speller */ + if (state == XED_TAB_STATE_NORMAL) + { + action = gtk_action_group_get_action (priv->action_group, "AutoSpell"); + + g_signal_handlers_block_by_func (action, auto_spell_cb, plugin); + set_auto_spell (priv->window, view, autospell); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), autospell); + g_signal_handlers_unblock_by_func (action, auto_spell_cb, plugin); + } + } + + gtk_action_group_set_sensitive (priv->action_group, + (view != NULL) && + gtk_text_view_get_editable (GTK_TEXT_VIEW (view))); } static void -free_action_data (gpointer data) +set_auto_spell_from_metadata (XedSpellPlugin *plugin, + XedView *view, + GtkActionGroup *action_group) { - g_return_if_fail (data != NULL); + gboolean active = FALSE; + gchar *active_str = NULL; + XedWindow *window; + XedDocument *doc; + XedDocument *active_doc; + XedSpellPluginAutocheckType autocheck_type; - g_slice_free (ActionData, data); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + + autocheck_type = get_autocheck_type (plugin); + + switch (autocheck_type) + { + case AUTOCHECK_ALWAYS: + { + active = TRUE; + break; + } + case AUTOCHECK_DOCUMENT: + { + active_str = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_ENABLED); + break; + } + case AUTOCHECK_NEVER: + default: + active = FALSE; + break; + } + + if (active_str) + { + active = *active_str == '1'; + + g_free (active_str); + } + + window = XED_WINDOW (plugin->priv->window); + + set_auto_spell (window, view, active); + + /* In case that the doc is the active one we mark the spell action */ + active_doc = xed_window_get_active_document (window); + + if (active_doc == doc && action_group != NULL) + { + GtkAction *action; + + action = gtk_action_group_get_action (action_group, "AutoSpell"); + + g_signal_handlers_block_by_func (action, auto_spell_cb, plugin); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active); + g_signal_handlers_unblock_by_func (action, auto_spell_cb, plugin); + } } static void -update_ui_real (XedWindow *window, - WindowData *data) +on_document_loaded (XedDocument *doc, + XedSpellPlugin *plugin) { - XedDocument *doc; - XedView *view; - gboolean autospell; - GtkAction *action; - xed_debug (DEBUG_PLUGINS); + XedSpellChecker *spell; + XedView *view; - doc = xed_window_get_active_document (window); - view = xed_window_get_active_view (window); + spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id)); + if (spell != NULL) + { + set_language_from_metadata (spell, doc); + } - autospell = (doc != NULL && - xed_automatic_spell_checker_get_from_document (doc) != NULL); + view = XED_VIEW (g_object_get_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW)); - if (doc != NULL) - { - XedTab *tab; - XedTabState state; - - tab = xed_window_get_active_tab (window); - state = xed_tab_get_state (tab); - - /* If the document is loading we can't get the metadata so we - endup with an useless speller */ - if (state == XED_TAB_STATE_NORMAL) - { - action = gtk_action_group_get_action (data->action_group, - "AutoSpell"); - - g_signal_handlers_block_by_func (action, auto_spell_cb, - window); - set_auto_spell (window, doc, autospell); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - autospell); - g_signal_handlers_unblock_by_func (action, auto_spell_cb, - window); - } - } - - gtk_action_group_set_sensitive (data->action_group, - (view != NULL) && - gtk_text_view_get_editable (GTK_TEXT_VIEW (view))); + set_auto_spell_from_metadata (plugin, view, plugin->priv->action_group); } static void -set_auto_spell_from_metadata (XedWindow *window, - XedDocument *doc, - GtkActionGroup *action_group) +on_document_saved (XedDocument *doc, + XedSpellPlugin *plugin) { - gboolean active = FALSE; - gchar *active_str = NULL; - XedDocument *active_doc; - XedSpellPluginAutocheckType autocheck_type; - WindowData *data; + XedAutomaticSpellChecker *autospell; + XedSpellChecker *spell; + const gchar *key; - data = g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); + /* Make sure to save the metadata here too */ + autospell = xed_automatic_spell_checker_get_from_document (doc); + spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id)); - autocheck_type = get_autocheck_type(data->plugin); + if (spell != NULL) + { + key = xed_spell_checker_language_to_key (xed_spell_checker_get_language (spell)); + } + else + { + key = NULL; + } - switch (autocheck_type) - { - case AUTOCHECK_ALWAYS: - { - active = TRUE; - break; - } - case AUTOCHECK_DOCUMENT: - { - active_str = xed_document_get_metadata (doc, - XED_METADATA_ATTRIBUTE_SPELL_ENABLED); - break; - } - case AUTOCHECK_NEVER: - default: - active = FALSE; - break; - } + if (get_autocheck_type (plugin) == AUTOCHECK_DOCUMENT) + { - if (active_str) - { - active = *active_str == '1'; - - g_free (active_str); - } - - set_auto_spell (window, doc, active); - - /* In case that the doc is the active one we mark the spell action */ - active_doc = xed_window_get_active_document (window); - - if (active_doc == doc && action_group != NULL) - { - GtkAction *action; - - action = gtk_action_group_get_action (action_group, - "AutoSpell"); - - g_signal_handlers_block_by_func (action, auto_spell_cb, - window); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - active); - g_signal_handlers_unblock_by_func (action, auto_spell_cb, - window); - } + xed_document_set_metadata (doc, + XED_METADATA_ATTRIBUTE_SPELL_ENABLED, + autospell != NULL ? "1" : NULL, + XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, + key, + NULL); + } + else + { + xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, key, NULL); + } } static void -on_document_loaded (XedDocument *doc, - const GError *error, - XedWindow *window) +tab_added_cb (XedWindow *window, + XedTab *tab, + XedSpellPlugin *plugin) { - if (error == NULL) - { - WindowData *data; - XedSpellChecker *spell; + XedView *view; + XedDocument *doc; - spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), - spell_checker_id)); - if (spell != NULL) - { - set_language_from_metadata (spell, doc); - } + view = xed_tab_get_view (tab); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - data = g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); + g_object_set_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW, view); - set_auto_spell_from_metadata (window, doc, data->action_group); - } + g_signal_connect (doc, "loaded", + G_CALLBACK (on_document_loaded), plugin); + + g_signal_connect (doc, "saved", + G_CALLBACK (on_document_saved), plugin); } static void -on_document_saved (XedDocument *doc, - const GError *error, - XedWindow *window) +tab_removed_cb (XedWindow *window, + XedTab *tab, + XedSpellPlugin *plugin) { - XedAutomaticSpellChecker *autospell; - XedSpellChecker *spell; - const gchar *key; - WindowData *data; + XedDocument *doc; - if (error != NULL) - { - return; - } + doc = xed_tab_get_document (tab); + g_object_set_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW, NULL); - /* Make sure to save the metadata here too */ - autospell = xed_automatic_spell_checker_get_from_document (doc); - spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id)); - - if (spell != NULL) - { - key = xed_spell_checker_language_to_key (xed_spell_checker_get_language (spell)); - } - else - { - key = NULL; - } - - data = g_object_get_data (G_OBJECT (window), - WINDOW_DATA_KEY); - - if (get_autocheck_type(data->plugin) == AUTOCHECK_DOCUMENT) - { - - xed_document_set_metadata (doc, - XED_METADATA_ATTRIBUTE_SPELL_ENABLED, - autospell != NULL ? "1" : NULL, - XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, - key, - NULL); - } - else - { - xed_document_set_metadata (doc, - XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, - key, - NULL); - } + g_signal_handlers_disconnect_by_func (doc, on_document_loaded, plugin); + g_signal_handlers_disconnect_by_func (doc, on_document_saved, plugin); } static void -tab_added_cb (XedWindow *window, - XedTab *tab, - gpointer useless) +xed_spell_plugin_activate (XedWindowActivatable *activatable) { - XedDocument *doc; + XedSpellPluginPrivate *priv; + GtkUIManager *manager; + GList *views, *l; - doc = xed_tab_get_document (tab); + xed_debug (DEBUG_PLUGINS); - g_signal_connect (doc, "loaded", - G_CALLBACK (on_document_loaded), - window); + priv = XED_SPELL_PLUGIN (activatable)->priv; - g_signal_connect (doc, "saved", - G_CALLBACK (on_document_saved), - window); + manager = xed_window_get_ui_manager (priv->window); + + priv->action_group = gtk_action_group_new ("XedSpellPluginActions"); + gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions (priv->action_group, + action_entries, + G_N_ELEMENTS (action_entries), + activatable); + gtk_action_group_add_toggle_actions (priv->action_group, + toggle_action_entries, + G_N_ELEMENTS (toggle_action_entries), + activatable); + + gtk_ui_manager_insert_action_group (manager, priv->action_group, -1); + + priv->ui_id = gtk_ui_manager_new_merge_id (manager); + + priv->message_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR (xed_window_get_statusbar (priv->window)), + "spell_plugin_message"); + + gtk_ui_manager_add_ui (manager, + priv->ui_id, + MENU_PATH, + "CheckSpell", + "CheckSpell", + GTK_UI_MANAGER_MENUITEM, + FALSE); + + gtk_ui_manager_add_ui (manager, + priv->ui_id, + MENU_PATH, + "AutoSpell", + "AutoSpell", + GTK_UI_MANAGER_MENUITEM, + FALSE); + + gtk_ui_manager_add_ui (manager, + priv->ui_id, + MENU_PATH, + "ConfigSpell", + "ConfigSpell", + GTK_UI_MANAGER_MENUITEM, + FALSE); + + update_ui (XED_SPELL_PLUGIN (activatable)); + + views = xed_window_get_views (priv->window); + for (l = views; l != NULL; l = g_list_next (l)) + { + XedView *view = XED_VIEW (l->data); + + set_auto_spell_from_metadata (XED_SPELL_PLUGIN (activatable), view, priv->action_group); + } + + priv->tab_added_id = g_signal_connect (priv->window, "tab-added", + G_CALLBACK (tab_added_cb), activatable); + priv->tab_removed_id = g_signal_connect (priv->window, "tab-removed", + G_CALLBACK (tab_removed_cb), activatable); } static void -tab_removed_cb (XedWindow *window, - XedTab *tab, - gpointer useless) +xed_spell_plugin_deactivate (XedWindowActivatable *activatable) { - XedDocument *doc; + XedSpellPluginPrivate *priv; + GtkUIManager *manager; - doc = xed_tab_get_document (tab); - - g_signal_handlers_disconnect_by_func (doc, on_document_loaded, window); - g_signal_handlers_disconnect_by_func (doc, on_document_saved, window); + xed_debug (DEBUG_PLUGINS); + + priv = XED_SPELL_PLUGIN (activatable)->priv; + manager = xed_window_get_ui_manager (priv->window); + + gtk_ui_manager_remove_ui (manager, priv->ui_id); + gtk_ui_manager_remove_action_group (manager, priv->action_group); + + g_signal_handler_disconnect (priv->window, priv->tab_added_id); + g_signal_handler_disconnect (priv->window, priv->tab_removed_id); } static void -impl_activate (XedPlugin *plugin, - XedWindow *window) +xed_spell_plugin_update_state (XedWindowActivatable *activatable) { - GtkUIManager *manager; - WindowData *data; - ActionData *action_data; - GList *docs, *l; + xed_debug (DEBUG_PLUGINS); - xed_debug (DEBUG_PLUGINS); - - data = g_slice_new (WindowData); - data->plugin = XED_SPELL_PLUGIN (plugin); - action_data = g_slice_new (ActionData); - action_data->plugin = plugin; - action_data->window = window; - - manager = xed_window_get_ui_manager (window); - - data->action_group = gtk_action_group_new ("XedSpellPluginActions"); - gtk_action_group_set_translation_domain (data->action_group, - GETTEXT_PACKAGE); - gtk_action_group_add_actions_full (data->action_group, - action_entries, - G_N_ELEMENTS (action_entries), - action_data, - (GDestroyNotify) free_action_data); - gtk_action_group_add_toggle_actions (data->action_group, - toggle_action_entries, - G_N_ELEMENTS (toggle_action_entries), - window); - - gtk_ui_manager_insert_action_group (manager, data->action_group, -1); - - data->ui_id = gtk_ui_manager_new_merge_id (manager); - - data->message_cid = gtk_statusbar_get_context_id - (GTK_STATUSBAR (xed_window_get_statusbar (window)), - "spell_plugin_message"); - - g_object_set_data_full (G_OBJECT (window), - WINDOW_DATA_KEY, - data, - (GDestroyNotify) free_window_data); - - gtk_ui_manager_add_ui (manager, - data->ui_id, - MENU_PATH, - "CheckSpell", - "CheckSpell", - GTK_UI_MANAGER_MENUITEM, - FALSE); - - gtk_ui_manager_add_ui (manager, - data->ui_id, - MENU_PATH, - "AutoSpell", - "AutoSpell", - GTK_UI_MANAGER_MENUITEM, - FALSE); - - gtk_ui_manager_add_ui (manager, - data->ui_id, - MENU_PATH, - "ConfigSpell", - "ConfigSpell", - GTK_UI_MANAGER_MENUITEM, - FALSE); - - update_ui_real (window, data); - - docs = xed_window_get_documents (window); - for (l = docs; l != NULL; l = g_list_next (l)) - { - XedDocument *doc = XED_DOCUMENT (l->data); - - set_auto_spell_from_metadata (window, doc, - data->action_group); - - g_signal_handlers_disconnect_by_func (doc, - on_document_loaded, - window); - - g_signal_handlers_disconnect_by_func (doc, - on_document_saved, - window); - } - - data->tab_added_id = - g_signal_connect (window, "tab-added", - G_CALLBACK (tab_added_cb), NULL); - data->tab_removed_id = - g_signal_connect (window, "tab-removed", - G_CALLBACK (tab_removed_cb), NULL); -} - -static void -impl_deactivate (XedPlugin *plugin, - XedWindow *window) -{ - GtkUIManager *manager; - WindowData *data; - - xed_debug (DEBUG_PLUGINS); - - manager = xed_window_get_ui_manager (window); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - gtk_ui_manager_remove_ui (manager, data->ui_id); - gtk_ui_manager_remove_action_group (manager, data->action_group); - - g_signal_handler_disconnect (window, data->tab_added_id); - g_signal_handler_disconnect (window, data->tab_removed_id); - - g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL); -} - -static void -impl_update_ui (XedPlugin *plugin, - XedWindow *window) -{ - WindowData *data; - - xed_debug (DEBUG_PLUGINS); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - update_ui_real (window, data); + update_ui (XED_SPELL_PLUGIN (activatable)); } static GtkWidget * -impl_create_configure_dialog (XedPlugin *plugin) +xed_spell_plugin_create_configure_widget (PeasGtkConfigurable *configurable) { - SpellConfigureDialog *dialog; + SpellConfigureWidget *widget; - dialog = get_configure_dialog(XED_SPELL_PLUGIN (plugin)); + widget = get_configure_widget (XED_SPELL_PLUGIN (configurable)); - dialog->plugin = XED_SPELL_PLUGIN (plugin); - - g_signal_connect (dialog->dialog, - "response", - G_CALLBACK (configure_dialog_response_cb), - dialog); - - return GTK_WIDGET (dialog->dialog); + return widget->content; } static void xed_spell_plugin_class_init (XedSpellPluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_spell_plugin_finalize; + object_class->dispose = xed_spell_plugin_dispose; + object_class->set_property = xed_spell_plugin_set_property; + object_class->get_property = xed_spell_plugin_get_property; - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - plugin_class->update_ui = impl_update_ui; + if (spell_checker_id == 0) + { + spell_checker_id = g_quark_from_string ("XedSpellCheckerID"); + } - plugin_class->create_configure_dialog = impl_create_configure_dialog; + if (check_range_id == 0) + { + check_range_id = g_quark_from_string ("CheckRangeID"); + } - if (spell_checker_id == 0) - spell_checker_id = g_quark_from_string ("XedSpellCheckerID"); + g_object_class_override_property (object_class, PROP_WINDOW, "window"); - if (check_range_id == 0) - check_range_id = g_quark_from_string ("CheckRangeID"); - - g_type_class_add_private (object_class, sizeof (XedSpellPluginPrivate)); + g_type_class_add_private (object_class, sizeof (XedSpellPluginPrivate)); +} + +static void +xed_spell_plugin_class_finalize (XedSpellPluginClass *klass) +{ +} + +static void +xed_window_activatable_iface_init (XedWindowActivatableInterface *iface) +{ + iface->activate = xed_spell_plugin_activate; + iface->deactivate = xed_spell_plugin_deactivate; + iface->update_state = xed_spell_plugin_update_state; +} + +static void +peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface) +{ + iface->create_configure_widget = xed_spell_plugin_create_configure_widget; +} + +G_MODULE_EXPORT void +peas_register_types (PeasObjectModule *module) +{ + xed_spell_plugin_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + XED_TYPE_WINDOW_ACTIVATABLE, + XED_TYPE_SPELL_PLUGIN); + + peas_object_module_register_extension_type (module, + PEAS_GTK_TYPE_CONFIGURABLE, + XED_TYPE_SPELL_PLUGIN); } diff --git a/plugins/spell/xed-spell-plugin.h b/plugins/spell/xed-spell-plugin.h index 998ef40..febcd3d 100644 --- a/plugins/spell/xed-spell-plugin.h +++ b/plugins/spell/xed-spell-plugin.h @@ -1,7 +1,7 @@ /* * xed-spell-plugin.h - * - * Copyright (C) 2002-2005 Paolo Maggi + * + * Copyright (C) 2002-2005 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,52 +25,37 @@ #include #include -#include +#include +#include G_BEGIN_DECLS -/* - * Type checking and casting macros - */ -#define XED_TYPE_SPELL_PLUGIN (xed_spell_plugin_get_type ()) -#define XED_SPELL_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_SPELL_PLUGIN, XedSpellPlugin)) -#define XED_SPELL_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_SPELL_PLUGIN, XedSpellPluginClass)) -#define XED_IS_SPELL_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_SPELL_PLUGIN)) -#define XED_IS_SPELL_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_SPELL_PLUGIN)) -#define XED_SPELL_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_SPELL_PLUGIN, XedSpellPluginClass)) +#define XED_TYPE_SPELL_PLUGIN (xed_spell_plugin_get_type ()) +#define XED_SPELL_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_SPELL_PLUGIN, XedSpellPlugin)) +#define XED_SPELL_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_SPELL_PLUGIN, XedSpellPluginClass)) +#define XED_IS_SPELL_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_SPELL_PLUGIN)) +#define XED_IS_SPELL_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_SPELL_PLUGIN)) +#define XED_SPELL_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_SPELL_PLUGIN, XedSpellPluginClass)) -/* Private structure type */ -typedef struct _XedSpellPluginPrivate XedSpellPluginPrivate; - -/* - * Main object structure - */ -typedef struct _XedSpellPlugin XedSpellPlugin; +typedef struct _XedSpellPlugin XedSpellPlugin; +typedef struct _XedSpellPluginPrivate XedSpellPluginPrivate; +typedef struct _XedSpellPluginClass XedSpellPluginClass; struct _XedSpellPlugin { - XedPlugin parent_instance; + PeasExtensionBase parent_instance; - XedSpellPluginPrivate *priv; + XedSpellPluginPrivate *priv; }; -/* - * Class definition - */ -typedef struct _XedSpellPluginClass XedSpellPluginClass; - struct _XedSpellPluginClass { - XedPluginClass parent_class; + PeasExtensionBaseClass parent_class; }; -/* - * Public methods - */ -GType xed_spell_plugin_get_type (void) G_GNUC_CONST; +GType xed_spell_plugin_get_type (void) G_GNUC_CONST; -/* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule *module); +G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); G_END_DECLS diff --git a/plugins/spell/xed-spell-setup-dialog.ui b/plugins/spell/xed-spell-setup-dialog.ui index abc878d..d9b56ab 100644 --- a/plugins/spell/xed-spell-setup-dialog.ui +++ b/plugins/spell/xed-spell-setup-dialog.ui @@ -1,29 +1,25 @@ - + - + + False - _Configure Spell Checker plugin... - False - normal + dialog - True False - 8 + vertical + 2 - True False end - - gtk-help + + button True True - True - False - True + True True @@ -32,13 +28,11 @@ - - gtk-cancel + + button True True - True - False - True + True True @@ -47,13 +41,11 @@ - - gtk-ok + + button True True - True - False - True + True True @@ -64,42 +56,208 @@ False - True - end + False 0 - + True False + 12 + 8 vertical + 12 True False - Autocheck spelling on document load... + Autocheck settings 0 + False - False + True 0 - - _Never autocheck + True - True - False - True - 0 - True - True + False + 30 + vertical + 12 + + + True + False + 12 + + + True + True + False + 0 + True + True + + + 0 + 0 + 2 + + + + + True + False + Never + 0 + + + + + + 1 + 0 + + + + + True + False + Never autocheck spelling on document load + 0 + + + 1 + 1 + + + + + False + True + 0 + + + + + True + False + 12 + + + True + True + False + 0 + True + True + autocheck_never + + + 0 + 0 + 2 + + + + + True + False + Remember by document + 0 + + + + + + 1 + 0 + + + + + True + False + Remembers the setting for each document on load + 0 + + + 1 + 1 + + + + + False + True + 1 + + + + + True + False + 12 + + + True + True + False + 0 + True + True + autocheck_never + + + 0 + 0 + 2 + + + + + True + False + Always + 0 + + + + + + 1 + 0 + + + + + True + False + Always autocheck on document load + 0 + + + 1 + 1 + + + + + False + True + 2 + + False @@ -107,42 +265,6 @@ 1 - - - _Remember autocheck by document - True - True - False - True - 0 - True - True - autocheck_never - - - False - True - 2 - - - - - _Always autocheck - True - True - False - True - 0 - True - True - autocheck_never - - - False - True - 3 - - False @@ -152,10 +274,5 @@ - - button1 - button3 - button4 - diff --git a/plugins/spell/xed-spell-utils.c b/plugins/spell/xed-spell-utils.c index b9e592e..b36c736 100644 --- a/plugins/spell/xed-spell-utils.c +++ b/plugins/spell/xed-spell-utils.c @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ #include #include "xed-spell-utils.h" -#include +#include gboolean xed_spell_utils_is_digit (const char *text, gssize length) diff --git a/plugins/taglist/Makefile.am b/plugins/taglist/Makefile.am index d4c4f02..124d427 100644 --- a/plugins/taglist/Makefile.am +++ b/plugins/taglist/Makefile.am @@ -15,7 +15,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir) \ $(XED_CFLAGS) \ $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) + $(DISABLE_DEPRECATED_CFLAGS) plugin_LTLIBRARIES = libtaglist.la @@ -30,9 +30,9 @@ libtaglist_la_SOURCES = \ libtaglist_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) libtaglist_la_LIBADD = $(XED_LIBS) -plugin_in_files = taglist.xed-plugin.desktop.in +plugin_in_files = taglist.plugin.desktop.in -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) +%.plugin: %.plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache GZIP_ENV = -9 @@ -41,7 +41,7 @@ GZIP_ENV = -9 LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $(@:.gz=) -x -u -c $(top_builddir)/po/.intltool-merge-cache GZIP=$(GZIP_ENV) gzip -n -f $(@:.gz=) -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) +plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin) EXTRA_DIST = \ $(taglist_in_files) $(taglist_DATA) \ diff --git a/plugins/taglist/taglist.xed-plugin.desktop.in b/plugins/taglist/taglist.plugin.desktop.in similarity index 95% rename from plugins/taglist/taglist.xed-plugin.desktop.in rename to plugins/taglist/taglist.plugin.desktop.in index 774adcb..00b0795 100644 --- a/plugins/taglist/taglist.xed-plugin.desktop.in +++ b/plugins/taglist/taglist.plugin.desktop.in @@ -1,4 +1,4 @@ -[Xed Plugin] +[Plugin] Module=taglist IAge=2 _Name=Tag list diff --git a/plugins/taglist/xed-taglist-plugin-panel.c b/plugins/taglist/xed-taglist-plugin-panel.c index a5a95d5..17d52fe 100644 --- a/plugins/taglist/xed-taglist-plugin-panel.c +++ b/plugins/taglist/xed-taglist-plugin-panel.c @@ -39,7 +39,6 @@ #include #include -#include #include #include @@ -65,11 +64,11 @@ struct _XedTaglistPluginPanelPrivate GtkWidget *preview; TagGroup *selected_tag_group; - + gchar *data_dir; }; -XED_PLUGIN_DEFINE_TYPE (XedTaglistPluginPanel, xed_taglist_plugin_panel, GTK_TYPE_BOX) +G_DEFINE_DYNAMIC_TYPE (XedTaglistPluginPanel, xed_taglist_plugin_panel, GTK_TYPE_BOX) enum { @@ -133,7 +132,7 @@ static void xed_taglist_plugin_panel_finalize (GObject *object) { XedTaglistPluginPanel *panel = XED_TAGLIST_PLUGIN_PANEL (object); - + g_free (panel->priv->data_dir); G_OBJECT_CLASS (xed_taglist_plugin_panel_parent_class)->finalize (object); @@ -160,6 +159,12 @@ xed_taglist_plugin_panel_class_init (XedTaglistPluginPanelClass *klass) g_type_class_add_private (object_class, sizeof(XedTaglistPluginPanelPrivate)); } +static void +xed_taglist_plugin_panel_class_finalize (XedTaglistPluginPanelClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE */ +} + static void insert_tag (XedTaglistPluginPanel *panel, Tag *tag, @@ -431,7 +436,7 @@ selected_group_changed (GtkComboBox *combo, populate_tags_list (panel); } - + /* Clean up preview */ gtk_label_set_text (GTK_LABEL (panel->priv->preview), ""); @@ -634,8 +639,8 @@ add_preview_widget (XedTaglistPluginPanel *panel) gtk_widget_set_halign (panel->priv->preview, GTK_ALIGN_START); gtk_widget_set_valign (panel->priv->preview, GTK_ALIGN_START); - gtk_widget_set_margin_left (panel->priv->preview, 6); - gtk_widget_set_margin_right (panel->priv->preview, 6); + gtk_widget_set_margin_start (panel->priv->preview, 6); + gtk_widget_set_margin_end (panel->priv->preview, 6); gtk_widget_set_margin_top (panel->priv->preview, 6); gtk_widget_set_margin_bottom (panel->priv->preview, 6); @@ -781,8 +786,14 @@ xed_taglist_plugin_panel_new (XedWindow *window, panel = g_object_new (XED_TYPE_TAGLIST_PLUGIN_PANEL, "window", window, NULL); - + panel->priv->data_dir = g_strdup (data_dir); - + return GTK_WIDGET (panel); } + +void +_xed_taglist_plugin_panel_register_type (GTypeModule *type_module) +{ + xed_taglist_plugin_panel_register_type (type_module); +} diff --git a/plugins/taglist/xed-taglist-plugin-panel.h b/plugins/taglist/xed-taglist-plugin-panel.h index 72d1ec1..9583b8a 100644 --- a/plugins/taglist/xed-taglist-plugin-panel.h +++ b/plugins/taglist/xed-taglist-plugin-panel.h @@ -2,7 +2,7 @@ * xed-taglist-plugin-panel.h * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -56,12 +56,12 @@ typedef struct _XedTaglistPluginPanelPrivate XedTaglistPluginPanelPrivate; */ typedef struct _XedTaglistPluginPanel XedTaglistPluginPanel; -struct _XedTaglistPluginPanel +struct _XedTaglistPluginPanel { - GtkBox vbox; + GtkBox vbox; - /*< private > */ - XedTaglistPluginPanelPrivate *priv; + /*< private > */ + XedTaglistPluginPanelPrivate *priv; }; /* @@ -69,20 +69,20 @@ struct _XedTaglistPluginPanel */ typedef struct _XedTaglistPluginPanelClass XedTaglistPluginPanelClass; -struct _XedTaglistPluginPanelClass +struct _XedTaglistPluginPanelClass { - GtkBoxClass parent_class; + GtkBoxClass parent_class; }; /* * Public methods */ -GType xed_taglist_plugin_panel_register_type (GTypeModule *module); - -GType xed_taglist_plugin_panel_get_type (void) G_GNUC_CONST; +void _xed_taglist_plugin_panel_register_type (GTypeModule *module); -GtkWidget *xed_taglist_plugin_panel_new (XedWindow *window, - const gchar *data_dir); +GType xed_taglist_plugin_panel_get_type (void) G_GNUC_CONST; + +GtkWidget *xed_taglist_plugin_panel_new (XedWindow *window, + const gchar *data_dir); G_END_DECLS diff --git a/plugins/taglist/xed-taglist-plugin-parser.c b/plugins/taglist/xed-taglist-plugin-parser.c index 99c3ab4..bb0bdc1 100644 --- a/plugins/taglist/xed-taglist-plugin-parser.c +++ b/plugins/taglist/xed-taglist-plugin-parser.c @@ -44,7 +44,6 @@ #include "xed-taglist-plugin-parser.h" /* we screwed up so we still look here for compatibility */ -#define USER_XED_TAGLIST_PLUGIN_LOCATION_LEGACY ".xed/plugins/taglist/" #define USER_XED_TAGLIST_PLUGIN_LOCATION "xed/taglist/" TagList* taglist = NULL; @@ -603,32 +602,11 @@ TagList* create_taglist(const gchar* data_dir) } const gchar* home; - const gchar* envvar; /* load user's taglists */ - /* legacy dir */ home = g_get_home_dir (); if (home != NULL) - { - pdir = g_build_filename (home, - USER_XED_TAGLIST_PLUGIN_LOCATION_LEGACY, - NULL); - parse_taglist_dir (pdir); - g_free (pdir); - } - - /* Support old libmate env var */ - envvar = g_getenv ("MATE22_USER_DIR"); - if (envvar != NULL) - { - pdir = g_build_filename (envvar, - USER_XED_TAGLIST_PLUGIN_LOCATION, - NULL); - parse_taglist_dir (pdir); - g_free (pdir); - } - else if (home != NULL) { pdir = g_build_filename(home, ".config", USER_XED_TAGLIST_PLUGIN_LOCATION, NULL); parse_taglist_dir(pdir); diff --git a/plugins/taglist/xed-taglist-plugin.c b/plugins/taglist/xed-taglist-plugin.c index 8cfa239..ea23652 100644 --- a/plugins/taglist/xed-taglist-plugin.c +++ b/plugins/taglist/xed-taglist-plugin.c @@ -1,6 +1,6 @@ /* * xed-taglist-plugin.h - * + * * Copyright (C) 2002-2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify @@ -20,9 +20,9 @@ */ /* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2002-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -36,125 +36,190 @@ #include "xed-taglist-plugin-parser.h" #include -#include -#include +#include +#include #include -#define WINDOW_DATA_KEY "XedTaglistPluginWindowData" - #define XED_TAGLIST_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_TAGLIST_PLUGIN, XedTaglistPluginPrivate)) struct _XedTaglistPluginPrivate { - gpointer dummy; + XedWindow *window; + + GtkWidget *taglist_panel; }; -XED_PLUGIN_REGISTER_TYPE_WITH_CODE (XedTaglistPlugin, xed_taglist_plugin, - xed_taglist_plugin_panel_register_type (module); +static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedTaglistPlugin, + xed_taglist_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, + xed_window_activatable_iface_init) \ + \ + _xed_taglist_plugin_panel_register_type (type_module); \ ) +enum +{ + PROP_0, + PROP_WINDOW +}; + static void xed_taglist_plugin_init (XedTaglistPlugin *plugin) { - plugin->priv = XED_TAGLIST_PLUGIN_GET_PRIVATE (plugin); + plugin->priv = XED_TAGLIST_PLUGIN_GET_PRIVATE (plugin); - xed_debug_message (DEBUG_PLUGINS, "XedTaglistPlugin initializing"); + xed_debug_message (DEBUG_PLUGINS, "XedTaglistPlugin initializing"); +} + +static void +xed_taglist_plugin_dispose (GObject *object) +{ + XedTaglistPlugin *plugin = XED_TAGLIST_PLUGIN (object); + + xed_debug_message (DEBUG_PLUGINS, "XedTaglistPlugin disposing"); + + g_clear_object (&plugin->priv->window); + + G_OBJECT_CLASS (xed_taglist_plugin_parent_class)->dispose (object); } static void xed_taglist_plugin_finalize (GObject *object) { -/* - XedTaglistPlugin *plugin = XED_TAGLIST_PLUGIN (object); -*/ - xed_debug_message (DEBUG_PLUGINS, "XedTaglistPlugin finalizing"); + xed_debug_message (DEBUG_PLUGINS, "XedTaglistPlugin finalizing"); - free_taglist (); - - G_OBJECT_CLASS (xed_taglist_plugin_parent_class)->finalize (object); + free_taglist (); + + G_OBJECT_CLASS (xed_taglist_plugin_parent_class)->finalize (object); } static void -impl_activate (XedPlugin *plugin, - XedWindow *window) +xed_taglist_plugin_activate (XedWindowActivatable *activatable) { - XedPanel *side_panel; - GtkWidget *taglist_panel; - gchar *data_dir; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY) == NULL); - - side_panel = xed_window_get_side_panel (window); - - data_dir = xed_plugin_get_data_dir (plugin); - taglist_panel = xed_taglist_plugin_panel_new (window, data_dir); - g_free (data_dir); - - xed_panel_add_item_with_stock_icon (side_panel, - taglist_panel, - _("Tags"), - GTK_STOCK_ADD); + XedTaglistPluginPrivate *priv; + XedPanel *side_panel; + gchar *data_dir; - g_object_set_data (G_OBJECT (window), - WINDOW_DATA_KEY, - taglist_panel); + xed_debug (DEBUG_PLUGINS); + + priv = XED_TAGLIST_PLUGIN (activatable)->priv; + side_panel = xed_window_get_side_panel (priv->window); + + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (activatable)); + priv->taglist_panel = xed_taglist_plugin_panel_new (priv->window, data_dir); + g_free (data_dir); + + xed_panel_add_item (side_panel, priv->taglist_panel, _("Tags"), "list-add"); } static void -impl_deactivate (XedPlugin *plugin, - XedWindow *window) +xed_taglist_plugin_deactivate (XedWindowActivatable *activatable) { - XedPanel *side_panel; - gpointer data; - - xed_debug (DEBUG_PLUGINS); - - data = g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - side_panel = xed_window_get_side_panel (window); + XedTaglistPluginPrivate *priv; + XedPanel *side_panel; - xed_panel_remove_item (side_panel, - GTK_WIDGET (data)); - - g_object_set_data (G_OBJECT (window), - WINDOW_DATA_KEY, - NULL); + xed_debug (DEBUG_PLUGINS); + + priv = XED_TAGLIST_PLUGIN (activatable)->priv; + side_panel = xed_window_get_side_panel (priv->window); + + xed_panel_remove_item (side_panel, priv->taglist_panel); } static void -impl_update_ui (XedPlugin *plugin, - XedWindow *window) +xed_taglist_plugin_update_state (XedWindowActivatable *activatable) { - gpointer data; - XedView *view; - - xed_debug (DEBUG_PLUGINS); - - data = g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - view = xed_window_get_active_view (window); - - gtk_widget_set_sensitive (GTK_WIDGET (data), - (view != NULL) && - gtk_text_view_get_editable (GTK_TEXT_VIEW (view))); + XedTaglistPluginPrivate *priv; + XedView *view; + + xed_debug (DEBUG_PLUGINS); + + priv = XED_TAGLIST_PLUGIN (activatable)->priv; + view = xed_window_get_active_view (priv->window); + + gtk_widget_set_sensitive (priv->taglist_panel, + (view != NULL) && + gtk_text_view_get_editable (GTK_TEXT_VIEW (view))); +} + +static void +xed_taglist_plugin_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XedTaglistPlugin *plugin = XED_TAGLIST_PLUGIN (object); + + switch (prop_id) + { + case PROP_WINDOW: + plugin->priv->window = XED_WINDOW (g_value_dup_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_taglist_plugin_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XedTaglistPlugin *plugin = XED_TAGLIST_PLUGIN (object); + + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, plugin->priv->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_taglist_plugin_class_init (XedTaglistPluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_taglist_plugin_finalize; + object_class->finalize = xed_taglist_plugin_finalize; + object_class->dispose = xed_taglist_plugin_dispose; + object_class->set_property = xed_taglist_plugin_set_property; + object_class->get_property = xed_taglist_plugin_get_property; - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - plugin_class->update_ui = impl_update_ui; + g_object_class_override_property (object_class, PROP_WINDOW, "window"); - g_type_class_add_private (object_class, sizeof (XedTaglistPluginPrivate)); + g_type_class_add_private (object_class, sizeof (XedTaglistPluginPrivate)); +} + +static void +xed_taglist_plugin_class_finalize (XedTaglistPluginClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE_EXTENDED */ +} + +static void +xed_window_activatable_iface_init (XedWindowActivatableInterface *iface) +{ + iface->activate = xed_taglist_plugin_activate; + iface->deactivate = xed_taglist_plugin_deactivate; + iface->update_state = xed_taglist_plugin_update_state; +} + +G_MODULE_EXPORT void +peas_register_types (PeasObjectModule *module) +{ + xed_taglist_plugin_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + XED_TYPE_WINDOW_ACTIVATABLE, + XED_TYPE_TAGLIST_PLUGIN); } diff --git a/plugins/taglist/xed-taglist-plugin.h b/plugins/taglist/xed-taglist-plugin.h index a71083e..4a2d035 100644 --- a/plugins/taglist/xed-taglist-plugin.h +++ b/plugins/taglist/xed-taglist-plugin.h @@ -1,6 +1,6 @@ /* * xed-taglist-plugin.h - * + * * Copyright (C) 2002-2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify @@ -20,65 +20,51 @@ */ /* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ + * Modified by the xed Team, 2002-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ - + #ifndef __XED_TAGLIST_PLUGIN_H__ #define __XED_TAGLIST_PLUGIN_H__ #include #include -#include +#include +#include G_BEGIN_DECLS /* * Type checking and casting macros */ -#define XED_TYPE_TAGLIST_PLUGIN (xed_taglist_plugin_get_type ()) -#define XED_TAGLIST_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_TAGLIST_PLUGIN, XedTaglistPlugin)) -#define XED_TAGLIST_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_TAGLIST_PLUGIN, XedTaglistPluginClass)) -#define XED_IS_TAGLIST_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_TAGLIST_PLUGIN)) -#define XED_IS_TAGLIST_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_TAGLIST_PLUGIN)) -#define XED_TAGLIST_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_TAGLIST_PLUGIN, XedTaglistPluginClass)) +#define XED_TYPE_TAGLIST_PLUGIN (xed_taglist_plugin_get_type ()) +#define XED_TAGLIST_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_TAGLIST_PLUGIN, XedTaglistPlugin)) +#define XED_TAGLIST_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_TAGLIST_PLUGIN, XedTaglistPluginClass)) +#define XED_IS_TAGLIST_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_TAGLIST_PLUGIN)) +#define XED_IS_TAGLIST_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_TAGLIST_PLUGIN)) +#define XED_TAGLIST_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_TAGLIST_PLUGIN, XedTaglistPluginClass)) -/* Private structure type */ -typedef struct _XedTaglistPluginPrivate XedTaglistPluginPrivate; - -/* - * Main object structure - */ -typedef struct _XedTaglistPlugin XedTaglistPlugin; +typedef struct _XedTaglistPlugin XedTaglistPlugin; +typedef struct _XedTaglistPluginPrivate XedTaglistPluginPrivate; +typedef struct _XedTaglistPluginClass XedTaglistPluginClass; struct _XedTaglistPlugin { - XedPlugin parent_instance; + PeasExtensionBase parent_instance; - /*< private >*/ - XedTaglistPluginPrivate *priv; + /*< private >*/ + XedTaglistPluginPrivate *priv; }; -/* - * Class definition - */ -typedef struct _XedTaglistPluginClass XedTaglistPluginClass; - struct _XedTaglistPluginClass { - XedPluginClass parent_class; + PeasExtensionBaseClass parent_class; }; -/* - * Public methods - */ -GType xed_taglist_plugin_get_type (void) G_GNUC_CONST; +GType xed_taglist_plugin_get_type (void) G_GNUC_CONST; -/* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule *module); +G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); G_END_DECLS diff --git a/plugins/time/Makefile.am b/plugins/time/Makefile.am index afd1e26..808aef0 100644 --- a/plugins/time/Makefile.am +++ b/plugins/time/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir) \ $(XED_CFLAGS) \ $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) + $(DISABLE_DEPRECATED_CFLAGS) plugin_LTLIBRARIES = libtime.la @@ -21,11 +21,11 @@ ui_DATA = \ xed-time-dialog.ui \ xed-time-setup-dialog.ui -plugin_in_files = time.xed-plugin.desktop.in +plugin_in_files = time.plugin.desktop.in -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache +%.plugin: %.plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) +plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin) @INTLTOOL_XML_NOMERGE_RULE@ time_gschema_in = org.x.editor.plugins.time.gschema.xml.in diff --git a/plugins/time/time.xed-plugin.desktop.in b/plugins/time/time.plugin.desktop.in similarity index 95% rename from plugins/time/time.xed-plugin.desktop.in rename to plugins/time/time.plugin.desktop.in index aaaa6ed..a59f208 100644 --- a/plugins/time/time.xed-plugin.desktop.in +++ b/plugins/time/time.plugin.desktop.in @@ -1,4 +1,4 @@ -[Xed Plugin] +[Plugin] Module=time IAge=2 _Name=Insert Date/Time diff --git a/plugins/time/xed-time-plugin.c b/plugins/time/xed-time-plugin.c index da3a890..3fd3840 100644 --- a/plugins/time/xed-time-plugin.c +++ b/plugins/time/xed-time-plugin.c @@ -16,8 +16,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $Id$ */ /* @@ -34,1188 +32,1084 @@ #include #include "xed-time-plugin.h" -#include +#include #include #include -#include #include +#include +#include +#include #include #include #define XED_TIME_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_TIME_PLUGIN, \ - XedTimePluginPrivate)) + XED_TYPE_TIME_PLUGIN, \ + XedTimePluginPrivate)) -#define WINDOW_DATA_KEY "XedTimePluginWindowData" #define MENU_PATH "/MenuBar/EditMenu/EditOps_4" /* GSettings keys */ -#define TIME_SCHEMA "org.x.editor.plugins.time" -#define PROMPT_TYPE_KEY "prompt-type" -#define SELECTED_FORMAT_KEY "selected-format" -#define CUSTOM_FORMAT_KEY "custom-format" +#define TIME_SCHEMA "org.x.editor.plugins.time" +#define PROMPT_TYPE_KEY "prompt-type" +#define SELECTED_FORMAT_KEY "selected-format" +#define CUSTOM_FORMAT_KEY "custom-format" #define DEFAULT_CUSTOM_FORMAT "%d/%m/%Y %H:%M:%S" static const gchar *formats[] = { - "%c", - "%x", - "%X", - "%x %X", - "%Y-%m-%d %H:%M:%S", - "%a %b %d %H:%M:%S %Z %Y", - "%a %b %d %H:%M:%S %Y", - "%a %d %b %Y %H:%M:%S %Z", - "%a %d %b %Y %H:%M:%S", - "%d/%m/%Y", - "%d/%m/%y", - "%D", - "%A %d %B %Y", - "%A %B %d %Y", - "%Y-%m-%d", - "%d %B %Y", - "%B %d, %Y", - "%A %b %d", - "%H:%M:%S", - "%H:%M", - "%I:%M:%S %p", - "%I:%M %p", - "%H.%M.%S", - "%H.%M", - "%I.%M.%S %p", - "%I.%M %p", - "%d/%m/%Y %H:%M:%S", - "%d/%m/%y %H:%M:%S", + "%c", + "%x", + "%X", + "%x %X", + "%Y-%m-%d %H:%M:%S", + "%a %b %d %H:%M:%S %Z %Y", + "%a %b %d %H:%M:%S %Y", + "%a %d %b %Y %H:%M:%S %Z", + "%a %d %b %Y %H:%M:%S", + "%d/%m/%Y", + "%d/%m/%y", + "%D", + "%A %d %B %Y", + "%A %B %d %Y", + "%Y-%m-%d", + "%d %B %Y", + "%B %d, %Y", + "%A %b %d", + "%H:%M:%S", + "%H:%M", + "%I:%M:%S %p", + "%I:%M %p", + "%H.%M.%S", + "%H.%M", + "%I.%M.%S %p", + "%I.%M %p", + "%d/%m/%Y %H:%M:%S", + "%d/%m/%y %H:%M:%S", #if __GLIBC__ >= 2 - "%a, %d %b %Y %H:%M:%S %z", + "%a, %d %b %Y %H:%M:%S %z", #endif - NULL + NULL }; enum { - COLUMN_FORMATS = 0, - COLUMN_INDEX, - NUM_COLUMNS + COLUMN_FORMATS = 0, + COLUMN_INDEX, + NUM_COLUMNS }; -typedef struct _TimeConfigureDialog TimeConfigureDialog; - -struct _TimeConfigureDialog +typedef enum { - GtkWidget *dialog; + PROMPT_SELECTED_FORMAT = 0, /* Popup dialog with list preselected */ + PROMPT_CUSTOM_FORMAT, /* Popup dialog with entry preselected */ + USE_SELECTED_FORMAT, /* Use selected format directly */ + USE_CUSTOM_FORMAT /* Use custom format directly */ +} XedTimePluginPromptType; - GtkWidget *list; +typedef struct _TimeConfigureWidget TimeConfigureWidget; - /* Radio buttons to indicate what should be done */ - GtkWidget *prompt; - GtkWidget *use_list; - GtkWidget *custom; +struct _TimeConfigureWidget +{ + GtkWidget *content; - GtkWidget *custom_entry; - GtkWidget *custom_format_example; + GtkWidget *list; - /* Info needed for the response handler */ - XedTimePlugin *plugin; + /* Radio buttons to indicate what should be done */ + GtkWidget *prompt; + GtkWidget *use_list; + GtkWidget *custom; + + GtkWidget *custom_entry; + GtkWidget *custom_format_example; + + GSettings *settings; }; typedef struct _ChooseFormatDialog ChooseFormatDialog; struct _ChooseFormatDialog { - GtkWidget *dialog; + GtkWidget *dialog; - GtkWidget *list; + GtkWidget *list; - /* Radio buttons to indicate what should be done */ - GtkWidget *use_list; - GtkWidget *custom; + /* Radio buttons to indicate what should be done */ + GtkWidget *use_list; + GtkWidget *custom; - GtkWidget *custom_entry; - GtkWidget *custom_format_example; + GtkWidget *custom_entry; + GtkWidget *custom_format_example; - /* Info needed for the response handler */ - GtkTextBuffer *buffer; - XedTimePlugin *plugin; + /* Info needed for the response handler */ + GtkTextBuffer *buffer; + + GSettings *settings; }; -typedef enum -{ - PROMPT_SELECTED_FORMAT = 0, /* Popup dialog with list preselected */ - PROMPT_CUSTOM_FORMAT, /* Popup dialog with entry preselected */ - USE_SELECTED_FORMAT, /* Use selected format directly */ - USE_CUSTOM_FORMAT /* Use custom format directly */ -} XedTimePluginPromptType; - struct _XedTimePluginPrivate { - GSettings *settings; + XedWindow *window; + + GSettings *settings; + + GtkActionGroup *action_group; + guint ui_id; }; -XED_PLUGIN_REGISTER_TYPE(XedTimePlugin, xed_time_plugin) - -typedef struct +enum { - GtkActionGroup *action_group; - guint ui_id; -} WindowData; + PROP_0, + PROP_WINDOW +}; -typedef struct -{ - XedWindow *window; - XedTimePlugin *plugin; -} ActionData; +static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface); +static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface); -static void time_cb (GtkAction *action, ActionData *data); +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedTimePlugin, + xed_time_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, + xed_window_activatable_iface_init) + G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE, + peas_gtk_configurable_iface_init)) + +static void time_cb (GtkAction *action, + XedTimePlugin *plugin); static const GtkActionEntry action_entries[] = { - { - "InsertDateAndTime", - NULL, - N_("In_sert Date and Time..."), - NULL, - N_("Insert current date and time at the cursor position"), - G_CALLBACK (time_cb) - }, + { + "InsertDateAndTime", + NULL, + N_("In_sert Date and Time..."), + NULL, + N_("Insert current date and time at the cursor position"), + G_CALLBACK (time_cb) + }, }; static void xed_time_plugin_init (XedTimePlugin *plugin) { - xed_debug_message (DEBUG_PLUGINS, "XedTimePlugin initializing"); + xed_debug_message (DEBUG_PLUGINS, "XedTimePlugin initializing"); - plugin->priv = XED_TIME_PLUGIN_GET_PRIVATE (plugin); + plugin->priv = XED_TIME_PLUGIN_GET_PRIVATE (plugin); - plugin->priv->settings = g_settings_new (TIME_SCHEMA); + plugin->priv->settings = g_settings_new (TIME_SCHEMA); } static void xed_time_plugin_finalize (GObject *object) { - XedTimePlugin *plugin = XED_TIME_PLUGIN (object); + XedTimePlugin *plugin = XED_TIME_PLUGIN (object); - xed_debug_message (DEBUG_PLUGINS, "XedTimePlugin finalizing"); + xed_debug_message (DEBUG_PLUGINS, "XedTimePlugin finalizing"); - g_object_unref (G_OBJECT (plugin->priv->settings)); + g_object_unref (G_OBJECT (plugin->priv->settings)); - G_OBJECT_CLASS (xed_time_plugin_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_time_plugin_parent_class)->finalize (object); } static void -free_window_data (WindowData *data) +xed_time_plugin_dispose (GObject *object) { - g_return_if_fail (data != NULL); + XedTimePlugin *plugin = XED_TIME_PLUGIN (object); - g_object_unref (data->action_group); - g_free (data); + xed_debug_message (DEBUG_PLUGINS, "XedTimePlugin disposing"); + + g_clear_object (&plugin->priv->window); + g_clear_object (&plugin->priv->action_group); + + G_OBJECT_CLASS (xed_time_plugin_parent_class)->dispose (object); } static void -update_ui_real (XedWindow *window, - WindowData *data) +update_ui (XedTimePlugin *plugin) { - XedView *view; - GtkAction *action; + XedView *view; + GtkAction *action; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - view = xed_window_get_active_view (window); + view = xed_window_get_active_view (plugin->priv->window); - xed_debug_message (DEBUG_PLUGINS, "View: %p", view); + xed_debug_message (DEBUG_PLUGINS, "View: %p", view); - action = gtk_action_group_get_action (data->action_group, - "InsertDateAndTime"); - gtk_action_set_sensitive (action, - (view != NULL) && - gtk_text_view_get_editable (GTK_TEXT_VIEW (view))); + action = gtk_action_group_get_action (plugin->priv->action_group, "InsertDateAndTime"); + gtk_action_set_sensitive (action, (view != NULL) && gtk_text_view_get_editable (GTK_TEXT_VIEW (view))); } static void -impl_activate (XedPlugin *plugin, - XedWindow *window) +xed_time_plugin_activate (XedWindowActivatable *activatable) { - GtkUIManager *manager; - WindowData *data; - ActionData *action_data; + XedTimePluginPrivate *priv; + GtkUIManager *manager; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - data = g_new (WindowData, 1); - action_data = g_new (ActionData, 1); + priv = XED_TIME_PLUGIN (activatable)->priv; + manager = xed_window_get_ui_manager (priv->window); - action_data->plugin = XED_TIME_PLUGIN (plugin); - action_data->window = window; + priv->action_group = gtk_action_group_new ("XedTimePluginActions"); + gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions (priv->action_group, action_entries, G_N_ELEMENTS (action_entries), activatable); - manager = xed_window_get_ui_manager (window); + gtk_ui_manager_insert_action_group (manager, priv->action_group, -1); - data->action_group = gtk_action_group_new ("XedTimePluginActions"); - gtk_action_group_set_translation_domain (data->action_group, - GETTEXT_PACKAGE); - gtk_action_group_add_actions_full (data->action_group, - action_entries, - G_N_ELEMENTS (action_entries), - action_data, - (GDestroyNotify) g_free); + priv->ui_id = gtk_ui_manager_new_merge_id (manager); - gtk_ui_manager_insert_action_group (manager, data->action_group, -1); + gtk_ui_manager_add_ui (manager, + priv->ui_id, + MENU_PATH, + "InsertDateAndTime", + "InsertDateAndTime", + GTK_UI_MANAGER_MENUITEM, + FALSE); - data->ui_id = gtk_ui_manager_new_merge_id (manager); - - g_object_set_data_full (G_OBJECT (window), - WINDOW_DATA_KEY, - data, - (GDestroyNotify) free_window_data); - - gtk_ui_manager_add_ui (manager, - data->ui_id, - MENU_PATH, - "InsertDateAndTime", - "InsertDateAndTime", - GTK_UI_MANAGER_MENUITEM, - FALSE); - - update_ui_real (window, data); + update_ui (XED_TIME_PLUGIN (activatable)); } static void -impl_deactivate (XedPlugin *plugin, - XedWindow *window) +xed_time_plugin_deactivate (XedWindowActivatable *activatable) { - GtkUIManager *manager; - WindowData *data; + XedTimePluginPrivate *priv; + GtkUIManager *manager; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - manager = xed_window_get_ui_manager (window); + priv = XED_TIME_PLUGIN (activatable)->priv; + manager = xed_window_get_ui_manager (priv->window); - data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - gtk_ui_manager_remove_ui (manager, data->ui_id); - gtk_ui_manager_remove_action_group (manager, data->action_group); - - g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL); + gtk_ui_manager_remove_ui (manager, priv->ui_id); + gtk_ui_manager_remove_action_group (manager, priv->action_group); } static void -impl_update_ui (XedPlugin *plugin, - XedWindow *window) +xed_time_plugin_update_state (XedWindowActivatable *activatable) { - WindowData *data; + xed_debug (DEBUG_PLUGINS); - xed_debug (DEBUG_PLUGINS); - - data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY); - g_return_if_fail (data != NULL); - - update_ui_real (window, data); -} - -/* whether we should prompt the user or use the specified format */ -static XedTimePluginPromptType -get_prompt_type (XedTimePlugin *plugin) -{ - XedTimePluginPromptType prompt_type; - - prompt_type = g_settings_get_enum (plugin->priv->settings, - PROMPT_TYPE_KEY); - - return prompt_type; -} - -static void -set_prompt_type (XedTimePlugin *plugin, - XedTimePluginPromptType prompt_type) -{ - if (!g_settings_is_writable (plugin->priv->settings, - PROMPT_TYPE_KEY)) - { - return; - } - - g_settings_set_enum (plugin->priv->settings, - PROMPT_TYPE_KEY, - prompt_type); + update_ui (XED_TIME_PLUGIN (activatable)); } /* The selected format in the list */ static gchar * get_selected_format (XedTimePlugin *plugin) { - gchar *sel_format; + gchar *sel_format; - sel_format = g_settings_get_string (plugin->priv->settings, - SELECTED_FORMAT_KEY); + sel_format = g_settings_get_string (plugin->priv->settings, SELECTED_FORMAT_KEY); - return sel_format ? sel_format : g_strdup (formats [0]); -} - -static void -set_selected_format (XedTimePlugin *plugin, - const gchar *format) -{ - g_return_if_fail (format != NULL); - - if (!g_settings_is_writable (plugin->priv->settings, - SELECTED_FORMAT_KEY)) - { - return; - } - - g_settings_set_string (plugin->priv->settings, - SELECTED_FORMAT_KEY, - format); + return sel_format ? sel_format : g_strdup (formats [0]); } /* the custom format in the entry */ static gchar * get_custom_format (XedTimePlugin *plugin) { - gchar *format; + gchar *format; - format = g_settings_get_string (plugin->priv->settings, - CUSTOM_FORMAT_KEY); + format = g_settings_get_string (plugin->priv->settings, CUSTOM_FORMAT_KEY); - return format ? format : g_strdup (DEFAULT_CUSTOM_FORMAT); -} - -static void -set_custom_format (XedTimePlugin *plugin, - const gchar *format) -{ - g_return_if_fail (format != NULL); - - if (!g_settings_is_writable (plugin->priv->settings, - CUSTOM_FORMAT_KEY)) - return; - - g_settings_set_string (plugin->priv->settings, - CUSTOM_FORMAT_KEY, - format); + return format ? format : g_strdup (DEFAULT_CUSTOM_FORMAT); } static gchar * get_time (const gchar* format) { - gchar *out = NULL; - gchar *out_utf8 = NULL; - time_t clock; - struct tm *now; - size_t out_length = 0; - gchar *locale_format; + gchar *out = NULL; + gchar *out_utf8 = NULL; + time_t clock; + struct tm *now; + size_t out_length = 0; + gchar *locale_format; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_val_if_fail (format != NULL, NULL); + g_return_val_if_fail (format != NULL, NULL); - if (strlen (format) == 0) - return g_strdup (" "); + if (strlen (format) == 0) + { + return g_strdup (" "); + } - locale_format = g_locale_from_utf8 (format, -1, NULL, NULL, NULL); - if (locale_format == NULL) - return g_strdup (" "); + locale_format = g_locale_from_utf8 (format, -1, NULL, NULL, NULL); + if (locale_format == NULL) + { + return g_strdup (" "); + } - clock = time (NULL); - now = localtime (&clock); + clock = time (NULL); + now = localtime (&clock); - do - { - out_length += 255; - out = g_realloc (out, out_length); - } - while (strftime (out, out_length, locale_format, now) == 0); + do + { + out_length += 255; + out = g_realloc (out, out_length); + } + while (strftime (out, out_length, locale_format, now) == 0); - g_free (locale_format); + g_free (locale_format); - if (g_utf8_validate (out, -1, NULL)) - { - out_utf8 = out; - } - else - { - out_utf8 = g_locale_to_utf8 (out, -1, NULL, NULL, NULL); - g_free (out); + if (g_utf8_validate (out, -1, NULL)) + { + out_utf8 = out; + } + else + { + out_utf8 = g_locale_to_utf8 (out, -1, NULL, NULL, NULL); + g_free (out); - if (out_utf8 == NULL) - out_utf8 = g_strdup (" "); - } + if (out_utf8 == NULL) + { + out_utf8 = g_strdup (" "); + } + } - return out_utf8; + return out_utf8; } static void -dialog_disposed (GObject *obj, gpointer dialog_pointer) +configure_widget_destroyed (GtkWidget *widget, + gpointer data) { - xed_debug (DEBUG_PLUGINS); + TimeConfigureWidget *conf_widget = (TimeConfigureWidget *) data; - g_free (dialog_pointer); + xed_debug (DEBUG_PLUGINS); - xed_debug_message (DEBUG_PLUGINS, "END"); + g_object_unref (conf_widget->settings); + g_slice_free (TimeConfigureWidget, data); + + xed_debug_message (DEBUG_PLUGINS, "END"); +} + +static void +choose_format_dialog_destroyed (GtkWidget *widget, + gpointer data) +{ + xed_debug (DEBUG_PLUGINS); + + g_slice_free (ChooseFormatDialog, data); + + xed_debug_message (DEBUG_PLUGINS, "END"); } static GtkTreeModel * -create_model (GtkWidget *listview, - const gchar *sel_format, - XedTimePlugin *plugin) +create_model (GtkWidget *listview, + const gchar *sel_format, + XedTimePlugin *plugin) { - gint i = 0; - GtkListStore *store; - GtkTreeSelection *selection; - GtkTreeIter iter; + gint i = 0; + GtkListStore *store; + GtkTreeSelection *selection; + GtkTreeIter iter; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - /* create list store */ - store = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_INT); + /* create list store */ + store = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_INT); - /* Set tree view model*/ - gtk_tree_view_set_model (GTK_TREE_VIEW (listview), - GTK_TREE_MODEL (store)); - g_object_unref (G_OBJECT (store)); + /* Set tree view model*/ + gtk_tree_view_set_model (GTK_TREE_VIEW (listview), GTK_TREE_MODEL (store)); + g_object_unref (G_OBJECT (store)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (listview)); - g_return_val_if_fail (selection != NULL, GTK_TREE_MODEL (store)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (listview)); + g_return_val_if_fail (selection != NULL, GTK_TREE_MODEL (store)); - /* there should always be one line selected */ - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + /* there should always be one line selected */ + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - /* add data to the list store */ - while (formats[i] != NULL) - { - gchar *str; + /* add data to the list store */ + while (formats[i] != NULL) + { + gchar *str; - str = get_time (formats[i]); + str = get_time (formats[i]); - xed_debug_message (DEBUG_PLUGINS, "%d : %s", i, str); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COLUMN_FORMATS, str, - COLUMN_INDEX, i, - -1); - g_free (str); + xed_debug_message (DEBUG_PLUGINS, "%d : %s", i, str); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, COLUMN_FORMATS, str, COLUMN_INDEX, i, -1); + g_free (str); - if (sel_format && strcmp (formats[i], sel_format) == 0) - gtk_tree_selection_select_iter (selection, &iter); + if (sel_format && strcmp (formats[i], sel_format) == 0) + { + gtk_tree_selection_select_iter (selection, &iter); + } - ++i; - } + ++i; + } - /* fall back to select the first iter */ - if (!gtk_tree_selection_get_selected (selection, NULL, NULL)) - { - gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter); - gtk_tree_selection_select_iter (selection, &iter); - } + /* fall back to select the first iter */ + if (!gtk_tree_selection_get_selected (selection, NULL, NULL)) + { + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter); + gtk_tree_selection_select_iter (selection, &iter); + } - return GTK_TREE_MODEL (store); + return GTK_TREE_MODEL (store); } static void scroll_to_selected (GtkTreeView *tree_view) { - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - model = gtk_tree_view_get_model (tree_view); - g_return_if_fail (model != NULL); + model = gtk_tree_view_get_model (tree_view); + g_return_if_fail (model != NULL); - /* Scroll to selected */ - selection = gtk_tree_view_get_selection (tree_view); - g_return_if_fail (selection != NULL); + /* Scroll to selected */ + selection = gtk_tree_view_get_selection (tree_view); + g_return_if_fail (selection != NULL); - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - GtkTreePath* path; + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + GtkTreePath* path; - path = gtk_tree_model_get_path (model, &iter); - g_return_if_fail (path != NULL); + path = gtk_tree_model_get_path (model, &iter); + g_return_if_fail (path != NULL); - gtk_tree_view_scroll_to_cell (tree_view, - path, NULL, TRUE, 1.0, 0.0); - gtk_tree_path_free (path); - } + gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 1.0, 0.0); + gtk_tree_path_free (path); + } } static void -create_formats_list (GtkWidget *listview, - const gchar *sel_format, - XedTimePlugin *plugin) +create_formats_list (GtkWidget *listview, + const gchar *sel_format, + XedTimePlugin *plugin) { - GtkTreeViewColumn *column; - GtkCellRenderer *cell; + GtkTreeViewColumn *column; + GtkCellRenderer *cell; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_if_fail (listview != NULL); - g_return_if_fail (sel_format != NULL); + g_return_if_fail (listview != NULL); + g_return_if_fail (sel_format != NULL); - /* the Available formats column */ - cell = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ( - _("Available formats"), - cell, - "text", COLUMN_FORMATS, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (listview), column); + /* the Available formats column */ + cell = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Available formats"), + cell, + "text", COLUMN_FORMATS, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (listview), column); - /* Create model, it also add model to the tree view */ - create_model (listview, sel_format, plugin); + /* Create model, it also add model to the tree view */ + create_model (listview, sel_format, plugin); - g_signal_connect (listview, - "realize", - G_CALLBACK (scroll_to_selected), - NULL); + g_signal_connect (listview, "realize", + G_CALLBACK (scroll_to_selected), NULL); - gtk_widget_show (listview); + gtk_widget_show (listview); } static void updated_custom_format_example (GtkEntry *format_entry, - GtkLabel *format_example) + GtkLabel *format_example) { - const gchar *format; - gchar *time; - gchar *str; - gchar *escaped_time; + const gchar *format; + gchar *time; + gchar *str; + gchar *escaped_time; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_return_if_fail (GTK_IS_ENTRY (format_entry)); - g_return_if_fail (GTK_IS_LABEL (format_example)); + g_return_if_fail (GTK_IS_ENTRY (format_entry)); + g_return_if_fail (GTK_IS_LABEL (format_example)); - format = gtk_entry_get_text (format_entry); + format = gtk_entry_get_text (format_entry); - time = get_time (format); - escaped_time = g_markup_escape_text (time, -1); + time = get_time (format); + escaped_time = g_markup_escape_text (time, -1); - str = g_strdup_printf ("%s", escaped_time); + str = g_strdup_printf ("%s", escaped_time); - gtk_label_set_markup (format_example, str); + gtk_label_set_markup (format_example, str); - g_free (escaped_time); - g_free (time); - g_free (str); + g_free (escaped_time); + g_free (time); + g_free (str); } static void -choose_format_dialog_button_toggled (GtkToggleButton *button, - ChooseFormatDialog *dialog) +choose_format_dialog_button_toggled (GtkToggleButton *button, + ChooseFormatDialog *dialog) { - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->custom))) - { - gtk_widget_set_sensitive (dialog->list, FALSE); - gtk_widget_set_sensitive (dialog->custom_entry, TRUE); - gtk_widget_set_sensitive (dialog->custom_format_example, TRUE); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->custom))) + { + gtk_widget_set_sensitive (dialog->list, FALSE); + gtk_widget_set_sensitive (dialog->custom_entry, TRUE); + gtk_widget_set_sensitive (dialog->custom_format_example, TRUE); + } - return; - } - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_list))) - { - gtk_widget_set_sensitive (dialog->list, TRUE); - gtk_widget_set_sensitive (dialog->custom_entry, FALSE); - gtk_widget_set_sensitive (dialog->custom_format_example, FALSE); - - return; - } + else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_list))) + { + gtk_widget_set_sensitive (dialog->list, TRUE); + gtk_widget_set_sensitive (dialog->custom_entry, FALSE); + gtk_widget_set_sensitive (dialog->custom_format_example, FALSE); + } + else + { + g_return_if_reached (); + } } static void -configure_dialog_button_toggled (GtkToggleButton *button, TimeConfigureDialog *dialog) +configure_widget_button_toggled (GtkToggleButton *button, + TimeConfigureWidget *conf_widget) { - xed_debug (DEBUG_PLUGINS); + XedTimePluginPromptType prompt_type; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->custom))) - { - gtk_widget_set_sensitive (dialog->list, FALSE); - gtk_widget_set_sensitive (dialog->custom_entry, TRUE); - gtk_widget_set_sensitive (dialog->custom_format_example, TRUE); + xed_debug (DEBUG_PLUGINS); - return; - } + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (conf_widget->custom))) + { + gtk_widget_set_sensitive (conf_widget->list, FALSE); + gtk_widget_set_sensitive (conf_widget->custom_entry, TRUE); + gtk_widget_set_sensitive (conf_widget->custom_format_example, TRUE); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_list))) - { - gtk_widget_set_sensitive (dialog->list, TRUE); - gtk_widget_set_sensitive (dialog->custom_entry, FALSE); - gtk_widget_set_sensitive (dialog->custom_format_example, FALSE); + prompt_type = USE_CUSTOM_FORMAT; + } - return; - } + else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (conf_widget->use_list))) + { + gtk_widget_set_sensitive (conf_widget->list, TRUE); + gtk_widget_set_sensitive (conf_widget->custom_entry, FALSE); + gtk_widget_set_sensitive (conf_widget->custom_format_example, FALSE); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->prompt))) - { - gtk_widget_set_sensitive (dialog->list, FALSE); - gtk_widget_set_sensitive (dialog->custom_entry, FALSE); - gtk_widget_set_sensitive (dialog->custom_format_example, FALSE); + prompt_type = USE_SELECTED_FORMAT; + } - return; - } + else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (conf_widget->prompt))) + { + gtk_widget_set_sensitive (conf_widget->list, FALSE); + gtk_widget_set_sensitive (conf_widget->custom_entry, FALSE); + gtk_widget_set_sensitive (conf_widget->custom_format_example, FALSE); + + prompt_type = PROMPT_SELECTED_FORMAT; + } + else + { + g_return_if_reached (); + } + + g_settings_set_enum (conf_widget->settings, PROMPT_TYPE_KEY, prompt_type); } static gint get_format_from_list (GtkWidget *listview) { - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (listview)); - g_return_val_if_fail (model != NULL, 0); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (listview)); + g_return_val_if_fail (model != NULL, 0); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (listview)); - g_return_val_if_fail (selection != NULL, 0); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (listview)); + g_return_val_if_fail (selection != NULL, 0); - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - gint selected_value; + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + gint selected_value; - gtk_tree_model_get (model, &iter, COLUMN_INDEX, &selected_value, -1); + gtk_tree_model_get (model, &iter, COLUMN_INDEX, &selected_value, -1); - xed_debug_message (DEBUG_PLUGINS, "Sel value: %d", selected_value); + xed_debug_message (DEBUG_PLUGINS, "Sel value: %d", selected_value); - return selected_value; - } + return selected_value; + } - g_return_val_if_reached (0); + g_return_val_if_reached (0); } -static TimeConfigureDialog * -get_configure_dialog (XedTimePlugin *plugin) +static void +on_configure_widget_selection_changed (GtkTreeSelection *selection, + TimeConfigureWidget *conf_widget) { - TimeConfigureDialog *dialog = NULL; - gchar *data_dir; - gchar *ui_file; - GtkWidget *content; - GtkWidget *viewport; - XedTimePluginPromptType prompt_type; - gchar *sf, *cf; - GtkWidget *error_widget; - gboolean ret; - gchar *root_objects[] = { - "time_dialog_content", - NULL - }; + gint sel_format; - xed_debug (DEBUG_PLUGINS); + sel_format = get_format_from_list (conf_widget->list); + g_settings_set_string (conf_widget->settings, SELECTED_FORMAT_KEY, formats[sel_format]); +} - GtkWidget *dlg = gtk_dialog_new_with_buttons (_("Configure insert date/time plugin..."), - NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, - GTK_RESPONSE_OK, - GTK_STOCK_HELP, - GTK_RESPONSE_HELP, - NULL); +static TimeConfigureWidget * +get_configure_widget (XedTimePlugin *plugin) +{ + TimeConfigureWidget *widget = NULL; + GtkTreeSelection *selection; + gchar *data_dir; + gchar *ui_file; + GtkWidget *viewport; + XedTimePluginPromptType prompt_type; + gchar *sf; + GtkWidget *error_widget; + gboolean ret; + gchar *root_objects[] = { + "time_dialog_content", + NULL + }; - g_return_val_if_fail (dlg != NULL, NULL); + xed_debug (DEBUG_PLUGINS); - dialog = g_new0 (TimeConfigureDialog, 1); - dialog->dialog = dlg; + widget = g_slice_new (TimeConfigureWidget); + widget->settings = g_object_ref (plugin->priv->settings); - /* HIG defaults */ - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog->dialog)), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))), - 2); /* 2 * 5 + 2 = 12 */ - gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dialog->dialog))), - 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dialog->dialog))), 6); + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); + ui_file = g_build_filename (data_dir, "xed-time-setup-dialog.ui", NULL); + ret = xed_utils_get_ui_objects (ui_file, + root_objects, + &error_widget, + "time_dialog_content", &widget->content, + "formats_viewport", &viewport, + "formats_tree", &widget->list, + "always_prompt", &widget->prompt, + "never_prompt", &widget->use_list, + "use_custom", &widget->custom, + "custom_entry", &widget->custom_entry, + "custom_format_example", &widget->custom_format_example, + NULL); + g_free (data_dir); + g_free (ui_file); - data_dir = xed_plugin_get_data_dir (XED_PLUGIN (plugin)); - ui_file = g_build_filename (data_dir, "xed-time-setup-dialog.ui", NULL); - ret = xed_utils_get_ui_objects (ui_file, - root_objects, - &error_widget, - "time_dialog_content", &content, - "formats_viewport", &viewport, - "formats_tree", &dialog->list, - "always_prompt", &dialog->prompt, - "never_prompt", &dialog->use_list, - "use_custom", &dialog->custom, - "custom_entry", &dialog->custom_entry, - "custom_format_example", &dialog->custom_format_example, - NULL); + if (!ret) + { + return NULL; + } - g_free (data_dir); - g_free (ui_file); + sf = get_selected_format (plugin); + create_formats_list (widget->list, sf, plugin); + g_free (sf); - if (!ret) - { - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))), - error_widget, - TRUE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (error_widget), 5); + prompt_type = g_settings_get_enum (plugin->priv->settings, PROMPT_TYPE_KEY); - gtk_widget_show (error_widget); + g_settings_bind (widget->settings, CUSTOM_FORMAT_KEY, + widget->custom_entry, "text", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); - return dialog; - } + if (prompt_type == USE_CUSTOM_FORMAT) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->custom), TRUE); - gtk_window_set_resizable (GTK_WINDOW (dialog->dialog), FALSE); + gtk_widget_set_sensitive (widget->list, FALSE); + gtk_widget_set_sensitive (widget->custom_entry, TRUE); + gtk_widget_set_sensitive (widget->custom_format_example, TRUE); + } + else if (prompt_type == USE_SELECTED_FORMAT) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->use_list), TRUE); - sf = get_selected_format (plugin); - create_formats_list (dialog->list, sf, plugin); - g_free (sf); + gtk_widget_set_sensitive (widget->list, TRUE); + gtk_widget_set_sensitive (widget->custom_entry, FALSE); + gtk_widget_set_sensitive (widget->custom_format_example, FALSE); + } + else + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->prompt), TRUE); - prompt_type = get_prompt_type (plugin); + gtk_widget_set_sensitive (widget->list, FALSE); + gtk_widget_set_sensitive (widget->custom_entry, FALSE); + gtk_widget_set_sensitive (widget->custom_format_example, FALSE); + } - cf = get_custom_format (plugin); - gtk_entry_set_text (GTK_ENTRY(dialog->custom_entry), cf); - g_free (cf); + updated_custom_format_example (GTK_ENTRY (widget->custom_entry), GTK_LABEL (widget->custom_format_example)); - if (prompt_type == USE_CUSTOM_FORMAT) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->custom), TRUE); + /* setup a window of a sane size. */ + gtk_widget_set_size_request (GTK_WIDGET (viewport), 10, 200); - gtk_widget_set_sensitive (dialog->list, FALSE); - gtk_widget_set_sensitive (dialog->custom_entry, TRUE); - gtk_widget_set_sensitive (dialog->custom_format_example, TRUE); - } - else if (prompt_type == USE_SELECTED_FORMAT) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_list), TRUE); + g_signal_connect (widget->custom, "toggled", + G_CALLBACK (configure_widget_button_toggled), widget); + g_signal_connect (widget->prompt, "toggled", + G_CALLBACK (configure_widget_button_toggled), widget); + g_signal_connect (widget->use_list, "toggled", + G_CALLBACK (configure_widget_button_toggled), widget); + g_signal_connect (widget->content, "destroy", + G_CALLBACK (configure_widget_destroyed), widget); + g_signal_connect (widget->custom_entry, "changed", + G_CALLBACK (updated_custom_format_example), widget->custom_format_example); - gtk_widget_set_sensitive (dialog->list, TRUE); - gtk_widget_set_sensitive (dialog->custom_entry, FALSE); - gtk_widget_set_sensitive (dialog->custom_format_example, FALSE); - } - else - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->prompt), TRUE); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->list)); + g_signal_connect (selection, "changed", + G_CALLBACK (on_configure_widget_selection_changed), widget); - gtk_widget_set_sensitive (dialog->list, FALSE); - gtk_widget_set_sensitive (dialog->custom_entry, FALSE); - gtk_widget_set_sensitive (dialog->custom_format_example, FALSE); - } - - updated_custom_format_example (GTK_ENTRY (dialog->custom_entry), - GTK_LABEL (dialog->custom_format_example)); - - /* setup a window of a sane size. */ - gtk_widget_set_size_request (GTK_WIDGET (viewport), 10, 200); - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))), - content, FALSE, FALSE, 0); - g_object_unref (content); - gtk_container_set_border_width (GTK_CONTAINER (content), 5); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog), - GTK_RESPONSE_OK); - - g_signal_connect (dialog->custom, - "toggled", - G_CALLBACK (configure_dialog_button_toggled), - dialog); - g_signal_connect (dialog->prompt, - "toggled", - G_CALLBACK (configure_dialog_button_toggled), - dialog); - g_signal_connect (dialog->use_list, - "toggled", - G_CALLBACK (configure_dialog_button_toggled), - dialog); - g_signal_connect (dialog->dialog, - "dispose", - G_CALLBACK (dialog_disposed), - dialog); - g_signal_connect (dialog->custom_entry, - "changed", - G_CALLBACK (updated_custom_format_example), - dialog->custom_format_example); - - return dialog; + return widget; } static void real_insert_time (GtkTextBuffer *buffer, - const gchar *the_time) + const gchar *the_time) { - xed_debug_message (DEBUG_PLUGINS, "Insert: %s", the_time); + xed_debug_message (DEBUG_PLUGINS, "Insert: %s", the_time); - gtk_text_buffer_begin_user_action (buffer); + gtk_text_buffer_begin_user_action (buffer); - gtk_text_buffer_insert_at_cursor (buffer, the_time, -1); - gtk_text_buffer_insert_at_cursor (buffer, " ", -1); + gtk_text_buffer_insert_at_cursor (buffer, the_time, -1); + gtk_text_buffer_insert_at_cursor (buffer, " ", -1); - gtk_text_buffer_end_user_action (buffer); + gtk_text_buffer_end_user_action (buffer); } static void choose_format_dialog_row_activated (GtkTreeView *list, - GtkTreePath *path, - GtkTreeViewColumn *column, - ChooseFormatDialog *dialog) + GtkTreePath *path, + GtkTreeViewColumn *column, + ChooseFormatDialog *dialog) { - gint sel_format; - gchar *the_time; + gint sel_format; + gchar *the_time; - sel_format = get_format_from_list (dialog->list); - the_time = get_time (formats[sel_format]); + sel_format = get_format_from_list (dialog->list); + the_time = get_time (formats[sel_format]); - set_prompt_type (dialog->plugin, PROMPT_SELECTED_FORMAT); - set_selected_format (dialog->plugin, formats[sel_format]); + g_settings_set_enum (dialog->settings, PROMPT_TYPE_KEY, PROMPT_SELECTED_FORMAT); + g_settings_set_string (dialog->settings, SELECTED_FORMAT_KEY, formats[sel_format]); - g_return_if_fail (the_time != NULL); + g_return_if_fail (the_time != NULL); - real_insert_time (dialog->buffer, the_time); + real_insert_time (dialog->buffer, the_time); - g_free (the_time); + g_free (the_time); } static ChooseFormatDialog * -get_choose_format_dialog (GtkWindow *parent, - XedTimePluginPromptType prompt_type, - XedTimePlugin *plugin) +get_choose_format_dialog (GtkWindow *parent, + XedTimePluginPromptType prompt_type, + XedTimePlugin *plugin) { - ChooseFormatDialog *dialog; - gchar *data_dir; - gchar *ui_file; - GtkWidget *error_widget; - gboolean ret; - gchar *sf, *cf; - GtkWindowGroup *wg = NULL; + ChooseFormatDialog *dialog; + gchar *data_dir; + gchar *ui_file; + GtkWidget *error_widget; + gboolean ret; + gchar *sf, *cf; + GtkWindowGroup *wg = NULL; - if (parent != NULL) - wg = gtk_window_get_group (parent); + if (parent != NULL) + { + wg = gtk_window_get_group (parent); + } - dialog = g_new0 (ChooseFormatDialog, 1); + dialog = g_slice_new (ChooseFormatDialog); + dialog->settings = plugin->priv->settings; - data_dir = xed_plugin_get_data_dir (XED_PLUGIN (plugin)); - ui_file = g_build_filename (data_dir, "xed-time-dialog.ui", NULL); - ret = xed_utils_get_ui_objects (ui_file, - NULL, - &error_widget, - "choose_format_dialog", &dialog->dialog, - "choice_list", &dialog->list, - "use_sel_format_radiobutton", &dialog->use_list, - "use_custom_radiobutton", &dialog->custom, - "custom_entry", &dialog->custom_entry, - "custom_format_example", &dialog->custom_format_example, - NULL); + data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); + ui_file = g_build_filename (data_dir, "xed-time-dialog.ui", NULL); + ret = xed_utils_get_ui_objects (ui_file, + NULL, + &error_widget, + "choose_format_dialog", &dialog->dialog, + "choice_list", &dialog->list, + "use_sel_format_radiobutton", &dialog->use_list, + "use_custom_radiobutton", &dialog->custom, + "custom_entry", &dialog->custom_entry, + "custom_format_example", &dialog->custom_format_example, + NULL); - g_free (data_dir); - g_free (ui_file); + g_free (data_dir); + g_free (ui_file); - if (!ret) - { - GtkWidget *err_dialog; + if (!ret) + { + GtkWidget *err_dialog; - err_dialog = gtk_dialog_new_with_buttons (NULL, - parent, - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, - NULL); + err_dialog = gtk_dialog_new_with_buttons (NULL, + parent, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + _("_OK"), GTK_RESPONSE_ACCEPT, + NULL); - if (wg != NULL) - gtk_window_group_add_window (wg, GTK_WINDOW (err_dialog)); + if (wg != NULL) + { + gtk_window_group_add_window (wg, GTK_WINDOW (err_dialog)); + } - gtk_window_set_resizable (GTK_WINDOW (err_dialog), FALSE); - gtk_dialog_set_default_response (GTK_DIALOG (err_dialog), GTK_RESPONSE_OK); + gtk_window_set_resizable (GTK_WINDOW (err_dialog), FALSE); + gtk_dialog_set_default_response (GTK_DIALOG (err_dialog), GTK_RESPONSE_OK); - gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (err_dialog))), - error_widget); + gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (err_dialog))), error_widget); - g_signal_connect (G_OBJECT (err_dialog), - "response", - G_CALLBACK (gtk_widget_destroy), - NULL); + g_signal_connect (G_OBJECT (err_dialog), "response", + G_CALLBACK (gtk_widget_destroy), NULL); - gtk_widget_show_all (err_dialog); + gtk_widget_show_all (err_dialog); - return NULL; - } + return NULL; + } - gtk_window_group_add_window (wg, - GTK_WINDOW (dialog->dialog)); - gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog), parent); - gtk_window_set_modal (GTK_WINDOW (dialog->dialog), TRUE); + gtk_window_group_add_window (wg, GTK_WINDOW (dialog->dialog)); + gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog), parent); + gtk_window_set_modal (GTK_WINDOW (dialog->dialog), TRUE); - sf = get_selected_format (plugin); - create_formats_list (dialog->list, sf, plugin); - g_free (sf); + sf = get_selected_format (plugin); + create_formats_list (dialog->list, sf, plugin); + g_free (sf); - cf = get_custom_format (plugin); - gtk_entry_set_text (GTK_ENTRY(dialog->custom_entry), cf); - g_free (cf); + cf = get_custom_format (plugin); + gtk_entry_set_text (GTK_ENTRY (dialog->custom_entry), cf); + g_free (cf); - updated_custom_format_example (GTK_ENTRY (dialog->custom_entry), - GTK_LABEL (dialog->custom_format_example)); + updated_custom_format_example (GTK_ENTRY (dialog->custom_entry), + GTK_LABEL (dialog->custom_format_example)); - if (prompt_type == PROMPT_CUSTOM_FORMAT) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->custom), TRUE); + if (prompt_type == PROMPT_CUSTOM_FORMAT) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->custom), TRUE); - gtk_widget_set_sensitive (dialog->list, FALSE); - gtk_widget_set_sensitive (dialog->custom_entry, TRUE); - gtk_widget_set_sensitive (dialog->custom_format_example, TRUE); - } - else if (prompt_type == PROMPT_SELECTED_FORMAT) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_list), TRUE); + gtk_widget_set_sensitive (dialog->list, FALSE); + gtk_widget_set_sensitive (dialog->custom_entry, TRUE); + gtk_widget_set_sensitive (dialog->custom_format_example, TRUE); + } + else if (prompt_type == PROMPT_SELECTED_FORMAT) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_list), TRUE); - gtk_widget_set_sensitive (dialog->list, TRUE); - gtk_widget_set_sensitive (dialog->custom_entry, FALSE); - gtk_widget_set_sensitive (dialog->custom_format_example, FALSE); - } - else - { - g_return_val_if_reached (NULL); - } + gtk_widget_set_sensitive (dialog->list, TRUE); + gtk_widget_set_sensitive (dialog->custom_entry, FALSE); + gtk_widget_set_sensitive (dialog->custom_format_example, FALSE); + } + else + { + g_return_val_if_reached (NULL); + } - /* setup a window of a sane size. */ - gtk_widget_set_size_request (dialog->list, 10, 200); + /* setup a window of a sane size. */ + gtk_widget_set_size_request (dialog->list, 10, 200); - gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog), - GTK_RESPONSE_OK); + gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog), GTK_RESPONSE_OK); - g_signal_connect (dialog->custom, - "toggled", - G_CALLBACK (choose_format_dialog_button_toggled), - dialog); - g_signal_connect (dialog->use_list, - "toggled", - G_CALLBACK (choose_format_dialog_button_toggled), - dialog); - g_signal_connect (dialog->dialog, - "dispose", - G_CALLBACK (dialog_disposed), - dialog); - g_signal_connect (dialog->custom_entry, - "changed", - G_CALLBACK (updated_custom_format_example), - dialog->custom_format_example); - g_signal_connect (dialog->list, - "row_activated", - G_CALLBACK (choose_format_dialog_row_activated), - dialog); + g_signal_connect (dialog->custom, "toggled", + G_CALLBACK (choose_format_dialog_button_toggled), dialog); + g_signal_connect (dialog->use_list, "toggled", + G_CALLBACK (choose_format_dialog_button_toggled), dialog); + g_signal_connect (dialog->dialog, "destroy", + G_CALLBACK (choose_format_dialog_destroyed), dialog); + g_signal_connect (dialog->custom_entry, "changed", + G_CALLBACK (updated_custom_format_example), dialog->custom_format_example); + g_signal_connect (dialog->list, "row_activated", + G_CALLBACK (choose_format_dialog_row_activated), dialog); - gtk_window_set_resizable (GTK_WINDOW (dialog->dialog), FALSE); + gtk_window_set_resizable (GTK_WINDOW (dialog->dialog), FALSE); - return dialog; + return dialog; } static void choose_format_dialog_response_cb (GtkWidget *widget, - gint response, - ChooseFormatDialog *dialog) + gint response, + ChooseFormatDialog *dialog) { - switch (response) - { - case GTK_RESPONSE_HELP: - { - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_HELP"); - xed_help_display (GTK_WINDOW (widget), - NULL, - "xed-insert-date-time-plugin"); - break; - } - case GTK_RESPONSE_OK: - { - gchar *the_time; + switch (response) + { + case GTK_RESPONSE_HELP: + { + xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_HELP"); + xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (widget), NULL, "xed-insert-date-time-plugin"); + break; + } + case GTK_RESPONSE_OK: + { + gchar *the_time; - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_OK"); + xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_OK"); - /* Get the user's chosen format */ - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_list))) - { - gint sel_format; + /* Get the user's chosen format */ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_list))) + { + gint sel_format; - sel_format = get_format_from_list (dialog->list); - the_time = get_time (formats[sel_format]); + sel_format = get_format_from_list (dialog->list); + the_time = get_time (formats[sel_format]); - set_prompt_type (dialog->plugin, PROMPT_SELECTED_FORMAT); - set_selected_format (dialog->plugin, formats[sel_format]); - } - else - { - const gchar *format; + g_settings_set_enum (dialog->settings, PROMPT_TYPE_KEY, PROMPT_SELECTED_FORMAT); + g_settings_set_string (dialog->settings, SELECTED_FORMAT_KEY, formats[sel_format]); + } + else + { + const gchar *format; - format = gtk_entry_get_text (GTK_ENTRY (dialog->custom_entry)); - the_time = get_time (format); + format = gtk_entry_get_text (GTK_ENTRY (dialog->custom_entry)); + the_time = get_time (format); - set_prompt_type (dialog->plugin, PROMPT_CUSTOM_FORMAT); - set_custom_format (dialog->plugin, format); - } + g_settings_set_enum (dialog->settings, PROMPT_TYPE_KEY, PROMPT_CUSTOM_FORMAT); + g_settings_set_string (dialog->settings, CUSTOM_FORMAT_KEY, format); + } - g_return_if_fail (the_time != NULL); + g_return_if_fail (the_time != NULL); - real_insert_time (dialog->buffer, the_time); - g_free (the_time); + real_insert_time (dialog->buffer, the_time); + g_free (the_time); - gtk_widget_destroy (dialog->dialog); - break; - } - case GTK_RESPONSE_CANCEL: - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_CANCEL"); - gtk_widget_destroy (dialog->dialog); - } + gtk_widget_destroy (dialog->dialog); + break; + } + case GTK_RESPONSE_CANCEL: + xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_CANCEL"); + gtk_widget_destroy (dialog->dialog); + } } static void -time_cb (GtkAction *action, - ActionData *data) +time_cb (GtkAction *action, + XedTimePlugin *plugin) { - GtkTextBuffer *buffer; - gchar *the_time = NULL; - XedTimePluginPromptType prompt_type; + XedTimePluginPrivate *priv; + GtkTextBuffer *buffer; + gchar *the_time = NULL; + XedTimePluginPromptType prompt_type; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - buffer = GTK_TEXT_BUFFER (xed_window_get_active_document (data->window)); - g_return_if_fail (buffer != NULL); + priv = plugin->priv; - prompt_type = get_prompt_type (data->plugin); + buffer = GTK_TEXT_BUFFER (xed_window_get_active_document (priv->window)); + g_return_if_fail (buffer != NULL); - if (prompt_type == USE_CUSTOM_FORMAT) + prompt_type = g_settings_get_enum (plugin->priv->settings, PROMPT_TYPE_KEY); + + if (prompt_type == USE_CUSTOM_FORMAT) + { + gchar *cf = get_custom_format (plugin); + the_time = get_time (cf); + g_free (cf); + } + else if (prompt_type == USE_SELECTED_FORMAT) + { + gchar *sf = get_selected_format (plugin); + the_time = get_time (sf); + g_free (sf); + } + else + { + ChooseFormatDialog *dialog; + + dialog = get_choose_format_dialog (GTK_WINDOW (priv->window), prompt_type, plugin); + if (dialog != NULL) { - gchar *cf = get_custom_format (data->plugin); - the_time = get_time (cf); - g_free (cf); - } - else if (prompt_type == USE_SELECTED_FORMAT) - { - gchar *sf = get_selected_format (data->plugin); - the_time = get_time (sf); - g_free (sf); - } - else - { - ChooseFormatDialog *dialog; + dialog->buffer = buffer; + dialog->settings = priv->settings; - dialog = get_choose_format_dialog (GTK_WINDOW (data->window), - prompt_type, - data->plugin); - if (dialog != NULL) - { - dialog->buffer = buffer; - dialog->plugin = data->plugin; + g_signal_connect (dialog->dialog, "response", + G_CALLBACK (choose_format_dialog_response_cb), dialog); - g_signal_connect (dialog->dialog, - "response", - G_CALLBACK (choose_format_dialog_response_cb), - dialog); + gtk_widget_show (GTK_WIDGET (dialog->dialog)); + } - gtk_widget_show (GTK_WIDGET (dialog->dialog)); - } + return; + } - return; - } + g_return_if_fail (the_time != NULL); - g_return_if_fail (the_time != NULL); + real_insert_time (buffer, the_time); - real_insert_time (buffer, the_time); - - g_free (the_time); -} - -static void -ok_button_pressed (TimeConfigureDialog *dialog) -{ - gint sel_format; - const gchar *custom_format; - - xed_debug (DEBUG_PLUGINS); - - sel_format = get_format_from_list (dialog->list); - - custom_format = gtk_entry_get_text (GTK_ENTRY (dialog->custom_entry)); - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->custom))) - { - set_prompt_type (dialog->plugin, USE_CUSTOM_FORMAT); - set_custom_format (dialog->plugin, custom_format); - } - else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_list))) - { - set_prompt_type (dialog->plugin, USE_SELECTED_FORMAT); - set_selected_format (dialog->plugin, formats [sel_format]); - } - else - { - /* Default to prompt the user with the list selected */ - set_prompt_type (dialog->plugin, PROMPT_SELECTED_FORMAT); - } - - xed_debug_message (DEBUG_PLUGINS, "Sel: %d", sel_format); -} - -static void -configure_dialog_response_cb (GtkWidget *widget, - gint response, - TimeConfigureDialog *dialog) -{ - switch (response) - { - case GTK_RESPONSE_HELP: - { - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_HELP"); - - xed_help_display (GTK_WINDOW (widget), - NULL, - "xed-insert-date-time-plugin#xed-date-time-configure"); - break; - } - case GTK_RESPONSE_OK: - { - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_OK"); - - ok_button_pressed (dialog); - - gtk_widget_destroy (dialog->dialog); - break; - } - case GTK_RESPONSE_CANCEL: - { - xed_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_CANCEL"); - gtk_widget_destroy (dialog->dialog); - } - } + g_free (the_time); } static GtkWidget * -impl_create_configure_dialog (XedPlugin *plugin) +xed_time_plugin_create_configure_widget (PeasGtkConfigurable *configurable) { - TimeConfigureDialog *dialog; + TimeConfigureWidget *widget; - dialog = get_configure_dialog (XED_TIME_PLUGIN (plugin)); + widget = get_configure_widget (XED_TIME_PLUGIN (configurable)); - dialog->plugin = XED_TIME_PLUGIN (plugin); + return widget->content; +} - g_signal_connect (dialog->dialog, - "response", - G_CALLBACK (configure_dialog_response_cb), - dialog); +static void +xed_time_plugin_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XedTimePlugin *plugin = XED_TIME_PLUGIN (object); - return GTK_WIDGET (dialog->dialog); + switch (prop_id) + { + case PROP_WINDOW: + plugin->priv->window = XED_WINDOW (g_value_dup_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_time_plugin_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XedTimePlugin *plugin = XED_TIME_PLUGIN (object); + + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, plugin->priv->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_time_plugin_class_init (XedTimePluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_time_plugin_finalize; + object_class->finalize = xed_time_plugin_finalize; + object_class->dispose = xed_time_plugin_dispose; + object_class->set_property = xed_time_plugin_set_property; + object_class->get_property = xed_time_plugin_get_property; - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - plugin_class->update_ui = impl_update_ui; + g_object_class_override_property (object_class, PROP_WINDOW, "window"); - plugin_class->create_configure_dialog = impl_create_configure_dialog; - - g_type_class_add_private (object_class, sizeof (XedTimePluginPrivate)); + g_type_class_add_private (object_class, sizeof (XedTimePluginPrivate)); +} + +static void +xed_time_plugin_class_finalize (XedTimePluginClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE_EXTENDED */ +} + +static void +xed_window_activatable_iface_init (XedWindowActivatableInterface *iface) +{ + iface->activate = xed_time_plugin_activate; + iface->deactivate = xed_time_plugin_deactivate; + iface->update_state = xed_time_plugin_update_state; +} + +static void +peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface) +{ + iface->create_configure_widget = xed_time_plugin_create_configure_widget; +} + +G_MODULE_EXPORT void +peas_register_types (PeasObjectModule *module) +{ + xed_time_plugin_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + XED_TYPE_WINDOW_ACTIVATABLE, + XED_TYPE_TIME_PLUGIN); + + peas_object_module_register_extension_type (module, + PEAS_GTK_TYPE_CONFIGURABLE, + XED_TYPE_TIME_PLUGIN); } diff --git a/plugins/time/xed-time-plugin.h b/plugins/time/xed-time-plugin.h index 41bf687..1019ce9 100644 --- a/plugins/time/xed-time-plugin.h +++ b/plugins/time/xed-time-plugin.h @@ -1,6 +1,6 @@ /* * xed-time-plugin.h - * + * * Copyright (C) 2002-2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify @@ -25,53 +25,39 @@ #include #include -#include +#include +#include G_BEGIN_DECLS -/* - * Type checking and casting macros - */ -#define XED_TYPE_TIME_PLUGIN (xed_time_plugin_get_type ()) -#define XED_TIME_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_TIME_PLUGIN, XedTimePlugin)) -#define XED_TIME_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_TIME_PLUGIN, XedTimePluginClass)) -#define XED_IS_TIME_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_TIME_PLUGIN)) -#define XED_IS_TIME_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_TIME_PLUGIN)) -#define XED_TIME_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_TIME_PLUGIN, XedTimePluginClass)) +#define XED_TYPE_TIME_PLUGIN (xed_time_plugin_get_type ()) +#define XED_TIME_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_TIME_PLUGIN, XedTimePlugin)) +#define XED_TIME_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_TIME_PLUGIN, XedTimePluginClass)) +#define XED_IS_TIME_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_TIME_PLUGIN)) +#define XED_IS_TIME_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_TIME_PLUGIN)) +#define XED_TIME_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_TIME_PLUGIN, XedTimePluginClass)) -/* Private structure type */ -typedef struct _XedTimePluginPrivate XedTimePluginPrivate; - -/* - * Main object structure - */ -typedef struct _XedTimePlugin XedTimePlugin; +typedef struct _XedTimePlugin XedTimePlugin; +typedef struct _XedTimePluginPrivate XedTimePluginPrivate; +typedef struct _XedTimePluginClass XedTimePluginClass; struct _XedTimePlugin { - XedPlugin parent_instance; + PeasExtensionBase parent_instance; - /*< private >*/ - XedTimePluginPrivate *priv; + /*< private >*/ + XedTimePluginPrivate *priv; }; -/* - * Class definition - */ -typedef struct _XedTimePluginClass XedTimePluginClass; - struct _XedTimePluginClass { - XedPluginClass parent_class; + PeasExtensionBaseClass parent_class; }; -/* - * Public methods - */ -GType xed_time_plugin_get_type (void) G_GNUC_CONST; +GType xed_time_plugin_get_type (void) G_GNUC_CONST; /* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule *module); +G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); G_END_DECLS diff --git a/plugins/trailsave/Makefile.am b/plugins/trailsave/Makefile.am index 77b99be..5705584 100644 --- a/plugins/trailsave/Makefile.am +++ b/plugins/trailsave/Makefile.am @@ -16,11 +16,11 @@ libtrailsave_la_SOURCES = \ libtrailsave_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) libtrailsave_la_LIBADD = $(XED_LIBS) -plugin_in_files = trailsave.xed-plugin.desktop.in +plugin_in_files = trailsave.plugin.desktop.in -%.xed-plugin: %.xed-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache +%.plugin: %.plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache -plugin_DATA = $(plugin_in_files:.xed-plugin.desktop.in=.xed-plugin) +plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin) EXTRA_DIST = $(plugin_in_files) diff --git a/plugins/trailsave/trailsave.xed-plugin.desktop.in b/plugins/trailsave/trailsave.plugin.desktop.in similarity index 95% rename from plugins/trailsave/trailsave.xed-plugin.desktop.in rename to plugins/trailsave/trailsave.plugin.desktop.in index d6a647a..b212431 100644 --- a/plugins/trailsave/trailsave.xed-plugin.desktop.in +++ b/plugins/trailsave/trailsave.plugin.desktop.in @@ -1,4 +1,4 @@ -[Xed Plugin] +[Plugin] Module=trailsave IAge=2 _Name=Save Without Trailing Spaces diff --git a/plugins/trailsave/xed-trail-save-plugin.c b/plugins/trailsave/xed-trail-save-plugin.c index b237d5d..b1e2495 100644 --- a/plugins/trailsave/xed-trail-save-plugin.c +++ b/plugins/trailsave/xed-trail-save-plugin.c @@ -14,8 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -24,191 +22,291 @@ #include "xed-trail-save-plugin.h" -XED_PLUGIN_REGISTER_TYPE(XedTrailSavePlugin, xed_trail_save_plugin) +#include +#include +#include + +#define XED_TRAIL_SAVE_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ + XED_TYPE_TRAIL_SAVE_PLUGIN, \ + XedTrailSavePluginPrivate)) + +static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedTrailSavePlugin, + xed_trail_save_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, + xed_window_activatable_iface_init)) + +struct _XedTrailSavePluginPrivate +{ + XedWindow *window; +}; + +enum +{ + PROP_0, + PROP_WINDOW +}; static void strip_trailing_spaces (GtkTextBuffer *text_buffer) { - gint line_count, line_num; - GtkTextIter line_start, line_end; - gchar *slice; - gchar byte; - gint byte_index; - gint strip_start_index, strip_end_index; - gboolean should_strip; - GtkTextIter strip_start, strip_end; + gint line_count, line_num; + GtkTextIter line_start, line_end; + gchar *slice; + gchar byte; + gint byte_index; + gint strip_start_index, strip_end_index; + gboolean should_strip; + GtkTextIter strip_start, strip_end; - g_assert (text_buffer != NULL); + g_assert (text_buffer != NULL); - line_count = gtk_text_buffer_get_line_count (text_buffer); + line_count = gtk_text_buffer_get_line_count (text_buffer); - for (line_num = 0; line_num < line_count; ++line_num) - { - /* Get line text */ - gtk_text_buffer_get_iter_at_line (text_buffer, &line_start, line_num); + for (line_num = 0; line_num < line_count; ++line_num) + { + /* Get line text */ + gtk_text_buffer_get_iter_at_line (text_buffer, &line_start, line_num); - if (line_num == line_count - 1) - { - gtk_text_buffer_get_end_iter (text_buffer, &line_end); - } - else - { - gtk_text_buffer_get_iter_at_line (text_buffer, &line_end, line_num + 1); - } + if (line_num == line_count - 1) + { + gtk_text_buffer_get_end_iter (text_buffer, &line_end); + } + else + { + gtk_text_buffer_get_iter_at_line (text_buffer, &line_end, line_num + 1); + } - slice = gtk_text_buffer_get_slice (text_buffer, &line_start, &line_end, TRUE); + slice = gtk_text_buffer_get_slice (text_buffer, &line_start, &line_end, TRUE); - if (slice == NULL) - { - continue; - } + if (slice == NULL) + { + continue; + } - /* Find indices of bytes that should be stripped */ - should_strip = FALSE; + /* Find indices of bytes that should be stripped */ + should_strip = FALSE; - for (byte_index = 0; slice [byte_index] != 0; ++byte_index) - { - byte = slice [byte_index]; + for (byte_index = 0; slice [byte_index] != 0; ++byte_index) + { + byte = slice [byte_index]; - if ((byte == ' ') || (byte == '\t')) - { - if (!should_strip) - { - strip_start_index = byte_index; - should_strip = TRUE; - } + if ((byte == ' ') || (byte == '\t')) + { + if (!should_strip) + { + strip_start_index = byte_index; + should_strip = TRUE; + } - strip_end_index = byte_index + 1; - } - else if ((byte == '\r') || (byte == '\n')) - { - break; - } - else - { - should_strip = FALSE; - } - } + strip_end_index = byte_index + 1; + } + else if ((byte == '\r') || (byte == '\n')) + { + break; + } + else + { + should_strip = FALSE; + } + } - g_free (slice); + g_free (slice); - /* Strip trailing spaces */ - if (should_strip) - { - gtk_text_buffer_get_iter_at_line_index (text_buffer, &strip_start, line_num, strip_start_index); - gtk_text_buffer_get_iter_at_line_index (text_buffer, &strip_end, line_num, strip_end_index); - gtk_text_buffer_delete (text_buffer, &strip_start, &strip_end); - } - } + /* Strip trailing spaces */ + if (should_strip) + { + gtk_text_buffer_get_iter_at_line_index (text_buffer, &strip_start, line_num, strip_start_index); + gtk_text_buffer_get_iter_at_line_index (text_buffer, &strip_end, line_num, strip_end_index); + gtk_text_buffer_delete (text_buffer, &strip_start, &strip_end); + } + } } static void -on_save (XedDocument *document, - const gchar *uri, - XedEncoding *encoding, - XedDocumentSaveFlags save_flags, - XedPlugin *plugin) +on_save (XedDocument *document, + XedTrailSavePlugin *plugin) { - GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (document); + GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (document); - strip_trailing_spaces (text_buffer); + strip_trailing_spaces (text_buffer); } static void -on_tab_added (XedWindow *window, - XedTab *tab, - XedPlugin *plugin) +on_tab_added (XedWindow *window, + XedTab *tab, + XedTrailSavePlugin *plugin) { - XedDocument *document; + XedDocument *document; - document = xed_tab_get_document (tab); - g_signal_connect (document, "save", G_CALLBACK (on_save), plugin); + document = xed_tab_get_document (tab); + g_signal_connect (document, "save", + G_CALLBACK (on_save), plugin); } static void -on_tab_removed (XedWindow *window, - XedTab *tab, - XedPlugin *plugin) +on_tab_removed (XedWindow *window, + XedTab *tab, + XedTrailSavePlugin *plugin) { - XedDocument *document; + XedDocument *document; - document = xed_tab_get_document (tab); - g_signal_handlers_disconnect_by_data (document, plugin); + document = xed_tab_get_document (tab); + g_signal_handlers_disconnect_by_data (document, plugin); } static void -impl_activate (XedPlugin *plugin, - XedWindow *window) +xed_trail_save_plugin_activate (XedWindowActivatable *activatable) { - GList *documents; - GList *documents_iter; - XedDocument *document; + XedTrailSavePluginPrivate *priv; + GList *documents; + GList *documents_iter; + XedDocument *document; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_signal_connect (window, "tab_added", G_CALLBACK (on_tab_added), plugin); - g_signal_connect (window, "tab_removed", G_CALLBACK (on_tab_removed), plugin); + priv = XED_TRAIL_SAVE_PLUGIN (activatable)->priv; - documents = xed_window_get_documents (window); + g_signal_connect (priv->window, "tab_added", + G_CALLBACK (on_tab_added), XED_TRAIL_SAVE_PLUGIN (activatable)); + g_signal_connect (priv->window, "tab_removed", + G_CALLBACK (on_tab_removed), XED_TRAIL_SAVE_PLUGIN (activatable)); - for (documents_iter = documents; - documents_iter && documents_iter->data; - documents_iter = documents_iter->next) - { - document = (XedDocument *) documents_iter->data; - g_signal_connect (document, "save", G_CALLBACK (on_save), plugin); - } + documents = xed_window_get_documents (priv->window); - g_list_free (documents); + for (documents_iter = documents; + documents_iter && documents_iter->data; + documents_iter = documents_iter->next) + { + document = (XedDocument *) documents_iter->data; + g_signal_connect (document, "save", + G_CALLBACK (on_save), XED_TRAIL_SAVE_PLUGIN (activatable)); + } + + g_list_free (documents); } static void -impl_deactivate (XedPlugin *plugin, - XedWindow *window) +xed_trail_save_plugin_deactivate (XedWindowActivatable *activatable) { - GList *documents; - GList *documents_iter; - XedDocument *document; + XedTrailSavePluginPrivate *priv; + GList *documents; + GList *documents_iter; + XedDocument *document; - xed_debug (DEBUG_PLUGINS); + xed_debug (DEBUG_PLUGINS); - g_signal_handlers_disconnect_by_data (window, plugin); + priv = XED_TRAIL_SAVE_PLUGIN (activatable)->priv; - documents = xed_window_get_documents (window); + g_signal_handlers_disconnect_by_data (priv->window, XED_TRAIL_SAVE_PLUGIN (activatable)); - for (documents_iter = documents; - documents_iter && documents_iter->data; - documents_iter = documents_iter->next) - { - document = (XedDocument *) documents_iter->data; - g_signal_handlers_disconnect_by_data (document, plugin); - } + documents = xed_window_get_documents (priv->window); - g_list_free (documents); + for (documents_iter = documents; + documents_iter && documents_iter->data; + documents_iter = documents_iter->next) + { + document = (XedDocument *) documents_iter->data; + g_signal_handlers_disconnect_by_data (document, XED_TRAIL_SAVE_PLUGIN (activatable)); + } + + g_list_free (documents); } static void xed_trail_save_plugin_init (XedTrailSavePlugin *plugin) { - xed_debug_message (DEBUG_PLUGINS, "XedTrailSavePlugin initializing"); + xed_debug_message (DEBUG_PLUGINS, "XedTrailSavePlugin initializing"); + + plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin, XED_TYPE_TRAIL_SAVE_PLUGIN, XedTrailSavePluginPrivate); } static void -xed_trail_save_plugin_finalize (GObject *object) +xed_trail_save_plugin_dispose (GObject *object) { - xed_debug_message (DEBUG_PLUGINS, "XedTrailSavePlugin finalizing"); + XedTrailSavePlugin *plugin = XED_TRAIL_SAVE_PLUGIN (object); - G_OBJECT_CLASS (xed_trail_save_plugin_parent_class)->finalize (object); + xed_debug_message (DEBUG_PLUGINS, "XedTrailSavePlugin disposing"); + + g_clear_object (&plugin->priv->window); + + G_OBJECT_CLASS (xed_trail_save_plugin_parent_class)->dispose (object); +} + +static void +xed_trail_save_plugin_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XedTrailSavePlugin *plugin = XED_TRAIL_SAVE_PLUGIN (object); + + switch (prop_id) + { + case PROP_WINDOW: + plugin->priv->window = XED_WINDOW (g_value_dup_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_trail_save_plugin_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XedTrailSavePlugin *plugin = XED_TRAIL_SAVE_PLUGIN (object); + + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, plugin->priv->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_trail_save_plugin_class_init (XedTrailSavePluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedPluginClass *plugin_class = XED_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_trail_save_plugin_finalize; + object_class->dispose = xed_trail_save_plugin_dispose; + object_class->set_property = xed_trail_save_plugin_set_property; + object_class->get_property = xed_trail_save_plugin_get_property; - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; + g_object_class_override_property (object_class, PROP_WINDOW, "window"); + + g_type_class_add_private (object_class, sizeof (XedTrailSavePluginPrivate)); +} + +static void +xed_trail_save_plugin_class_finalize (XedTrailSavePluginClass *klass) +{ + /* dummy function - used by G_DEFINE_DYNAMIC_TYPE_EXTENDED */ +} + +static void +xed_window_activatable_iface_init (XedWindowActivatableInterface *iface) +{ + iface->activate = xed_trail_save_plugin_activate; + iface->deactivate = xed_trail_save_plugin_deactivate; +} + +G_MODULE_EXPORT void +peas_register_types (PeasObjectModule *module) +{ + xed_trail_save_plugin_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + XED_TYPE_WINDOW_ACTIVATABLE, + XED_TYPE_TRAIL_SAVE_PLUGIN); } diff --git a/plugins/trailsave/xed-trail-save-plugin.h b/plugins/trailsave/xed-trail-save-plugin.h index d0ff1f3..ce66d8f 100644 --- a/plugins/trailsave/xed-trail-save-plugin.h +++ b/plugins/trailsave/xed-trail-save-plugin.h @@ -23,47 +23,38 @@ #include #include -#include +#include +#include G_BEGIN_DECLS -/* - * Type checking and casting macros - */ -#define XED_TYPE_TRAIL_SAVE_PLUGIN (xed_trail_save_plugin_get_type ()) -#define XED_TRAIL_SAVE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_TRAIL_SAVE_PLUGIN, XedTrailSavePlugin)) -#define XED_TRAIL_SAVE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_TRAIL_SAVE_PLUGIN, XedTrailSavePluginClass)) -#define XED_IS_TRAIL_SAVE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_TRAIL_SAVE_PLUGIN)) -#define XED_IS_TRAIL_SAVE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_TRAIL_SAVE_PLUGIN)) -#define XED_TRAIL_SAVE_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_TRAIL_SAVE_PLUGIN, XedTrailSavePluginClass)) +#define XED_TYPE_TRAIL_SAVE_PLUGIN (xed_trail_save_plugin_get_type ()) +#define XED_TRAIL_SAVE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_TRAIL_SAVE_PLUGIN, XedTrailSavePlugin)) +#define XED_TRAIL_SAVE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_TRAIL_SAVE_PLUGIN, XedTrailSavePluginClass)) +#define XED_IS_TRAIL_SAVE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_TRAIL_SAVE_PLUGIN)) +#define XED_IS_TRAIL_SAVE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_TRAIL_SAVE_PLUGIN)) +#define XED_TRAIL_SAVE_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_TRAIL_SAVE_PLUGIN, XedTrailSavePluginClass)) -/* - * Main object structure - */ -typedef struct _XedTrailSavePlugin XedTrailSavePlugin; +typedef struct _XedTrailSavePlugin XedTrailSavePlugin; +typedef struct _XedTrailSavePluginPrivate XedTrailSavePluginPrivate; +typedef struct _XedTrailSavePluginClass XedTrailSavePluginClass; struct _XedTrailSavePlugin { - XedPlugin parent_instance; -}; + PeasExtensionBase parent_instance; -/* - * Class definition - */ -typedef struct _XedTrailSavePluginClass XedTrailSavePluginClass; + /*< private >*/ + XedTrailSavePluginPrivate *priv; +}; struct _XedTrailSavePluginClass { - XedPluginClass parent_class; + PeasExtensionBaseClass parent_class; }; -/* - * Public methods - */ -GType xed_trail_save_plugin_get_type (void) G_GNUC_CONST; +GType xed_trail_save_plugin_get_type (void) G_GNUC_CONST; -/* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_xed_plugin (GTypeModule *module); +G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); G_END_DECLS diff --git a/po/POTFILES.in b/po/POTFILES.in index 0885337..9497faa 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -16,9 +16,7 @@ xed/xed-commands-help.c xed/xed-commands-search.c xed/xed-debug.c xed/xed-document.c -xed/xed-document-saver.c xed/xed-documents-panel.c -xed/xed-encodings.c xed/xed-encodings-combo-box.c xed/xed-file-chooser-dialog.c xed/xed-gio-document-loader.c @@ -27,7 +25,6 @@ xed/xed-help.c xed/xed-io-error-message-area.c xed/xed-notebook.c xed/xed-panel.c -xed/xed-plugin-manager.c xed/xed-plugins-engine.c xed/xed-prefs-manager.c xed/xed-print-job.c @@ -45,21 +42,19 @@ xed/xed-ui.xml xed/xed-utils.c xed/xed-view.c xed/xed-window.c -plugins/changecase/changecase.xed-plugin.desktop.in -plugins/changecase/xed-changecase-plugin.c -plugins/docinfo/docinfo.xed-plugin.desktop.in +plugins/docinfo/docinfo.plugin.desktop.in [type: gettext/glade]plugins/docinfo/docinfo.ui plugins/docinfo/xed-docinfo-plugin.c -plugins/filebrowser/filebrowser.xed-plugin.desktop.in +plugins/filebrowser/filebrowser.plugin.desktop.in [type: gettext/gsettings]plugins/filebrowser/org.x.editor.plugins.filebrowser.gschema.xml.in plugins/filebrowser/xed-file-bookmarks-store.c plugins/filebrowser/xed-file-browser-plugin.c plugins/filebrowser/xed-file-browser-store.c plugins/filebrowser/xed-file-browser-view.c plugins/filebrowser/xed-file-browser-widget.c -plugins/modelines/modelines.xed-plugin.desktop.in +plugins/modelines/modelines.plugin.desktop.in plugins/sort/xed-sort-plugin.c -plugins/sort/sort.xed-plugin.desktop.in +plugins/sort/sort.plugin.desktop.in [type: gettext/glade]plugins/sort/sort.ui [type: gettext/gsettings]plugins/spell/org.x.editor.plugins.spell.gschema.xml.in plugins/spell/xed-automatic-spell-checker.c @@ -71,18 +66,18 @@ plugins/spell/xed-spell-plugin.c [type: gettext/glade]plugins/spell/languages-dialog.ui [type: gettext/glade]plugins/spell/spell-checker.ui [type: gettext/glade]plugins/spell/xed-spell-setup-dialog.ui -plugins/spell/spell.xed-plugin.desktop.in +plugins/spell/spell.plugin.desktop.in plugins/taglist/xed-taglist-plugin.c plugins/taglist/xed-taglist-plugin-panel.c plugins/taglist/xed-taglist-plugin-parser.c plugins/taglist/HTML.tags.xml.in plugins/taglist/Latex.tags.xml.in -plugins/taglist/taglist.xed-plugin.desktop.in +plugins/taglist/taglist.plugin.desktop.in plugins/taglist/XSLT.tags.xml.in plugins/taglist/XUL.tags.xml.in [type: gettext/gsettings]plugins/time/org.x.editor.plugins.time.gschema.xml.in plugins/time/xed-time-plugin.c -plugins/time/time.xed-plugin.desktop.in -plugins/trailsave/trailsave.xed-plugin.desktop.in +plugins/time/time.plugin.desktop.in +plugins/trailsave/trailsave.plugin.desktop.in [type: gettext/glade]plugins/time/xed-time-dialog.ui [type: gettext/glade]plugins/time/xed-time-setup-dialog.ui diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index afec0a6..0000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -AM_CPPFLAGS = -g -I$(top_srcdir) -I$(top_srcdir)/xed $(XED_DEBUG_FLAGS) $(XED_CFLAGS) - -noinst_PROGRAMS = $(TEST_PROGS) -progs_ldadd = $(top_builddir)/xed/libxed.la - -TEST_PROGS = smart-converter -smart_converter_SOURCES = smart-converter.c -smart_converter_LDADD = $(progs_ldadd) - -TEST_PROGS += document-input-stream -document_input_stream_SOURCES = document-input-stream.c -document_input_stream_LDADD = $(progs_ldadd) - -TEST_PROGS += document-output-stream -document_output_stream_SOURCES = document-output-stream.c -document_output_stream_LDADD = $(progs_ldadd) - -TEST_PROGS += document-loader -document_loader_SOURCES = document-loader.c -document_loader_LDADD = $(progs_ldadd) - -TEST_PROGS += document-saver -document_saver_SOURCES = document-saver.c -document_saver_LDADD = $(progs_ldadd) - -TESTS = $(TEST_PROGS) - -EXTRA_DIST = setup-document-saver.sh diff --git a/tests/document-input-stream.c b/tests/document-input-stream.c deleted file mode 100644 index 7b03493..0000000 --- a/tests/document-input-stream.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * document-input-stream.c - * This file is part of xed - * - * Copyright (C) 2010 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - - -#include "xed-document-input-stream.h" -#include -#include -#include -#include - -static void -test_consecutive_read (const gchar *inbuf, - const gchar *outbuf, - XedDocumentNewlineType type, - gsize read_chunk_len) -{ - GtkTextBuffer *buf; - GInputStream *in; - gsize outlen; - gssize n, r; - GError *err = NULL; - gchar *b; - gboolean close; - - buf = gtk_text_buffer_new (NULL); - gtk_text_buffer_set_text (buf, inbuf, -1); - - b = g_malloc (200); - in = xed_document_input_stream_new (buf, type); - - outlen = strlen (outbuf); - n = 0; - - do - { - r = g_input_stream_read (in, b + n, read_chunk_len, NULL, &err); - g_assert_cmpint (r, >=, 0); - g_assert_no_error (err); - - n += r; - } while (r != 0); - - g_assert_cmpint (n, ==, outlen); - - b[n] = '\0'; - - g_assert_cmpstr (b, ==, outbuf); - - close = g_input_stream_close (in, NULL, &err); - g_assert (close); - g_assert_no_error (err); - - g_object_unref (buf); - g_object_unref (in); - g_free (b); -} - -static void -test_empty () -{ - /* empty file should not have a trailing newline */ - test_consecutive_read ("", "", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 10); -} - -static void -test_consecutive_cut_char () -{ - /* first \n is read then fo and then is added \r but not \n */ - test_consecutive_read ("\nfo\nbar\n\nblah\n", "\r\nfo\r\nbar\r\n\r\nblah\r\n\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 8); - test_consecutive_read ("\nfo\nbar\n\nblah", "\r\nfo\r\nbar\r\n\r\nblah\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 8); -} - -static void -test_consecutive_big_read () -{ - test_consecutive_read ("\nfo\nbar\n\nblah\n", "\rfo\rbar\r\rblah\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 200); - test_consecutive_read ("\nfo\nbar\n\nblah", "\rfo\rbar\r\rblah\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 200); - - test_consecutive_read ("\rfo\rbar\r\rblah\r", "\nfo\nbar\n\nblah\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200); - test_consecutive_read ("\rfo\rbar\r\rblah", "\nfo\nbar\n\nblah\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200); - - test_consecutive_read ("\r\nfo\r\nbar\r\n\r\nblah\r\n", "\nfo\nbar\n\nblah\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200); - test_consecutive_read ("\r\nfo\r\nbar\r\n\r\nblah", "\nfo\nbar\n\nblah\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200); - - test_consecutive_read ("\nfo\nbar\n\nblah\n", "\r\nfo\r\nbar\r\n\r\nblah\r\n\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 200); - test_consecutive_read ("\nfo\nbar\n\nblah", "\r\nfo\r\nbar\r\n\r\nblah\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 200); -} - -static void -test_consecutive_middle_read () -{ - test_consecutive_read ("\nfo\nbar\n\nblah\n", "\rfo\rbar\r\rblah\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 6); - test_consecutive_read ("\nfo\nbar\n\nblah", "\rfo\rbar\r\rblah\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 6); - - test_consecutive_read ("\rfo\rbar\r\rblah\r", "\nfo\nbar\n\nblah\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6); - test_consecutive_read ("\rfo\rbar\r\rblah", "\nfo\nbar\n\nblah\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6); - - test_consecutive_read ("\r\nfo\r\nbar\r\n\r\nblah\r\n", "\nfo\nbar\n\nblah\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6); - test_consecutive_read ("\r\nfo\r\nbar\r\n\r\nblah", "\nfo\nbar\n\nblah\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6); - - test_consecutive_read ("\nfo\nbar\n\nblah\n", "\r\nfo\r\nbar\r\n\r\nblah\r\n\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 6); - test_consecutive_read ("\nfo\nbar\n\nblah", "\r\nfo\r\nbar\r\n\r\nblah\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 6); -} - -static void -test_consecutive_multibyte_cut () -{ - test_consecutive_read ("hello\nhello\xe6\x96\x87\nworld\n", "hello\rhello\xe6\x96\x87\rworld\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 6); - test_consecutive_read ("hello\rhello\xe6\x96\x87\rworld\r", "hello\rhello\xe6\x96\x87\rworld\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 6); - test_consecutive_read ("hello\nhello\xe6\x96\x87\nworld\n", "hello\nhello\xe6\x96\x87\nworld\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6); -} - -static void -test_consecutive_multibyte_big_read () -{ - test_consecutive_read ("hello\nhello\xe6\x96\x87\nworld\n", "hello\rhello\xe6\x96\x87\rworld\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 200); - test_consecutive_read ("hello\rhello\xe6\x96\x87\rworld\r", "hello\rhello\xe6\x96\x87\rworld\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 200); - test_consecutive_read ("hello\nhello\xe6\x96\x87\nworld\n", "hello\nhello\xe6\x96\x87\nworld\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200); -} - -int main (int argc, - char *argv[]) -{ - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/document-input-stream/empty", test_empty); - - g_test_add_func ("/document-input-stream/consecutive_cut_char", test_consecutive_cut_char); - g_test_add_func ("/document-input-stream/consecutive_big_read", test_consecutive_big_read); - g_test_add_func ("/document-input-stream/consecutive_middle_read", test_consecutive_middle_read); - - g_test_add_func ("/document-input-stream/consecutive_multibyte_cut", test_consecutive_multibyte_cut); - g_test_add_func ("/document-input-stream/consecutive_multibyte_big_read", test_consecutive_multibyte_big_read); - - return g_test_run (); -} diff --git a/tests/document-loader.c b/tests/document-loader.c deleted file mode 100644 index 68df659..0000000 --- a/tests/document-loader.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * document-loader.c - * This file is part of xed - * - * Copyright (C) 2010 - Jesse van den Kieboom - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#include "xed-gio-document-loader.h" -#include "xed-prefs-manager-app.h" -#include -#include -#include -#include - -static gboolean test_completed; - -typedef struct -{ - const gchar *in_buffer; - gint newline_type; - GFile *file; -} LoaderTestData; - -static GFile * -create_document (const gchar *filename, - const gchar *contents) -{ - GError *error = NULL; - XedDocument *document; - gchar *uri; - - if (!g_file_set_contents (filename, contents, -1, &error)) - { - g_assert_no_error (error); - } - - return g_file_new_for_path (filename); -} - -static void -delete_document (GFile *location) -{ - if (g_file_query_exists (location, NULL)) - { - GError *err = NULL; - - g_file_delete (location, NULL, &err); - g_assert_no_error (err); - } - - test_completed = TRUE; -} - -static void -on_document_loaded (XedDocument *document, - GError *error, - LoaderTestData *data) -{ - GtkTextIter start, end; - - g_assert_no_error (error); - - if (data->in_buffer != NULL) - { - gchar *text; - - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (document), &start, &end); - text = gtk_text_iter_get_slice (&start, &end); - - g_assert_cmpstr (text, ==, data->in_buffer); - - g_free (text); - } - - if (data->newline_type != -1) - { - g_assert_cmpint (xed_document_get_newline_type (document), - ==, - data->newline_type); - } - - delete_document (data->file); -} - -static void -test_loader (const gchar *filename, - const gchar *contents, - const gchar *in_buffer, - gint newline_type) -{ - GFile *file; - gchar *uri; - XedDocument *document; - - file = create_document (filename, contents); - - document = xed_document_new (); - - LoaderTestData *data = g_slice_new (LoaderTestData); - data->in_buffer = in_buffer; - data->newline_type = newline_type; - data->file = file; - - test_completed = FALSE; - - g_signal_connect (document, - "loaded", - G_CALLBACK (on_document_loaded), - data); - - uri = g_file_get_uri (file); - - xed_document_load (document, uri, xed_encoding_get_utf8 (), 0, FALSE); - - g_free (uri); - - while (!test_completed) - { - g_main_context_iteration (NULL, TRUE); - } - - g_slice_free (LoaderTestData, data); - g_object_unref (file); - g_object_unref (document); -} - -static void -test_end_line_stripping () -{ - test_loader ("document-loader.txt", - "hello world\n", - "hello world", - -1); - - test_loader ("document-loader.txt", - "hello world", - "hello world", - -1); - - test_loader ("document-loader.txt", - "\nhello world", - "\nhello world", - -1); - - test_loader ("document-loader.txt", - "\nhello world\n", - "\nhello world", - -1); - - test_loader ("document-loader.txt", - "hello world\n\n", - "hello world\n", - -1); - - test_loader ("document-loader.txt", - "hello world\r\n", - "hello world", - -1); - - test_loader ("document-loader.txt", - "hello world\r\n\r\n", - "hello world\r\n", - -1); - - test_loader ("document-loader.txt", - "\n", - "", - -1); - - test_loader ("document-loader.txt", - "\r\n", - "", - -1); - - test_loader ("document-loader.txt", - "\n\n", - "\n", - -1); - - test_loader ("document-loader.txt", - "\r\n\r\n", - "\r\n", - -1); -} - -static void -test_end_new_line_detection () -{ - test_loader ("document-loader.txt", - "hello world\n", - NULL, - XED_DOCUMENT_NEWLINE_TYPE_LF); - - test_loader ("document-loader.txt", - "hello world\r\n", - NULL, - XED_DOCUMENT_NEWLINE_TYPE_CR_LF); - - test_loader ("document-loader.txt", - "hello world\r", - NULL, - XED_DOCUMENT_NEWLINE_TYPE_CR); -} - -static void -test_begin_new_line_detection () -{ - test_loader ("document-loader.txt", - "\nhello world", - NULL, - XED_DOCUMENT_NEWLINE_TYPE_LF); - - test_loader ("document-loader.txt", - "\r\nhello world", - NULL, - XED_DOCUMENT_NEWLINE_TYPE_CR_LF); - - test_loader ("document-loader.txt", - "\rhello world", - NULL, - XED_DOCUMENT_NEWLINE_TYPE_CR); -} - -int main (int argc, - char *argv[]) -{ - g_test_init (&argc, &argv, NULL); - - xed_prefs_manager_app_init (); - - g_test_add_func ("/document-loader/end-line-stripping", test_end_line_stripping); - g_test_add_func ("/document-loader/end-new-line-detection", test_end_new_line_detection); - g_test_add_func ("/document-loader/begin-new-line-detection", test_begin_new_line_detection); - - return g_test_run (); -} diff --git a/tests/document-output-stream.c b/tests/document-output-stream.c deleted file mode 100644 index b64bbe5..0000000 --- a/tests/document-output-stream.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * document-output-stream.c - * This file is part of xed - * - * Copyright (C) 2010 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - - -#include "xed-document-output-stream.h" -#include "xed-prefs-manager-app.h" -#include -#include -#include -#include - -static void -test_consecutive_write (const gchar *inbuf, - const gchar *outbuf, - gsize write_chunk_len, - XedDocumentNewlineType newline_type) -{ - XedDocument *doc; - GOutputStream *out; - gsize len; - gssize n, w; - GError *err = NULL; - gchar *b; - XedDocumentNewlineType type; - - doc = xed_document_new (); - out = xed_document_output_stream_new (doc); - - n = 0; - - do - { - len = MIN (write_chunk_len, strlen (inbuf + n)); - w = g_output_stream_write (out, inbuf + n, len, NULL, &err); - g_assert_cmpint (w, >=, 0); - g_assert_no_error (err); - - n += w; - } while (w != 0); - - g_assert(g_output_stream_flush (out, NULL, &err) == TRUE); - g_assert_no_error (err); - - g_object_get (G_OBJECT (doc), "text", &b, NULL); - - g_assert_cmpstr (inbuf, ==, b); - g_free (b); - - type = xed_document_output_stream_detect_newline_type (XED_DOCUMENT_OUTPUT_STREAM (out)); - g_assert (type == newline_type); - - g_output_stream_close (out, NULL, &err); - g_assert_no_error (err); - - g_object_get (G_OBJECT (doc), "text", &b, NULL); - - g_assert_cmpstr (outbuf, ==, b); - g_free (b); - - g_assert (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)) == FALSE); - - g_object_unref (doc); - g_object_unref (out); -} - -static void -test_empty () -{ - test_consecutive_write ("", "", 10, XED_DOCUMENT_NEWLINE_TYPE_DEFAULT); - test_consecutive_write ("\r\n", "", 10, XED_DOCUMENT_NEWLINE_TYPE_CR_LF); - test_consecutive_write ("\r", "", 10, XED_DOCUMENT_NEWLINE_TYPE_CR); - test_consecutive_write ("\n", "", 10, XED_DOCUMENT_NEWLINE_TYPE_LF); -} - -static void -test_consecutive () -{ - test_consecutive_write ("hello\nhow\nare\nyou", "hello\nhow\nare\nyou", 3, - XED_DOCUMENT_NEWLINE_TYPE_LF); - test_consecutive_write ("hello\rhow\rare\ryou", "hello\rhow\rare\ryou", 3, - XED_DOCUMENT_NEWLINE_TYPE_CR); - test_consecutive_write ("hello\r\nhow\r\nare\r\nyou", "hello\r\nhow\r\nare\r\nyou", 3, - XED_DOCUMENT_NEWLINE_TYPE_CR_LF); -} - -static void -test_consecutive_tnewline () -{ - test_consecutive_write ("hello\nhow\nare\nyou\n", "hello\nhow\nare\nyou", 3, - XED_DOCUMENT_NEWLINE_TYPE_LF); - test_consecutive_write ("hello\rhow\rare\ryou\r", "hello\rhow\rare\ryou", 3, - XED_DOCUMENT_NEWLINE_TYPE_CR); - test_consecutive_write ("hello\r\nhow\r\nare\r\nyou\r\n", "hello\r\nhow\r\nare\r\nyou", 3, - XED_DOCUMENT_NEWLINE_TYPE_CR_LF); -} - -static void -test_big_char () -{ - test_consecutive_write ("\343\203\200\343\203\200", "\343\203\200\343\203\200", 2, - XED_DOCUMENT_NEWLINE_TYPE_LF); -} - -int main (int argc, - char *argv[]) -{ - g_test_init (&argc, &argv, NULL); - - xed_prefs_manager_app_init (); - - g_test_add_func ("/document-output-stream/empty", test_empty); - - g_test_add_func ("/document-output-stream/consecutive", test_consecutive); - g_test_add_func ("/document-output-stream/consecutive_tnewline", test_consecutive_tnewline); - g_test_add_func ("/document-output-stream/big-char", test_big_char); - - return g_test_run (); -} diff --git a/tests/document-saver.c b/tests/document-saver.c deleted file mode 100644 index 2748fe0..0000000 --- a/tests/document-saver.c +++ /dev/null @@ -1,727 +0,0 @@ -/* - * document-saver.c - * This file is part of xed - * - * Copyright (C) 2010 - Jesse van den Kieboom - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#include "xed-gio-document-loader.h" -#include "xed-prefs-manager-app.h" -#include -#include -#include -#include -#include -#include - -#define DEFAULT_LOCAL_URI "/tmp/xed-document-saver-test.txt" -#define DEFAULT_REMOTE_URI "sftp://localhost/tmp/xed-document-saver-test.txt" -#define DEFAULT_CONTENT "hello world!" -#define DEFAULT_CONTENT_RESULT "hello world!\n" - -#define UNOWNED_LOCAL_DIRECTORY "/tmp/xed-document-saver-unowned" -#define UNOWNED_LOCAL_URI "/tmp/xed-document-saver-unowned/xed-document-saver-test.txt" - -#define UNOWNED_REMOTE_DIRECTORY "sftp://localhost/tmp/xed-document-saver-unowned" -#define UNOWNED_REMOTE_URI "sftp://localhost/tmp/xed-document-saver-unowned/xed-document-saver-test.txt" - -#define UNOWNED_GROUP_LOCAL_URI "/tmp/xed-document-saver-unowned-group.txt" -#define UNOWNED_GROUP_REMOTE_URI "sftp://localhost/tmp/xed-document-saver-unowned-group.txt" - -static gboolean test_completed; -static gboolean mount_completed; -static gboolean mount_success; - -typedef struct -{ - gchar *uri; - const gchar *test_contents; - gpointer data; -} SaverTestData; - -static SaverTestData * -saver_test_data_new (const gchar *uri, const gchar *test_contents, gpointer data) -{ - SaverTestData *ret = g_slice_new (SaverTestData); - - ret->uri = g_strdup (uri); - ret->test_contents = test_contents; - ret->data = data; - - return ret; -} - -static void -saver_test_data_free (SaverTestData *data) -{ - if (data == NULL) - { - return; - } - - g_free (data->uri); - g_slice_free (SaverTestData, data); -} - -static XedDocument * -create_document (const gchar *contents) -{ - XedDocument *document = xed_document_new (); - - gtk_text_buffer_set_text (GTK_TEXT_BUFFER (document), contents, -1); - return document; -} - -static void -complete_test_error (XedDocument *document, - GError *error, - SaverTestData *data) -{ - g_assert_no_error (error); -} - -static const gchar * -read_file (const gchar *uri) -{ - GFile *file = g_file_new_for_commandline_arg (uri); - GError *error = NULL; - static gchar buffer[4096]; - gsize read; - - GInputStream *stream = G_INPUT_STREAM (g_file_read (file, NULL, &error)); - - g_assert_no_error (error); - - g_input_stream_read_all (stream, buffer, sizeof (buffer) - 1, &read, NULL, &error); - g_assert_no_error (error); - - buffer[read] = '\0'; - - g_input_stream_close (stream, NULL, NULL); - - g_object_unref (stream); - g_object_unref (file); - - return buffer; -} - -static void -complete_test (XedDocument *document, - GError *error, - SaverTestData *data) -{ - test_completed = TRUE; - - if (data && data->test_contents && data->uri) - { - g_assert_cmpstr (data->test_contents, ==, read_file (data->uri)); - } -} - -static void -mount_ready_callback (GObject *object, - GAsyncResult *result, - gpointer data) -{ - GError *error = NULL; - mount_success = g_file_mount_enclosing_volume_finish (G_FILE (object), - result, - &error); - - if (error && error->code == G_IO_ERROR_ALREADY_MOUNTED) - { - mount_success = TRUE; - g_error_free (error); - } - else - { - g_assert_no_error (error); - } - - mount_completed = TRUE; -} - -static gboolean -ensure_mounted (GFile *file) -{ - GMountOperation *mo; - - mount_success = FALSE; - mount_completed = FALSE; - - if (g_file_is_native (file)) - { - return TRUE; - } - - mo = gtk_mount_operation_new (NULL); - - g_file_mount_enclosing_volume (file, - G_MOUNT_MOUNT_NONE, - mo, - NULL, - mount_ready_callback, - NULL); - - while (!mount_completed) - { - g_main_context_iteration (NULL, TRUE); - } - - g_object_unref (mo); - - return mount_success; -} - -static void -test_saver (const gchar *filename_or_uri, - const gchar *contents, - XedDocumentNewlineType newline_type, - XedDocumentSaveFlags save_flags, - GCallback saved_callback, - SaverTestData *data) -{ - GFile *file; - gchar *uri; - XedDocument *document; - gboolean existed; - - document = create_document (contents); - xed_document_set_newline_type (document, newline_type); - - g_signal_connect (document, "saved", G_CALLBACK (complete_test_error), data); - - if (saved_callback) - { - g_signal_connect (document, "saved", saved_callback, data); - } - - g_signal_connect_after (document, "saved", G_CALLBACK (complete_test), data); - - test_completed = FALSE; - - file = g_file_new_for_commandline_arg (filename_or_uri); - uri = g_file_get_uri (file); - existed = g_file_query_exists (file, NULL); - - ensure_mounted (file); - - xed_document_save_as (document, uri, xed_encoding_get_utf8 (), save_flags); - - while (!test_completed) - { - g_main_context_iteration (NULL, TRUE); - } - - if (!existed) - { - g_file_delete (file, NULL, NULL); - } - - g_free (uri); - g_object_unref (file); - - saver_test_data_free (data); -} - -typedef struct -{ - XedDocumentNewlineType type; - const gchar *text; - const gchar *result; -} NewLineTestData; - -static NewLineTestData newline_test_data[] = { - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\nworld", "\nhello\nworld\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\nworld\n", "\nhello\nworld\n\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\nworld\n\n", "\nhello\nworld\n\n\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\r\nhello\r\nworld", "\nhello\nworld\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\r\nhello\r\nworld\r\n", "\nhello\nworld\n\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\rhello\rworld", "\nhello\nworld\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\rhello\rworld\r", "\nhello\nworld\n\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\r\nworld", "\nhello\nworld\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\r\nworld\r", "\nhello\nworld\n\n"}, - - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\nworld", "\r\nhello\r\nworld\r\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\nworld\n", "\r\nhello\r\nworld\r\n\r\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\nworld\n\n", "\r\nhello\r\nworld\r\n\r\n\r\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\r\nhello\r\nworld", "\r\nhello\r\nworld\r\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\r\nhello\r\nworld\r\n", "\r\nhello\r\nworld\r\n\r\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\rhello\rworld", "\r\nhello\r\nworld\r\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\rhello\rworld\r", "\r\nhello\r\nworld\r\n\r\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\r\nworld", "\r\nhello\r\nworld\r\n"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\r\nworld\r", "\r\nhello\r\nworld\r\n\r\n"}, - - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\nworld", "\rhello\rworld\r"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\nworld\n", "\rhello\rworld\r\r"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\nworld\n\n", "\rhello\rworld\r\r\r"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\r\nhello\r\nworld", "\rhello\rworld\r"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\r\nhello\r\nworld\r\n", "\rhello\rworld\r\r"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\rhello\rworld", "\rhello\rworld\r"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\rhello\rworld\r", "\rhello\rworld\r\r"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\r\nworld", "\rhello\rworld\r"}, - {XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\r\nworld\r", "\rhello\rworld\r\r"} -}; - -static void -test_new_line (const gchar *filename, XedDocumentSaveFlags save_flags) -{ - gint i; - gint num = sizeof (newline_test_data) / sizeof (NewLineTestData); - - for (i = 0; i < num; ++i) - { - NewLineTestData *nt = &(newline_test_data[i]); - - test_saver (filename, - nt->text, - nt->type, - save_flags, - NULL, - saver_test_data_new (filename, nt->result, NULL)); - } -} - -static void -test_local_newline () -{ - test_new_line (DEFAULT_LOCAL_URI, 0); -} - -static void -test_local () -{ - test_saver (DEFAULT_LOCAL_URI, - "hello world", - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - NULL, - saver_test_data_new (DEFAULT_LOCAL_URI, "hello world\n", NULL)); - - test_saver (DEFAULT_LOCAL_URI, - "hello world\r\n", - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - NULL, - saver_test_data_new (DEFAULT_LOCAL_URI, "hello world\n\n", NULL)); - - test_saver (DEFAULT_LOCAL_URI, - "hello world\n", - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - NULL, - saver_test_data_new (DEFAULT_LOCAL_URI, "hello world\n\n", NULL)); -} - -static void -test_remote_newline () -{ - test_new_line (DEFAULT_REMOTE_URI, 0); -} - -static void -test_remote () -{ - test_saver (DEFAULT_REMOTE_URI, - "hello world", - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - NULL, - saver_test_data_new (DEFAULT_REMOTE_URI, "hello world\n", NULL)); - - test_saver (DEFAULT_REMOTE_URI, - "hello world\r\n", - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - NULL, - saver_test_data_new (DEFAULT_REMOTE_URI, "hello world\n\n", NULL)); - - test_saver (DEFAULT_REMOTE_URI, - "hello world\n", - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - NULL, - saver_test_data_new (DEFAULT_REMOTE_URI, "hello world\n\n", NULL)); -} - -static void -check_permissions (GFile *file, - guint permissions) -{ - GError *error = NULL; - GFileInfo *info; - - info = g_file_query_info (file, - G_FILE_ATTRIBUTE_UNIX_MODE, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - - g_assert_no_error (error); - - g_assert_cmpint (permissions, - ==, - g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE) & ACCESSPERMS); - - g_object_unref (info); -} - -static void -check_permissions_saved (XedDocument *document, - GError *error, - SaverTestData *data) -{ - guint permissions = (guint)GPOINTER_TO_INT (data->data); - GFile *file = xed_document_get_location (document); - - check_permissions (file, permissions); - - g_object_unref (file); -} - -static void -test_permissions (const gchar *uri, - guint permissions) -{ - GError *error = NULL; - GFile *file = g_file_new_for_commandline_arg (uri); - GFileOutputStream *stream; - GFileInfo *info; - guint mode; - - g_file_delete (file, NULL, NULL); - stream = g_file_create (file, 0, NULL, &error); - - g_assert_no_error (error); - - g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL); - g_object_unref (stream); - - info = g_file_query_info (file, - G_FILE_ATTRIBUTE_UNIX_MODE, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - - g_assert_no_error (error); - - mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE); - g_object_unref (info); - - g_file_set_attribute_uint32 (file, - G_FILE_ATTRIBUTE_UNIX_MODE, - (mode & ~ACCESSPERMS) | permissions, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - g_assert_no_error (error); - - check_permissions (file, permissions); - - test_saver (uri, - DEFAULT_CONTENT, - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - G_CALLBACK (check_permissions_saved), - saver_test_data_new (uri, - DEFAULT_CONTENT_RESULT, - GINT_TO_POINTER ((gint)permissions))); - - g_file_delete (file, NULL, NULL); - g_object_unref (file); -} - -static void -test_local_permissions () -{ - test_permissions (DEFAULT_LOCAL_URI, 0600); - test_permissions (DEFAULT_LOCAL_URI, 0660); - test_permissions (DEFAULT_LOCAL_URI, 0666); - test_permissions (DEFAULT_LOCAL_URI, 0760); -} - -static void -test_local_unowned_directory () -{ - test_saver (UNOWNED_LOCAL_URI, - DEFAULT_CONTENT, - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - NULL, - saver_test_data_new (UNOWNED_LOCAL_URI, - DEFAULT_CONTENT_RESULT, - NULL)); -} - -static void -test_remote_unowned_directory () -{ - test_saver (UNOWNED_REMOTE_URI, - DEFAULT_CONTENT, - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - NULL, - saver_test_data_new (UNOWNED_REMOTE_URI, - DEFAULT_CONTENT_RESULT, - NULL)); -} - -static void -test_remote_permissions () -{ - test_permissions (DEFAULT_REMOTE_URI, 0600); - test_permissions (DEFAULT_REMOTE_URI, 0660); - test_permissions (DEFAULT_REMOTE_URI, 0666); - test_permissions (DEFAULT_REMOTE_URI, 0760); -} - -static void -test_unowned_group_permissions (XedDocument *document, - GError *error, - SaverTestData *data) -{ - GFile *file = g_file_new_for_commandline_arg (data->uri); - GError *err = NULL; - const gchar *group; - guint32 mode; - - GFileInfo *info = g_file_query_info (file, - G_FILE_ATTRIBUTE_OWNER_GROUP "," - G_FILE_ATTRIBUTE_UNIX_MODE, - G_FILE_QUERY_INFO_NONE, - NULL, - &err); - - g_assert_no_error (err); - - group = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP); - g_assert_cmpstr (group, ==, "root"); - - mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE); - - g_assert_cmpint (mode & ACCESSPERMS, ==, 0660); - - g_object_unref (file); - g_object_unref (info); -} - -static void -test_unowned_group (const gchar *uri) -{ - test_saver (uri, - DEFAULT_CONTENT, - XED_DOCUMENT_NEWLINE_TYPE_LF, - 0, - G_CALLBACK (test_unowned_group_permissions), - saver_test_data_new (uri, - DEFAULT_CONTENT_RESULT, - NULL)); -} - -static void -test_local_unowned_group () -{ - test_unowned_group (UNOWNED_GROUP_LOCAL_URI); -} - -static void -test_remote_unowned_group () -{ - test_unowned_group (UNOWNED_GROUP_REMOTE_URI); -} - -static gboolean -check_unowned_directory () -{ - GFile *unowned = g_file_new_for_path (UNOWNED_LOCAL_DIRECTORY); - GFile *unowned_file; - GFileInfo *info; - GError *error = NULL; - - g_printf ("*** Checking for unowned directory test... "); - - info = g_file_query_info (unowned, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - - if (error) - { - g_object_unref (unowned); - g_printf ("NO: directory does not exist\n"); - - g_error_free (error); - return FALSE; - } - - if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) - { - g_object_unref (unowned); - - g_printf ("NO: directory is writable\n"); - g_object_unref (info); - return FALSE; - } - - g_object_unref (info); - g_object_unref (unowned); - - unowned_file = g_file_new_for_commandline_arg (UNOWNED_LOCAL_URI); - - info = g_file_query_info (unowned_file, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - - if (error) - { - g_object_unref (unowned_file); - g_error_free (error); - - g_printf ("NO: file does not exist\n"); - return FALSE; - } - - if (!g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) - { - g_object_unref (unowned_file); - - g_printf ("NO: file is not writable\n"); - g_object_unref (info); - return FALSE; - } - - g_object_unref (info); - g_object_unref (unowned_file); - - g_printf ("YES\n"); - return TRUE; -} - -static gboolean -check_unowned_group () -{ - GFile *unowned = g_file_new_for_path (UNOWNED_GROUP_LOCAL_URI); - GFileInfo *info; - GError *error = NULL; - - g_printf ("*** Checking for unowned group test... "); - - info = g_file_query_info (unowned, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "," - G_FILE_ATTRIBUTE_OWNER_GROUP "," - G_FILE_ATTRIBUTE_UNIX_MODE, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - - if (error) - { - g_object_unref (unowned); - g_printf ("NO: file does not exist\n"); - - g_error_free (error); - return FALSE; - } - - if (!g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) - { - g_object_unref (unowned); - - g_printf ("NO: file is not writable\n"); - g_object_unref (info); - return FALSE; - } - - if (g_strcmp0 (g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP), - "root") != 0) - { - g_object_unref (unowned); - - g_printf ("NO: group is not root (%s)\n", g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP)); - g_object_unref (info); - return FALSE; - } - - if ((g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE) & ACCESSPERMS) != 0660) - { - g_object_unref (unowned); - - g_printf ("NO: file has wrong permissions\n"); - g_object_unref (info); - return FALSE; - } - - g_object_unref (info); - g_object_unref (unowned); - - g_printf ("YES\n"); - return TRUE; -} - -int main (int argc, - char *argv[]) -{ - gboolean have_unowned; - gboolean have_unowned_group; - - g_test_init (&argc, &argv, NULL); - - xed_prefs_manager_app_init (); - - g_printf ("\n***\n"); - have_unowned = check_unowned_directory (); - have_unowned_group = check_unowned_group (); - g_printf ("***\n\n"); - - g_test_add_func ("/document-saver/local", test_local); - g_test_add_func ("/document-saver/local-new-line", test_local_newline); - - if (have_unowned) - { - g_test_add_func ("/document-saver/local-unowned-directory", test_local_unowned_directory); - } - - g_test_add_func ("/document-saver/remote", test_remote); - g_test_add_func ("/document-saver/remote-new-line", test_remote_newline); - - - if (have_unowned) - { - g_test_add_func ("/document-saver/remote-unowned-directory", test_remote_unowned_directory); - } - - if (have_unowned_group) - { - /* FIXME: there is a bug in gvfs sftp which doesn't pass this test */ - /* g_test_add_func ("/document-saver/remote-unowned-group", test_remote_unowned_group); */ - } - - g_test_add_func ("/document-saver/local-permissions", test_local_permissions); - - if (have_unowned_group) - { - g_test_add_func ("/document-saver/local-unowned-group", test_local_unowned_group); - } - - g_test_add_func ("/document-saver/remote-permissions", test_remote_permissions); - - return g_test_run (); -} diff --git a/tests/setup-document-saver.sh b/tests/setup-document-saver.sh deleted file mode 100644 index 05b894d..0000000 --- a/tests/setup-document-saver.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -# This script is used to setup some special directory structures, permissions -# for the saver test - -UNOWNED_DIRECTORY="/tmp/xed-document-saver-unowned" -UNOWNED_FILE="/tmp/xed-document-saver-unowned/xed-document-saver-test.txt" - -UNOWNED_GROUP="/tmp/xed-document-saver-unowned-group.txt" - -if [ -f "$UNOWNED_FILE" ]; then - sudo rm "$UNOWNED_FILE" -fi - -if [ -d "$UNOWNED_DIRECTORY" ]; then - sudo rmdir "$UNOWNED_DIRECTORY" -fi - -mkdir "$UNOWNED_DIRECTORY" -touch "$UNOWNED_FILE" - -sudo chown nobody "$UNOWNED_DIRECTORY" - -sudo touch "$UNOWNED_GROUP" -sudo chgrp root "$UNOWNED_GROUP" -sudo chmod u+w,g+w,o-rwx "$UNOWNED_GROUP" -sudo chown $USER "$UNOWNED_GROUP" diff --git a/tests/smart-converter.c b/tests/smart-converter.c deleted file mode 100644 index 9dd322c..0000000 --- a/tests/smart-converter.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * smart-converter.c - * This file is part of xed - * - * Copyright (C) 2009 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - - -#include "xed-smart-charset-converter.h" -#include "xed-encodings.h" -#include -#include -#include -#include - -#define TEXT_TO_CONVERT "this is some text to make the tests" -#define TEXT_TO_GUESS "hello \xe6\x96\x87 world" - -static void -print_hex (gchar *ptr, gint len) -{ - gint i; - - for (i = 0; i < len; ++i) - { - g_printf ("\\x%02x", (unsigned char)ptr[i]); - } - - g_printf ("\n"); -} - -static gchar * -get_encoded_text (const gchar *text, - gsize nread, - const XedEncoding *to, - const XedEncoding *from, - gsize *bytes_written_aux, - gboolean care_about_error) -{ - GCharsetConverter *converter; - gchar *out, *out_aux; - gsize bytes_read, bytes_read_aux; - gsize bytes_written; - GConverterResult res; - GError *err; - - converter = g_charset_converter_new (xed_encoding_get_charset (to), - xed_encoding_get_charset (from), - NULL); - - out = g_malloc (200); - out_aux = g_malloc (200); - err = NULL; - bytes_read_aux = 0; - *bytes_written_aux = 0; - - if (nread == -1) - { - nread = strlen (text); - } - - do - { - res = g_converter_convert (G_CONVERTER (converter), - text + bytes_read_aux, - nread, - out_aux, - 200, - G_CONVERTER_INPUT_AT_END, - &bytes_read, - &bytes_written, - &err); - memcpy (out + *bytes_written_aux, out_aux, bytes_written); - bytes_read_aux += bytes_read; - *bytes_written_aux += bytes_written; - nread -= bytes_read; - } while (res != G_CONVERTER_FINISHED && res != G_CONVERTER_ERROR); - - if (care_about_error) - { - g_assert_no_error (err); - } - else if (err) - { - g_printf ("** You don't care, but there was an error: %s", err->message); - return NULL; - } - - out[*bytes_written_aux] = '\0'; - - if (!g_utf8_validate (out, *bytes_written_aux, NULL) && !care_about_error) - { - if (!care_about_error) - { - return NULL; - } - else - { - g_assert_not_reached (); - } - } - - return out; -} - -static GSList * -get_all_encodings () -{ - GSList *encs = NULL; - gint i = 0; - - while (TRUE) - { - const XedEncoding *enc; - - enc = xed_encoding_get_from_index (i); - - if (enc == NULL) - break; - - encs = g_slist_prepend (encs, (gpointer)enc); - i++; - } - - return encs; -} - -static gchar * -do_test (const gchar *test_in, - const gchar *enc, - GSList *encodings, - gsize nread, - const XedEncoding **guessed) -{ - XedSmartCharsetConverter *converter; - gchar *out, *out_aux; - gsize bytes_read, bytes_read_aux; - gsize bytes_written, bytes_written_aux; - GConverterResult res; - GError *err; - - if (enc != NULL) - { - encodings = NULL; - encodings = g_slist_prepend (encodings, (gpointer)xed_encoding_get_from_charset (enc)); - } - - converter = xed_smart_charset_converter_new (encodings); - - out = g_malloc (200); - out_aux = g_malloc (200); - err = NULL; - bytes_read_aux = 0; - bytes_written_aux = 0; - - do - { - res = g_converter_convert (G_CONVERTER (converter), - test_in + bytes_read_aux, - nread, - out_aux, - 200, - G_CONVERTER_INPUT_AT_END, - &bytes_read, - &bytes_written, - &err); - memcpy (out + bytes_written_aux, out_aux, bytes_written); - bytes_read_aux += bytes_read; - bytes_written_aux += bytes_written; - nread -= bytes_read; - } while (res != G_CONVERTER_FINISHED && res != G_CONVERTER_ERROR); - - g_assert_no_error (err); - out[bytes_written_aux] = '\0'; - - if (guessed != NULL) - *guessed = xed_smart_charset_converter_get_guessed (converter); - - return out; -} - -static void -do_test_roundtrip (const char *str, const char *charset) -{ - gsize len; - gchar *buf, *p; - GInputStream *in, *tmp; - GCharsetConverter *c1; - XedSmartCharsetConverter *c2; - gsize n, tot; - GError *err; - GSList *enc = NULL; - - len = strlen(str); - buf = g_new0 (char, len); - - in = g_memory_input_stream_new_from_data (str, -1, NULL); - - c1 = g_charset_converter_new (charset, "UTF-8", NULL); - - tmp = in; - in = g_converter_input_stream_new (in, G_CONVERTER (c1)); - g_object_unref (tmp); - g_object_unref (c1); - - enc = g_slist_prepend (enc, (gpointer)xed_encoding_get_from_charset (charset)); - c2 = xed_smart_charset_converter_new (enc); - g_slist_free (enc); - - tmp = in; - in = g_converter_input_stream_new (in, G_CONVERTER (c2)); - g_object_unref (tmp); - g_object_unref (c2); - - tot = 0; - p = buf; - n = len; - while (TRUE) - { - gssize res; - - err = NULL; - res = g_input_stream_read (in, p, n, NULL, &err); - g_assert_no_error (err); - if (res == 0) - break; - - p += res; - n -= res; - tot += res; - } - - g_assert_cmpint (tot, ==, len); - g_assert_cmpstr (str, ==, buf); - - g_free (buf); - g_object_unref (in); -} - -static void -test_utf8_utf8 () -{ - gchar *aux; - - aux = do_test (TEXT_TO_CONVERT, "UTF-8", NULL, strlen (TEXT_TO_CONVERT), NULL); - g_assert_cmpstr (aux, ==, TEXT_TO_CONVERT); - - aux = do_test ("foobar\xc3\xa8\xc3\xa8\xc3\xa8zzzzzz", "UTF-8", NULL, 18, NULL); - g_assert_cmpstr (aux, ==, "foobar\xc3\xa8\xc3\xa8\xc3\xa8zzzzzz"); - - aux = do_test ("foobar\xc3\xa8\xc3\xa8\xc3\xa8zzzzzz", "UTF-8", NULL, 9, NULL); - g_assert_cmpstr (aux, ==, "foobar\xc3\xa8\xc3"); - - /* FIXME: Use the utf8 stream for a fallback? */ - //do_test_with_error ("\xef\xbf\xbezzzzzz", encs, G_IO_ERROR_FAILED); -} - -static void -test_xxx_xxx () -{ - GSList *encs, *l; - - encs = get_all_encodings (); - - /* Here we just test all encodings it is just to know that the conversions - are done ok */ - for (l = encs; l != NULL; l = g_slist_next (l)) - { - do_test_roundtrip (TEXT_TO_CONVERT, xed_encoding_get_charset ((const XedEncoding *)l->data)); - } - - g_slist_free (encs); -} - -static void -test_empty () -{ - const XedEncoding *guessed; - gchar *out; - GSList *encodings = NULL; - - /* testing the case of an empty file and list of encodings with no - utf-8. In this case, the smart converter cannot determine the right - encoding (because there is no input), but should still default to - utf-8 for the detection */ - encodings = g_slist_prepend (encodings, (gpointer)xed_encoding_get_from_charset ("UTF-16")); - encodings = g_slist_prepend (encodings, (gpointer)xed_encoding_get_from_charset ("ISO-8859-15")); - - out = do_test ("", NULL, encodings, 0, &guessed); - - g_assert_cmpstr (out, ==, ""); - - g_assert (guessed == xed_encoding_get_utf8 ()); -} - -static void -test_guessed () -{ - GSList *encs = NULL; - gchar *aux, *aux2, *fail; - gsize aux_len, fail_len; - const XedEncoding *guessed; - - aux = get_encoded_text (TEXT_TO_GUESS, -1, - xed_encoding_get_from_charset ("UTF-16"), - xed_encoding_get_from_charset ("UTF-8"), - &aux_len, - TRUE); - - fail = get_encoded_text (aux, aux_len, - xed_encoding_get_from_charset ("UTF-8"), - xed_encoding_get_from_charset ("ISO-8859-15"), - &fail_len, - FALSE); - - g_assert (fail == NULL); - - /* ISO-8859-15 should fail */ - encs = g_slist_append (encs, (gpointer)xed_encoding_get_from_charset ("ISO-8859-15")); - encs = g_slist_append (encs, (gpointer)xed_encoding_get_from_charset ("UTF-16")); - - aux2 = do_test (aux, NULL, encs, aux_len, &guessed); - - g_assert (guessed == xed_encoding_get_from_charset ("UTF-16")); -} - -int main (int argc, - char *argv[]) -{ - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/smart-converter/utf8-utf8", test_utf8_utf8); - //g_test_add_func ("/smart-converter/xxx-xxx", test_xxx_xxx); - g_test_add_func ("/smart-converter/guessed", test_guessed); - g_test_add_func ("/smart-converter/empty", test_empty); - - return g_test_run (); -} diff --git a/tools/plugin_template/xed-plugin.desktop.in b/tools/plugin_template/xed-plugin.desktop.in index df3a5cd..7b54a27 100644 --- a/tools/plugin_template/xed-plugin.desktop.in +++ b/tools/plugin_template/xed-plugin.desktop.in @@ -1,7 +1,4 @@ [Xed Plugin] -##ifdef WITH_PYTHON -Loader=python -##endif Module=##(PLUGIN_MODULE) IAge=2 _Name=##(PLUGIN_NAME) diff --git a/xed/Makefile.am b/xed/Makefile.am index c5018fe..0720e42 100644 --- a/xed/Makefile.am +++ b/xed/Makefile.am @@ -1,35 +1,33 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = dialogs smclient bin_PROGRAMS = xed -noinst_LTLIBRARIES = libxed.la +pkglib_LTLIBRARIES = libxed.la -AM_CPPFLAGS = \ - -I$(top_srcdir) \ +AM_CPPFLAGS = \ + -I$(top_srcdir) \ -I$(srcdir) \ - -I$(srcdir)/smclient \ - $(XED_CFLAGS) \ - $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) \ - -DDATADIR=\""$(datadir)"\" \ + $(XED_CFLAGS) \ + $(WARN_CFLAGS) \ + $(INTROSPECTION_CFLAGS) \ + $(DISABLE_DEPRECATED_CFLAGS) \ + -DDATADIR=\""$(datadir)"\" \ -DLIBDIR=\""$(libdir)"\" xed_SOURCES = \ xed.c -xed_LDADD = libxed.la $(XED_LIBS) $(EGG_SMCLIENT_LIBS) +xed_LDADD = \ + libxed.la \ + $(XED_LIBS) \ + $(INTROSPECTION_LIBS) xed_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*" -libxed_la_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*" - -libxed_la_LIBADD = \ - dialogs/libdialogs.la \ - smclient/libeggsmclient.la +libxed_la_LDFLAGS = -avoid-version -export-dynamic -no-undefined -export-symbols-regex "^[^_].*" # XED_LIBS must be the last to ensure correct order on some platforms -libxed_la_LIBADD += $(XED_LIBS) -lICE +libxed_la_LIBADD = $(XED_LIBS) BUILT_SOURCES = \ xed-enum-types.c \ @@ -38,61 +36,47 @@ BUILT_SOURCES = \ xed-marshal.h -NOINST_H_FILES = \ - xed-close-button.h \ - xed-dirs.h \ - xed-document-input-stream.h \ - xed-document-loader.h \ - xed-document-output-stream.h \ - xed-document-saver.h \ - xed-documents-panel.h \ - xed-gio-document-loader.h \ - xed-gio-document-saver.h \ - xed-history-entry.h \ - xed-io-error-message-area.h \ - xed-language-manager.h \ - xed-object-module.h \ - xed-plugin-info.h \ - xed-plugin-info-priv.h \ - xed-plugin-loader.h \ - xed-plugin-manager.h \ - xed-plugins-engine.h \ - xed-prefs-manager-private.h \ - xed-print-job.h \ - xed-print-preview.h \ - xed-session.h \ - xed-smart-charset-converter.h \ - xed-style-scheme-manager.h \ - xed-tab-label.h \ - xedtextregion.h \ - xed-ui.h \ +NOINST_H_FILES = \ + xed-close-button.h \ + xed-close-confirmation-dialog.h \ + xed-dirs.h \ + xed-documents-panel.h \ + xed-encodings-dialog.h \ + xed-history-entry.h \ + xed-io-error-info-bar.h \ + xed-plugins-engine.h \ + xed-preferences-dialog.h \ + xed-print-job.h \ + xed-print-preview.h \ + xed-settings.h \ + xed-status-combo-box.h \ + xed-tab-label.h \ + xed-ui.h \ + xed-utils.h \ + xed-view-frame.h \ xed-window-private.h -INST_H_FILES = \ - xed-app.h \ - xed-commands.h \ - xed-debug.h \ - xed-document.h \ - xed-encodings.h \ - xed-encodings-combo-box.h \ - xed-file-chooser-dialog.h \ - xed-help.h \ - xed-message-bus.h \ - xed-message-type.h \ - xed-message.h \ - xed-notebook.h \ - xed-panel.h \ - xed-plugin.h \ - xed-prefs-manager-app.h \ - xed-prefs-manager.h \ - xed-progress-message-area.h \ - xed-searchbar.h \ - xed-statusbar.h \ - xed-status-combo-box.h \ - xed-tab.h \ - xed-utils.h \ - xed-view.h \ - xed-window.h +INST_H_FILES = \ + xed-app.h \ + xed-app-activatable.h \ + xed-commands.h \ + xed-debug.h \ + xed-document.h \ + xed-encodings-combo-box.h \ + xed-file-chooser-dialog.h \ + xed-message-bus.h \ + xed-message-type.h \ + xed-message.h \ + xed-notebook.h \ + xed-panel.h \ + xed-progress-info-bar.h \ + xed-searchbar.h \ + xed-statusbar.h \ + xed-tab.h \ + xed-view.h \ + xed-view-activatable.h \ + xed-window.h \ + xed-window-activatable.h if !ENABLE_GVFS_METADATA INST_H_FILES += xed-metadata-manager.h @@ -100,70 +84,62 @@ endif headerdir = $(prefix)/include/xed -header_DATA = \ +header_DATA = \ $(INST_H_FILES) +BUILT_SOURCES_PRIVATE = \ + xed-resources.c -libxed_la_SOURCES = \ - $(BUILT_SOURCES) \ - $(BACON_FILES) \ - $(POSIXIO_FILES) \ - xed-app.c \ - xed-close-button.c \ - xed-commands-documents.c \ - xed-commands-edit.c \ - xed-commands-file.c \ - xed-commands-file-print.c \ - xed-commands-help.c \ - xed-commands-search.c \ - xed-commands-view.c \ - xed-debug.c \ - xed-dirs.c \ - xed-document.c \ - xed-document-input-stream.c \ - xed-document-loader.c \ - xed-document-output-stream.c \ - xed-gio-document-loader.c \ - xed-document-saver.c \ - xed-gio-document-saver.c \ - xed-documents-panel.c \ - xed-encodings.c \ - xed-encodings-combo-box.c \ - xed-file-chooser-dialog.c \ - xed-help.c \ - xed-history-entry.c \ - xed-io-error-message-area.c \ - xed-language-manager.c \ - xed-message-bus.c \ - xed-message-type.c \ - xed-message.c \ - xed-object-module.c \ - xed-notebook.c \ - xed-panel.c \ - xed-plugin-info.c \ - xed-plugin.c \ - xed-plugin-loader.c \ - xed-plugin-manager.c \ - xed-plugins-engine.c \ - xed-prefs-manager-app.c \ - xed-prefs-manager.c \ - xed-prefs-manager-private.h \ - xed-print-job.c \ - xed-print-preview.c \ - xed-progress-message-area.c \ - xed-session.c \ - xed-smart-charset-converter.c \ - xed-searchbar.c \ - xed-statusbar.c \ - xed-status-combo-box.c \ - xed-style-scheme-manager.c \ - xed-tab.c \ - xed-tab-label.c \ - xed-utils.c \ - xed-view.c \ - xed-window.c \ - xedtextregion.c \ - $(NOINST_H_FILES) \ +libxed_c_files = \ + xed-app.c \ + xed-app-activatable.c \ + xed-view-activatable.c \ + xed-window-activatable.c \ + xed-resources.c \ + xed-close-button.c \ + xed-close-confirmation-dialog.c \ + xed-commands-documents.c \ + xed-commands-edit.c \ + xed-commands-file.c \ + xed-commands-file-print.c \ + xed-commands-help.c \ + xed-commands-search.c \ + xed-commands-view.c \ + xed-debug.c \ + xed-dirs.c \ + xed-document.c \ + xed-documents-panel.c \ + xed-encodings-combo-box.c \ + xed-encodings-dialog.c \ + xed-file-chooser-dialog.c \ + xed-history-entry.c \ + xed-io-error-info-bar.c \ + xed-message-bus.c \ + xed-message-type.c \ + xed-message.c \ + xed-notebook.c \ + xed-panel.c \ + xed-plugins-engine.c \ + xed-preferences-dialog.c \ + xed-print-job.c \ + xed-print-preview.c \ + xed-progress-info-bar.c \ + xed-settings.c \ + xed-searchbar.c \ + xed-statusbar.c \ + xed-status-combo-box.c \ + xed-tab.c \ + xed-tab-label.c \ + xed-utils.c \ + xed-view.c \ + xed-view-frame.c \ + xed-window.c + +libxed_la_SOURCES = \ + $(BUILT_SOURCES) \ + $(libxed_c_files) \ + $(POSIXIO_FILES) \ + $(NOINST_H_FILES) \ $(INST_H_FILES) if !ENABLE_GVFS_METADATA @@ -183,28 +159,48 @@ xed-marshal.c: xed-marshal.list $(GLIB_GENMARSHAL) $(AM_V_GEN) echo "#include \"xed-marshal.h\"" > $@ && \ $(GLIB_GENMARSHAL) $< --body --prefix=xed_marshal >> $@ -uidir = $(datadir)/xed/ui/ -ui_DATA = \ - xed-ui.xml \ - xed-searchbar.ui \ - xed-print-preferences.ui +xed-resources.c: resources/xed.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir)/resources --generate-dependencies $(srcdir)/resources/xed.gresource.xml) + $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir)/resources --generate-source $(srcdir)/resources/xed.gresource.xml -EXTRA_DIST = \ - $(ui_DATA) \ - xed-enum-types.h.template \ - xed-enum-types.c.template \ - xed-marshal.list \ - xed.rc +EXTRA_DIST = \ + xed-enum-types.h.template \ + xed-enum-types.c.template \ + xed-marshal.list \ + xed.rc \ + resources/xed.gresource.xml \ + resources/ui/xed-ui.xml \ + resources/ui/xed-encodings-dialog.ui \ + resources/ui/xed-preferences-dialog.ui \ + resources/ui/xed-print-preferences.ui \ + resources/ui/xed-searchbar.ui \ + resources/ui/xed-view-frame.ui -CLEANFILES = $(BUILT_SOURCES) +CLEANFILES = $(BUILT_SOURCES) $(BUILT_SOURCES_PRIVATE) + +if HAVE_INTROSPECTION +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = Xed-1.0.gir + +Xed-1.0.gir: xed +INTROSPECTION_SCANNER_ARGS = -I$(top_srcdir) --warn-all +Xed_1_0_gir_NAMESPACE = Xed +Xed_1_0_gir_VERSION = 1.0 +Xed_1_0_gir_PROGRAM = $(builddir)/xed +Xed_1_0_gir_FILES = $(INST_H_FILES) $(libxed_c_files) $(BUILT_SOURCES) +Xed_1_0_gir_INCLUDES = Gtk-3.0 GtkSource-3.0 + +girdir = $(datadir)/xed/gir-1.0 +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(libdir)/xed/girepository-1.0 +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + +CLEANFILES += \ + $(gir_DATA) \ + $(typelib_DATA) +endif dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - -BACON_DIR=$(srcdir)/../../libbacon/src/ -BACON_FILES=bacon-message-connection.h bacon-message-connection.c - -regenerate-built-sources: - BACONFILES="$(BACON_FILES)" BACONDIR="$(BACON_DIR)" $(top_srcdir)/xed/update-from-bacon.sh + cd $(distdir); rm -f $(BUILT_SOURCES) $(BUILT_SOURCES_PRIVATE) -include $(top_srcdir)/git.mk diff --git a/xed/bacon-message-connection.c b/xed/bacon-message-connection.c deleted file mode 100644 index 7b35342..0000000 --- a/xed/bacon-message-connection.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright (C) 2003 Bastien Nocera - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bacon-message-connection.h" - -#ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX 108 -#endif - -struct BaconMessageConnection { - /* A server accepts connections */ - gboolean is_server; - - /* The socket path itself */ - char *path; - - /* File descriptor of the socket */ - int fd; - /* Channel to watch */ - GIOChannel *chan; - /* Event id returned by g_io_add_watch() */ - int conn_id; - - /* Connections accepted by this connection */ - GSList *accepted_connections; - - /* callback */ - void (*func) (const char *message, gpointer user_data); - gpointer data; -}; - -static gboolean -test_is_socket (const char *path) -{ - struct stat s; - - if (stat (path, &s) == -1) - return FALSE; - - if (S_ISSOCK (s.st_mode)) - return TRUE; - - return FALSE; -} - -static gboolean -is_owned_by_user_and_socket (const char *path) -{ - struct stat s; - - if (stat (path, &s) == -1) - return FALSE; - - if (s.st_uid != geteuid ()) - return FALSE; - - if ((s.st_mode & S_IFSOCK) != S_IFSOCK) - return FALSE; - - return TRUE; -} - -static gboolean server_cb (GIOChannel *source, - GIOCondition condition, gpointer data); - -static gboolean -setup_connection (BaconMessageConnection *conn) -{ - g_return_val_if_fail (conn->chan == NULL, FALSE); - - conn->chan = g_io_channel_unix_new (conn->fd); - if (!conn->chan) { - return FALSE; - } - g_io_channel_set_line_term (conn->chan, "\n", 1); - conn->conn_id = g_io_add_watch (conn->chan, G_IO_IN, server_cb, conn); - - return TRUE; -} - -static void -accept_new_connection (BaconMessageConnection *server_conn) -{ - BaconMessageConnection *conn; - int alen; - - g_return_if_fail (server_conn->is_server); - - conn = g_new0 (BaconMessageConnection, 1); - conn->is_server = FALSE; - conn->func = server_conn->func; - conn->data = server_conn->data; - - conn->fd = accept (server_conn->fd, NULL, (guint *)&alen); - - server_conn->accepted_connections = - g_slist_prepend (server_conn->accepted_connections, conn); - - setup_connection (conn); -} - -static gboolean -server_cb (GIOChannel *source, GIOCondition condition, gpointer data) -{ - BaconMessageConnection *conn = (BaconMessageConnection *)data; - char *message, *subs, buf; - int cd, rc, offset; - gboolean finished; - - offset = 0; - if (conn->is_server && conn->fd == g_io_channel_unix_get_fd (source)) { - accept_new_connection (conn); - return TRUE; - } - message = g_malloc (1); - cd = conn->fd; - rc = read (cd, &buf, 1); - while (rc > 0 && buf != '\n') - { - message = g_realloc (message, rc + offset + 1); - message[offset] = buf; - offset = offset + rc; - rc = read (cd, &buf, 1); - } - if (rc <= 0) { - g_io_channel_shutdown (conn->chan, FALSE, NULL); - g_io_channel_unref (conn->chan); - conn->chan = NULL; - close (conn->fd); - conn->fd = -1; - g_free (message); - conn->conn_id = 0; - - return FALSE; - } - message[offset] = '\0'; - - subs = message; - finished = FALSE; - - while (finished == FALSE && *subs != '\0') - { - if (conn->func != NULL) - (*conn->func) (subs, conn->data); - - subs += strlen (subs) + 1; - if (subs - message >= offset) - finished = TRUE; - } - - g_free (message); - - return TRUE; -} - -static char * -find_file_with_pattern (const char *dir, const char *pattern) -{ - GDir *filedir; - char *found_filename; - const char *filename; - GPatternSpec *pat; - - filedir = g_dir_open (dir, 0, NULL); - if (filedir == NULL) - return NULL; - - pat = g_pattern_spec_new (pattern); - if (pat == NULL) - { - g_dir_close (filedir); - return NULL; - } - - found_filename = NULL; - - while ((filename = g_dir_read_name (filedir))) - { - if (g_pattern_match_string (pat, filename)) - { - char *tmp = g_build_filename (dir, filename, NULL); - if (is_owned_by_user_and_socket (tmp)) - found_filename = g_strdup (filename); - g_free (tmp); - } - - if (found_filename != NULL) - break; - } - - g_pattern_spec_free (pat); - g_dir_close (filedir); - - return found_filename; -} - -static char * -socket_filename (const char *prefix) -{ - char *pattern, *newfile, *path, *filename; - const char *tmpdir; - - pattern = g_strdup_printf ("%s.%s.*", prefix, g_get_user_name ()); - tmpdir = g_get_tmp_dir (); - filename = find_file_with_pattern (tmpdir, pattern); - if (filename == NULL) - { - newfile = g_strdup_printf ("%s.%s.%u", prefix, - g_get_user_name (), g_random_int ()); - path = g_build_filename (tmpdir, newfile, NULL); - g_free (newfile); - } else { - path = g_build_filename (tmpdir, filename, NULL); - g_free (filename); - } - - g_free (pattern); - return path; -} - -static gboolean -try_server (BaconMessageConnection *conn) -{ - struct sockaddr_un uaddr; - - uaddr.sun_family = AF_UNIX; - strncpy (uaddr.sun_path, conn->path, - MIN (strlen(conn->path)+1, UNIX_PATH_MAX)); - conn->fd = socket (PF_UNIX, SOCK_STREAM, 0); - if (bind (conn->fd, (struct sockaddr *) &uaddr, sizeof (uaddr)) == -1) - { - conn->fd = -1; - return FALSE; - } - listen (conn->fd, 5); - - if (!setup_connection (conn)) - return FALSE; - return TRUE; -} - -static gboolean -try_client (BaconMessageConnection *conn) -{ - struct sockaddr_un uaddr; - - uaddr.sun_family = AF_UNIX; - strncpy (uaddr.sun_path, conn->path, - MIN(strlen(conn->path)+1, UNIX_PATH_MAX)); - conn->fd = socket (PF_UNIX, SOCK_STREAM, 0); - if (connect (conn->fd, (struct sockaddr *) &uaddr, - sizeof (uaddr)) == -1) - { - conn->fd = -1; - return FALSE; - } - - return setup_connection (conn); -} - -BaconMessageConnection * -bacon_message_connection_new (const char *prefix) -{ - BaconMessageConnection *conn; - - g_return_val_if_fail (prefix != NULL, NULL); - - conn = g_new0 (BaconMessageConnection, 1); - conn->path = socket_filename (prefix); - - if (test_is_socket (conn->path) == FALSE) - { - if (!try_server (conn)) - { - bacon_message_connection_free (conn); - return NULL; - } - - conn->is_server = TRUE; - return conn; - } - - if (try_client (conn) == FALSE) - { - unlink (conn->path); - try_server (conn); - if (conn->fd == -1) - { - bacon_message_connection_free (conn); - return NULL; - } - - conn->is_server = TRUE; - return conn; - } - - conn->is_server = FALSE; - return conn; -} - -void -bacon_message_connection_free (BaconMessageConnection *conn) -{ - GSList *child_conn; - - g_return_if_fail (conn != NULL); - /* Only servers can accept other connections */ - g_return_if_fail (conn->is_server != FALSE || - conn->accepted_connections == NULL); - - child_conn = conn->accepted_connections; - while (child_conn != NULL) { - bacon_message_connection_free (child_conn->data); - child_conn = g_slist_next (child_conn); - } - g_slist_free (conn->accepted_connections); - - if (conn->conn_id) { - g_source_remove (conn->conn_id); - conn->conn_id = 0; - } - if (conn->chan) { - g_io_channel_shutdown (conn->chan, FALSE, NULL); - g_io_channel_unref (conn->chan); - } - - if (conn->is_server != FALSE) { - unlink (conn->path); - } - if (conn->fd != -1) { - close (conn->fd); - } - - g_free (conn->path); - g_free (conn); -} - -void -bacon_message_connection_set_callback (BaconMessageConnection *conn, - BaconMessageReceivedFunc func, - gpointer user_data) -{ - g_return_if_fail (conn != NULL); - - conn->func = func; - conn->data = user_data; -} - -void -bacon_message_connection_send (BaconMessageConnection *conn, - const char *message) -{ - g_return_if_fail (conn != NULL); - g_return_if_fail (message != NULL); - - g_io_channel_write_chars (conn->chan, message, strlen (message), - NULL, NULL); - g_io_channel_write_chars (conn->chan, "\n", 1, NULL, NULL); - g_io_channel_flush (conn->chan, NULL); -} - -gboolean -bacon_message_connection_get_is_server (BaconMessageConnection *conn) -{ - g_return_val_if_fail (conn != NULL, FALSE); - - return conn->is_server; -} - diff --git a/xed/bacon-message-connection.h b/xed/bacon-message-connection.h deleted file mode 100644 index adefa62..0000000 --- a/xed/bacon-message-connection.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2003 Bastien Nocera - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef BACON_MESSAGE_CONNECTION_H -#define BACON_MESSAGE_CONNECTION_H - -#include - -G_BEGIN_DECLS - -typedef void (*BaconMessageReceivedFunc) (const char *message, - gpointer user_data); - -typedef struct BaconMessageConnection BaconMessageConnection; - -BaconMessageConnection *bacon_message_connection_new (const char *prefix); -void bacon_message_connection_free (BaconMessageConnection *conn); -void bacon_message_connection_set_callback (BaconMessageConnection *conn, - BaconMessageReceivedFunc func, - gpointer user_data); -void bacon_message_connection_send (BaconMessageConnection *conn, - const char *message); -gboolean bacon_message_connection_get_is_server (BaconMessageConnection *conn); - -G_END_DECLS - -#endif /* BACON_MESSAGE_CONNECTION_H */ diff --git a/xed/dialogs/Makefile.am b/xed/dialogs/Makefile.am deleted file mode 100755 index 152e6ad..0000000 --- a/xed/dialogs/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -uidir = $(datadir)/xed/ui/ - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/xed \ - -I$(top_builddir)/xed \ - $(XED_CFLAGS) \ - $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED_CFLAGS) - -noinst_LTLIBRARIES = libdialogs.la - -libdialogs_la_SOURCES = \ - xed-preferences-dialog.h \ - xed-preferences-dialog.c \ - xed-close-confirmation-dialog.c \ - xed-close-confirmation-dialog.h \ - xed-encodings-dialog.c \ - xed-encodings-dialog.h - -ui_DATA = \ - xed-encodings-dialog.ui \ - xed-preferences-dialog.ui - -EXTRA_DIST = $(ui_DATA) - --include $(top_srcdir)/git.mk diff --git a/xed/dialogs/xed-close-confirmation-dialog.c b/xed/dialogs/xed-close-confirmation-dialog.c deleted file mode 100755 index 7219f47..0000000 --- a/xed/dialogs/xed-close-confirmation-dialog.c +++ /dev/null @@ -1,756 +0,0 @@ -/* - * xed-close-confirmation-dialog.c - * This file is part of xed - * - * Copyright (C) 2004-2005 GNOME Foundation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2004-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "xed-close-confirmation-dialog.h" -#include -#include -#include - - -/* Properties */ -enum -{ - PROP_0, - PROP_UNSAVED_DOCUMENTS, - PROP_LOGOUT_MODE -}; - -/* Mode */ -enum -{ - SINGLE_DOC_MODE, - MULTIPLE_DOCS_MODE -}; - -/* Columns */ -enum -{ - SAVE_COLUMN, - NAME_COLUMN, - DOC_COLUMN, /* a handy pointer to the document */ - N_COLUMNS -}; - -struct _XedCloseConfirmationDialogPrivate -{ - gboolean logout_mode; - - GList *unsaved_documents; - - GList *selected_documents; - - GtkTreeModel *list_store; - -}; - -#define XED_CLOSE_CONFIRMATION_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - XED_TYPE_CLOSE_CONFIRMATION_DIALOG, \ - XedCloseConfirmationDialogPrivate)) - -#define GET_MODE(priv) (((priv->unsaved_documents != NULL) && \ - (priv->unsaved_documents->next == NULL)) ? \ - SINGLE_DOC_MODE : MULTIPLE_DOCS_MODE) - -G_DEFINE_TYPE(XedCloseConfirmationDialog, xed_close_confirmation_dialog, GTK_TYPE_DIALOG) - -static void set_unsaved_document (XedCloseConfirmationDialog *dlg, - const GList *list); - -static GList *get_selected_docs (GtkTreeModel *store); - -/* Since we connect in the costructor we are sure this handler will be called - * before the user ones - */ -static void -response_cb (XedCloseConfirmationDialog *dlg, - gint response_id, - gpointer data) -{ - XedCloseConfirmationDialogPrivate *priv; - - g_return_if_fail (XED_IS_CLOSE_CONFIRMATION_DIALOG (dlg)); - - priv = dlg->priv; - - if (priv->selected_documents != NULL) - g_list_free (priv->selected_documents); - - if (response_id == GTK_RESPONSE_YES) - { - if (GET_MODE (priv) == SINGLE_DOC_MODE) - { - priv->selected_documents = - g_list_copy (priv->unsaved_documents); - } - else - { - g_return_if_fail (priv->list_store); - - priv->selected_documents = - get_selected_docs (priv->list_store); - } - } - else - priv->selected_documents = NULL; -} - -static void -set_logout_mode (XedCloseConfirmationDialog *dlg, - gboolean logout_mode) -{ - dlg->priv->logout_mode = logout_mode; - - if (logout_mode) - { - gtk_dialog_add_button (GTK_DIALOG (dlg), - _("Log Out _without Saving"), - GTK_RESPONSE_NO); - - xed_dialog_add_button (GTK_DIALOG (dlg), - _("_Cancel Logout"), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL); - } - else - { - gtk_dialog_add_button (GTK_DIALOG (dlg), - _("Close _without Saving"), - GTK_RESPONSE_NO); - - gtk_dialog_add_button (GTK_DIALOG (dlg), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - } - - - const gchar *stock_id = GTK_STOCK_SAVE; - - if (GET_MODE (dlg->priv) == SINGLE_DOC_MODE) - { - XedDocument *doc; - - doc = XED_DOCUMENT (dlg->priv->unsaved_documents->data); - - if (xed_document_get_readonly (doc) || - xed_document_is_untitled (doc)) - stock_id = GTK_STOCK_SAVE_AS; - } - - gtk_dialog_add_button (GTK_DIALOG (dlg), - stock_id, - GTK_RESPONSE_YES); - - gtk_dialog_set_default_response (GTK_DIALOG (dlg), - GTK_RESPONSE_YES); -} - -static void -xed_close_confirmation_dialog_init (XedCloseConfirmationDialog *dlg) -{ - AtkObject *atk_obj; - - dlg->priv = XED_CLOSE_CONFIRMATION_DIALOG_GET_PRIVATE (dlg); - - gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - 14); - gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE); - gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dlg), TRUE); - - gtk_window_set_title (GTK_WINDOW (dlg), ""); - - gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); - gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE); - - atk_obj = gtk_widget_get_accessible (GTK_WIDGET (dlg)); - atk_object_set_role (atk_obj, ATK_ROLE_ALERT); - atk_object_set_name (atk_obj, _("Question")); - - g_signal_connect (dlg, - "response", - G_CALLBACK (response_cb), - NULL); -} - -static void -xed_close_confirmation_dialog_finalize (GObject *object) -{ - XedCloseConfirmationDialogPrivate *priv; - - priv = XED_CLOSE_CONFIRMATION_DIALOG (object)->priv; - - if (priv->unsaved_documents != NULL) - g_list_free (priv->unsaved_documents); - - if (priv->selected_documents != NULL) - g_list_free (priv->selected_documents); - - /* Call the parent's destructor */ - G_OBJECT_CLASS (xed_close_confirmation_dialog_parent_class)->finalize (object); -} - -static void -xed_close_confirmation_dialog_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedCloseConfirmationDialog *dlg; - - dlg = XED_CLOSE_CONFIRMATION_DIALOG (object); - - switch (prop_id) - { - case PROP_UNSAVED_DOCUMENTS: - set_unsaved_document (dlg, g_value_get_pointer (value)); - break; - - case PROP_LOGOUT_MODE: - set_logout_mode (dlg, g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_close_confirmation_dialog_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - XedCloseConfirmationDialogPrivate *priv; - - priv = XED_CLOSE_CONFIRMATION_DIALOG (object)->priv; - - switch( prop_id ) - { - case PROP_UNSAVED_DOCUMENTS: - g_value_set_pointer (value, priv->unsaved_documents); - break; - - case PROP_LOGOUT_MODE: - g_value_set_boolean (value, priv->logout_mode); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_close_confirmation_dialog_class_init (XedCloseConfirmationDialogClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = xed_close_confirmation_dialog_set_property; - gobject_class->get_property = xed_close_confirmation_dialog_get_property; - gobject_class->finalize = xed_close_confirmation_dialog_finalize; - - g_type_class_add_private (klass, sizeof (XedCloseConfirmationDialogPrivate)); - - g_object_class_install_property (gobject_class, - PROP_UNSAVED_DOCUMENTS, - g_param_spec_pointer ("unsaved_documents", - "Unsaved Documents", - "List of Unsaved Documents", - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY))); - - g_object_class_install_property (gobject_class, - PROP_LOGOUT_MODE, - g_param_spec_boolean ("logout_mode", - "Logout Mode", - "Whether the dialog is in logout mode", - FALSE, - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY))); -} - -static GList * -get_selected_docs (GtkTreeModel *store) -{ - GList *list; - gboolean valid; - GtkTreeIter iter; - - list = NULL; - valid = gtk_tree_model_get_iter_first (store, &iter); - - while (valid) - { - gboolean to_save; - XedDocument *doc; - - gtk_tree_model_get (store, &iter, - SAVE_COLUMN, &to_save, - DOC_COLUMN, &doc, - -1); - if (to_save) - list = g_list_prepend (list, doc); - - valid = gtk_tree_model_iter_next (store, &iter); - } - - list = g_list_reverse (list); - - return list; -} - -GList * -xed_close_confirmation_dialog_get_selected_documents (XedCloseConfirmationDialog *dlg) -{ - g_return_val_if_fail (XED_IS_CLOSE_CONFIRMATION_DIALOG (dlg), NULL); - - return g_list_copy (dlg->priv->selected_documents); -} - -GtkWidget * -xed_close_confirmation_dialog_new (GtkWindow *parent, - GList *unsaved_documents, - gboolean logout_mode) -{ - GtkWidget *dlg; - g_return_val_if_fail (unsaved_documents != NULL, NULL); - - dlg = GTK_WIDGET (g_object_new (XED_TYPE_CLOSE_CONFIRMATION_DIALOG, - "unsaved_documents", unsaved_documents, - "logout_mode", logout_mode, - NULL)); - g_return_val_if_fail (dlg != NULL, NULL); - - if (parent != NULL) - { - gtk_window_group_add_window (xed_window_get_group (XED_WINDOW (parent)), - GTK_WINDOW (dlg)); - - gtk_window_set_transient_for (GTK_WINDOW (dlg), parent); - } - - return dlg; -} - -GtkWidget * -xed_close_confirmation_dialog_new_single (GtkWindow *parent, - XedDocument *doc, - gboolean logout_mode) -{ - GtkWidget *dlg; - GList *unsaved_documents; - g_return_val_if_fail (doc != NULL, NULL); - - unsaved_documents = g_list_prepend (NULL, doc); - - dlg = xed_close_confirmation_dialog_new (parent, - unsaved_documents, - logout_mode); - - g_list_free (unsaved_documents); - - return dlg; -} - -static gchar * -get_text_secondary_label (XedDocument *doc) -{ - glong seconds; - gchar *secondary_msg; - - seconds = MAX (1, _xed_document_get_seconds_since_last_save_or_load (doc)); - - if (seconds < 55) - { - secondary_msg = g_strdup_printf ( - ngettext ("If you don't save, changes from the last %ld second " - "will be permanently lost.", - "If you don't save, changes from the last %ld seconds " - "will be permanently lost.", - seconds), - seconds); - } - else if (seconds < 75) /* 55 <= seconds < 75 */ - { - secondary_msg = g_strdup (_("If you don't save, changes from the last minute " - "will be permanently lost.")); - } - else if (seconds < 110) /* 75 <= seconds < 110 */ - { - secondary_msg = g_strdup_printf ( - ngettext ("If you don't save, changes from the last minute and %ld " - "second will be permanently lost.", - "If you don't save, changes from the last minute and %ld " - "seconds will be permanently lost.", - seconds - 60 ), - seconds - 60); - } - else if (seconds < 3600) - { - secondary_msg = g_strdup_printf ( - ngettext ("If you don't save, changes from the last %ld minute " - "will be permanently lost.", - "If you don't save, changes from the last %ld minutes " - "will be permanently lost.", - seconds / 60), - seconds / 60); - } - else if (seconds < 7200) - { - gint minutes; - seconds -= 3600; - - minutes = seconds / 60; - if (minutes < 5) - { - secondary_msg = g_strdup (_("If you don't save, changes from the last hour " - "will be permanently lost.")); - } - else - { - secondary_msg = g_strdup_printf ( - ngettext ("If you don't save, changes from the last hour and %d " - "minute will be permanently lost.", - "If you don't save, changes from the last hour and %d " - "minutes will be permanently lost.", - minutes), - minutes); - } - } - else - { - gint hours; - - hours = seconds / 3600; - - secondary_msg = g_strdup_printf ( - ngettext ("If you don't save, changes from the last %d hour " - "will be permanently lost.", - "If you don't save, changes from the last %d hours " - "will be permanently lost.", - hours), - hours); - } - - return secondary_msg; -} - -static void -build_single_doc_dialog (XedCloseConfirmationDialog *dlg) -{ - GtkWidget *hbox; - GtkWidget *vbox; - GtkWidget *primary_label; - GtkWidget *secondary_label; - GtkWidget *image; - XedDocument *doc; - gchar *doc_name; - gchar *str; - gchar *markup_str; - - g_return_if_fail (dlg->priv->unsaved_documents->data != NULL); - doc = XED_DOCUMENT (dlg->priv->unsaved_documents->data); - - /* Image */ - image = gtk_image_new_from_icon_name ("dialog-warning", - GTK_ICON_SIZE_DIALOG); - gtk_widget_set_halign (image, GTK_ALIGN_START); - gtk_widget_set_valign (image, GTK_ALIGN_END); - - /* Primary label */ - primary_label = gtk_label_new (NULL); - gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); - gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5); - gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); - gtk_widget_set_can_focus (GTK_WIDGET (primary_label), FALSE); - - doc_name = xed_document_get_short_name_for_display (doc); - - str = g_markup_printf_escaped (_("Save changes to document \"%s\" before closing?"), doc_name); - - g_free (doc_name); - - markup_str = g_strconcat ("", str, "", NULL); - g_free (str); - - gtk_label_set_markup (GTK_LABEL (primary_label), markup_str); - g_free (markup_str); - - /* Secondary label */ - str = get_text_secondary_label (doc); - secondary_label = gtk_label_new (str); - g_free (str); - gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5); - gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); - gtk_widget_set_can_focus (GTK_WIDGET (secondary_label), FALSE); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); - - gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); - - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (vbox), primary_label, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (vbox), secondary_label, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - hbox, - FALSE, - FALSE, - 0); - - gtk_widget_show_all (hbox); -} - -static void -populate_model (GtkTreeModel *store, GList *docs) -{ - GtkTreeIter iter; - - while (docs != NULL) - { - XedDocument *doc; - gchar *name; - - doc = XED_DOCUMENT (docs->data); - - name = xed_document_get_short_name_for_display (doc); - - gtk_list_store_append (GTK_LIST_STORE (store), &iter); - gtk_list_store_set (GTK_LIST_STORE (store), &iter, - SAVE_COLUMN, TRUE, - NAME_COLUMN, name, - DOC_COLUMN, doc, - -1); - - g_free (name); - - docs = g_list_next (docs); - } -} - -static void -save_toggled (GtkCellRendererToggle *renderer, gchar *path_str, GtkTreeModel *store) -{ - GtkTreePath *path = gtk_tree_path_new_from_string (path_str); - GtkTreeIter iter; - gboolean active; - - gtk_tree_model_get_iter (store, &iter, path); - gtk_tree_model_get (store, &iter, SAVE_COLUMN, &active, -1); - - active ^= 1; - - gtk_list_store_set (GTK_LIST_STORE (store), &iter, - SAVE_COLUMN, active, -1); - - gtk_tree_path_free (path); -} - -static GtkWidget * -create_treeview (XedCloseConfirmationDialogPrivate *priv) -{ - GtkListStore *store; - GtkWidget *treeview; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - - treeview = gtk_tree_view_new (); - gtk_widget_set_size_request (treeview, 260, 120); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); - gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE); - - /* Create and populate the model */ - store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER); - populate_model (GTK_TREE_MODEL (store), priv->unsaved_documents); - - /* Set model to the treeview */ - gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); - g_object_unref (store); - - priv->list_store = GTK_TREE_MODEL (store); - - /* Add columns */ - - renderer = gtk_cell_renderer_toggle_new (); - g_signal_connect (renderer, "toggled", - G_CALLBACK (save_toggled), store); - - column = gtk_tree_view_column_new_with_attributes ("Save?", - renderer, - "active", - SAVE_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Name", - renderer, - "text", - NAME_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - - return treeview; -} - -static void -build_multiple_docs_dialog (XedCloseConfirmationDialog *dlg) -{ - XedCloseConfirmationDialogPrivate *priv; - GtkWidget *hbox; - GtkWidget *image; - GtkWidget *vbox; - GtkWidget *primary_label; - GtkWidget *vbox2; - GtkWidget *select_label; - GtkWidget *scrolledwindow; - GtkWidget *treeview; - GtkWidget *secondary_label; - gchar *str; - gchar *markup_str; - - priv = dlg->priv; - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - hbox, TRUE, TRUE, 0); - - /* Image */ - image = gtk_image_new_from_icon_name ("dialog-warning", - GTK_ICON_SIZE_DIALOG); - gtk_widget_set_halign (image, GTK_ALIGN_CENTER); - gtk_widget_set_valign (image, GTK_ALIGN_START); - gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); - gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - - /* Primary label */ - primary_label = gtk_label_new (NULL); - gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); - gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5); - gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); - - str = g_strdup_printf ( - ngettext ("There is %d document with unsaved changes. " - "Save changes before closing?", - "There are %d documents with unsaved changes. " - "Save changes before closing?", - g_list_length (priv->unsaved_documents)), - g_list_length (priv->unsaved_documents)); - - markup_str = g_strconcat ("", str, "", NULL); - g_free (str); - - gtk_label_set_markup (GTK_LABEL (primary_label), markup_str); - g_free (markup_str); - gtk_box_pack_start (GTK_BOX (vbox), primary_label, FALSE, FALSE, 0); - - vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); - gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0); - - select_label = gtk_label_new_with_mnemonic (_("S_elect the documents you want to save:")); - - gtk_box_pack_start (GTK_BOX (vbox2), select_label, FALSE, FALSE, 0); - gtk_label_set_line_wrap (GTK_LABEL (select_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (select_label), 0.0, 0.5); - - scrolledwindow = gtk_scrolled_window_new (NULL, NULL); - gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), - GTK_SHADOW_IN); - gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolledwindow), 60); - - treeview = create_treeview (priv); - gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview); - - /* Secondary label */ - secondary_label = gtk_label_new (_("If you don't save, " - "all your changes will be permanently lost.")); - - gtk_box_pack_start (GTK_BOX (vbox2), secondary_label, FALSE, FALSE, 0); - gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5); - gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); - - gtk_label_set_mnemonic_widget (GTK_LABEL (select_label), treeview); - - gtk_widget_show_all (hbox); -} - -static void -set_unsaved_document (XedCloseConfirmationDialog *dlg, - const GList *list) -{ - XedCloseConfirmationDialogPrivate *priv; - - g_return_if_fail (list != NULL); - - priv = dlg->priv; - g_return_if_fail (priv->unsaved_documents == NULL); - - priv->unsaved_documents = g_list_copy ((GList *)list); - - if (GET_MODE (priv) == SINGLE_DOC_MODE) - { - build_single_doc_dialog (dlg); - } - else - { - build_multiple_docs_dialog (dlg); - } -} - -const GList * -xed_close_confirmation_dialog_get_unsaved_documents (XedCloseConfirmationDialog *dlg) -{ - g_return_val_if_fail (XED_IS_CLOSE_CONFIRMATION_DIALOG (dlg), NULL); - - return dlg->priv->unsaved_documents; -} - diff --git a/xed/dialogs/xed-encodings-dialog.c b/xed/dialogs/xed-encodings-dialog.c deleted file mode 100755 index a92c11e..0000000 --- a/xed/dialogs/xed-encodings-dialog.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * xed-encodings-dialog.c - * This file is part of xed - * - * Copyright (C) 2002-2005 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include -#include -#include - -#include "xed-encodings-dialog.h" -#include "xed-encodings.h" -#include "xed-prefs-manager.h" -#include "xed-utils.h" -#include "xed-debug.h" -#include "xed-help.h" -#include "xed-dirs.h" - -#define XED_ENCODINGS_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_ENCODINGS_DIALOG, \ - XedEncodingsDialogPrivate)) - -struct _XedEncodingsDialogPrivate -{ - GtkListStore *available_liststore; - GtkListStore *displayed_liststore; - GtkWidget *available_treeview; - GtkWidget *displayed_treeview; - GtkWidget *add_button; - GtkWidget *remove_button; - - GSList *show_in_menu_list; -}; - -G_DEFINE_TYPE(XedEncodingsDialog, xed_encodings_dialog, GTK_TYPE_DIALOG) - -static void -xed_encodings_dialog_finalize (GObject *object) -{ - XedEncodingsDialogPrivate *priv = XED_ENCODINGS_DIALOG (object)->priv; - - g_slist_free (priv->show_in_menu_list); - - G_OBJECT_CLASS (xed_encodings_dialog_parent_class)->finalize (object); -} - -static void -xed_encodings_dialog_class_init (XedEncodingsDialogClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_encodings_dialog_finalize; - - g_type_class_add_private (object_class, sizeof (XedEncodingsDialogPrivate)); -} - -enum { - COLUMN_NAME, - COLUMN_CHARSET, - N_COLUMNS -}; - -static void -count_selected_items_func (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer data) -{ - int *count = data; - - *count += 1; -} - -static void -available_selection_changed_callback (GtkTreeSelection *selection, - XedEncodingsDialog *dialogs) -{ - int count; - - count = 0; - gtk_tree_selection_selected_foreach (selection, - count_selected_items_func, - &count); - - gtk_widget_set_sensitive (dialogs->priv->add_button, count > 0); -} - -static void -displayed_selection_changed_callback (GtkTreeSelection *selection, - XedEncodingsDialog *dialogs) -{ - int count; - - count = 0; - gtk_tree_selection_selected_foreach (selection, - count_selected_items_func, - &count); - - gtk_widget_set_sensitive (dialogs->priv->remove_button, count > 0); -} - -static void -get_selected_encodings_func (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer data) -{ - GSList **list = data; - gchar *charset; - const XedEncoding *enc; - - charset = NULL; - gtk_tree_model_get (model, iter, COLUMN_CHARSET, &charset, -1); - - enc = xed_encoding_get_from_charset (charset); - g_free (charset); - - *list = g_slist_prepend (*list, (gpointer)enc); -} - -static void -update_shown_in_menu_tree_model (GtkListStore *store, - GSList *list) -{ - GtkTreeIter iter; - - gtk_list_store_clear (store); - - while (list != NULL) - { - const XedEncoding *enc; - - enc = (const XedEncoding*) list->data; - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COLUMN_CHARSET, - xed_encoding_get_charset (enc), - COLUMN_NAME, - xed_encoding_get_name (enc), -1); - - list = g_slist_next (list); - } -} - -static void -add_button_clicked_callback (GtkWidget *button, - XedEncodingsDialog *dialog) -{ - GtkTreeSelection *selection; - GSList *encodings; - GSList *tmp; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->available_treeview)); - - encodings = NULL; - gtk_tree_selection_selected_foreach (selection, - get_selected_encodings_func, - &encodings); - - tmp = encodings; - while (tmp != NULL) - { - if (g_slist_find (dialog->priv->show_in_menu_list, tmp->data) == NULL) - dialog->priv->show_in_menu_list = g_slist_prepend (dialog->priv->show_in_menu_list, - tmp->data); - - tmp = g_slist_next (tmp); - } - - g_slist_free (encodings); - - update_shown_in_menu_tree_model (GTK_LIST_STORE (dialog->priv->displayed_liststore), - dialog->priv->show_in_menu_list); -} - -static void -remove_button_clicked_callback (GtkWidget *button, - XedEncodingsDialog *dialog) -{ - GtkTreeSelection *selection; - GSList *encodings; - GSList *tmp; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->displayed_treeview)); - - encodings = NULL; - gtk_tree_selection_selected_foreach (selection, - get_selected_encodings_func, - &encodings); - - tmp = encodings; - while (tmp != NULL) - { - dialog->priv->show_in_menu_list = g_slist_remove (dialog->priv->show_in_menu_list, - tmp->data); - - tmp = g_slist_next (tmp); - } - - g_slist_free (encodings); - - update_shown_in_menu_tree_model (GTK_LIST_STORE (dialog->priv->displayed_liststore), - dialog->priv->show_in_menu_list); -} - -static void -init_shown_in_menu_tree_model (XedEncodingsDialog *dialog) -{ - GtkTreeIter iter; - GSList *list, *tmp; - - /* add data to the list store */ - list = xed_prefs_manager_get_shown_in_menu_encodings (); - - tmp = list; - - while (tmp != NULL) - { - const XedEncoding *enc; - - enc = (const XedEncoding *) tmp->data; - - dialog->priv->show_in_menu_list = g_slist_prepend (dialog->priv->show_in_menu_list, - tmp->data); - - gtk_list_store_append (dialog->priv->displayed_liststore, - &iter); - gtk_list_store_set (dialog->priv->displayed_liststore, - &iter, - COLUMN_CHARSET, - xed_encoding_get_charset (enc), - COLUMN_NAME, - xed_encoding_get_name (enc), -1); - - tmp = g_slist_next (tmp); - } - - g_slist_free (list); -} - -static void -response_handler (GtkDialog *dialog, - gint response_id, - XedEncodingsDialog *dlg) -{ - if (response_id == GTK_RESPONSE_HELP) - { - xed_help_display (GTK_WINDOW (dialog), "xed", NULL); - g_signal_stop_emission_by_name (dialog, "response"); - return; - } - - if (response_id == GTK_RESPONSE_OK) - { - g_return_if_fail (xed_prefs_manager_shown_in_menu_encodings_can_set ()); - xed_prefs_manager_set_shown_in_menu_encodings (dlg->priv->show_in_menu_list); - } -} - -static void -xed_encodings_dialog_init (XedEncodingsDialog *dlg) -{ - GtkWidget *content; - GtkCellRenderer *cell_renderer; - GtkTreeModel *sort_model; - GtkTreeViewColumn *column; - GtkTreeIter parent_iter; - GtkTreeSelection *selection; - const XedEncoding *enc; - GtkWidget *error_widget; - int i; - gboolean ret; - gchar *file; - gchar *root_objects[] = { - "encodings-dialog-contents", - NULL - }; - - dlg->priv = XED_ENCODINGS_DIALOG_GET_PRIVATE (dlg); - - gtk_dialog_add_buttons (GTK_DIALOG (dlg), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, - GTK_RESPONSE_OK, - GTK_STOCK_HELP, - GTK_RESPONSE_HELP, - NULL); - - gtk_window_set_title (GTK_WINDOW (dlg), _("Character Encodings")); - gtk_window_set_default_size (GTK_WINDOW (dlg), 650, 400); - - /* HIG defaults */ - gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - 2); /* 2 * 5 + 2 = 12 */ - gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), - 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 6); - - gtk_dialog_set_default_response (GTK_DIALOG (dlg), - GTK_RESPONSE_OK); - - g_signal_connect (dlg, - "response", - G_CALLBACK (response_handler), - dlg); - - file = xed_dirs_get_ui_file ("xed-encodings-dialog.ui"); - ret = xed_utils_get_ui_objects (file, - root_objects, - &error_widget, - "encodings-dialog-contents", &content, - "add-button", &dlg->priv->add_button, - "remove-button", &dlg->priv->remove_button, - "available-treeview", &dlg->priv->available_treeview, - "displayed-treeview", &dlg->priv->displayed_treeview, - NULL); - g_free (file); - - if (!ret) - { - gtk_widget_show (error_widget); - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - error_widget, - TRUE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (error_widget), 5); - - return; - } - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - content, TRUE, TRUE, 0); - g_object_unref (content); - gtk_container_set_border_width (GTK_CONTAINER (content), 5); - - g_signal_connect (dlg->priv->add_button, - "clicked", - G_CALLBACK (add_button_clicked_callback), - dlg); - g_signal_connect (dlg->priv->remove_button, - "clicked", - G_CALLBACK (remove_button_clicked_callback), - dlg); - - /* Tree view of available encodings */ - dlg->priv->available_liststore = gtk_list_store_new (N_COLUMNS, - G_TYPE_STRING, - G_TYPE_STRING); - - cell_renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("_Description"), - cell_renderer, - "text", COLUMN_NAME, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->available_treeview), - column); - gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME); - - cell_renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("_Encoding"), - cell_renderer, - "text", - COLUMN_CHARSET, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->available_treeview), - column); - gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET); - - /* Add the data */ - i = 0; - while ((enc = xed_encoding_get_from_index (i)) != NULL) - { - gtk_list_store_append (dlg->priv->available_liststore, - &parent_iter); - gtk_list_store_set (dlg->priv->available_liststore, - &parent_iter, - COLUMN_CHARSET, - xed_encoding_get_charset (enc), - COLUMN_NAME, - xed_encoding_get_name (enc), -1); - - ++i; - } - - /* Sort model */ - sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->available_liststore)); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), - COLUMN_NAME, - GTK_SORT_ASCENDING); - - gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->available_treeview), - sort_model); - g_object_unref (G_OBJECT (dlg->priv->available_liststore)); - g_object_unref (G_OBJECT (sort_model)); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->available_treeview)); - gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), - GTK_SELECTION_MULTIPLE); - - available_selection_changed_callback (selection, dlg); - g_signal_connect (selection, - "changed", - G_CALLBACK (available_selection_changed_callback), - dlg); - - /* Tree view of selected encodings */ - dlg->priv->displayed_liststore = gtk_list_store_new (N_COLUMNS, - G_TYPE_STRING, - G_TYPE_STRING); - - cell_renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("_Description"), - cell_renderer, - "text", COLUMN_NAME, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->displayed_treeview), - column); - gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME); - - cell_renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("_Encoding"), - cell_renderer, - "text", - COLUMN_CHARSET, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->displayed_treeview), - column); - gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET); - - /* Add the data */ - init_shown_in_menu_tree_model (dlg); - - /* Sort model */ - sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->displayed_liststore)); - - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE - (sort_model), COLUMN_NAME, - GTK_SORT_ASCENDING); - - gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->displayed_treeview), - sort_model); - g_object_unref (G_OBJECT (sort_model)); - g_object_unref (G_OBJECT (dlg->priv->displayed_liststore)); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->displayed_treeview)); - gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), - GTK_SELECTION_MULTIPLE); - - displayed_selection_changed_callback (selection, dlg); - g_signal_connect (selection, - "changed", - G_CALLBACK (displayed_selection_changed_callback), - dlg); -} - -GtkWidget * -xed_encodings_dialog_new (void) -{ - GtkWidget *dlg; - - dlg = GTK_WIDGET (g_object_new (XED_TYPE_ENCODINGS_DIALOG, NULL)); - - return dlg; -} - diff --git a/xed/dialogs/xed-preferences-dialog.c b/xed/dialogs/xed-preferences-dialog.c deleted file mode 100755 index faf930c..0000000 --- a/xed/dialogs/xed-preferences-dialog.c +++ /dev/null @@ -1,1189 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-preferences-dialog.c - * This file is part of xed - * - * Copyright (C) 2001-2005 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2001-2003. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include -#include -#include - -#include - -#include "xed-preferences-dialog.h" -#include "xed-utils.h" -#include "xed-debug.h" -#include "xed-document.h" -#include "xed-style-scheme-manager.h" -#include "xed-plugin-manager.h" -#include "xed-help.h" -#include "xed-dirs.h" - -/* - * xed-preferences dialog is a singleton since we don't - * want two dialogs showing an inconsistent state of the - * preferences. - * When xed_show_preferences_dialog is called and there - * is already a prefs dialog dialog open, it is reparented - * and shown. - */ - -static GtkWidget *preferences_dialog = NULL; - - -enum -{ - ID_COLUMN = 0, - NAME_COLUMN, - DESC_COLUMN, - NUM_COLUMNS -}; - - -#define XED_PREFERENCES_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_PREFERENCES_DIALOG, \ - XedPreferencesDialogPrivate)) - -struct _XedPreferencesDialogPrivate -{ - GtkWidget *notebook; - - /* Font */ - GtkWidget *default_font_checkbutton; - GtkWidget *font_button; - GtkWidget *font_hbox; - - /* Style Scheme */ - GtkListStore *schemes_treeview_model; - GtkWidget *schemes_treeview; - GtkWidget *install_scheme_button; - GtkWidget *uninstall_scheme_button; - - GtkWidget *install_scheme_file_schooser; - - /* Tabs */ - GtkWidget *tabs_width_spinbutton; - GtkWidget *insert_spaces_checkbutton; - GtkWidget *tabs_width_hbox; - - /* Auto indentation */ - GtkWidget *auto_indent_checkbutton; - - /* Text Wrapping */ - GtkWidget *wrap_text_checkbutton; - GtkWidget *split_checkbutton; - - /* File Saving */ - GtkWidget *backup_copy_checkbutton; - GtkWidget *auto_save_checkbutton; - GtkWidget *auto_save_spinbutton; - GtkWidget *autosave_hbox; - - /* Line numbers */ - GtkWidget *display_line_numbers_checkbutton; - - /* Highlight current line */ - GtkWidget *highlight_current_line_checkbutton; - - /* Highlight matching bracket */ - GtkWidget *bracket_matching_checkbutton; - - /* Right margin */ - GtkWidget *right_margin_checkbutton; - GtkWidget *right_margin_position_spinbutton; - GtkWidget *right_margin_position_hbox; - - /* Plugins manager */ - GtkWidget *plugin_manager_place_holder; - - /* Style Scheme editor dialog */ - GtkWidget *style_scheme_dialog; -}; - - -G_DEFINE_TYPE(XedPreferencesDialog, xed_preferences_dialog, GTK_TYPE_DIALOG) - - -static void -xed_preferences_dialog_class_init (XedPreferencesDialogClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (XedPreferencesDialogPrivate)); -} - -static void -dialog_response_handler (GtkDialog *dlg, - gint res_id) -{ - xed_debug (DEBUG_PREFS); - - switch (res_id) - { - case GTK_RESPONSE_HELP: - xed_help_display (GTK_WINDOW (dlg), - NULL, - "xed-prefs"); - - g_signal_stop_emission_by_name (dlg, "response"); - - break; - - default: - gtk_widget_destroy (GTK_WIDGET(dlg)); - } -} - -static void -tabs_width_spinbutton_value_changed (GtkSpinButton *spin_button, - XedPreferencesDialog *dlg) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (spin_button == GTK_SPIN_BUTTON (dlg->priv->tabs_width_spinbutton)); - - xed_prefs_manager_set_tabs_size (gtk_spin_button_get_value_as_int (spin_button)); -} - -static void -insert_spaces_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->insert_spaces_checkbutton)); - - xed_prefs_manager_set_insert_spaces (gtk_toggle_button_get_active (button)); -} - -static void -auto_indent_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->auto_indent_checkbutton)); - - xed_prefs_manager_set_auto_indent (gtk_toggle_button_get_active (button)); -} - -static void -auto_save_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->auto_save_checkbutton)); - - if (gtk_toggle_button_get_active (button)) - { - gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton, - xed_prefs_manager_auto_save_interval_can_set()); - - xed_prefs_manager_set_auto_save (TRUE); - } - else - { - gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton, FALSE); - xed_prefs_manager_set_auto_save (FALSE); - } -} - -static void -backup_copy_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->backup_copy_checkbutton)); - - xed_prefs_manager_set_create_backup_copy (gtk_toggle_button_get_active (button)); -} - -static void -auto_save_spinbutton_value_changed (GtkSpinButton *spin_button, - XedPreferencesDialog *dlg) -{ - g_return_if_fail (spin_button == GTK_SPIN_BUTTON (dlg->priv->auto_save_spinbutton)); - - xed_prefs_manager_set_auto_save_interval ( - MAX (1, gtk_spin_button_get_value_as_int (spin_button))); -} - -static void -setup_editor_page (XedPreferencesDialog *dlg) -{ - gboolean auto_save; - gint auto_save_interval; - - xed_debug (DEBUG_PREFS); - - /* Set initial state */ - gtk_spin_button_set_value (GTK_SPIN_BUTTON (dlg->priv->tabs_width_spinbutton), - (guint) xed_prefs_manager_get_tabs_size ()); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->insert_spaces_checkbutton), - xed_prefs_manager_get_insert_spaces ()); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->auto_indent_checkbutton), - xed_prefs_manager_get_auto_indent ()); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->backup_copy_checkbutton), - xed_prefs_manager_get_create_backup_copy ()); - - auto_save = xed_prefs_manager_get_auto_save (); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->auto_save_checkbutton), - auto_save); - - auto_save_interval = xed_prefs_manager_get_auto_save_interval (); - if (auto_save_interval <= 0) - auto_save_interval = GPM_DEFAULT_AUTO_SAVE_INTERVAL; - - gtk_spin_button_set_value (GTK_SPIN_BUTTON (dlg->priv->auto_save_spinbutton), - auto_save_interval); - - /* Set widget sensitivity */ - gtk_widget_set_sensitive (dlg->priv->tabs_width_hbox, - xed_prefs_manager_tabs_size_can_set ()); - gtk_widget_set_sensitive (dlg->priv->insert_spaces_checkbutton, - xed_prefs_manager_insert_spaces_can_set ()); - gtk_widget_set_sensitive (dlg->priv->auto_indent_checkbutton, - xed_prefs_manager_auto_indent_can_set ()); - gtk_widget_set_sensitive (dlg->priv->backup_copy_checkbutton, - xed_prefs_manager_create_backup_copy_can_set ()); - gtk_widget_set_sensitive (dlg->priv->autosave_hbox, - xed_prefs_manager_auto_save_can_set ()); - gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton, - auto_save && - xed_prefs_manager_auto_save_interval_can_set ()); - - /* Connect signal */ - g_signal_connect (dlg->priv->tabs_width_spinbutton, - "value_changed", - G_CALLBACK (tabs_width_spinbutton_value_changed), - dlg); - g_signal_connect (dlg->priv->insert_spaces_checkbutton, - "toggled", - G_CALLBACK (insert_spaces_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->auto_indent_checkbutton, - "toggled", - G_CALLBACK (auto_indent_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->auto_save_checkbutton, - "toggled", - G_CALLBACK (auto_save_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->backup_copy_checkbutton, - "toggled", - G_CALLBACK (backup_copy_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->auto_save_spinbutton, - "value_changed", - G_CALLBACK (auto_save_spinbutton_value_changed), - dlg); -} - -static void -display_line_numbers_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - g_return_if_fail (button == - GTK_TOGGLE_BUTTON (dlg->priv->display_line_numbers_checkbutton)); - - xed_prefs_manager_set_display_line_numbers (gtk_toggle_button_get_active (button)); -} - -static void -highlight_current_line_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - g_return_if_fail (button == - GTK_TOGGLE_BUTTON (dlg->priv->highlight_current_line_checkbutton)); - - xed_prefs_manager_set_highlight_current_line (gtk_toggle_button_get_active (button)); -} - -static void -bracket_matching_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - g_return_if_fail (button == - GTK_TOGGLE_BUTTON (dlg->priv->bracket_matching_checkbutton)); - - xed_prefs_manager_set_bracket_matching ( - gtk_toggle_button_get_active (button)); -} - -static gboolean split_button_state = TRUE; - -static void -wrap_mode_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton))) - { - xed_prefs_manager_set_wrap_mode (GTK_WRAP_NONE); - - gtk_widget_set_sensitive (dlg->priv->split_checkbutton, - FALSE); - gtk_toggle_button_set_inconsistent ( - GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE); - } - else - { - gtk_widget_set_sensitive (dlg->priv->split_checkbutton, - TRUE); - - gtk_toggle_button_set_inconsistent ( - GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), FALSE); - - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton))) - { - split_button_state = TRUE; - - xed_prefs_manager_set_wrap_mode (GTK_WRAP_WORD); - } - else - { - split_button_state = FALSE; - - xed_prefs_manager_set_wrap_mode (GTK_WRAP_CHAR); - } - } -} - -static void -right_margin_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - gboolean active; - - g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->right_margin_checkbutton)); - - active = gtk_toggle_button_get_active (button); - - xed_prefs_manager_set_display_right_margin (active); - - gtk_widget_set_sensitive (dlg->priv->right_margin_position_hbox, - active && - xed_prefs_manager_right_margin_position_can_set ()); -} - -static void -right_margin_position_spinbutton_value_changed (GtkSpinButton *spin_button, - XedPreferencesDialog *dlg) -{ - gint value; - - g_return_if_fail (spin_button == GTK_SPIN_BUTTON (dlg->priv->right_margin_position_spinbutton)); - - value = CLAMP (gtk_spin_button_get_value_as_int (spin_button), 1, 160); - - xed_prefs_manager_set_right_margin_position (value); -} - -static void -setup_view_page (XedPreferencesDialog *dlg) -{ - GtkWrapMode wrap_mode; - gboolean display_right_margin; - gboolean wrap_mode_can_set; - - xed_debug (DEBUG_PREFS); - - /* Set initial state */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->display_line_numbers_checkbutton), - xed_prefs_manager_get_display_line_numbers ()); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->highlight_current_line_checkbutton), - xed_prefs_manager_get_highlight_current_line ()); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->bracket_matching_checkbutton), - xed_prefs_manager_get_bracket_matching ()); - - wrap_mode = xed_prefs_manager_get_wrap_mode (); - switch (wrap_mode ) - { - case GTK_WRAP_WORD: - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), TRUE); - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE); - break; - case GTK_WRAP_CHAR: - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), TRUE); - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), FALSE); - break; - default: - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), FALSE); - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), split_button_state); - gtk_toggle_button_set_inconsistent ( - GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE); - - } - - display_right_margin = xed_prefs_manager_get_display_right_margin (); - - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (dlg->priv->right_margin_checkbutton), - display_right_margin); - - gtk_spin_button_set_value ( - GTK_SPIN_BUTTON (dlg->priv->right_margin_position_spinbutton), - (guint)CLAMP (xed_prefs_manager_get_right_margin_position (), 1, 160)); - - /* Set widgets sensitivity */ - gtk_widget_set_sensitive (dlg->priv->display_line_numbers_checkbutton, - xed_prefs_manager_display_line_numbers_can_set ()); - gtk_widget_set_sensitive (dlg->priv->highlight_current_line_checkbutton, - xed_prefs_manager_highlight_current_line_can_set ()); - gtk_widget_set_sensitive (dlg->priv->bracket_matching_checkbutton, - xed_prefs_manager_bracket_matching_can_set ()); - wrap_mode_can_set = xed_prefs_manager_wrap_mode_can_set (); - gtk_widget_set_sensitive (dlg->priv->wrap_text_checkbutton, - wrap_mode_can_set); - gtk_widget_set_sensitive (dlg->priv->split_checkbutton, - wrap_mode_can_set && - (wrap_mode != GTK_WRAP_NONE)); - gtk_widget_set_sensitive (dlg->priv->right_margin_checkbutton, - xed_prefs_manager_display_right_margin_can_set ()); - gtk_widget_set_sensitive (dlg->priv->right_margin_position_hbox, - display_right_margin && - xed_prefs_manager_right_margin_position_can_set ()); - - /* Connect signals */ - g_signal_connect (dlg->priv->display_line_numbers_checkbutton, - "toggled", - G_CALLBACK (display_line_numbers_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->highlight_current_line_checkbutton, - "toggled", - G_CALLBACK (highlight_current_line_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->bracket_matching_checkbutton, - "toggled", - G_CALLBACK (bracket_matching_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->wrap_text_checkbutton, - "toggled", - G_CALLBACK (wrap_mode_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->split_checkbutton, - "toggled", - G_CALLBACK (wrap_mode_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->right_margin_checkbutton, - "toggled", - G_CALLBACK (right_margin_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->right_margin_position_spinbutton, - "value_changed", - G_CALLBACK (right_margin_position_spinbutton_value_changed), - dlg); -} - -static void -default_font_font_checkbutton_toggled (GtkToggleButton *button, - XedPreferencesDialog *dlg) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->default_font_checkbutton)); - - if (gtk_toggle_button_get_active (button)) - { - gtk_widget_set_sensitive (dlg->priv->font_hbox, FALSE); - xed_prefs_manager_set_use_default_font (TRUE); - } - else - { - gtk_widget_set_sensitive (dlg->priv->font_hbox, - xed_prefs_manager_editor_font_can_set ()); - xed_prefs_manager_set_use_default_font (FALSE); - } -} - -static void -editor_font_button_font_set (GtkFontButton *font_button, - XedPreferencesDialog *dlg) -{ - const gchar *font_name; - - xed_debug (DEBUG_PREFS); - - g_return_if_fail (font_button == GTK_FONT_BUTTON (dlg->priv->font_button)); - - /* FIXME: Can this fail? Gtk docs are a bit terse... 21-02-2004 pbor */ - font_name = gtk_font_button_get_font_name (font_button); - if (!font_name) - { - g_warning ("Could not get font name"); - return; - } - - xed_prefs_manager_set_editor_font (font_name); -} - -static void -setup_font_colors_page_font_section (XedPreferencesDialog *dlg) -{ - gboolean use_default_font; - gchar *editor_font = NULL; - gchar *label; - - xed_debug (DEBUG_PREFS); - - gtk_widget_set_tooltip_text (dlg->priv->font_button, - _("Click on this button to select the font to be used by the editor")); - - xed_utils_set_atk_relation (dlg->priv->font_button, - dlg->priv->default_font_checkbutton, - ATK_RELATION_CONTROLLED_BY); - xed_utils_set_atk_relation (dlg->priv->default_font_checkbutton, - dlg->priv->font_button, - ATK_RELATION_CONTROLLER_FOR); - - editor_font = xed_prefs_manager_get_system_font (); - label = g_strdup_printf(_("_Use the system fixed width font (%s)"), - editor_font); - gtk_button_set_label (GTK_BUTTON (dlg->priv->default_font_checkbutton), - label); - g_free (editor_font); - g_free (label); - - /* read current config and setup initial state */ - use_default_font = xed_prefs_manager_get_use_default_font (); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->default_font_checkbutton), - use_default_font); - - editor_font = xed_prefs_manager_get_editor_font (); - if (editor_font != NULL) - { - gtk_font_button_set_font_name (GTK_FONT_BUTTON (dlg->priv->font_button), - editor_font); - g_free (editor_font); - } - - /* Connect signals */ - g_signal_connect (dlg->priv->default_font_checkbutton, - "toggled", - G_CALLBACK (default_font_font_checkbutton_toggled), - dlg); - g_signal_connect (dlg->priv->font_button, - "font_set", - G_CALLBACK (editor_font_button_font_set), - dlg); - - /* Set initial widget sensitivity */ - gtk_widget_set_sensitive (dlg->priv->default_font_checkbutton, - xed_prefs_manager_use_default_font_can_set ()); - - if (use_default_font) - gtk_widget_set_sensitive (dlg->priv->font_hbox, FALSE); - else - gtk_widget_set_sensitive (dlg->priv->font_hbox, - xed_prefs_manager_editor_font_can_set ()); -} - -static void -set_buttons_sensisitivity_according_to_scheme (XedPreferencesDialog *dlg, - const gchar *scheme_id) -{ - gboolean editable; - - editable = (scheme_id != NULL) && - _xed_style_scheme_manager_scheme_is_xed_user_scheme ( - xed_get_style_scheme_manager (), - scheme_id); - - gtk_widget_set_sensitive (dlg->priv->uninstall_scheme_button, - editable); -} - -static void -style_scheme_changed (GtkWidget *treeview, - XedPreferencesDialog *dlg) -{ - GtkTreePath *path; - GtkTreeIter iter; - gchar *id; - - gtk_tree_view_get_cursor (GTK_TREE_VIEW (dlg->priv->schemes_treeview), &path, NULL); - gtk_tree_model_get_iter (GTK_TREE_MODEL (dlg->priv->schemes_treeview_model), - &iter, path); - gtk_tree_path_free (path); - gtk_tree_model_get (GTK_TREE_MODEL (dlg->priv->schemes_treeview_model), - &iter, ID_COLUMN, &id, -1); - - xed_prefs_manager_set_source_style_scheme (id); - - set_buttons_sensisitivity_according_to_scheme (dlg, id); - - g_free (id); -} - -static const gchar * -ensure_color_scheme_id (const gchar *id) -{ - GtkSourceStyleScheme *scheme = NULL; - GtkSourceStyleSchemeManager *manager = xed_get_style_scheme_manager (); - - if (id == NULL) - { - gchar *pref_id; - - pref_id = xed_prefs_manager_get_source_style_scheme (); - scheme = gtk_source_style_scheme_manager_get_scheme (manager, - pref_id); - g_free (pref_id); - } - else - { - scheme = gtk_source_style_scheme_manager_get_scheme (manager, - id); - } - - if (scheme == NULL) - { - /* Fall-back to classic style scheme */ - scheme = gtk_source_style_scheme_manager_get_scheme (manager, - "classic"); - } - - if (scheme == NULL) - { - /* Cannot determine default style scheme -> broken GtkSourceView installation */ - return NULL; - } - - return gtk_source_style_scheme_get_id (scheme); -} - -/* If def_id is NULL, use the default scheme as returned by - * xed_style_scheme_manager_get_default_scheme. If this one returns NULL - * use the first available scheme as default */ -static const gchar * -populate_color_scheme_list (XedPreferencesDialog *dlg, const gchar *def_id) -{ - GSList *schemes; - GSList *l; - - gtk_list_store_clear (dlg->priv->schemes_treeview_model); - - def_id = ensure_color_scheme_id (def_id); - if (def_id == NULL) - { - g_warning ("Cannot build the list of available color schemes.\n" - "Please check your GtkSourceView installation."); - return NULL; - } - - schemes = xed_style_scheme_manager_list_schemes_sorted (xed_get_style_scheme_manager ()); - l = schemes; - while (l != NULL) - { - GtkSourceStyleScheme *scheme; - const gchar *id; - const gchar *name; - const gchar *description; - GtkTreeIter iter; - - scheme = GTK_SOURCE_STYLE_SCHEME (l->data); - - id = gtk_source_style_scheme_get_id (scheme); - name = gtk_source_style_scheme_get_name (scheme); - description = gtk_source_style_scheme_get_description (scheme); - - gtk_list_store_append (dlg->priv->schemes_treeview_model, &iter); - gtk_list_store_set (dlg->priv->schemes_treeview_model, - &iter, - ID_COLUMN, id, - NAME_COLUMN, name, - DESC_COLUMN, description, - -1); - - g_return_val_if_fail (def_id != NULL, NULL); - if (strcmp (id, def_id) == 0) - { - GtkTreeSelection *selection; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview)); - gtk_tree_selection_select_iter (selection, &iter); - } - - l = g_slist_next (l); - } - - g_slist_free (schemes); - - return def_id; -} - -static void -add_scheme_chooser_response_cb (GtkDialog *chooser, - gint res_id, - XedPreferencesDialog *dlg) -{ - gchar* filename; - const gchar *scheme_id; - - if (res_id != GTK_RESPONSE_ACCEPT) - { - gtk_widget_hide (GTK_WIDGET (chooser)); - return; - } - - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); - if (filename == NULL) - return; - - gtk_widget_hide (GTK_WIDGET (chooser)); - - scheme_id = _xed_style_scheme_manager_install_scheme ( - xed_get_style_scheme_manager (), - filename); - g_free (filename); - - if (scheme_id == NULL) - { - xed_warning (GTK_WINDOW (dlg), - _("The selected color scheme cannot be installed.")); - - return; - } - - xed_prefs_manager_set_source_style_scheme (scheme_id); - - scheme_id = populate_color_scheme_list (dlg, scheme_id); - - set_buttons_sensisitivity_according_to_scheme (dlg, scheme_id); -} - -static void -install_scheme_clicked (GtkButton *button, - XedPreferencesDialog *dlg) -{ - GtkWidget *chooser; - GtkFileFilter *filter; - - if (dlg->priv->install_scheme_file_schooser != NULL) { - gtk_window_present (GTK_WINDOW (dlg->priv->install_scheme_file_schooser)); - gtk_widget_grab_focus (dlg->priv->install_scheme_file_schooser); - return; - } - - chooser = gtk_file_chooser_dialog_new (_("Add Scheme"), - GTK_WINDOW (dlg), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - NULL); - - xed_dialog_add_button (GTK_DIALOG (chooser), - _("A_dd Scheme"), - GTK_STOCK_ADD, - GTK_RESPONSE_ACCEPT); - - gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE); - - /* Filters */ - filter = gtk_file_filter_new (); - gtk_file_filter_set_name (filter, _("Color Scheme Files")); - gtk_file_filter_add_pattern (filter, "*.xml"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter); - - gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter); - - filter = gtk_file_filter_new (); - gtk_file_filter_set_name (filter, _("All Files")); - gtk_file_filter_add_pattern (filter, "*"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter); - - gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT); - - g_signal_connect (chooser, - "response", - G_CALLBACK (add_scheme_chooser_response_cb), - dlg); - - dlg->priv->install_scheme_file_schooser = chooser; - - g_object_add_weak_pointer (G_OBJECT (chooser), - (gpointer) &dlg->priv->install_scheme_file_schooser); - - gtk_widget_show (chooser); -} - -static void -uninstall_scheme_clicked (GtkButton *button, - XedPreferencesDialog *dlg) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview)); - model = GTK_TREE_MODEL (dlg->priv->schemes_treeview_model); - - if (gtk_tree_selection_get_selected (selection, - &model, - &iter)) - { - gchar *id; - gchar *name; - - gtk_tree_model_get (model, &iter, - ID_COLUMN, &id, - NAME_COLUMN, &name, - -1); - - if (!_xed_style_scheme_manager_uninstall_scheme (xed_get_style_scheme_manager (), id)) - { - xed_warning (GTK_WINDOW (dlg), - _("Could not remove color scheme \"%s\"."), - name); - } - else - { - const gchar *real_new_id; - gchar *new_id = NULL; - GtkTreePath *path; - GtkTreeIter new_iter; - gboolean new_iter_set = FALSE; - - /* If the removed style scheme is the last of the list, - * set as new default style scheme the previous one, - * otherwise set the next one. - * To make this possible, we need to get the id of the - * new default style scheme before re-populating the list. - * Fall back to "classic" if it is not possible to get - * the id - */ - path = gtk_tree_model_get_path (model, &iter); - - /* Try to move to the next path */ - gtk_tree_path_next (path); - if (!gtk_tree_model_get_iter (model, &new_iter, path)) - { - /* It seems the removed style scheme was the - * last of the list. Try to move to the - * previous one */ - gtk_tree_path_free (path); - - path = gtk_tree_model_get_path (model, &iter); - - gtk_tree_path_prev (path); - if (gtk_tree_model_get_iter (model, &new_iter, path)) - new_iter_set = TRUE; - } - else - new_iter_set = TRUE; - - gtk_tree_path_free (path); - - if (new_iter_set) - gtk_tree_model_get (model, &new_iter, - ID_COLUMN, &new_id, - -1); - - real_new_id = populate_color_scheme_list (dlg, new_id); - g_free (new_id); - - set_buttons_sensisitivity_according_to_scheme (dlg, real_new_id); - - if (real_new_id != NULL) - xed_prefs_manager_set_source_style_scheme (real_new_id); - } - - g_free (id); - g_free (name); - } -} - -static void -scheme_description_cell_data_func (GtkTreeViewColumn *column, - GtkCellRenderer *renderer, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer data) -{ - gchar *name; - gchar *desc; - gchar *text; - - gtk_tree_model_get (model, iter, - NAME_COLUMN, &name, - DESC_COLUMN, &desc, - -1); - - if (desc != NULL) - { - text = g_markup_printf_escaped ("%s - %s", - name, - desc); - } - else - { - text = g_markup_printf_escaped ("%s", - name); - } - - g_free (name); - g_free (desc); - - g_object_set (G_OBJECT (renderer), - "markup", - text, - NULL); - - g_free (text); -} - -static void -setup_font_colors_page_style_scheme_section (XedPreferencesDialog *dlg) -{ - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GtkTreeSelection *selection; - const gchar *def_id; - - xed_debug (DEBUG_PREFS); - - /* Create GtkListStore for styles & setup treeview. */ - dlg->priv->schemes_treeview_model = gtk_list_store_new (NUM_COLUMNS, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (dlg->priv->schemes_treeview_model), - 0, - GTK_SORT_ASCENDING); - gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->schemes_treeview), - GTK_TREE_MODEL (dlg->priv->schemes_treeview_model)); - - column = gtk_tree_view_column_new (); - - renderer = gtk_cell_renderer_text_new (); - g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_set_cell_data_func (column, - renderer, - scheme_description_cell_data_func, - dlg, - NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->schemes_treeview), - column); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - - def_id = populate_color_scheme_list (dlg, NULL); - - /* Connect signals */ - g_signal_connect (dlg->priv->schemes_treeview, - "cursor-changed", - G_CALLBACK (style_scheme_changed), - dlg); - g_signal_connect (dlg->priv->install_scheme_button, - "clicked", - G_CALLBACK (install_scheme_clicked), - dlg); - g_signal_connect (dlg->priv->uninstall_scheme_button, - "clicked", - G_CALLBACK (uninstall_scheme_clicked), - dlg); - - /* Set initial widget sensitivity */ - set_buttons_sensisitivity_according_to_scheme (dlg, def_id); -} - -static void -setup_font_colors_page (XedPreferencesDialog *dlg) -{ - setup_font_colors_page_font_section (dlg); - setup_font_colors_page_style_scheme_section (dlg); -} - -static void -setup_plugins_page (XedPreferencesDialog *dlg) -{ - GtkWidget *page_content; - - xed_debug (DEBUG_PREFS); - - page_content = xed_plugin_manager_new (); - g_return_if_fail (page_content != NULL); - - gtk_box_pack_start (GTK_BOX (dlg->priv->plugin_manager_place_holder), - page_content, - TRUE, - TRUE, - 0); - - gtk_widget_show_all (page_content); -} - -static void -xed_preferences_dialog_init (XedPreferencesDialog *dlg) -{ - GtkWidget *error_widget; - gboolean ret; - gchar *file; - gchar *root_objects[] = { - "notebook", - "adjustment1", - "adjustment2", - "adjustment3", - "install_scheme_image", - NULL - }; - - xed_debug (DEBUG_PREFS); - - dlg->priv = XED_PREFERENCES_DIALOG_GET_PRIVATE (dlg); - - gtk_dialog_add_buttons (GTK_DIALOG (dlg), - GTK_STOCK_CLOSE, - GTK_RESPONSE_CLOSE, - GTK_STOCK_HELP, - GTK_RESPONSE_HELP, - NULL); - - gtk_window_set_title (GTK_WINDOW (dlg), _("Xed Preferences")); - gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE); - gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE); - - /* HIG defaults */ - gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), 2); /* 2 * 5 + 2 = 12 */ - gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 6); - - g_signal_connect (dlg, - "response", - G_CALLBACK (dialog_response_handler), - NULL); - - file = xed_dirs_get_ui_file ("xed-preferences-dialog.ui"); - ret = xed_utils_get_ui_objects (file, - root_objects, - &error_widget, - - "notebook", &dlg->priv->notebook, - - "display_line_numbers_checkbutton", &dlg->priv->display_line_numbers_checkbutton, - "highlight_current_line_checkbutton", &dlg->priv->highlight_current_line_checkbutton, - "bracket_matching_checkbutton", &dlg->priv->bracket_matching_checkbutton, - "wrap_text_checkbutton", &dlg->priv->wrap_text_checkbutton, - "split_checkbutton", &dlg->priv->split_checkbutton, - - "right_margin_checkbutton", &dlg->priv->right_margin_checkbutton, - "right_margin_position_spinbutton", &dlg->priv->right_margin_position_spinbutton, - "right_margin_position_hbox", &dlg->priv->right_margin_position_hbox, - - "tabs_width_spinbutton", &dlg->priv->tabs_width_spinbutton, - "tabs_width_hbox", &dlg->priv->tabs_width_hbox, - "insert_spaces_checkbutton", &dlg->priv->insert_spaces_checkbutton, - - "auto_indent_checkbutton", &dlg->priv->auto_indent_checkbutton, - - "autosave_hbox", &dlg->priv->autosave_hbox, - "backup_copy_checkbutton", &dlg->priv->backup_copy_checkbutton, - "auto_save_checkbutton", &dlg->priv->auto_save_checkbutton, - "auto_save_spinbutton", &dlg->priv->auto_save_spinbutton, - - "default_font_checkbutton", &dlg->priv->default_font_checkbutton, - "font_button", &dlg->priv->font_button, - "font_hbox", &dlg->priv->font_hbox, - - "schemes_treeview", &dlg->priv->schemes_treeview, - "install_scheme_button", &dlg->priv->install_scheme_button, - "uninstall_scheme_button", &dlg->priv->uninstall_scheme_button, - - "plugin_manager_place_holder", &dlg->priv->plugin_manager_place_holder, - - NULL); - g_free (file); - - if (!ret) - { - gtk_widget_show (error_widget); - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - error_widget, - TRUE, TRUE, 0); - - return; - } - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - dlg->priv->notebook, FALSE, FALSE, 0); - g_object_unref (dlg->priv->notebook); - gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->notebook), 5); - - setup_editor_page (dlg); - setup_view_page (dlg); - setup_font_colors_page (dlg); - setup_plugins_page (dlg); -} - -void -xed_show_preferences_dialog (XedWindow *parent) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (XED_IS_WINDOW (parent)); - - if (preferences_dialog == NULL) - { - preferences_dialog = GTK_WIDGET (g_object_new (XED_TYPE_PREFERENCES_DIALOG, NULL)); - g_signal_connect (preferences_dialog, - "destroy", - G_CALLBACK (gtk_widget_destroyed), - &preferences_dialog); - } - - if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (preferences_dialog))) - { - gtk_window_set_transient_for (GTK_WINDOW (preferences_dialog), - GTK_WINDOW (parent)); - } - - gtk_window_present (GTK_WINDOW (preferences_dialog)); -} diff --git a/xed/dialogs/xed-encodings-dialog.ui b/xed/resources/ui/xed-encodings-dialog.ui similarity index 100% rename from xed/dialogs/xed-encodings-dialog.ui rename to xed/resources/ui/xed-encodings-dialog.ui diff --git a/xed/dialogs/xed-preferences-dialog.ui b/xed/resources/ui/xed-preferences-dialog.ui similarity index 80% rename from xed/dialogs/xed-preferences-dialog.ui rename to xed/resources/ui/xed-preferences-dialog.ui index ac801a9..7194dd4 100755 --- a/xed/dialogs/xed-preferences-dialog.ui +++ b/xed/resources/ui/xed-preferences-dialog.ui @@ -1,1063 +1,47 @@ - + + - - + - 80 1 160 + 80 1 10 - 8 1 24 + 8 1 4 - 8 1 100 + 8 1 10 + False gtk-add + False Preferences False True dialog - + True + False vertical - - - True - True - 6 - - - True - 12 - vertical - 18 - - - True - vertical - 6 - - - True - 0 - Text Wrapping - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - vertical - 6 - - - Enable text _wrapping - True - True - False - True - True - - - False - False - 0 - - - - - Do not _split words over two lines - True - True - False - True - True - - - False - False - 1 - - - - - 1 - - - - - 1 - - - - - 0 - - - - - True - vertical - 6 - - - True - 0 - Line Numbers - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - 6 - - - _Display line numbers - True - True - False - True - True - - - False - False - 0 - - - - - 1 - - - - - 1 - - - - - False - False - 1 - - - - - True - vertical - 6 - - - True - 0 - Current Line - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - vertical - 6 - - - Highlight current _line - True - True - False - True - True - - - False - False - 0 - - - - - 1 - - - - - 1 - - - - - False - 2 - - - - - True - vertical - 6 - - - True - 0 - Right Margin - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - vertical - 6 - - - Display right _margin - True - True - False - True - True - - - False - False - 0 - - - - - True - 6 - - - True - 0 - _Right margin at column: - True - right_margin_position_spinbutton - - - False - False - 0 - - - - - True - True - adjustment1 - 1 - True - True - - - False - False - 1 - - - - - False - False - 1 - - - - - 1 - - - - - 1 - - - - - False - False - 3 - - - - - True - vertical - 6 - - - True - 0 - Bracket Matching - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - vertical - 6 - - - Highlight matching _bracket - True - True - False - True - True - - - False - False - 0 - - - - - 1 - - - - - 1 - - - - - 4 - - - - - - - True - View - - - False - - - - - True - 12 - vertical - 18 - - - True - vertical - 6 - - - True - 0 - Tab Stops - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - vertical - 6 - - - True - 6 - - - True - _Tab width: - True - center - tabs_width_spinbutton - - - False - False - 0 - - - - - True - True - adjustment2 - 1 - True - - - False - False - 1 - - - - - 0 - - - - - Insert _spaces instead of tabs - True - True - False - True - True - - - False - False - 1 - - - - - False - False - 1 - - - - - False - False - 1 - - - - - False - False - 0 - - - - - True - vertical - 6 - - - True - 0 - Automatic Indentation - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - _Enable automatic indentation - True - True - False - True - True - - - False - False - 1 - - - - - False - False - 1 - - - - - False - False - 1 - - - - - True - vertical - 6 - - - True - 0 - File Saving - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - vertical - 6 - - - Create a _backup copy of files before saving - True - True - False - True - True - - - False - False - 0 - - - - - True - 6 - - - _Autosave files every - True - True - False - True - True - - - False - False - 0 - - - - - True - True - adjustment3 - 1 - True - - - False - False - 1 - - - - - True - _minutes - True - center - auto_save_spinbutton - - - False - False - 2 - - - - - 1 - - - - - False - False - 1 - - - - - 1 - - - - - False - False - 2 - - - - - 1 - - - - - True - Editor - - - 1 - False - - - - - True - 12 - vertical - 18 - - - True - vertical - 6 - - - True - 0 - Font - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - vertical - 6 - - - _Use the system fixed width font (%s) - True - True - False - True - True - - - False - False - 0 - - - - - True - 12 - - - True - 0 - Editor _font: - True - center - font_button - - - False - False - 0 - - - - - True - True - False - Pick the editor font - True - - - 1 - - - - - False - False - 1 - - - - - 1 - - - - - 1 - - - - - False - False - 0 - - - - - True - vertical - 6 - - - True - 0 - Color Scheme - - - - - - False - False - 0 - - - - - True - - - True - - - - False - False - 0 - - - - - True - vertical - 6 - - - True - True - automatic - automatic - etched-in - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - True - - - - - 0 - - - - - True - 6 - end - - - _Add... - True - True - False - install_scheme_image - True - - - False - False - 0 - - - - - gtk-remove - True - True - False - True - - - False - False - 1 - - - - - False - 1 - - - - - 1 - - - - - 1 - - - - - 1 - - - - - 2 - - - - - True - Font & Colors - - - 2 - False - - - - - True - 12 - vertical - - - - - - 3 - - - - - True - Plugins - - - 3 - False - - - - - 1 - - - + True + False end @@ -1092,10 +76,1219 @@ False + False end 0 + + + True + True + 6 + + + True + False + 12 + 18 + + + True + False + 6 + + + True + False + Text Wrapping + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + Enable text _wrapping + True + True + False + True + 0.5 + True + + + False + False + 0 + + + + + Do not _split words over two lines + True + True + False + True + 0.5 + True + + + False + False + 1 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + True + True + 0 + + + + + True + False + 6 + + + True + False + Line Numbers + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + _Display line numbers + True + True + False + True + 0.5 + True + + + False + False + 0 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + False + False + 1 + + + + + True + False + 6 + + + True + False + Current Line + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + Highlight current _line + True + True + False + True + 0.5 + True + + + False + False + 0 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + False + True + 2 + + + + + True + False + 6 + + + True + False + Right Margin + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + Display right _margin + True + True + False + True + 0.5 + True + + + False + False + 0 + + + + + True + False + 6 + + + True + False + _Right margin at column: + True + right_margin_position_spinbutton + 0 + + + False + False + 0 + + + + + True + True + adjustment1 + 1 + True + True + + + False + False + 1 + + + + + False + False + 1 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + False + False + 3 + + + + + True + False + 6 + + + True + False + Bracket Matching + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + Highlight matching _bracket + True + True + False + True + 0.5 + True + + + False + False + 0 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + True + True + 4 + + + + + + + True + False + View + + + False + + + + + True + False + 12 + 18 + + + True + False + 6 + + + True + False + Tab Stops + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + True + False + 6 + + + True + False + _Tab width: + True + center + tabs_width_spinbutton + + + False + False + 0 + + + + + True + True + adjustment2 + 1 + True + + + False + False + 1 + + + + + True + True + 0 + + + + + Insert _spaces instead of tabs + True + True + False + True + 0.5 + True + + + False + False + 1 + + + + + False + False + 1 + + + + + False + False + 1 + + + + + False + False + 0 + + + + + True + False + 6 + + + True + False + Automatic Indentation + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + _Enable automatic indentation + True + True + False + True + 0.5 + True + + + False + False + 1 + + + + + False + False + 1 + + + + + False + False + 1 + + + + + True + False + 6 + + + True + False + File Saving + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + Create a _backup copy of files before saving + True + True + False + True + 0.5 + True + + + False + False + 0 + + + + + True + False + 6 + + + _Autosave files every + True + True + False + True + 0.5 + True + + + False + False + 0 + + + + + True + True + adjustment3 + 1 + True + + + False + False + 1 + + + + + True + False + _minutes + True + center + auto_save_spinbutton + + + False + False + 2 + + + + + True + True + 1 + + + + + False + False + 1 + + + + + True + True + 1 + + + + + False + False + 2 + + + + + True + False + vertical + 6 + + + True + False + Tab Scrolling + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + True + 0 + + + + + Allow mouse wheel scrolling to change tabs + True + True + False + 0 + True + + + False + True + 1 + + + + + False + False + 1 + + + + + True + True + 3 + + + + + 1 + + + + + True + False + Editor + + + 1 + False + + + + + True + False + 12 + 18 + + + True + False + 6 + + + True + False + Font + 0 + + + + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + _Use the system fixed width font (%s) + True + True + False + True + 0.5 + True + + + False + False + 0 + + + + + True + False + 12 + + + True + False + Editor _font: + True + center + font_button + 0 + + + False + False + 0 + + + + + True + True + False + Sans 12 + Pick the editor font + True + + + True + True + 1 + + + + + False + False + 1 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + False + False + 0 + + + + + True + False + 6 + + + True + False + Color Scheme + 0 + + + + + + False + False + 0 + + + + + Use dark theme variant (if available) + True + True + False + 12 + 0 + True + + + False + False + 1 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + True + False + 6 + + + True + True + etched-in + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + True + + + + + + + + True + True + 0 + + + + + True + False + 6 + end + + + _Add... + True + True + False + install_scheme_image + True + + + False + False + 0 + + + + + gtk-remove + True + True + False + True + + + False + False + 1 + + + + + False + True + 1 + + + + + True + True + 1 + + + + + True + True + 2 + + + + + True + True + 1 + + + + + 2 + + + + + True + False + Font & Colors + + + 2 + False + + + + + True + False + 12 + + + + + + 3 + + + + + True + False + Plugins + + + 3 + False + + + + + False + True + 1 + + diff --git a/xed/xed-print-preferences.ui b/xed/resources/ui/xed-print-preferences.ui similarity index 100% rename from xed/xed-print-preferences.ui rename to xed/resources/ui/xed-print-preferences.ui diff --git a/xed/xed-searchbar.ui b/xed/resources/ui/xed-searchbar.ui similarity index 91% rename from xed/xed-searchbar.ui rename to xed/resources/ui/xed-searchbar.ui index 948001b..0ecddef 100755 --- a/xed/xed-searchbar.ui +++ b/xed/resources/ui/xed-searchbar.ui @@ -112,6 +112,26 @@ True False + + + True + True + True + Regular expression + + + True + False + xapp-use-regex-symbolic + + + + + False + True + 0 + + True @@ -130,7 +150,7 @@ False False - 0 + 1 @@ -151,7 +171,7 @@ False False - 1 + 2 @@ -172,7 +192,7 @@ False True - 2 + 3 + + + True + False + horizontal + + + True + True + 25 + + + + + + + + + + diff --git a/xed/resources/xed.gresource.xml b/xed/resources/xed.gresource.xml new file mode 100644 index 0000000..f960a0d --- /dev/null +++ b/xed/resources/xed.gresource.xml @@ -0,0 +1,11 @@ + + + + ui/xed-ui.xml + ui/xed-encodings-dialog.ui + ui/xed-preferences-dialog.ui + ui/xed-print-preferences.ui + ui/xed-searchbar.ui + ui/xed-view-frame.ui + + \ No newline at end of file diff --git a/xed/smclient/Makefile.am b/xed/smclient/Makefile.am deleted file mode 100644 index d7dbbb5..0000000 --- a/xed/smclient/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -platform_defines = -DEGG_SM_CLIENT_BACKEND_XSMP -platform_libs = libeggdesktopfile.la -platform_ltlibraries = libeggdesktopfile.la -platform_sources = eggsmclient-xsmp.c - -AM_CPPFLAGS = \ - -DG_LOG_DOMAIN=\""EggSMClient"\" \ - $(XED_CFLAGS) \ - $(platform_defines) \ - $(EGG_SMCLIENT_CFLAGS) - -noinst_LTLIBRARIES = \ - libeggsmclient.la \ - $(platform_ltlibraries) - -libeggsmclient_la_LIBADD = \ - $(EGG_SMCLIENT_LIBS) \ - $(platform_libs) - -libeggsmclient_la_LDFLAGS = \ - $(platform_ldflags) - -libeggsmclient_la_SOURCES = \ - eggsmclient.c \ - eggsmclient.h \ - eggsmclient-private.h \ - $(platform_sources) - -libeggdesktopfile_la_LIBADD = \ - $(EGG_LIBS) - -libeggdesktopfile_la_SOURCES = \ - eggdesktopfile.c \ - eggdesktopfile.h - -EXTRA_DIST = \ - eggsmclient-xsmp.c - --include $(top_srcdir)/git.mk diff --git a/xed/smclient/eggdesktopfile.c b/xed/smclient/eggdesktopfile.c deleted file mode 100644 index 384fd47..0000000 --- a/xed/smclient/eggdesktopfile.c +++ /dev/null @@ -1,1502 +0,0 @@ -/* eggdesktopfile.c - Freedesktop.Org Desktop Files - * Copyright (C) 2007 Novell, Inc. - * - * Based on mate-desktop-item.c - * Copyright (C) 1999, 2000 Red Hat Inc. - * Copyright (C) 2001 George Lebl - * - * 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 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; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 151 Franklin Street, - * Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "eggdesktopfile.h" - -#include -#include - -#include -#include -#include - -struct EggDesktopFile { - GKeyFile *key_file; - char *source; - - char *name, *icon; - EggDesktopFileType type; - char document_code; -}; - -/** - * egg_desktop_file_new: - * @desktop_file_path: path to a Freedesktop-style Desktop file - * @error: error pointer - * - * Creates a new #EggDesktopFile for @desktop_file. - * - * Return value: the new #EggDesktopFile, or %NULL on error. - **/ -EggDesktopFile * -egg_desktop_file_new (const char *desktop_file_path, GError **error) -{ - GKeyFile *key_file; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_file (key_file, desktop_file_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } - - return egg_desktop_file_new_from_key_file (key_file, desktop_file_path, - error); -} - -/** - * egg_desktop_file_new_from_data_dirs: - * @desktop_file_path: relative path to a Freedesktop-style Desktop file - * @error: error pointer - * - * Looks for @desktop_file_path in the paths returned from - * g_get_user_data_dir() and g_get_system_data_dirs(), and creates - * a new #EggDesktopFile from it. - * - * Return value: the new #EggDesktopFile, or %NULL on error. - **/ -EggDesktopFile * -egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, - GError **error) -{ - EggDesktopFile *desktop_file; - GKeyFile *key_file; - char *full_path; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_data_dirs (key_file, desktop_file_path, - &full_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } - - desktop_file = egg_desktop_file_new_from_key_file (key_file, - full_path, - error); - g_free (full_path); - return desktop_file; -} - -/** - * egg_desktop_file_new_from_dirs: - * @desktop_file_path: relative path to a Freedesktop-style Desktop file - * @search_dirs: NULL-terminated array of directories to search - * @error: error pointer - * - * Looks for @desktop_file_path in the paths returned from - * g_get_user_data_dir() and g_get_system_data_dirs(), and creates - * a new #EggDesktopFile from it. - * - * Return value: the new #EggDesktopFile, or %NULL on error. - **/ -EggDesktopFile * -egg_desktop_file_new_from_dirs (const char *desktop_file_path, - const char **search_dirs, - GError **error) -{ - EggDesktopFile *desktop_file; - GKeyFile *key_file; - char *full_path; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_dirs (key_file, desktop_file_path, search_dirs, - &full_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } - - desktop_file = egg_desktop_file_new_from_key_file (key_file, - full_path, - error); - g_free (full_path); - return desktop_file; -} - -/** - * egg_desktop_file_new_from_key_file: - * @key_file: a #GKeyFile representing a desktop file - * @source: the path or URI that @key_file was loaded from, or %NULL - * @error: error pointer - * - * Creates a new #EggDesktopFile for @key_file. Assumes ownership of - * @key_file (on success or failure); you should consider @key_file to - * be freed after calling this function. - * - * Return value: the new #EggDesktopFile, or %NULL on error. - **/ -EggDesktopFile * -egg_desktop_file_new_from_key_file (GKeyFile *key_file, - const char *source, - GError **error) -{ - EggDesktopFile *desktop_file; - char *version, *type; - - if (!g_key_file_has_group (key_file, EGG_DESKTOP_FILE_GROUP)) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_INVALID, - _("File is not a valid .desktop file")); - g_key_file_free (key_file); - return NULL; - } - - version = g_key_file_get_value (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_VERSION, - NULL); - if (version) - { - double version_num; - char *end; - - version_num = g_ascii_strtod (version, &end); - if (*end) - { - g_warning ("Invalid Version string '%s' in %s", - version, source ? source : "(unknown)"); - } - else if (version_num > 1.0) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_INVALID, - _("Unrecognized desktop file Version '%s'"), version); - g_free (version); - g_key_file_free (key_file); - return NULL; - } - g_free (version); - } - - desktop_file = g_new0 (EggDesktopFile, 1); - desktop_file->key_file = key_file; - - if (g_path_is_absolute (source)) - desktop_file->source = g_filename_to_uri (source, NULL, NULL); - else - desktop_file->source = g_strdup (source); - - desktop_file->name = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NAME, error); - if (!desktop_file->name) - { - egg_desktop_file_free (desktop_file); - return NULL; - } - - type = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TYPE, error); - if (!type) - { - egg_desktop_file_free (desktop_file); - return NULL; - } - - if (!strcmp (type, "Application")) - { - char *exec, *p; - - desktop_file->type = EGG_DESKTOP_FILE_TYPE_APPLICATION; - - exec = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - error); - if (!exec) - { - egg_desktop_file_free (desktop_file); - g_free (type); - return NULL; - } - - /* See if it takes paths or URIs or neither */ - for (p = exec; *p; p++) - { - if (*p == '%') - { - if (p[1] == '\0' || strchr ("FfUu", p[1])) - { - desktop_file->document_code = p[1]; - break; - } - p++; - } - } - - g_free (exec); - } - else if (!strcmp (type, "Link")) - { - char *url; - - desktop_file->type = EGG_DESKTOP_FILE_TYPE_LINK; - - url = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_URL, - error); - if (!url) - { - egg_desktop_file_free (desktop_file); - g_free (type); - return NULL; - } - g_free (url); - } - else if (!strcmp (type, "Directory")) - desktop_file->type = EGG_DESKTOP_FILE_TYPE_DIRECTORY; - else - desktop_file->type = EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED; - - g_free (type); - - /* Check the Icon key */ - desktop_file->icon = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_ICON, - NULL); - if (desktop_file->icon && !g_path_is_absolute (desktop_file->icon)) - { - char *ext; - - /* Lots of .desktop files still get this wrong */ - ext = strrchr (desktop_file->icon, '.'); - if (ext && (!strcmp (ext, ".png") || - !strcmp (ext, ".xpm") || - !strcmp (ext, ".svg"))) - { - g_warning ("Desktop file '%s' has malformed Icon key '%s'" - "(should not include extension)", - source ? source : "(unknown)", - desktop_file->icon); - *ext = '\0'; - } - } - - return desktop_file; -} - -/** - * egg_desktop_file_free: - * @desktop_file: an #EggDesktopFile - * - * Frees @desktop_file. - **/ -void -egg_desktop_file_free (EggDesktopFile *desktop_file) -{ - g_key_file_free (desktop_file->key_file); - g_free (desktop_file->source); - g_free (desktop_file->name); - g_free (desktop_file->icon); - g_free (desktop_file); -} - -/** - * egg_desktop_file_get_source: - * @desktop_file: an #EggDesktopFile - * - * Gets the URI that @desktop_file was loaded from. - * - * Return value: @desktop_file's source URI - **/ -const char * -egg_desktop_file_get_source (EggDesktopFile *desktop_file) -{ - return desktop_file->source; -} - -/** - * egg_desktop_file_get_desktop_file_type: - * @desktop_file: an #EggDesktopFile - * - * Gets the desktop file type of @desktop_file. - * - * Return value: @desktop_file's type - **/ -EggDesktopFileType -egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file) -{ - return desktop_file->type; -} - -/** - * egg_desktop_file_get_name: - * @desktop_file: an #EggDesktopFile - * - * Gets the (localized) value of @desktop_file's "Name" key. - * - * Return value: the application/link name - **/ -const char * -egg_desktop_file_get_name (EggDesktopFile *desktop_file) -{ - return desktop_file->name; -} - -/** - * egg_desktop_file_get_icon: - * @desktop_file: an #EggDesktopFile - * - * Gets the value of @desktop_file's "Icon" key. - * - * If the icon string is a full path (that is, if g_path_is_absolute() - * returns %TRUE when called on it), it points to a file containing an - * unthemed icon. If the icon string is not a full path, it is the - * name of a themed icon, which can be looked up with %GtkIconTheme, - * or passed directly to a theme-aware widget like %GtkImage or - * %GtkCellRendererPixbuf. - * - * Return value: the icon path or name - **/ -const char * -egg_desktop_file_get_icon (EggDesktopFile *desktop_file) -{ - return desktop_file->icon; -} - -gboolean -egg_desktop_file_has_key (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -char * -egg_desktop_file_get_string (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -char * -egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - GError **error) -{ - return g_key_file_get_locale_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, locale, - error); -} - -gboolean -egg_desktop_file_get_boolean (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -double -egg_desktop_file_get_numeric (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_get_double (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -char ** -egg_desktop_file_get_string_list (EggDesktopFile *desktop_file, - const char *key, - gsize *length, - GError **error) -{ - return g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, length, - error); -} - -char ** -egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - gsize *length, - GError **error) -{ - return g_key_file_get_locale_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - locale, length, - error); -} - -/** - * egg_desktop_file_can_launch: - * @desktop_file: an #EggDesktopFile - * @desktop_environment: the name of the running desktop environment, - * or %NULL - * - * Tests if @desktop_file can/should be launched in the current - * environment. If @desktop_environment is non-%NULL, @desktop_file's - * "OnlyShowIn" and "NotShowIn" keys are checked to make sure that - * this desktop_file is appropriate for the named environment. - * - * Furthermore, if @desktop_file has type - * %EGG_DESKTOP_FILE_TYPE_APPLICATION, its "TryExec" key (if any) is - * also checked, to make sure the binary it points to exists. - * - * egg_desktop_file_can_launch() does NOT check the value of the - * "Hidden" key. - * - * Return value: %TRUE if @desktop_file can be launched - **/ -gboolean -egg_desktop_file_can_launch (EggDesktopFile *desktop_file, - const char *desktop_environment) -{ - char *try_exec, *found_program; - char **only_show_in, **not_show_in; - gboolean found; - int i; - - if (desktop_file->type != EGG_DESKTOP_FILE_TYPE_APPLICATION && - desktop_file->type != EGG_DESKTOP_FILE_TYPE_LINK) - return FALSE; - - if (desktop_environment) - { - only_show_in = g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN, - NULL, NULL); - if (only_show_in) - { - for (i = 0, found = FALSE; only_show_in[i] && !found; i++) - { - if (!strcmp (only_show_in[i], desktop_environment)) - found = TRUE; - } - - g_strfreev (only_show_in); - - if (!found) - return FALSE; - } - - not_show_in = g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN, - NULL, NULL); - if (not_show_in) - { - for (i = 0, found = FALSE; not_show_in[i] && !found; i++) - { - if (!strcmp (not_show_in[i], desktop_environment)) - found = TRUE; - } - - g_strfreev (not_show_in); - - if (found) - return FALSE; - } - } - - if (desktop_file->type == EGG_DESKTOP_FILE_TYPE_APPLICATION) - { - try_exec = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TRY_EXEC, - NULL); - if (try_exec) - { - found_program = g_find_program_in_path (try_exec); - g_free (try_exec); - - if (!found_program) - return FALSE; - g_free (found_program); - } - } - - return TRUE; -} - -/** - * egg_desktop_file_accepts_documents: - * @desktop_file: an #EggDesktopFile - * - * Tests if @desktop_file represents an application that can accept - * documents on the command line. - * - * Return value: %TRUE or %FALSE - **/ -gboolean -egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file) -{ - return desktop_file->document_code != 0; -} - -/** - * egg_desktop_file_accepts_multiple: - * @desktop_file: an #EggDesktopFile - * - * Tests if @desktop_file can accept multiple documents at once. - * - * If this returns %FALSE, you can still pass multiple documents to - * egg_desktop_file_launch(), but that will result in multiple copies - * of the application being launched. See egg_desktop_file_launch() - * for more details. - * - * Return value: %TRUE or %FALSE - **/ -gboolean -egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file) -{ - return (desktop_file->document_code == 'F' || - desktop_file->document_code == 'U'); -} - -/** - * egg_desktop_file_accepts_uris: - * @desktop_file: an #EggDesktopFile - * - * Tests if @desktop_file can accept (non-"file:") URIs as documents to - * open. - * - * Return value: %TRUE or %FALSE - **/ -gboolean -egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file) -{ - return (desktop_file->document_code == 'U' || - desktop_file->document_code == 'u'); -} - -static void -append_quoted_word (GString *str, - const char *s, - gboolean in_single_quotes, - gboolean in_double_quotes) -{ - const char *p; - - if (!in_single_quotes && !in_double_quotes) - g_string_append_c (str, '\''); - else if (!in_single_quotes && in_double_quotes) - g_string_append (str, "\"'"); - - if (!strchr (s, '\'')) - g_string_append (str, s); - else - { - for (p = s; *p != '\0'; p++) - { - if (*p == '\'') - g_string_append (str, "'\\''"); - else - g_string_append_c (str, *p); - } - } - - if (!in_single_quotes && !in_double_quotes) - g_string_append_c (str, '\''); - else if (!in_single_quotes && in_double_quotes) - g_string_append (str, "'\""); -} - -static void -do_percent_subst (EggDesktopFile *desktop_file, - char code, - GString *str, - GSList **documents, - gboolean in_single_quotes, - gboolean in_double_quotes) -{ - GSList *d; - char *doc; - - switch (code) - { - case '%': - g_string_append_c (str, '%'); - break; - - case 'F': - case 'U': - for (d = *documents; d; d = d->next) - { - doc = d->data; - g_string_append (str, " "); - append_quoted_word (str, doc, in_single_quotes, in_double_quotes); - } - *documents = NULL; - break; - - case 'f': - case 'u': - if (*documents) - { - doc = (*documents)->data; - g_string_append (str, " "); - append_quoted_word (str, doc, in_single_quotes, in_double_quotes); - *documents = (*documents)->next; - } - break; - - case 'i': - if (desktop_file->icon) - { - g_string_append (str, "--icon "); - append_quoted_word (str, desktop_file->icon, - in_single_quotes, in_double_quotes); - } - break; - - case 'c': - if (desktop_file->name) - { - append_quoted_word (str, desktop_file->name, - in_single_quotes, in_double_quotes); - } - break; - - case 'k': - if (desktop_file->source) - { - append_quoted_word (str, desktop_file->source, - in_single_quotes, in_double_quotes); - } - break; - - case 'D': - case 'N': - case 'd': - case 'n': - case 'v': - case 'm': - /* Deprecated; skip */ - break; - - default: - g_warning ("Unrecognized %%-code '%%%c' in Exec", code); - break; - } -} - -static char * -parse_exec (EggDesktopFile *desktop_file, - GSList **documents, - GError **error) -{ - char *exec, *p, *command; - gboolean escape, single_quot, double_quot; - GString *gs; - - exec = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - error); - if (!exec) - return NULL; - - /* Build the command */ - gs = g_string_new (NULL); - escape = single_quot = double_quot = FALSE; - - for (p = exec; *p != '\0'; p++) - { - if (escape) - { - escape = FALSE; - g_string_append_c (gs, *p); - } - else if (*p == '\\') - { - if (!single_quot) - escape = TRUE; - g_string_append_c (gs, *p); - } - else if (*p == '\'') - { - g_string_append_c (gs, *p); - if (!single_quot && !double_quot) - single_quot = TRUE; - else if (single_quot) - single_quot = FALSE; - } - else if (*p == '"') - { - g_string_append_c (gs, *p); - if (!single_quot && !double_quot) - double_quot = TRUE; - else if (double_quot) - double_quot = FALSE; - } - else if (*p == '%' && p[1]) - { - do_percent_subst (desktop_file, p[1], gs, documents, - single_quot, double_quot); - p++; - } - else - g_string_append_c (gs, *p); - } - - g_free (exec); - command = g_string_free (gs, FALSE); - - /* Prepend "xdg-terminal " if needed (FIXME: use gvfs) */ - if (g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TERMINAL, - NULL)) - { - GError *terminal_error = NULL; - gboolean use_terminal = - g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TERMINAL, - &terminal_error); - if (terminal_error) - { - g_free (command); - g_propagate_error (error, terminal_error); - return NULL; - } - - if (use_terminal) - { - gs = g_string_new ("xdg-terminal "); - append_quoted_word (gs, command, FALSE, FALSE); - g_free (command); - command = g_string_free (gs, FALSE); - } - } - - return command; -} - -static GSList * -translate_document_list (EggDesktopFile *desktop_file, GSList *documents) -{ - gboolean accepts_uris = egg_desktop_file_accepts_uris (desktop_file); - GSList *ret, *d; - - for (d = documents, ret = NULL; d; d = d->next) - { - const char *document = d->data; - gboolean is_uri = !g_path_is_absolute (document); - char *translated; - - if (accepts_uris) - { - if (is_uri) - translated = g_strdup (document); - else - translated = g_filename_to_uri (document, NULL, NULL); - } - else - { - if (is_uri) - translated = g_filename_from_uri (document, NULL, NULL); - else - translated = g_strdup (document); - } - - if (translated) - ret = g_slist_prepend (ret, translated); - } - - return g_slist_reverse (ret); -} - -static void -free_document_list (GSList *documents) -{ - GSList *d; - - for (d = documents; d; d = d->next) - g_free (d->data); - g_slist_free (documents); -} - -/** - * egg_desktop_file_parse_exec: - * @desktop_file: a #EggDesktopFile - * @documents: a list of document paths or URIs - * @error: error pointer - * - * Parses @desktop_file's Exec key, inserting @documents into it, and - * returns the result. - * - * If @documents contains non-file: URIs and @desktop_file does not - * accept URIs, those URIs will be ignored. Likewise, if @documents - * contains more elements than @desktop_file accepts, the extra - * documents will be ignored. - * - * Return value: the parsed Exec string - **/ -char * -egg_desktop_file_parse_exec (EggDesktopFile *desktop_file, - GSList *documents, - GError **error) -{ - GSList *translated, *docs; - char *command; - - docs = translated = translate_document_list (desktop_file, documents); - command = parse_exec (desktop_file, &docs, error); - free_document_list (translated); - - return command; -} - -static gboolean -parse_link (EggDesktopFile *desktop_file, - EggDesktopFile **app_desktop_file, - GSList **documents, - GError **error) -{ - char *url; - GKeyFile *key_file; - - url = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_URL, - error); - if (!url) - return FALSE; - *documents = g_slist_prepend (NULL, url); - - /* FIXME: use gvfs */ - key_file = g_key_file_new (); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NAME, - "xdg-open"); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TYPE, - "Application"); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - "xdg-open %u"); - *app_desktop_file = egg_desktop_file_new_from_key_file (key_file, NULL, NULL); - return TRUE; -} - -static char * -start_startup_notification (GdkDisplay *display, - EggDesktopFile *desktop_file, - const char *argv0, - int screen, - int workspace, - guint32 launch_time) -{ - static int sequence = 0; - char *startup_id; - char *description, *wmclass; - char *screen_str, *workspace_str; - - if (g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, - NULL)) - { - if (!g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, - NULL)) - return NULL; - wmclass = NULL; - } - else - { - wmclass = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS, - NULL); - if (!wmclass) - return NULL; - } - - if (launch_time == (guint32)-1) - launch_time = gdk_x11_display_get_user_time (display); - startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu", - g_get_prgname (), - (unsigned long)getpid (), - g_get_host_name (), - argv0, - sequence++, - (unsigned long)launch_time); - - description = g_strdup_printf (_("Starting %s"), desktop_file->name); - screen_str = g_strdup_printf ("%d", screen); - workspace_str = workspace == -1 ? NULL : g_strdup_printf ("%d", workspace); - - gdk_x11_display_broadcast_startup_message (display, "new", - "ID", startup_id, - "NAME", desktop_file->name, - "SCREEN", screen_str, - "BIN", argv0, - "ICON", desktop_file->icon, - "DESKTOP", workspace_str, - "DESCRIPTION", description, - "WMCLASS", wmclass, - NULL); - - g_free (description); - g_free (wmclass); - g_free (screen_str); - g_free (workspace_str); - - return startup_id; -} - -static void -end_startup_notification (GdkDisplay *display, - const char *startup_id) -{ - gdk_x11_display_broadcast_startup_message (display, "remove", - "ID", startup_id, - NULL); -} - -#define EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH (30 /* seconds */) - -typedef struct { - GdkDisplay *display; - char *startup_id; -} StartupNotificationData; - -static gboolean -startup_notification_timeout (gpointer data) -{ - StartupNotificationData *sn_data = data; - - end_startup_notification (sn_data->display, sn_data->startup_id); - g_object_unref (sn_data->display); - g_free (sn_data->startup_id); - g_free (sn_data); - - return FALSE; -} - -static void -set_startup_notification_timeout (GdkDisplay *display, - const char *startup_id) -{ - StartupNotificationData *sn_data; - - sn_data = g_new (StartupNotificationData, 1); - sn_data->display = g_object_ref (display); - sn_data->startup_id = g_strdup (startup_id); - - g_timeout_add_seconds (EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH, - startup_notification_timeout, sn_data); -} - -static GPtrArray * -array_putenv (GPtrArray *env, char *variable) -{ - guint i, keylen; - - if (!env) - { - char **envp; - - env = g_ptr_array_new (); - - envp = g_listenv (); - for (i = 0; envp[i]; i++) - { - const char *value; - - value = g_getenv (envp[i]); - g_ptr_array_add (env, g_strdup_printf ("%s=%s", envp[i], - value ? value : "")); - } - g_strfreev (envp); - } - - keylen = strcspn (variable, "="); - - /* Remove old value of key */ - for (i = 0; i < env->len; i++) - { - char *envvar = env->pdata[i]; - - if (!strncmp (envvar, variable, keylen) && envvar[keylen] == '=') - { - g_free (envvar); - g_ptr_array_remove_index_fast (env, i); - break; - } - } - - /* Add new value */ - g_ptr_array_add (env, g_strdup (variable)); - - return env; -} - -static gboolean -egg_desktop_file_launchv (EggDesktopFile *desktop_file, - GSList *documents, va_list args, - GError **error) -{ - EggDesktopFileLaunchOption option; - GSList *translated_documents = NULL, *docs = NULL; - char *command, **argv; - int argc, i, screen_num; - gboolean success, current_success; - GdkDisplay *display; - char *startup_id; - - GPtrArray *env = NULL; - char **variables = NULL; - GdkScreen *screen = NULL; - int workspace = -1; - const char *directory = NULL; - guint32 launch_time = (guint32)-1; - GSpawnFlags flags = G_SPAWN_SEARCH_PATH; - GSpawnChildSetupFunc setup_func = NULL; - gpointer setup_data = NULL; - - GPid *ret_pid = NULL; - int *ret_stdin = NULL, *ret_stdout = NULL, *ret_stderr = NULL; - char **ret_startup_id = NULL; - - if (documents && desktop_file->document_code == 0) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - _("Application does not accept documents on command line")); - return FALSE; - } - - /* Read the options: technically it's incorrect for the caller to - * NULL-terminate the list of options (rather than 0-terminating - * it), but NULL-terminating lets us use G_GNUC_NULL_TERMINATED, - * it's more consistent with other glib/gtk methods, and it will - * work as long as sizeof (int) <= sizeof (NULL), and NULL is - * represented as 0. (Which is true everywhere we care about.) - */ - while ((option = va_arg (args, EggDesktopFileLaunchOption))) - { - switch (option) - { - case EGG_DESKTOP_FILE_LAUNCH_CLEARENV: - if (env) - g_ptr_array_free (env, TRUE); - env = g_ptr_array_new (); - break; - case EGG_DESKTOP_FILE_LAUNCH_PUTENV: - variables = va_arg (args, char **); - for (i = 0; variables[i]; i++) - env = array_putenv (env, variables[i]); - break; - - case EGG_DESKTOP_FILE_LAUNCH_SCREEN: - screen = va_arg (args, GdkScreen *); - break; - case EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: - workspace = va_arg (args, int); - break; - - case EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: - directory = va_arg (args, const char *); - break; - case EGG_DESKTOP_FILE_LAUNCH_TIME: - launch_time = va_arg (args, guint32); - break; - case EGG_DESKTOP_FILE_LAUNCH_FLAGS: - flags |= va_arg (args, GSpawnFlags); - /* Make sure they didn't set any flags that don't make sense. */ - flags &= ~G_SPAWN_FILE_AND_ARGV_ZERO; - break; - case EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC: - setup_func = va_arg (args, GSpawnChildSetupFunc); - setup_data = va_arg (args, gpointer); - break; - - case EGG_DESKTOP_FILE_LAUNCH_RETURN_PID: - ret_pid = va_arg (args, GPid *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE: - ret_stdin = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE: - ret_stdout = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE: - ret_stderr = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID: - ret_startup_id = va_arg (args, char **); - break; - - default: - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION, - _("Unrecognized launch option: %d"), - GPOINTER_TO_INT (option)); - success = FALSE; - goto out; - } - } - - if (screen) - { - char *display_name = gdk_screen_make_display_name (screen); - char *display_env = g_strdup_printf ("DISPLAY=%s", display_name); - env = array_putenv (env, display_env); - g_free (display_name); - g_free (display_env); - - display = gdk_screen_get_display (screen); - } - else - { - display = gdk_display_get_default (); - screen = gdk_display_get_default_screen (display); - } - screen_num = gdk_screen_get_number (screen); - - translated_documents = translate_document_list (desktop_file, documents); - docs = translated_documents; - - success = FALSE; - - do - { - command = parse_exec (desktop_file, &docs, error); - if (!command) - goto out; - - if (!g_shell_parse_argv (command, &argc, &argv, error)) - { - g_free (command); - goto out; - } - g_free (command); - - startup_id = start_startup_notification (display, desktop_file, - argv[0], screen_num, - workspace, launch_time); - if (startup_id) - { - char *startup_id_env = g_strdup_printf ("DESKTOP_STARTUP_ID=%s", - startup_id); - env = array_putenv (env, startup_id_env); - g_free (startup_id_env); - } - - if (env != NULL) - g_ptr_array_add (env, NULL); - - current_success = - g_spawn_async_with_pipes (directory, - argv, - env ? (char **)(env->pdata) : NULL, - flags, - setup_func, setup_data, - ret_pid, - ret_stdin, ret_stdout, ret_stderr, - error); - g_strfreev (argv); - - if (startup_id) - { - if (current_success) - { - set_startup_notification_timeout (display, startup_id); - - if (ret_startup_id) - *ret_startup_id = startup_id; - else - g_free (startup_id); - } - else - g_free (startup_id); - } - else if (ret_startup_id) - *ret_startup_id = NULL; - - if (current_success) - { - /* If we successfully launch any instances of the app, make - * sure we return TRUE and don't set @error. - */ - success = TRUE; - error = NULL; - - /* Also, only set the output params on the first one */ - ret_pid = NULL; - ret_stdin = ret_stdout = ret_stderr = NULL; - ret_startup_id = NULL; - } - } - while (docs && current_success); - - out: - if (env) - { - g_ptr_array_foreach (env, (GFunc)g_free, NULL); - g_ptr_array_free (env, TRUE); - } - free_document_list (translated_documents); - - return success; -} - -/** - * egg_desktop_file_launch: - * @desktop_file: an #EggDesktopFile - * @documents: a list of URIs or paths to documents to open - * @error: error pointer - * @...: additional options - * - * Launches @desktop_file with the given arguments. Additional options - * can be specified as follows: - * - * %EGG_DESKTOP_FILE_LAUNCH_CLEARENV: (no arguments) - * clears the environment in the child process - * %EGG_DESKTOP_FILE_LAUNCH_PUTENV: (char **variables) - * adds the NAME=VALUE strings in the given %NULL-terminated - * array to the child process's environment - * %EGG_DESKTOP_FILE_LAUNCH_SCREEN: (GdkScreen *screen) - * causes the application to be launched on the given screen - * %EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: (int workspace) - * causes the application to be launched on the given workspace - * %EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: (char *dir) - * causes the application to be launched in the given directory - * %EGG_DESKTOP_FILE_LAUNCH_TIME: (guint32 launch_time) - * sets the "launch time" for the application. If the user - * interacts with another window after @launch_time but before - * the launched application creates its first window, the window - * manager may choose to not give focus to the new application. - * Passing 0 for @launch_time will explicitly request that the - * application not receive focus. - * %EGG_DESKTOP_FILE_LAUNCH_FLAGS (GSpawnFlags flags) - * Sets additional #GSpawnFlags to use. See g_spawn_async() for - * more details. - * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC (GSpawnChildSetupFunc, gpointer) - * Sets the child setup callback and the data to pass to it. - * (See g_spawn_async() for more details.) - * - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID (GPid **pid) - * On a successful launch, sets *@pid to the PID of the launched - * application. - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID (char **startup_id) - * On a successful launch, sets *@startup_id to the Startup - * Notification "startup id" of the launched application. - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE (int *fd) - * On a successful launch, sets *@fd to the file descriptor of - * a pipe connected to the application's stdin. - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE (int *fd) - * On a successful launch, sets *@fd to the file descriptor of - * a pipe connected to the application's stdout. - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE (int *fd) - * On a successful launch, sets *@fd to the file descriptor of - * a pipe connected to the application's stderr. - * - * The options should be terminated with a single %NULL. - * - * If @documents contains multiple documents, but - * egg_desktop_file_accepts_multiple() returns %FALSE for - * @desktop_file, then egg_desktop_file_launch() will actually launch - * multiple instances of the application. In that case, the return - * value (as well as any values passed via - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, etc) will only reflect the - * first instance of the application that was launched (but the - * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC will be called for each - * instance). - * - * Return value: %TRUE if the application was successfully launched. - **/ -gboolean -egg_desktop_file_launch (EggDesktopFile *desktop_file, - GSList *documents, GError **error, - ...) -{ - va_list args; - gboolean success; - EggDesktopFile *app_desktop_file; - - switch (desktop_file->type) - { - case EGG_DESKTOP_FILE_TYPE_APPLICATION: - va_start (args, error); - success = egg_desktop_file_launchv (desktop_file, documents, - args, error); - va_end (args); - break; - - case EGG_DESKTOP_FILE_TYPE_LINK: - if (documents) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - _("Can't pass document URIs to a 'Type=Link' desktop entry")); - return FALSE; - } - - if (!parse_link (desktop_file, &app_desktop_file, &documents, error)) - return FALSE; - - va_start (args, error); - success = egg_desktop_file_launchv (app_desktop_file, documents, - args, error); - va_end (args); - - egg_desktop_file_free (app_desktop_file); - free_document_list (documents); - break; - - case EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED: - case EGG_DESKTOP_FILE_TYPE_DIRECTORY: - default: - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - _("Not a launchable item")); - success = FALSE; - break; - } - - return success; -} - - -GQuark -egg_desktop_file_error_quark (void) -{ - return g_quark_from_static_string ("egg-desktop_file-error-quark"); -} - - -G_LOCK_DEFINE_STATIC (egg_desktop_file); -static EggDesktopFile *egg_desktop_file; - -static void -egg_set_desktop_file_internal (const char *desktop_file_path, - gboolean set_defaults) -{ - GError *error = NULL; - - G_LOCK (egg_desktop_file); - if (egg_desktop_file) - egg_desktop_file_free (egg_desktop_file); - - egg_desktop_file = egg_desktop_file_new (desktop_file_path, &error); - if (error) - { - g_warning ("Could not load desktop file '%s': %s", - desktop_file_path, error->message); - g_error_free (error); - } - - if (set_defaults && egg_desktop_file != NULL) { - /* Set localized application name and default window icon */ - if (egg_desktop_file->name) - g_set_application_name (egg_desktop_file->name); - if (egg_desktop_file->icon) - { - if (g_path_is_absolute (egg_desktop_file->icon)) - gtk_window_set_default_icon_from_file (egg_desktop_file->icon, NULL); - else - gtk_window_set_default_icon_name (egg_desktop_file->icon); - } - } - - G_UNLOCK (egg_desktop_file); -} - -/** - * egg_set_desktop_file: - * @desktop_file_path: path to the application's desktop file - * - * Creates an #EggDesktopFile for the application from the data at - * @desktop_file_path. This will also call g_set_application_name() - * with the localized application name from the desktop file, and - * gtk_window_set_default_icon_name() or - * gtk_window_set_default_icon_from_file() with the application's - * icon. Other code may use additional information from the desktop - * file. - * See egg_set_desktop_file_without_defaults() for a variant of this - * function that does not set the application name and default window - * icon. - * - * Note that for thread safety reasons, this function can only - * be called once, and is mutually exclusive with calling - * egg_set_desktop_file_without_defaults(). - **/ -void -egg_set_desktop_file (const char *desktop_file_path) -{ - egg_set_desktop_file_internal (desktop_file_path, TRUE); -} - -/** - * egg_set_desktop_file_without_defaults: - * @desktop_file_path: path to the application's desktop file - * - * Creates an #EggDesktopFile for the application from the data at - * @desktop_file_path. - * See egg_set_desktop_file() for a variant of this function that - * sets the application name and default window icon from the information - * in the desktop file. - * - * Note that for thread safety reasons, this function can only - * be called once, and is mutually exclusive with calling - * egg_set_desktop_file(). - **/ -void -egg_set_desktop_file_without_defaults (const char *desktop_file_path) -{ - egg_set_desktop_file_internal (desktop_file_path, FALSE); -} - -/** - * egg_get_desktop_file: - * - * Gets the application's #EggDesktopFile, as set by - * egg_set_desktop_file(). - * - * Return value: the #EggDesktopFile, or %NULL if it hasn't been set. - **/ -EggDesktopFile * -egg_get_desktop_file (void) -{ - EggDesktopFile *retval; - - G_LOCK (egg_desktop_file); - retval = egg_desktop_file; - G_UNLOCK (egg_desktop_file); - - return retval; -} diff --git a/xed/smclient/eggdesktopfile.h b/xed/smclient/eggdesktopfile.h deleted file mode 100644 index d9e69ec..0000000 --- a/xed/smclient/eggdesktopfile.h +++ /dev/null @@ -1,160 +0,0 @@ -/* eggdesktopfile.h - Freedesktop.Org Desktop Files - * Copyright (C) 2007 Novell, Inc. - * - * 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 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; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 151 Franklin Street, - * Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __EGG_DESKTOP_FILE_H__ -#define __EGG_DESKTOP_FILE_H__ - -#include - -G_BEGIN_DECLS - -typedef struct EggDesktopFile EggDesktopFile; - -typedef enum { - EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED, - - EGG_DESKTOP_FILE_TYPE_APPLICATION, - EGG_DESKTOP_FILE_TYPE_LINK, - EGG_DESKTOP_FILE_TYPE_DIRECTORY -} EggDesktopFileType; - -EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path, - GError **error); - -EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, - GError **error); -EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path, - const char **search_dirs, - GError **error); -EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file, - const char *source, - GError **error); - -void egg_desktop_file_free (EggDesktopFile *desktop_file); - -const char *egg_desktop_file_get_source (EggDesktopFile *desktop_file); - -EggDesktopFileType egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file); - -const char *egg_desktop_file_get_name (EggDesktopFile *desktop_file); -const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file); - -gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file, - const char *desktop_environment); - -gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file); -gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file); -gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file); - -char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file, - GSList *documents, - GError **error); - -gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file, - GSList *documents, - GError **error, - ...) G_GNUC_NULL_TERMINATED; - -typedef enum { - EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1, - EGG_DESKTOP_FILE_LAUNCH_PUTENV, - EGG_DESKTOP_FILE_LAUNCH_SCREEN, - EGG_DESKTOP_FILE_LAUNCH_WORKSPACE, - EGG_DESKTOP_FILE_LAUNCH_DIRECTORY, - EGG_DESKTOP_FILE_LAUNCH_TIME, - EGG_DESKTOP_FILE_LAUNCH_FLAGS, - EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC, - EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID -} EggDesktopFileLaunchOption; - -/* Standard Keys */ -#define EGG_DESKTOP_FILE_GROUP "Desktop Entry" - -#define EGG_DESKTOP_FILE_KEY_TYPE "Type" -#define EGG_DESKTOP_FILE_KEY_VERSION "Version" -#define EGG_DESKTOP_FILE_KEY_NAME "Name" -#define EGG_DESKTOP_FILE_KEY_GENERIC_NAME "GenericName" -#define EGG_DESKTOP_FILE_KEY_NO_DISPLAY "NoDisplay" -#define EGG_DESKTOP_FILE_KEY_COMMENT "Comment" -#define EGG_DESKTOP_FILE_KEY_ICON "Icon" -#define EGG_DESKTOP_FILE_KEY_HIDDEN "Hidden" -#define EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN "OnlyShowIn" -#define EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN "NotShowIn" -#define EGG_DESKTOP_FILE_KEY_TRY_EXEC "TryExec" -#define EGG_DESKTOP_FILE_KEY_EXEC "Exec" -#define EGG_DESKTOP_FILE_KEY_PATH "Path" -#define EGG_DESKTOP_FILE_KEY_TERMINAL "Terminal" -#define EGG_DESKTOP_FILE_KEY_MIME_TYPE "MimeType" -#define EGG_DESKTOP_FILE_KEY_CATEGORIES "Categories" -#define EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY "StartupNotify" -#define EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS "StartupWMClass" -#define EGG_DESKTOP_FILE_KEY_URL "URL" - -/* Accessors */ -gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file, - const char *key, - GError **error); -char *egg_desktop_file_get_string (EggDesktopFile *desktop_file, - const char *key, - GError **error) G_GNUC_MALLOC; -char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - GError **error) G_GNUC_MALLOC; -gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file, - const char *key, - GError **error); -double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file, - const char *key, - GError **error); -char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file, - const char *key, - gsize *length, - GError **error) G_GNUC_MALLOC; -char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - gsize *length, - GError **error) G_GNUC_MALLOC; - - -/* Errors */ -#define EGG_DESKTOP_FILE_ERROR egg_desktop_file_error_quark() - -GQuark egg_desktop_file_error_quark (void); - -typedef enum { - EGG_DESKTOP_FILE_ERROR_INVALID, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION -} EggDesktopFileError; - -/* Global application desktop file */ -void egg_set_desktop_file (const char *desktop_file_path); -void egg_set_desktop_file_without_defaults (const char *desktop_file_path); -EggDesktopFile *egg_get_desktop_file (void); - - -G_END_DECLS - -#endif /* __EGG_DESKTOP_FILE_H__ */ diff --git a/xed/smclient/eggsmclient-private.h b/xed/smclient/eggsmclient-private.h deleted file mode 100644 index 9a63555..0000000 --- a/xed/smclient/eggsmclient-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* eggsmclient-private.h - * Copyright (C) 2007 Novell, Inc. - * - * 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 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 __EGG_SM_CLIENT_PRIVATE_H__ -#define __EGG_SM_CLIENT_PRIVATE_H__ - -#include -#include "eggsmclient.h" - -G_BEGIN_DECLS - -GKeyFile *egg_sm_client_save_state (EggSMClient *client); -void egg_sm_client_quit_requested (EggSMClient *client); -void egg_sm_client_quit_cancelled (EggSMClient *client); -void egg_sm_client_quit (EggSMClient *client); - -GType egg_sm_client_xsmp_get_type (void); -EggSMClient *egg_sm_client_xsmp_new (void); - -G_END_DECLS - - -#endif /* __EGG_SM_CLIENT_PRIVATE_H__ */ diff --git a/xed/smclient/eggsmclient-xsmp.c b/xed/smclient/eggsmclient-xsmp.c deleted file mode 100644 index 15bcf74..0000000 --- a/xed/smclient/eggsmclient-xsmp.c +++ /dev/null @@ -1,1365 +0,0 @@ -/* - * Copyright (C) 2007 Novell, Inc. - * - * Inspired by various other pieces of code including GsmClient (C) - * 2001 Havoc Pennington, MateClient (C) 1998 Carsten Schaar, and twm - * session code (C) 1998 The Open Group. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library 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 "config.h" - -#include "eggsmclient.h" -#include "eggsmclient-private.h" - -#include "eggdesktopfile.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define EGG_TYPE_SM_CLIENT_XSMP (egg_sm_client_xsmp_get_type ()) -#define EGG_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMP)) -#define EGG_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)) -#define EGG_IS_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_XSMP)) -#define EGG_IS_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_XSMP)) -#define EGG_SM_CLIENT_XSMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)) - -typedef struct _EggSMClientXSMP EggSMClientXSMP; -typedef struct _EggSMClientXSMPClass EggSMClientXSMPClass; - -/* These mostly correspond to the similarly-named states in section - * 9.1 of the XSMP spec. Some of the states there aren't represented - * here, because we don't need them. SHUTDOWN_CANCELLED is slightly - * different from the spec; we use it when the client is IDLE after a - * ShutdownCancelled message, but the application is still interacting - * and doesn't know the shutdown has been cancelled yet. - */ -typedef enum -{ - XSMP_STATE_IDLE, - XSMP_STATE_SAVE_YOURSELF, - XSMP_STATE_INTERACT_REQUEST, - XSMP_STATE_INTERACT, - XSMP_STATE_SAVE_YOURSELF_DONE, - XSMP_STATE_SHUTDOWN_CANCELLED, - XSMP_STATE_CONNECTION_CLOSED -} EggSMClientXSMPState; - -static const char *state_names[] = { - "idle", - "save-yourself", - "interact-request", - "interact", - "save-yourself-done", - "shutdown-cancelled", - "connection-closed" -}; - -#define EGG_SM_CLIENT_XSMP_STATE(xsmp) (state_names[(xsmp)->state]) - -struct _EggSMClientXSMP -{ - EggSMClient parent; - - SmcConn connection; - char *client_id; - - EggSMClientXSMPState state; - char **restart_command; - gboolean set_restart_command; - int restart_style; - - guint idle; - - /* Current SaveYourself state */ - guint expecting_initial_save_yourself : 1; - guint need_save_state : 1; - guint need_quit_requested : 1; - guint interact_errors : 1; - guint shutting_down : 1; - - /* Todo list */ - guint waiting_to_set_initial_properties : 1; - guint waiting_to_emit_quit : 1; - guint waiting_to_emit_quit_cancelled : 1; - guint waiting_to_save_myself : 1; - -}; - -struct _EggSMClientXSMPClass -{ - EggSMClientClass parent_class; - -}; - -static void sm_client_xsmp_startup (EggSMClient *client, - const char *client_id); -static void sm_client_xsmp_set_restart_command (EggSMClient *client, - int argc, - const char **argv); -static void sm_client_xsmp_will_quit (EggSMClient *client, - gboolean will_quit); -static gboolean sm_client_xsmp_end_session (EggSMClient *client, - EggSMClientEndStyle style, - gboolean request_confirmation); - -static void xsmp_save_yourself (SmcConn smc_conn, - SmPointer client_data, - int save_style, - Bool shutdown, - int interact_style, - Bool fast); -static void xsmp_die (SmcConn smc_conn, - SmPointer client_data); -static void xsmp_save_complete (SmcConn smc_conn, - SmPointer client_data); -static void xsmp_shutdown_cancelled (SmcConn smc_conn, - SmPointer client_data); -static void xsmp_interact (SmcConn smc_conn, - SmPointer client_data); - -static SmProp *array_prop (const char *name, - ...); -static SmProp *ptrarray_prop (const char *name, - GPtrArray *values); -static SmProp *string_prop (const char *name, - const char *value); -static SmProp *card8_prop (const char *name, - unsigned char value); - -static void set_properties (EggSMClientXSMP *xsmp, ...); -static void delete_properties (EggSMClientXSMP *xsmp, ...); - -static GPtrArray *generate_command (char **restart_command, - const char *client_id, - const char *state_file); - -static void save_state (EggSMClientXSMP *xsmp); -static void do_save_yourself (EggSMClientXSMP *xsmp); -static void update_pending_events (EggSMClientXSMP *xsmp); - -static void ice_init (void); -static gboolean process_ice_messages (IceConn ice_conn); -static void smc_error_handler (SmcConn smc_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence, - int error_class, - int severity, - SmPointer values); - -G_DEFINE_TYPE (EggSMClientXSMP, egg_sm_client_xsmp, EGG_TYPE_SM_CLIENT) - -static void -egg_sm_client_xsmp_init (EggSMClientXSMP *xsmp) -{ - xsmp->state = XSMP_STATE_CONNECTION_CLOSED; - xsmp->connection = NULL; - xsmp->restart_style = SmRestartIfRunning; -} - -static void -egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass) -{ - EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass); - - sm_client_class->startup = sm_client_xsmp_startup; - sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command; - sm_client_class->will_quit = sm_client_xsmp_will_quit; - sm_client_class->end_session = sm_client_xsmp_end_session; -} - -EggSMClient * -egg_sm_client_xsmp_new (void) -{ - if (!g_getenv ("SESSION_MANAGER")) - return NULL; - - return g_object_new (EGG_TYPE_SM_CLIENT_XSMP, NULL); -} - -static gboolean -sm_client_xsmp_set_initial_properties (gpointer user_data) -{ - EggSMClientXSMP *xsmp = user_data; - EggDesktopFile *desktop_file; - GPtrArray *clone, *restart; - char pid_str[64]; - - if (xsmp->idle) - { - g_source_remove (xsmp->idle); - xsmp->idle = 0; - } - xsmp->waiting_to_set_initial_properties = FALSE; - - if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART) - xsmp->restart_style = SmRestartNever; - - /* Parse info out of desktop file */ - desktop_file = egg_get_desktop_file (); - if (desktop_file) - { - GError *err = NULL; - char *cmdline, **argv; - int argc; - - if (xsmp->restart_style == SmRestartIfRunning) - { - if (egg_desktop_file_get_boolean (desktop_file, - "X-MATE-AutoRestart", NULL)) - xsmp->restart_style = SmRestartImmediately; - } - - if (!xsmp->set_restart_command) - { - cmdline = egg_desktop_file_parse_exec (desktop_file, NULL, &err); - if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err)) - { - egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp), - argc, (const char **)argv); - g_strfreev (argv); - } - else - { - g_warning ("Could not parse Exec line in desktop file: %s", - err->message); - g_error_free (err); - } - g_free (cmdline); - } - } - - if (!xsmp->set_restart_command) - xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1); - - clone = generate_command (xsmp->restart_command, NULL, NULL); - restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL); - - g_debug ("Setting initial properties"); - - /* Program, CloneCommand, RestartCommand, and UserID are required. - * ProcessID isn't required, but the SM may be able to do something - * useful with it. - */ - g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ()); - set_properties (xsmp, - string_prop (SmProgram, g_get_prgname ()), - ptrarray_prop (SmCloneCommand, clone), - ptrarray_prop (SmRestartCommand, restart), - string_prop (SmUserID, g_get_user_name ()), - string_prop (SmProcessID, pid_str), - card8_prop (SmRestartStyleHint, xsmp->restart_style), - NULL); - g_ptr_array_free (clone, TRUE); - g_ptr_array_free (restart, TRUE); - - if (desktop_file) - { - set_properties (xsmp, - string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)), - NULL); - } - - update_pending_events (xsmp); - return FALSE; -} - -/* This gets called from two different places: xsmp_die() (when the - * server asks us to disconnect) and process_ice_messages() (when the - * server disconnects unexpectedly). - */ -static void -sm_client_xsmp_disconnect (EggSMClientXSMP *xsmp) -{ - SmcConn connection; - - if (!xsmp->connection) - return; - - g_debug ("Disconnecting"); - - connection = xsmp->connection; - xsmp->connection = NULL; - SmcCloseConnection (connection, 0, NULL); - xsmp->state = XSMP_STATE_CONNECTION_CLOSED; - - xsmp->waiting_to_save_myself = FALSE; - update_pending_events (xsmp); -} - -static void -sm_client_xsmp_startup (EggSMClient *client, - const char *client_id) -{ - EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; - SmcCallbacks callbacks; - char *ret_client_id; - char error_string_ret[256]; - - xsmp->client_id = g_strdup (client_id); - - ice_init (); - SmcSetErrorHandler (smc_error_handler); - - callbacks.save_yourself.callback = xsmp_save_yourself; - callbacks.die.callback = xsmp_die; - callbacks.save_complete.callback = xsmp_save_complete; - callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled; - - callbacks.save_yourself.client_data = xsmp; - callbacks.die.client_data = xsmp; - callbacks.save_complete.client_data = xsmp; - callbacks.shutdown_cancelled.client_data = xsmp; - - client_id = NULL; - error_string_ret[0] = '\0'; - xsmp->connection = - SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor, - SmcSaveYourselfProcMask | SmcDieProcMask | - SmcSaveCompleteProcMask | - SmcShutdownCancelledProcMask, - &callbacks, - xsmp->client_id, &ret_client_id, - sizeof (error_string_ret), error_string_ret); - - if (!xsmp->connection) - { - g_warning ("Failed to connect to the session manager: %s\n", - error_string_ret[0] ? - error_string_ret : "no error message given"); - xsmp->state = XSMP_STATE_CONNECTION_CLOSED; - return; - } - - /* We expect a pointless initial SaveYourself if either (a) we - * didn't have an initial client ID, or (b) we DID have an initial - * client ID, but the server rejected it and gave us a new one. - */ - if (!xsmp->client_id || - (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0)) - xsmp->expecting_initial_save_yourself = TRUE; - - if (ret_client_id) - { - g_free (xsmp->client_id); - xsmp->client_id = g_strdup (ret_client_id); - free (ret_client_id); - - gdk_x11_set_sm_client_id (xsmp->client_id); - - g_debug ("Got client ID \"%s\"", xsmp->client_id); - } - - xsmp->state = XSMP_STATE_IDLE; - - /* Do not set the initial properties until we reach the main loop, - * so that the application has a chance to call - * egg_set_desktop_file(). (This may also help the session manager - * have a better idea of when the application is fully up and - * running.) - */ - xsmp->waiting_to_set_initial_properties = TRUE; - xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client); -} - -static void -sm_client_xsmp_set_restart_command (EggSMClient *client, - int argc, - const char **argv) -{ - EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; - int i; - - g_strfreev (xsmp->restart_command); - - xsmp->restart_command = g_new (char *, argc + 1); - for (i = 0; i < argc; i++) - xsmp->restart_command[i] = g_strdup (argv[i]); - xsmp->restart_command[i] = NULL; - - xsmp->set_restart_command = TRUE; -} - -static void -sm_client_xsmp_will_quit (EggSMClient *client, - gboolean will_quit) -{ - EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; - - if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED) - { - /* The session manager has already exited! Schedule a quit - * signal. - */ - xsmp->waiting_to_emit_quit = TRUE; - update_pending_events (xsmp); - return; - } - else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) - { - /* We received a ShutdownCancelled message while the application - * was interacting; Schedule a quit_cancelled signal. - */ - xsmp->waiting_to_emit_quit_cancelled = TRUE; - update_pending_events (xsmp); - return; - } - - g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT); - - g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True"); - SmcInteractDone (xsmp->connection, !will_quit); - - if (will_quit && xsmp->need_save_state) - save_state (xsmp); - - g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False"); - SmcSaveYourselfDone (xsmp->connection, will_quit); - xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; -} - -static gboolean -sm_client_xsmp_end_session (EggSMClient *client, - EggSMClientEndStyle style, - gboolean request_confirmation) -{ - EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; - int save_type; - - /* To end the session via XSMP, we have to send a - * SaveYourselfRequest. We aren't allowed to do that if anything - * else is going on, but we don't want to expose this fact to the - * application. So we do our best to patch things up here... - * - * In the worst case, this method might block for some length of - * time in process_ice_messages, but the only time that code path is - * honestly likely to get hit is if the application tries to end the - * session as the very first thing it does, in which case it - * probably won't actually block anyway. It's not worth gunking up - * the API to try to deal nicely with the other 0.01% of cases where - * this happens. - */ - - while (xsmp->state != XSMP_STATE_IDLE || - xsmp->expecting_initial_save_yourself) - { - /* If we're already shutting down, we don't need to do anything. */ - if (xsmp->shutting_down) - return TRUE; - - switch (xsmp->state) - { - case XSMP_STATE_CONNECTION_CLOSED: - return FALSE; - - case XSMP_STATE_SAVE_YOURSELF: - /* Trying to log out from the save_state callback? Whatever. - * Abort the save_state. - */ - SmcSaveYourselfDone (xsmp->connection, FALSE); - xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; - break; - - case XSMP_STATE_INTERACT_REQUEST: - case XSMP_STATE_INTERACT: - case XSMP_STATE_SHUTDOWN_CANCELLED: - /* Already in a shutdown-related state, just ignore - * the new shutdown request... - */ - return TRUE; - - case XSMP_STATE_IDLE: - if (xsmp->waiting_to_set_initial_properties) - sm_client_xsmp_set_initial_properties (xsmp); - - if (!xsmp->expecting_initial_save_yourself) - break; - /* else fall through */ - - case XSMP_STATE_SAVE_YOURSELF_DONE: - /* We need to wait for some response from the server.*/ - process_ice_messages (SmcGetIceConnection (xsmp->connection)); - break; - - default: - /* Hm... shouldn't happen */ - return FALSE; - } - } - - /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and - * the user chooses to save the session. But mate-session will do - * the wrong thing if we pass SmSaveBoth and the user chooses NOT to - * save the session... Sigh. - */ - if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session")) - save_type = SmSaveBoth; - else - save_type = SmSaveGlobal; - - g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : ""); - SmcRequestSaveYourself (xsmp->connection, - save_type, - True, /* shutdown */ - SmInteractStyleAny, - !request_confirmation, /* fast */ - True /* global */); - return TRUE; -} - -static gboolean -idle_do_pending_events (gpointer data) -{ - EggSMClientXSMP *xsmp = data; - EggSMClient *client = data; - - xsmp->idle = 0; - - if (xsmp->waiting_to_emit_quit) - { - xsmp->waiting_to_emit_quit = FALSE; - egg_sm_client_quit (client); - goto out; - } - - if (xsmp->waiting_to_emit_quit_cancelled) - { - xsmp->waiting_to_emit_quit_cancelled = FALSE; - egg_sm_client_quit_cancelled (client); - xsmp->state = XSMP_STATE_IDLE; - } - - if (xsmp->waiting_to_save_myself) - { - xsmp->waiting_to_save_myself = FALSE; - do_save_yourself (xsmp); - } - - out: - return FALSE; -} - -static void -update_pending_events (EggSMClientXSMP *xsmp) -{ - gboolean want_idle = - xsmp->waiting_to_emit_quit || - xsmp->waiting_to_emit_quit_cancelled || - xsmp->waiting_to_save_myself; - - if (want_idle) - { - if (xsmp->idle == 0) - xsmp->idle = g_idle_add (idle_do_pending_events, xsmp); - } - else - { - if (xsmp->idle != 0) - g_source_remove (xsmp->idle); - xsmp->idle = 0; - } -} - -static void -fix_broken_state (EggSMClientXSMP *xsmp, const char *message, - gboolean send_interact_done, - gboolean send_save_yourself_done) -{ - g_warning ("Received XSMP %s message in state %s: client or server error", - message, EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - /* Forget any pending SaveYourself plans we had */ - xsmp->waiting_to_save_myself = FALSE; - update_pending_events (xsmp); - - if (send_interact_done) - SmcInteractDone (xsmp->connection, False); - if (send_save_yourself_done) - SmcSaveYourselfDone (xsmp->connection, True); - - xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE; -} - -/* SM callbacks */ - -static void -xsmp_save_yourself (SmcConn smc_conn, - SmPointer client_data, - int save_type, - Bool shutdown, - int interact_style, - Bool fast) -{ - EggSMClientXSMP *xsmp = client_data; - gboolean wants_quit_requested; - - g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s", - save_type == SmSaveLocal ? "SmSaveLocal" : - save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth", - shutdown ? "Shutdown" : "!Shutdown", - interact_style == SmInteractStyleAny ? "SmInteractStyleAny" : - interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" : - "SmInteractStyleNone", fast ? "Fast" : "!Fast", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - if (xsmp->state != XSMP_STATE_IDLE && - xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED) - { - fix_broken_state (xsmp, "SaveYourself", FALSE, TRUE); - return; - } - - if (xsmp->waiting_to_set_initial_properties) - sm_client_xsmp_set_initial_properties (xsmp); - - /* If this is the initial SaveYourself, ignore it; we've already set - * properties and there's no reason to actually save state too. - */ - if (xsmp->expecting_initial_save_yourself) - { - xsmp->expecting_initial_save_yourself = FALSE; - - if (save_type == SmSaveLocal && - interact_style == SmInteractStyleNone && - !shutdown && !fast) - { - g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself"); - SmcSaveYourselfDone (xsmp->connection, True); - /* As explained in the comment at the end of - * do_save_yourself(), SAVE_YOURSELF_DONE is the correct - * state here, not IDLE. - */ - xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; - return; - } - else - g_warning ("First SaveYourself was not the expected one!"); - } - - /* Even ignoring the "fast" flag completely, there are still 18 - * different combinations of save_type, shutdown and interact_style. - * We interpret them as follows: - * - * Type Shutdown Interact Interpretation - * G F A/E/N do nothing (1) - * G T N do nothing (1)* - * G T A/E quit_requested (2) - * L/B F A/E/N save_state (3) - * L/B T N save_state (3)* - * L/B T A/E quit_requested, then save_state (4) - * - * 1. Do nothing, because the SM asked us to do something - * uninteresting (save open files, but then don't quit - * afterward) or rude (save open files without asking the user - * for confirmation). - * - * 2. Request interaction and then emit ::quit_requested. This - * perhaps isn't quite correct for the SmInteractStyleErrors - * case, but we don't care. - * - * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these - * rows essentially get demoted to SmSaveLocal, because their - * Global halves correspond to "do nothing". - * - * 4. Request interaction, emit ::quit_requested, and then emit - * ::save_state after interacting. This is the SmSaveBoth - * equivalent of #2, but we also promote SmSaveLocal shutdown - * SaveYourselfs to SmSaveBoth here, because we want to give - * the user a chance to save open files before quitting. - * - * (* It would be nice if we could do something useful when the - * session manager sends a SaveYourself with shutdown True and - * SmInteractStyleNone. But we can't, so we just pretend it didn't - * even tell us it was shutting down. The docs for ::quit mention - * that it might not always be preceded by ::quit_requested.) - */ - - /* As an optimization, we don't actually request interaction and - * emit ::quit_requested if the application isn't listening to the - * signal. - */ - wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT), 0, FALSE); - - xsmp->need_save_state = (save_type != SmSaveGlobal); - xsmp->need_quit_requested = (shutdown && wants_quit_requested && - interact_style != SmInteractStyleNone); - xsmp->interact_errors = (interact_style == SmInteractStyleErrors); - - xsmp->shutting_down = shutdown; - - do_save_yourself (xsmp); -} - -static void -do_save_yourself (EggSMClientXSMP *xsmp) -{ - if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) - { - /* The SM cancelled a previous SaveYourself, but we haven't yet - * had a chance to tell the application, so we can't start - * processing this SaveYourself yet. - */ - xsmp->waiting_to_save_myself = TRUE; - update_pending_events (xsmp); - return; - } - - if (xsmp->need_quit_requested) - { - xsmp->state = XSMP_STATE_INTERACT_REQUEST; - - g_debug ("Sending InteractRequest(%s)", - xsmp->interact_errors ? "Error" : "Normal"); - SmcInteractRequest (xsmp->connection, - xsmp->interact_errors ? SmDialogError : SmDialogNormal, - xsmp_interact, - xsmp); - return; - } - - if (xsmp->need_save_state) - { - save_state (xsmp); - - /* Though unlikely, the client could have been disconnected - * while the application was saving its state. - */ - if (!xsmp->connection) - return; - } - - g_debug ("Sending SaveYourselfDone(True)"); - SmcSaveYourselfDone (xsmp->connection, True); - - /* The client state diagram in the XSMP spec says that after a - * non-shutdown SaveYourself, we go directly back to "idle". But - * everything else in both the XSMP spec and the libSM docs - * disagrees. - */ - xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; -} - -static void -save_state (EggSMClientXSMP *xsmp) -{ - GKeyFile *state_file; - char *state_file_path, *data; - EggDesktopFile *desktop_file; - GPtrArray *restart; - int offset, fd; - - /* We set xsmp->state before emitting save_state, but our caller is - * responsible for setting it back afterward. - */ - xsmp->state = XSMP_STATE_SAVE_YOURSELF; - - state_file = egg_sm_client_save_state ((EggSMClient *)xsmp); - if (!state_file) - { - restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL); - set_properties (xsmp, - ptrarray_prop (SmRestartCommand, restart), - NULL); - g_ptr_array_free (restart, TRUE); - delete_properties (xsmp, SmDiscardCommand, NULL); - return; - } - - desktop_file = egg_get_desktop_file (); - if (desktop_file) - { - GKeyFile *merged_file; - char *desktop_file_path; - - merged_file = g_key_file_new (); - desktop_file_path = - g_filename_from_uri (egg_desktop_file_get_source (desktop_file), - NULL, NULL); - if (desktop_file_path && - g_key_file_load_from_file (merged_file, desktop_file_path, - G_KEY_FILE_KEEP_COMMENTS | - G_KEY_FILE_KEEP_TRANSLATIONS, NULL)) - { - guint g, k, i; - char **groups, **keys, *value, *exec; - - groups = g_key_file_get_groups (state_file, NULL); - for (g = 0; groups[g]; g++) - { - keys = g_key_file_get_keys (state_file, groups[g], NULL, NULL); - for (k = 0; keys[k]; k++) - { - value = g_key_file_get_value (state_file, groups[g], - keys[k], NULL); - if (value) - { - g_key_file_set_value (merged_file, groups[g], - keys[k], value); - g_free (value); - } - } - g_strfreev (keys); - } - g_strfreev (groups); - - g_key_file_free (state_file); - state_file = merged_file; - - /* Update Exec key using "--sm-client-state-file %k" */ - restart = generate_command (xsmp->restart_command, - NULL, "%k"); - for (i = 0; i < restart->len; i++) - restart->pdata[i] = g_shell_quote (restart->pdata[i]); - g_ptr_array_add (restart, NULL); - exec = g_strjoinv (" ", (char **)restart->pdata); - g_strfreev ((char **)restart->pdata); - g_ptr_array_free (restart, FALSE); - - g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - exec); - g_free (exec); - } - else - desktop_file = NULL; - - g_free (desktop_file_path); - } - - /* Now write state_file to disk. (We can't use mktemp(), because - * that requires the filename to end with "XXXXXX", and we want - * it to end with ".desktop".) - */ - - data = g_key_file_to_data (state_file, NULL, NULL); - g_key_file_free (state_file); - - offset = 0; - while (1) - { - state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s", - g_get_user_config_dir (), - G_DIR_SEPARATOR, G_DIR_SEPARATOR, - g_get_prgname (), - (long)time (NULL) + offset, - desktop_file ? "desktop" : "state"); - - fd = open (state_file_path, O_WRONLY | O_CREAT | O_EXCL, 0644); - if (fd == -1) - { - if (errno == EEXIST) - { - offset++; - g_free (state_file_path); - continue; - } - else if (errno == ENOTDIR || errno == ENOENT) - { - char *sep = strrchr (state_file_path, G_DIR_SEPARATOR); - - *sep = '\0'; - if (g_mkdir_with_parents (state_file_path, 0755) != 0) - { - g_warning ("Could not create directory '%s'", - state_file_path); - g_free (state_file_path); - state_file_path = NULL; - break; - } - - continue; - } - - g_warning ("Could not create file '%s': %s", - state_file_path, g_strerror (errno)); - g_free (state_file_path); - state_file_path = NULL; - break; - } - - close (fd); - g_file_set_contents (state_file_path, data, -1, NULL); - break; - } - g_free (data); - - restart = generate_command (xsmp->restart_command, xsmp->client_id, - state_file_path); - set_properties (xsmp, - ptrarray_prop (SmRestartCommand, restart), - NULL); - g_ptr_array_free (restart, TRUE); - - if (state_file_path) - { - set_properties (xsmp, - array_prop (SmDiscardCommand, - "/bin/rm", "-rf", state_file_path, - NULL), - NULL); - g_free (state_file_path); - } -} - -static void -xsmp_interact (SmcConn smc_conn, - SmPointer client_data) -{ - EggSMClientXSMP *xsmp = client_data; - EggSMClient *client = client_data; - - g_debug ("Received Interact message in state %s", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - if (xsmp->state != XSMP_STATE_INTERACT_REQUEST) - { - fix_broken_state (xsmp, "Interact", TRUE, TRUE); - return; - } - - xsmp->state = XSMP_STATE_INTERACT; - egg_sm_client_quit_requested (client); -} - -static void -xsmp_die (SmcConn smc_conn, - SmPointer client_data) -{ - EggSMClientXSMP *xsmp = client_data; - EggSMClient *client = client_data; - - g_debug ("Received Die message in state %s", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - sm_client_xsmp_disconnect (xsmp); - egg_sm_client_quit (client); -} - -static void -xsmp_save_complete (SmcConn smc_conn, - SmPointer client_data) -{ - EggSMClientXSMP *xsmp = client_data; - - g_debug ("Received SaveComplete message in state %s", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE) - xsmp->state = XSMP_STATE_IDLE; - else - fix_broken_state (xsmp, "SaveComplete", FALSE, FALSE); -} - -static void -xsmp_shutdown_cancelled (SmcConn smc_conn, - SmPointer client_data) -{ - EggSMClientXSMP *xsmp = client_data; - EggSMClient *client = client_data; - - g_debug ("Received ShutdownCancelled message in state %s", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - xsmp->shutting_down = FALSE; - - if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE) - { - /* We've finished interacting and now the SM has agreed to - * cancel the shutdown. - */ - xsmp->state = XSMP_STATE_IDLE; - egg_sm_client_quit_cancelled (client); - } - else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) - { - /* Hm... ok, so we got a shutdown SaveYourself, which got - * cancelled, but the application was still interacting, so we - * didn't tell it yet, and then *another* SaveYourself arrived, - * which we must still be waiting to tell the app about, except - * that now that SaveYourself has been cancelled too! Dizzy yet? - */ - xsmp->waiting_to_save_myself = FALSE; - update_pending_events (xsmp); - } - else - { - g_debug ("Sending SaveYourselfDone(False)"); - SmcSaveYourselfDone (xsmp->connection, False); - - if (xsmp->state == XSMP_STATE_INTERACT) - { - /* The application is currently interacting, so we can't - * tell it about the cancellation yet; we will wait until - * after it calls egg_sm_client_will_quit(). - */ - xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED; - } - else - { - /* The shutdown was cancelled before the application got a - * chance to interact. - */ - xsmp->state = XSMP_STATE_IDLE; - } - } -} - -/* Utilities */ - -/* Create a restart/clone/Exec command based on @restart_command. - * If @client_id is non-%NULL, add "--sm-client-id @client_id". - * If @state_file is non-%NULL, add "--sm-client-state-file @state_file". - * - * None of the input strings are g_strdup()ed; the caller must keep - * them around until it is done with the returned GPtrArray, and must - * then free the array, but not its contents. - */ -static GPtrArray * -generate_command (char **restart_command, const char *client_id, - const char *state_file) -{ - GPtrArray *cmd; - int i; - - cmd = g_ptr_array_new (); - g_ptr_array_add (cmd, restart_command[0]); - - if (client_id) - { - g_ptr_array_add (cmd, (char *)"--sm-client-id"); - g_ptr_array_add (cmd, (char *)client_id); - } - - if (state_file) - { - g_ptr_array_add (cmd, (char *)"--sm-client-state-file"); - g_ptr_array_add (cmd, (char *)state_file); - } - - for (i = 1; restart_command[i]; i++) - g_ptr_array_add (cmd, restart_command[i]); - - return cmd; -} - -/* Takes a NULL-terminated list of SmProp * values, created by - * array_prop, ptrarray_prop, string_prop, card8_prop, sets them, and - * frees them. - */ -static void -set_properties (EggSMClientXSMP *xsmp, ...) -{ - GPtrArray *props; - SmProp *prop; - va_list ap; - guint i; - - props = g_ptr_array_new (); - - va_start (ap, xsmp); - while ((prop = va_arg (ap, SmProp *))) - g_ptr_array_add (props, prop); - va_end (ap); - - if (xsmp->connection) - { - SmcSetProperties (xsmp->connection, props->len, - (SmProp **)props->pdata); - } - - for (i = 0; i < props->len; i++) - { - prop = props->pdata[i]; - g_free (prop->vals); - g_free (prop); - } - g_ptr_array_free (props, TRUE); -} - -/* Takes a NULL-terminated list of property names and deletes them. */ -static void -delete_properties (EggSMClientXSMP *xsmp, ...) -{ - GPtrArray *props; - char *prop; - va_list ap; - - if (!xsmp->connection) - return; - - props = g_ptr_array_new (); - - va_start (ap, xsmp); - while ((prop = va_arg (ap, char *))) - g_ptr_array_add (props, prop); - va_end (ap); - - SmcDeleteProperties (xsmp->connection, props->len, - (char **)props->pdata); - - g_ptr_array_free (props, TRUE); -} - -/* Takes an array of strings and creates a LISTofARRAY8 property. The - * strings are neither dupped nor freed; they need to remain valid - * until you're done with the SmProp. - */ -static SmProp * -array_prop (const char *name, ...) -{ - SmProp *prop; - SmPropValue pv; - GArray *vals; - char *value; - va_list ap; - - prop = g_new (SmProp, 1); - prop->name = (char *)name; - prop->type = (char *)SmLISTofARRAY8; - - vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue)); - - va_start (ap, name); - while ((value = va_arg (ap, char *))) - { - pv.length = strlen (value); - pv.value = value; - g_array_append_val (vals, pv); - } - va_end (ap); - - prop->num_vals = vals->len; - prop->vals = (SmPropValue *)vals->data; - - g_array_free (vals, FALSE); - - return prop; -} - -/* Takes a GPtrArray of strings and creates a LISTofARRAY8 property. - * The array contents are neither dupped nor freed; they need to - * remain valid until you're done with the SmProp. - */ -static SmProp * -ptrarray_prop (const char *name, GPtrArray *values) -{ - SmProp *prop; - SmPropValue pv; - GArray *vals; - guint i; - - prop = g_new (SmProp, 1); - prop->name = (char *)name; - prop->type = (char *)SmLISTofARRAY8; - - vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue)); - - for (i = 0; i < values->len; i++) - { - pv.length = strlen (values->pdata[i]); - pv.value = values->pdata[i]; - g_array_append_val (vals, pv); - } - - prop->num_vals = vals->len; - prop->vals = (SmPropValue *)vals->data; - - g_array_free (vals, FALSE); - - return prop; -} - -/* Takes a string and creates an ARRAY8 property. The string is - * neither dupped nor freed; it needs to remain valid until you're - * done with the SmProp. - */ -static SmProp * -string_prop (const char *name, const char *value) -{ - SmProp *prop; - - prop = g_new (SmProp, 1); - prop->name = (char *)name; - prop->type = (char *)SmARRAY8; - - prop->num_vals = 1; - prop->vals = g_new (SmPropValue, 1); - - prop->vals[0].length = strlen (value); - prop->vals[0].value = (char *)value; - - return prop; -} - -/* Takes a char and creates a CARD8 property. */ -static SmProp * -card8_prop (const char *name, unsigned char value) -{ - SmProp *prop; - char *card8val; - - /* To avoid having to allocate and free prop->vals[0], we cheat and - * make vals a 2-element-long array and then use the second element - * to store value. - */ - - prop = g_new (SmProp, 1); - prop->name = (char *)name; - prop->type = (char *)SmCARD8; - - prop->num_vals = 1; - prop->vals = g_new (SmPropValue, 2); - card8val = (char *)(&prop->vals[1]); - card8val[0] = value; - - prop->vals[0].length = 1; - prop->vals[0].value = card8val; - - return prop; -} - -/* ICE code. This makes no effort to play nice with anyone else trying - * to use libICE. Fortunately, no one uses libICE for anything other - * than SM. (DCOP uses ICE, but it has its own private copy of - * libICE.) - * - * When this moves to gtk, it will need to be cleverer, to avoid - * tripping over old apps that use MateClient or that use libSM - * directly. - */ - -#include -#include - -static void ice_error_handler (IceConn ice_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence, - int error_class, - int severity, - IcePointer values); -static void ice_io_error_handler (IceConn ice_conn); -static void ice_connection_watch (IceConn ice_conn, - IcePointer client_data, - Bool opening, - IcePointer *watch_data); - -static void -ice_init (void) -{ - IceSetIOErrorHandler (ice_io_error_handler); - IceSetErrorHandler (ice_error_handler); - IceAddConnectionWatch (ice_connection_watch, NULL); -} - -static gboolean -process_ice_messages (IceConn ice_conn) -{ - IceProcessMessagesStatus status; - - status = IceProcessMessages (ice_conn, NULL, NULL); - - switch (status) - { - case IceProcessMessagesSuccess: - return TRUE; - - case IceProcessMessagesIOError: - sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn)); - return FALSE; - - case IceProcessMessagesConnectionClosed: - return FALSE; - - default: - g_assert_not_reached (); - } -} - -static gboolean -ice_iochannel_watch (GIOChannel *channel, - GIOCondition condition, - gpointer client_data) -{ - return process_ice_messages (client_data); -} - -static void -ice_connection_watch (IceConn ice_conn, - IcePointer client_data, - Bool opening, - IcePointer *watch_data) -{ - guint watch_id; - - if (opening) - { - GIOChannel *channel; - int fd = IceConnectionNumber (ice_conn); - - fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC); - channel = g_io_channel_unix_new (fd); - watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR, - ice_iochannel_watch, ice_conn); - g_io_channel_unref (channel); - - *watch_data = GUINT_TO_POINTER (watch_id); - } - else - { - watch_id = GPOINTER_TO_UINT (*watch_data); - g_source_remove (watch_id); - } -} - -static void -ice_error_handler (IceConn ice_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence, - int error_class, - int severity, - IcePointer values) -{ - /* Do nothing */ -} - -static void -ice_io_error_handler (IceConn ice_conn) -{ - /* Do nothing */ -} - -static void -smc_error_handler (SmcConn smc_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence, - int error_class, - int severity, - SmPointer values) -{ - /* Do nothing */ -} diff --git a/xed/smclient/eggsmclient.c b/xed/smclient/eggsmclient.c deleted file mode 100644 index 4fc64da..0000000 --- a/xed/smclient/eggsmclient.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (C) 2007 Novell, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library 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 "config.h" - -#include -#include - -#include "eggsmclient.h" -#include "eggsmclient-private.h" - -static void egg_sm_client_debug_handler (const char *log_domain, - GLogLevelFlags log_level, - const char *message, - gpointer user_data); - -enum { - SAVE_STATE, - QUIT_REQUESTED, - QUIT_CANCELLED, - QUIT, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -struct _EggSMClientPrivate { - GKeyFile *state_file; -}; - -#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate)) - -G_DEFINE_TYPE (EggSMClient, egg_sm_client, G_TYPE_OBJECT) - -static EggSMClient *global_client; -static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL; - -static void -egg_sm_client_init (EggSMClient *client) -{ - ; -} - -static void -egg_sm_client_class_init (EggSMClientClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (EggSMClientPrivate)); - - /** - * EggSMClient::save_state: - * @client: the client - * @state_file: a #GKeyFile to save state information into - * - * Emitted when the session manager has requested that the - * application save information about its current state. The - * application should save its state into @state_file, and then the - * session manager may then restart the application in a future - * session and tell it to initialize itself from that state. - * - * You should not save any data into @state_file's "start group" - * (ie, the %NULL group). Instead, applications should save their - * data into groups with names that start with the application name, - * and libraries that connect to this signal should save their data - * into groups with names that start with the library name. - * - * Alternatively, rather than (or in addition to) using @state_file, - * the application can save its state by calling - * egg_sm_client_set_restart_command() during the processing of this - * signal (eg, to include a list of files to open). - **/ - signals[SAVE_STATE] = - g_signal_new ("save_state", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggSMClientClass, save_state), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, G_TYPE_POINTER); - - /** - * EggSMClient::quit_requested: - * @client: the client - * - * Emitted when the session manager requests that the application - * exit (generally because the user is logging out). The application - * should decide whether or not it is willing to quit (perhaps after - * asking the user what to do with documents that have unsaved - * changes) and then call egg_sm_client_will_quit(), passing %TRUE - * or %FALSE to give its answer to the session manager. (It does not - * need to give an answer before returning from the signal handler; - * it can interact with the user asynchronously and then give its - * answer later on.) If the application does not connect to this - * signal, then #EggSMClient will automatically return %TRUE on its - * behalf. - * - * The application should not save its session state as part of - * handling this signal; if the user has requested that the session - * be saved when logging out, then ::save_state will be emitted - * separately. - * - * If the application agrees to quit, it should then wait for either - * the ::quit_cancelled or ::quit signals to be emitted. - **/ - signals[QUIT_REQUESTED] = - g_signal_new ("quit_requested", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggSMClientClass, quit_requested), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - /** - * EggSMClient::quit_cancelled: - * @client: the client - * - * Emitted when the session manager decides to cancel a logout after - * the application has already agreed to quit. After receiving this - * signal, the application can go back to what it was doing before - * receiving the ::quit_requested signal. - **/ - signals[QUIT_CANCELLED] = - g_signal_new ("quit_cancelled", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - /** - * EggSMClient::quit: - * @client: the client - * - * Emitted when the session manager wants the application to quit - * (generally because the user is logging out). The application - * should exit as soon as possible after receiving this signal; if - * it does not, the session manager may choose to forcibly kill it. - * - * Normally a GUI application would only be sent a ::quit if it - * agreed to quit in response to a ::quit_requested signal. However, - * this is not guaranteed; in some situations the session manager - * may decide to end the session without giving applications a - * chance to object. - **/ - signals[QUIT] = - g_signal_new ("quit", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggSMClientClass, quit), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} - -static gboolean sm_client_disable = FALSE; -static char *sm_client_state_file = NULL; -static char *sm_client_id = NULL; -static char *sm_config_prefix = NULL; - -static gboolean -sm_client_post_parse_func (GOptionContext *context, - GOptionGroup *group, - gpointer data, - GError **error) -{ - EggSMClient *client = egg_sm_client_get (); - - if (sm_client_id == NULL) - { - const gchar *desktop_autostart_id; - - desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID"); - - if (desktop_autostart_id != NULL) - sm_client_id = g_strdup (desktop_autostart_id); - } - - /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to - * use the same client id. */ - g_unsetenv ("DESKTOP_AUTOSTART_ID"); - - if (EGG_SM_CLIENT_GET_CLASS (client)->startup) - EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id); - return TRUE; -} - -/** - * egg_sm_client_get_option_group: - * - * Creates a %GOptionGroup containing the session-management-related - * options. You should add this group to the application's - * %GOptionContext if you want to use #EggSMClient. - * - * Return value: the %GOptionGroup - **/ -GOptionGroup * -egg_sm_client_get_option_group (void) -{ - const GOptionEntry entries[] = { - { "sm-client-disable", 0, 0, - G_OPTION_ARG_NONE, &sm_client_disable, - N_("Disable connection to session manager"), NULL }, - { "sm-client-state-file", 0, 0, - G_OPTION_ARG_FILENAME, &sm_client_state_file, - N_("Specify file containing saved configuration"), N_("FILE") }, - { "sm-client-id", 0, 0, - G_OPTION_ARG_STRING, &sm_client_id, - N_("Specify session management ID"), N_("ID") }, - /* MateClient compatibility option */ - { "sm-disable", 0, G_OPTION_FLAG_HIDDEN, - G_OPTION_ARG_NONE, &sm_client_disable, - NULL, NULL }, - /* MateClient compatibility option. This is a dummy option that only - * exists so that sessions saved by apps with MateClient can be restored - * later when they've switched to EggSMClient. See bug #575308. - */ - { "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN, - G_OPTION_ARG_STRING, &sm_config_prefix, - NULL, NULL }, - { NULL } - }; - GOptionGroup *group; - - /* Use our own debug handler for the "EggSMClient" domain. */ - g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, - egg_sm_client_debug_handler, NULL); - - group = g_option_group_new ("sm-client", - _("Session management options:"), - _("Show session management options"), - NULL, NULL); - g_option_group_add_entries (group, entries); - g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func); - - return group; -} - -/** - * egg_sm_client_set_mode: - * @mode: an #EggSMClient mode - * - * Sets the "mode" of #EggSMClient as follows: - * - * %EGG_SM_CLIENT_MODE_DISABLED: Session management is completely - * disabled. The application will not even connect to the session - * manager. (egg_sm_client_get() will still return an #EggSMClient, - * but it will just be a dummy object.) - * - * %EGG_SM_CLIENT_MODE_NO_RESTART: The application will connect to - * the session manager (and thus will receive notification when the - * user is logging out, etc), but will request to not be - * automatically restarted with saved state in future sessions. - * - * %EGG_SM_CLIENT_MODE_NORMAL: The default. #EggSMCLient will - * function normally. - * - * This must be called before the application's main loop begins. - **/ -void -egg_sm_client_set_mode (EggSMClientMode mode) -{ - global_client_mode = mode; -} - -/** - * egg_sm_client_get_mode: - * - * Gets the global #EggSMClientMode. See egg_sm_client_set_mode() - * for details. - * - * Return value: the global #EggSMClientMode - **/ -EggSMClientMode -egg_sm_client_get_mode (void) -{ - return global_client_mode; -} - -/** - * egg_sm_client_get: - * - * Returns the master #EggSMClient for the application. - * - * On platforms that support saved sessions (ie, POSIX/X11), the - * application will only request to be restarted by the session - * manager if you call egg_set_desktop_file() to set an application - * desktop file. In particular, if the desktop file contains the key - * "X - * - * Return value: the master #EggSMClient. - **/ -EggSMClient * -egg_sm_client_get (void) -{ - if (!global_client) - { - if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED && - !sm_client_disable) - { - global_client = egg_sm_client_xsmp_new (); - } - - /* Fallback: create a dummy client, so that callers don't have - * to worry about a %NULL return value. - */ - if (!global_client) - global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL); - } - - return global_client; -} - -/** - * egg_sm_client_is_resumed: - * @client: the client - * - * Checks whether or not the current session has been resumed from - * a previous saved session. If so, the application should call - * egg_sm_client_get_state_file() and restore its state from the - * returned #GKeyFile. - * - * Return value: %TRUE if the session has been resumed - **/ -gboolean -egg_sm_client_is_resumed (EggSMClient *client) -{ - g_return_val_if_fail (client == global_client, FALSE); - - return sm_client_state_file != NULL; -} - -/** - * egg_sm_client_get_state_file: - * @client: the client - * - * If the application was resumed by the session manager, this will - * return the #GKeyFile containing its state from the previous - * session. - * - * Note that other libraries and #EggSMClient itself may also store - * state in the key file, so if you call egg_sm_client_get_groups(), - * on it, the return value will likely include groups that you did not - * put there yourself. (It is also not guaranteed that the first - * group created by the application will still be the "start group" - * when it is resumed.) - * - * Return value: the #GKeyFile containing the application's earlier - * state, or %NULL on error. You should not free this key file; it - * is owned by @client. - **/ -GKeyFile * -egg_sm_client_get_state_file (EggSMClient *client) -{ - EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client); - char *state_file_path; - GError *err = NULL; - - g_return_val_if_fail (client == global_client, NULL); - - if (!sm_client_state_file) - return NULL; - if (priv->state_file) - return priv->state_file; - - if (!strncmp (sm_client_state_file, "file://", 7)) - state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL); - else - state_file_path = g_strdup (sm_client_state_file); - - priv->state_file = g_key_file_new (); - if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err)) - { - g_warning ("Could not load SM state file '%s': %s", - sm_client_state_file, err->message); - g_clear_error (&err); - g_key_file_free (priv->state_file); - priv->state_file = NULL; - } - - g_free (state_file_path); - return priv->state_file; -} - -/** - * egg_sm_client_set_restart_command: - * @client: the client - * @argc: the length of @argv - * @argv: argument vector - * - * Sets the command used to restart @client if it does not have a - * .desktop file that can be used to find its restart command. - * - * This can also be used when handling the ::save_state signal, to - * save the current state via an updated command line. (Eg, providing - * a list of filenames to open when the application is resumed.) - **/ -void -egg_sm_client_set_restart_command (EggSMClient *client, - int argc, - const char **argv) -{ - g_return_if_fail (EGG_IS_SM_CLIENT (client)); - - if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command) - EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv); -} - -/** - * egg_sm_client_will_quit: - * @client: the client - * @will_quit: whether or not the application is willing to quit - * - * This MUST be called in response to the ::quit_requested signal, to - * indicate whether or not the application is willing to quit. The - * application may call it either directly from the signal handler, or - * at some later point (eg, after asynchronously interacting with the - * user). - * - * If the application does not connect to ::quit_requested, - * #EggSMClient will call this method on its behalf (passing %TRUE - * for @will_quit). - * - * After calling this method, the application should wait to receive - * either ::quit_cancelled or ::quit. - **/ -void -egg_sm_client_will_quit (EggSMClient *client, - gboolean will_quit) -{ - g_return_if_fail (EGG_IS_SM_CLIENT (client)); - - if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit) - EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit); -} - -/** - * egg_sm_client_end_session: - * @style: a hint at how to end the session - * @request_confirmation: whether or not the user should get a chance - * to confirm the action - * - * Requests that the session manager end the current session. @style - * indicates how the session should be ended, and - * @request_confirmation indicates whether or not the user should be - * given a chance to confirm the logout/reboot/shutdown. Both of these - * flags are merely hints though; the session manager may choose to - * ignore them. - * - * Return value: %TRUE if the request was sent; %FALSE if it could not - * be (eg, because it could not connect to the session manager). - **/ -gboolean -egg_sm_client_end_session (EggSMClientEndStyle style, - gboolean request_confirmation) -{ - EggSMClient *client = egg_sm_client_get (); - - g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE); - - if (EGG_SM_CLIENT_GET_CLASS (client)->end_session) - { - return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style, - request_confirmation); - } - else - return FALSE; -} - -/* Signal-emitting callbacks from platform-specific code */ - -GKeyFile * -egg_sm_client_save_state (EggSMClient *client) -{ - GKeyFile *state_file; - char *group; - - g_return_val_if_fail (client == global_client, NULL); - - state_file = g_key_file_new (); - - g_debug ("Emitting save_state"); - g_signal_emit (client, signals[SAVE_STATE], 0, state_file); - g_debug ("Done emitting save_state"); - - group = g_key_file_get_start_group (state_file); - if (group) - { - g_free (group); - return state_file; - } - else - { - g_key_file_free (state_file); - return NULL; - } -} - -void -egg_sm_client_quit_requested (EggSMClient *client) -{ - g_return_if_fail (client == global_client); - - if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE)) - { - g_debug ("Not emitting quit_requested because no one is listening"); - egg_sm_client_will_quit (client, TRUE); - return; - } - - g_debug ("Emitting quit_requested"); - g_signal_emit (client, signals[QUIT_REQUESTED], 0); - g_debug ("Done emitting quit_requested"); -} - -void -egg_sm_client_quit_cancelled (EggSMClient *client) -{ - g_return_if_fail (client == global_client); - - g_debug ("Emitting quit_cancelled"); - g_signal_emit (client, signals[QUIT_CANCELLED], 0); - g_debug ("Done emitting quit_cancelled"); -} - -void -egg_sm_client_quit (EggSMClient *client) -{ - g_return_if_fail (client == global_client); - - g_debug ("Emitting quit"); - g_signal_emit (client, signals[QUIT], 0); - g_debug ("Done emitting quit"); - - /* FIXME: should we just call gtk_main_quit() here? */ -} - -static void -egg_sm_client_debug_handler (const char *log_domain, - GLogLevelFlags log_level, - const char *message, - gpointer user_data) -{ - static int debug = -1; - - if (debug < 0) - debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL); - - if (debug) - g_log_default_handler (log_domain, log_level, message, NULL); -} diff --git a/xed/smclient/eggsmclient.h b/xed/smclient/eggsmclient.h deleted file mode 100644 index d87f670..0000000 --- a/xed/smclient/eggsmclient.h +++ /dev/null @@ -1,117 +0,0 @@ -/* eggsmclient.h - * Copyright (C) 2007 Novell, Inc. - * - * 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 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 __EGG_SM_CLIENT_H__ -#define __EGG_SM_CLIENT_H__ - -#include - -G_BEGIN_DECLS - -#define EGG_TYPE_SM_CLIENT (egg_sm_client_get_type ()) -#define EGG_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT, EggSMClient)) -#define EGG_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT, EggSMClientClass)) -#define EGG_IS_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT)) -#define EGG_IS_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT)) -#define EGG_SM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT, EggSMClientClass)) - -typedef struct _EggSMClient EggSMClient; -typedef struct _EggSMClientClass EggSMClientClass; -typedef struct _EggSMClientPrivate EggSMClientPrivate; - -typedef enum { - EGG_SM_CLIENT_END_SESSION_DEFAULT, - EGG_SM_CLIENT_LOGOUT, - EGG_SM_CLIENT_REBOOT, - EGG_SM_CLIENT_SHUTDOWN -} EggSMClientEndStyle; - -typedef enum { - EGG_SM_CLIENT_MODE_DISABLED, - EGG_SM_CLIENT_MODE_NO_RESTART, - EGG_SM_CLIENT_MODE_NORMAL -} EggSMClientMode; - -struct _EggSMClient -{ - GObject parent; - -}; - -struct _EggSMClientClass -{ - GObjectClass parent_class; - - /* signals */ - void (*save_state) (EggSMClient *client, - GKeyFile *state_file); - - void (*quit_requested) (EggSMClient *client); - void (*quit_cancelled) (EggSMClient *client); - void (*quit) (EggSMClient *client); - - /* virtual methods */ - void (*startup) (EggSMClient *client, - const char *client_id); - void (*set_restart_command) (EggSMClient *client, - int argc, - const char **argv); - void (*will_quit) (EggSMClient *client, - gboolean will_quit); - gboolean (*end_session) (EggSMClient *client, - EggSMClientEndStyle style, - gboolean request_confirmation); - - /* Padding for future expansion */ - void (*_egg_reserved1) (void); - void (*_egg_reserved2) (void); - void (*_egg_reserved3) (void); - void (*_egg_reserved4) (void); -}; - -GType egg_sm_client_get_type (void) G_GNUC_CONST; - -GOptionGroup *egg_sm_client_get_option_group (void); - -/* Initialization */ -void egg_sm_client_set_mode (EggSMClientMode mode); -EggSMClientMode egg_sm_client_get_mode (void); -EggSMClient *egg_sm_client_get (void); - -/* Resuming a saved session */ -gboolean egg_sm_client_is_resumed (EggSMClient *client); -GKeyFile *egg_sm_client_get_state_file (EggSMClient *client); - -/* Alternate means of saving state */ -void egg_sm_client_set_restart_command (EggSMClient *client, - int argc, - const char **argv); - -/* Handling "quit_requested" signal */ -void egg_sm_client_will_quit (EggSMClient *client, - gboolean will_quit); - -/* Initiate a logout/reboot/shutdown */ -gboolean egg_sm_client_end_session (EggSMClientEndStyle style, - gboolean request_confirmation); - -G_END_DECLS - - -#endif /* __EGG_SM_CLIENT_H__ */ diff --git a/xed/xed-app-activatable.c b/xed/xed-app-activatable.c new file mode 100644 index 0000000..086e0c9 --- /dev/null +++ b/xed/xed-app-activatable.c @@ -0,0 +1,108 @@ +/* + * xed-app-activatable.h + * This file is part of xed + * + * Copyright (C) 2010 Steve Frécinaux + * Copyright (C) 2010 Jesse van den Kieboom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xed-app-activatable.h" +#include "xed-app.h" + +/** + * SECTION:xed-app-activatable + * @short_description: Interface for activatable extensions on apps + * @see_also: #PeasExtensionSet + * + * #XedAppActivatable is an interface which should be implemented by + * extensions that should be activated on a xed application. + **/ + +G_DEFINE_INTERFACE(XedAppActivatable, xed_app_activatable, G_TYPE_OBJECT) + +void +xed_app_activatable_default_init (XedAppActivatableInterface *iface) +{ + static gboolean initialized = FALSE; + + if (!initialized) + { + /** + * XedAppActivatable:app: + * + * The app property contains the xed app for this + * #XedAppActivatable instance. + */ + g_object_interface_install_property (iface, + g_param_spec_object ("app", + "App", + "The xed app", + XED_TYPE_APP, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + initialized = TRUE; + } +} + +/** + * xed_app_activatable_activate: + * @activatable: A #XedAppActivatable. + * + * Activates the extension on the application. + */ +void +xed_app_activatable_activate (XedAppActivatable *activatable) +{ + XedAppActivatableInterface *iface; + + g_return_if_fail (XED_IS_APP_ACTIVATABLE (activatable)); + + iface = XED_APP_ACTIVATABLE_GET_IFACE (activatable); + + if (iface->activate != NULL) + { + iface->activate (activatable); + } +} + +/** + * xed_app_activatable_deactivate: + * @activatable: A #XedAppActivatable. + * + * Deactivates the extension from the application. + * + */ +void +xed_app_activatable_deactivate (XedAppActivatable *activatable) +{ + XedAppActivatableInterface *iface; + + g_return_if_fail (XED_IS_APP_ACTIVATABLE (activatable)); + + iface = XED_APP_ACTIVATABLE_GET_IFACE (activatable); + + if (iface->deactivate != NULL) + { + iface->deactivate (activatable); + } +} diff --git a/xed/xed-app-activatable.h b/xed/xed-app-activatable.h new file mode 100644 index 0000000..19dca02 --- /dev/null +++ b/xed/xed-app-activatable.h @@ -0,0 +1,61 @@ +/* + * xed-app-activatable.h + * This file is part of xed + * + * Copyright (C) 2010 - Steve Frécinaux + * Copyright (C) 2010 - Jesse van den Kieboom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __XED_APP_ACTIVATABLE_H__ +#define __XED_APP_ACTIVATABLE_H__ + +#include + +G_BEGIN_DECLS + +/* + * Type checking and casting macros + */ +#define XED_TYPE_APP_ACTIVATABLE (xed_app_activatable_get_type ()) +#define XED_APP_ACTIVATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_APP_ACTIVATABLE, XedAppActivatable)) +#define XED_APP_ACTIVATABLE_IFACE(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), XED_TYPE_APP_ACTIVATABLE, XedAppActivatableInterface)) +#define XED_IS_APP_ACTIVATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_APP_ACTIVATABLE)) +#define XED_APP_ACTIVATABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), XED_TYPE_APP_ACTIVATABLE, XedAppActivatableInterface)) + +typedef struct _XedAppActivatable XedAppActivatable; /* dummy typedef */ +typedef struct _XedAppActivatableInterface XedAppActivatableInterface; + +struct _XedAppActivatableInterface +{ + GTypeInterface g_iface; + + /* Virtual public methods */ + void (*activate) (XedAppActivatable *activatable); + void (*deactivate) (XedAppActivatable *activatable); +}; + +/* + * Public methods + */ +GType xed_app_activatable_get_type (void) G_GNUC_CONST; + +void xed_app_activatable_activate (XedAppActivatable *activatable); +void xed_app_activatable_deactivate (XedAppActivatable *activatable); + +G_END_DECLS + +#endif /* __XED_APP_ACTIVATABLE_H__ */ diff --git a/xed/xed-app.c b/xed/xed-app.c index 25d4673..ffb202c 100644 --- a/xed/xed-app.c +++ b/xed/xed-app.c @@ -34,498 +34,992 @@ #include #include +#include #include +#include +#include + +#ifdef ENABLE_INTROSPECTION +#include +#endif #include "xed-app.h" -#include "xed-prefs-manager-app.h" #include "xed-commands.h" #include "xed-notebook.h" #include "xed-debug.h" #include "xed-utils.h" #include "xed-enum-types.h" #include "xed-dirs.h" +#include "xed-app-activatable.h" +#include "xed-plugins-engine.h" +#include "xed-settings.h" -#define XED_PAGE_SETUP_FILE "xed-page-setup" -#define XED_PRINT_SETTINGS_FILE "xed-print-settings" +#ifndef ENABLE_GVFS_METADATA +#include "xed-metadata-manager.h" +#define METADATA_FILE "xed-metadata.xml" +#endif + +#define XED_PAGE_SETUP_FILE "xed-page-setup" +#define XED_PRINT_SETTINGS_FILE "xed-print-settings" #define XED_APP_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_APP, XedAppPrivate)) /* Properties */ enum { - PROP_0, + PROP_0, }; struct _XedAppPrivate { - GList *windows; - XedWindow *active_window; - GtkPageSetup *page_setup; - GtkPrintSettings *print_settings; + XedPluginsEngine *engine; + + GtkPageSetup *page_setup; + GtkPrintSettings *print_settings; + + GObject *settings; + GSettings *window_settings; + GSettings *editor_settings; + + PeasExtensionSet *extensions; + + /* command line parsing */ + gboolean new_window; + gboolean new_document; + gchar *geometry; + const GtkSourceEncoding *encoding; + GInputStream *stdin_stream; + GSList *file_list; + gint line_position; + GApplicationCommandLine *command_line; }; -G_DEFINE_TYPE(XedApp, xed_app, G_TYPE_OBJECT) +G_DEFINE_TYPE (XedApp, xed_app, GTK_TYPE_APPLICATION) + +static const GOptionEntry options[] = +{ + /* Version */ + { + "version", 'V', 0, G_OPTION_ARG_NONE, NULL, + N_("Show the application's version"), NULL + }, + + /* List available encodings */ + { + "list-encodings", '\0', 0, G_OPTION_ARG_NONE, NULL, + N_("Display list of possible values for the encoding option"), + NULL + }, + + /* Encoding */ + { + "encoding", '\0', 0, G_OPTION_ARG_STRING, NULL, + N_("Set the character encoding to be used to open the files listed on the command line"), + N_("ENCODING") + }, + + /* Open a new window */ + { + "new-window", '\0', 0, G_OPTION_ARG_NONE, NULL, + N_("Create a new top-level window in an existing instance of xed"), + NULL + }, + + /* Create a new empty document */ + { + "new-document", '\0', 0, G_OPTION_ARG_NONE, NULL, + N_("Create a new document in an existing instance of xed"), + NULL + }, + + /* Window geometry */ + { + "geometry", 'g', 0, G_OPTION_ARG_STRING, NULL, + N_("Set the size and position of the window (WIDTHxHEIGHT+X+Y)"), + N_("GEOMETRY") + }, + + /* Wait for closing documents */ + { + "wait", 'w', 0, G_OPTION_ARG_NONE, NULL, + N_("Open files and block process until files are closed"), + NULL + }, + + /* New instance */ + { + "standalone", 's', 0, G_OPTION_ARG_NONE, NULL, + N_("Run xed in standalone mode"), + NULL + }, + + /* collects file arguments */ + { + G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL, NULL, + N_("[FILE...] [+LINE]") + }, + + {NULL} +}; static void -xed_app_finalize (GObject *object) +xed_app_dispose (GObject *object) { - XedApp *app = XED_APP (object); + XedApp *app = XED_APP (object); - g_list_free (app->priv->windows); + g_clear_object (&app->priv->window_settings); + g_clear_object (&app->priv->editor_settings); + g_clear_object (&app->priv->settings); + g_clear_object (&app->priv->page_setup); + g_clear_object (&app->priv->print_settings); + g_clear_object (&app->priv->extensions); + g_clear_object (&app->priv->engine); - if (app->priv->page_setup) - g_object_unref (app->priv->page_setup); - if (app->priv->print_settings) - g_object_unref (app->priv->print_settings); - - G_OBJECT_CLASS (xed_app_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_app_parent_class)->dispose (object); } static void xed_app_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedApp *app = XED_APP (object); - - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -xed_app_class_init (XedAppClass *klass) +extension_added (PeasExtensionSet *extensions, + PeasPluginInfo *info, + PeasExtension *exten, + XedApp *app) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + peas_extension_call (exten, "activate"); +} - object_class->finalize = xed_app_finalize; - object_class->get_property = xed_app_get_property; +static void +extension_removed (PeasExtensionSet *extensions, + PeasPluginInfo *info, + PeasExtension *exten, + XedApp *app) +{ + peas_extension_call (exten, "deactivate"); +} - g_type_class_add_private (object_class, sizeof(XedAppPrivate)); +static void +set_initial_theme_style (XedApp *app) +{ + if (g_settings_get_boolean (app->priv->editor_settings, XED_SETTINGS_PREFER_DARK_THEME)) + { + GtkSettings *gtk_settings; + + gtk_settings = gtk_settings_get_default (); + g_object_set (G_OBJECT (gtk_settings), "gtk-application-prefer-dark-theme", TRUE, NULL); + } +} + +static void +xed_app_startup (GApplication *application) +{ + XedApp *app = XED_APP (application); + GtkSourceStyleSchemeManager *manager; + const gchar *dir; + gchar *icon_dir; +#ifndef ENABLE_GVFS_METADATA + const gchar *cache_dir; + gchar *metadata_filename; +#endif + + G_APPLICATION_CLASS (xed_app_parent_class)->startup (application); + + /* Setup debugging */ + xed_debug_init (); + xed_debug_message (DEBUG_APP, "Startup"); + xed_debug_message (DEBUG_APP, "Set icon"); + + dir = xed_dirs_get_xed_data_dir (); + icon_dir = g_build_filename (dir, "icons", NULL); + + gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), icon_dir); + g_free (icon_dir); + +#ifndef ENABLE_GVFS_METADATA + /* Setup metadata-manager */ + cache_dir = xed_dirs_get_user_cache_dir (); + + metadata_filename = g_build_filename (cache_dir, METADATA_FILE, NULL); + + xed_metadata_manager_init (metadata_filename); + + g_free (metadata_filename); +#endif + + /* Load settings */ + app->priv->settings = xed_settings_new (); + app->priv->window_settings = g_settings_new ("org.x.editor.state.window"); + app->priv->editor_settings = g_settings_new ("org.x.editor.preferences.editor"); + + set_initial_theme_style (app); + + /* + * We use the default gtksourceview style scheme manager so that plugins + * can obtain it easily without a xed specific api, but we need to + * add our search path at startup before the manager is actually used. + */ + manager = gtk_source_style_scheme_manager_get_default (); + gtk_source_style_scheme_manager_append_search_path (manager, xed_dirs_get_user_styles_dir ()); + + app->priv->engine = xed_plugins_engine_get_default (); + app->priv->extensions = peas_extension_set_new (PEAS_ENGINE (app->priv->engine), + XED_TYPE_APP_ACTIVATABLE, + "app", app, + NULL); + + g_signal_connect (app->priv->extensions, "extension-added", + G_CALLBACK (extension_added), app); + + g_signal_connect (app->priv->extensions, "extension-removed", + G_CALLBACK (extension_removed), app); + + peas_extension_set_foreach (app->priv->extensions, + (PeasExtensionSetForeachFunc) extension_added, + app); +} + +static gboolean +is_in_viewport (GtkWindow *window, + GdkScreen *screen, + gint workspace, + gint viewport_x, + gint viewport_y) +{ + GdkScreen *s; + GdkDisplay *display; + GdkWindow *gdkwindow; + const gchar *cur_name; + const gchar *name; + gint cur_n; + gint n; + gint ws; + gint sc_width, sc_height; + gint x, y, width, height; + gint vp_x, vp_y; + + /* Check for screen and display match */ + display = gdk_screen_get_display (screen); + cur_name = gdk_display_get_name (display); + cur_n = gdk_screen_get_number (screen); + + s = gtk_window_get_screen (window); + display = gdk_screen_get_display (s); + name = gdk_display_get_name (display); + n = gdk_screen_get_number (s); + + if (strcmp (cur_name, name) != 0 || cur_n != n) + { + return FALSE; + } + + /* Check for workspace match */ + ws = xed_utils_get_window_workspace (window); + if (ws != workspace && ws != XED_ALL_WORKSPACES) + { + return FALSE; + } + + /* Check for viewport match */ + gdkwindow = gtk_widget_get_window (GTK_WIDGET (window)); + gdk_window_get_position (gdkwindow, &x, &y); + width = gdk_window_get_width (gdkwindow); + height = gdk_window_get_height (gdkwindow); + xed_utils_get_current_viewport (screen, &vp_x, &vp_y); + x += vp_x; + y += vp_y; + + sc_width = gdk_screen_get_width (screen); + sc_height = gdk_screen_get_height (screen); + + return x + width * .25 >= viewport_x && + x + width * .75 <= viewport_x + sc_width && + y >= viewport_y && + y + height <= viewport_y + sc_height; +} + +static XedWindow * +get_active_window (GtkApplication *app) +{ + GdkScreen *screen; + guint workspace; + gint viewport_x, viewport_y; + GList *windows, *l; + + screen = gdk_screen_get_default (); + + workspace = xed_utils_get_current_workspace (screen); + xed_utils_get_current_viewport (screen, &viewport_x, &viewport_y); + + /* Gtk documentation says the window list is always in MRU order */ + windows = gtk_application_get_windows (app); + for (l = windows; l != NULL; l = l->next) + { + GtkWindow *window = l->data; + + if (is_in_viewport (window, screen, workspace, viewport_x, viewport_y)) + { + return XED_WINDOW (window); + } + } + + return NULL; +} + +static void +set_command_line_wait (XedApp *app, + XedTab *tab) +{ + g_object_set_data_full (G_OBJECT (tab), + "XedTabCommandLineWait", + g_object_ref (app->priv->command_line), + (GDestroyNotify)g_object_unref); +} + +static void +open_files (GApplication *application, + gboolean new_window, + gboolean new_document, + gchar *geometry, + gint line_position, + const GtkSourceEncoding *encoding, + GInputStream *stdin_stream, + GSList *file_list, + GApplicationCommandLine *command_line) +{ + XedWindow *window = NULL; + XedTab *tab; + gboolean doc_created = FALSE; + + if (!new_window) + { + window = get_active_window (GTK_APPLICATION (application)); + } + + if (window == NULL) + { + xed_debug_message (DEBUG_APP, "Create main window"); + window = xed_app_create_window (XED_APP (application), NULL); + + xed_debug_message (DEBUG_APP, "Show window"); + gtk_widget_show (GTK_WIDGET (window)); + } + + if (geometry) + { + gtk_window_parse_geometry (GTK_WINDOW (window), geometry); + } + + if (stdin_stream) + { + xed_debug_message (DEBUG_APP, "Load stdin"); + + tab = xed_window_create_tab_from_stream (window, + stdin_stream, + encoding, + line_position, + TRUE); + doc_created = tab != NULL; + + if (doc_created && command_line) + { + set_command_line_wait (XED_APP (application), tab); + } + g_input_stream_close (stdin_stream, NULL, NULL); + } + + if (file_list != NULL) + { + GSList *loaded; + + xed_debug_message (DEBUG_APP, "Load files"); + loaded = _xed_cmd_load_files_from_prompt (window, file_list, encoding, line_position); + + doc_created = doc_created || loaded != NULL; + + if (command_line) + { + g_slist_foreach (loaded, (GFunc)set_command_line_wait, NULL); + } + g_slist_free (loaded); + } + + if (!doc_created || new_document) + { + xed_debug_message (DEBUG_APP, "Create tab"); + tab = xed_window_create_tab (window, TRUE); + + if (command_line) + { + set_command_line_wait (XED_APP (application), tab); + } + } + + gtk_window_present (GTK_WINDOW (window)); +} + +static void +xed_app_activate (GApplication *application) +{ + XedAppPrivate *priv = XED_APP (application)->priv; + + open_files (application, + priv->new_window, + priv->new_document, + priv->geometry, + priv->line_position, + priv->encoding, + priv->stdin_stream, + priv->file_list, + priv->command_line); +} + +static void +clear_options (XedApp *app) +{ + XedAppPrivate *priv = app->priv; + + g_free (priv->geometry); + g_clear_object (&priv->stdin_stream); + g_slist_free_full (priv->file_list, g_object_unref); + + priv->new_window = FALSE; + priv->new_document = FALSE; + priv->geometry = NULL; + priv->encoding = NULL; + priv->file_list = NULL; + priv->line_position = 0; + priv->command_line = NULL; +} + +static void +get_line_position (const gchar *arg, + gint *line) +{ + *line = atoi (arg); +} + +static gint +xed_app_command_line (GApplication *application, + GApplicationCommandLine *cl) +{ + XedAppPrivate *priv; + GVariantDict *options; + const gchar *encoding_charset; + const gchar **remaining_args; + + priv = XED_APP (application)->priv; + + options = g_application_command_line_get_options_dict (cl); + + g_variant_dict_lookup (options, "new-window", "b", &priv->new_window); + g_variant_dict_lookup (options, "new-document", "b", &priv->new_document); + g_variant_dict_lookup (options, "geometry", "s", &priv->geometry); + + if (g_variant_dict_contains (options, "wait")) + { + priv->command_line = cl; + } + + if (g_variant_dict_lookup (options, "encoding", "&s", &encoding_charset)) + { + priv->encoding = gtk_source_encoding_get_from_charset (encoding_charset); + + if (priv->encoding == NULL) + { + g_application_command_line_printerr (cl, _("%s: invalid encoding."), encoding_charset); + } + } + + /* Parse filenames */ + if (g_variant_dict_lookup (options, G_OPTION_REMAINING, "^a&ay", &remaining_args)) + { + gint i; + + for (i = 0; remaining_args[i]; i++) + { + if (*remaining_args[i] == '+') + { + if (*(remaining_args[i] + 1) == '\0') + { + /* goto the last line of the document */ + priv->line_position = G_MAXINT; + } + else + { + get_line_position (remaining_args[i] + 1, &priv->line_position); + } + } + + else if (*remaining_args[i] == '-' && *(remaining_args[i] + 1) == '\0') + { + priv->stdin_stream = g_application_command_line_get_stdin (cl); + } + else + { + GFile *file; + + file = g_application_command_line_create_file_for_arg (cl, remaining_args[i]); + priv->file_list = g_slist_prepend (priv->file_list, file); + } + } + + priv->file_list = g_slist_reverse (priv->file_list); + g_free (remaining_args); + } + + g_application_activate (application); + clear_options (XED_APP (application)); + + return 0; +} + +static void +print_all_encodings (void) +{ + GSList *all_encodings; + GSList *l; + + all_encodings = gtk_source_encoding_get_all (); + + for (l = all_encodings; l != NULL; l = l->next) + { + const GtkSourceEncoding *encoding = l->data; + g_print ("%s\n", gtk_source_encoding_get_charset (encoding)); + } + + g_slist_free (all_encodings); +} + +static gint +xed_app_handle_local_options (GApplication *application, + GVariantDict *options) +{ + if (g_variant_dict_contains (options, "version")) + { + g_print ("%s - Version %s\n", g_get_application_name (), VERSION); + return 0; + } + + if (g_variant_dict_contains (options, "list-encodings")) + { + print_all_encodings (); + return 0; + } + + if (g_variant_dict_contains (options, "standalone")) + { + GApplicationFlags old_flags; + + old_flags = g_application_get_flags (application); + g_application_set_flags (application, old_flags | G_APPLICATION_NON_UNIQUE); + } + + if (g_variant_dict_contains (options, "wait")) + { + GApplicationFlags old_flags; + + old_flags = g_application_get_flags (application); + g_application_set_flags (application, old_flags | G_APPLICATION_IS_LAUNCHER); + } + + return -1; +} + +/* Note: when launched from command line we do not reach this method + * since we manually handle the command line parameters in order to + * parse +LINE, stdin, etc. + * However this method is called when open() is called via dbus, for + * instance when double clicking on a file in nautilus + */ +static void +xed_app_open (GApplication *application, + GFile **files, + gint n_files, + const gchar *hint) +{ + gint i; + GSList *file_list = NULL; + + for (i = 0; i < n_files; i++) + { + file_list = g_slist_prepend (file_list, files[i]); + } + + file_list = g_slist_reverse (file_list); + + open_files (application, + FALSE, + FALSE, + NULL, + 0, + NULL, + NULL, + file_list, + NULL); + + g_slist_free (file_list); } static gboolean ensure_user_config_dir (void) { - gchar *config_dir; - gboolean ret = TRUE; - gint res; + const gchar *config_dir; + gboolean ret = TRUE; + gint res; - config_dir = xed_dirs_get_user_config_dir (); - if (config_dir == NULL) - { - g_warning ("Could not get config directory\n"); - return FALSE; - } + config_dir = xed_dirs_get_user_config_dir (); + if (config_dir == NULL) + { + g_warning ("Could not get config directory\n"); + return FALSE; + } - res = g_mkdir_with_parents (config_dir, 0755); - if (res < 0) - { - g_warning ("Could not create config directory\n"); - ret = FALSE; - } + res = g_mkdir_with_parents (config_dir, 0755); + if (res < 0) + { + g_warning ("Could not create config directory\n"); + ret = FALSE; + } - g_free (config_dir); - - return ret; -} - -static void -load_accels (void) -{ - gchar *filename; - - filename = xed_dirs_get_user_accels_file (); - if (filename != NULL) - { - xed_debug_message (DEBUG_APP, "Loading keybindings from %s\n", filename); - gtk_accel_map_load (filename); - g_free (filename); - } + return ret; } static void save_accels (void) { - gchar *filename; + gchar *filename; - filename = xed_dirs_get_user_accels_file (); - if (filename != NULL) - { - xed_debug_message (DEBUG_APP, "Saving keybindings in %s\n", filename); - gtk_accel_map_save (filename); - g_free (filename); - } + filename = g_build_filename (xed_dirs_get_user_config_dir (), "accels", NULL); + if (filename != NULL) + { + xed_debug_message (DEBUG_APP, "Saving keybindings in %s\n", filename); + gtk_accel_map_save (filename); + g_free (filename); + } } static gchar * get_page_setup_file (void) { - gchar *config_dir; - gchar *setup = NULL; + const gchar *config_dir; + gchar *setup = NULL; - config_dir = xed_dirs_get_user_config_dir (); + config_dir = xed_dirs_get_user_config_dir (); - if (config_dir != NULL) - { - setup = g_build_filename (config_dir, - XED_PAGE_SETUP_FILE, - NULL); - g_free (config_dir); - } + if (config_dir != NULL) + { + setup = g_build_filename (config_dir, XED_PAGE_SETUP_FILE, NULL); + } - return setup; -} - -static void -load_page_setup (XedApp *app) -{ - gchar *filename; - GError *error = NULL; - - g_return_if_fail (app->priv->page_setup == NULL); - - filename = get_page_setup_file (); - - app->priv->page_setup = gtk_page_setup_new_from_file (filename, - &error); - if (error) - { - /* Ignore file not found error */ - if (error->domain != G_FILE_ERROR || - error->code != G_FILE_ERROR_NOENT) - { - g_warning ("%s", error->message); - } - - g_error_free (error); - } - - g_free (filename); - - /* fall back to default settings */ - if (app->priv->page_setup == NULL) - app->priv->page_setup = gtk_page_setup_new (); + return setup; } static void save_page_setup (XedApp *app) { - gchar *filename; - GError *error = NULL; + gchar *filename; + GError *error = NULL; - if (app->priv->page_setup == NULL) - return; + if (app->priv->page_setup == NULL) + { + return; + } - filename = get_page_setup_file (); + filename = get_page_setup_file (); - gtk_page_setup_to_file (app->priv->page_setup, - filename, - &error); - if (error) - { - g_warning ("%s", error->message); - g_error_free (error); - } + gtk_page_setup_to_file (app->priv->page_setup, filename, &error); + if (error) + { + g_warning ("%s", error->message); + g_error_free (error); + } - g_free (filename); + g_free (filename); } static gchar * get_print_settings_file (void) { - gchar *config_dir; - gchar *settings = NULL; + const gchar *config_dir; + gchar *settings = NULL; - config_dir = xed_dirs_get_user_config_dir (); + config_dir = xed_dirs_get_user_config_dir (); - if (config_dir != NULL) - { - settings = g_build_filename (config_dir, - XED_PRINT_SETTINGS_FILE, - NULL); - g_free (config_dir); - } + if (config_dir != NULL) + { + settings = g_build_filename (config_dir, XED_PRINT_SETTINGS_FILE, NULL); + } - return settings; -} - -static void -load_print_settings (XedApp *app) -{ - gchar *filename; - GError *error = NULL; - - g_return_if_fail (app->priv->print_settings == NULL); - - filename = get_print_settings_file (); - - app->priv->print_settings = gtk_print_settings_new_from_file (filename, - &error); - if (error) - { - /* Ignore file not found error */ - if (error->domain != G_FILE_ERROR || - error->code != G_FILE_ERROR_NOENT) - { - g_warning ("%s", error->message); - } - - g_error_free (error); - } - - g_free (filename); - - /* fall back to default settings */ - if (app->priv->print_settings == NULL) - app->priv->print_settings = gtk_print_settings_new (); + return settings; } static void save_print_settings (XedApp *app) { - gchar *filename; - GError *error = NULL; + gchar *filename; + GError *error = NULL; - if (app->priv->print_settings == NULL) - return; + if (app->priv->print_settings == NULL) + { + return; + } - filename = get_print_settings_file (); + filename = get_print_settings_file (); - gtk_print_settings_to_file (app->priv->print_settings, - filename, - &error); - if (error) - { - g_warning ("%s", error->message); - g_error_free (error); - } + gtk_print_settings_to_file (app->priv->print_settings, filename, &error); + if (error) + { + g_warning ("%s", error->message); + g_error_free (error); + } - g_free (filename); + g_free (filename); +} + +static void +xed_app_shutdown (GApplication *app) +{ + xed_debug_message (DEBUG_APP, "Quitting\n"); + + /* Last window is gone... save some settings and exit */ + ensure_user_config_dir (); + + save_accels (); + save_page_setup (XED_APP (app)); + save_print_settings (XED_APP (app)); + + /* GTK+ can still hold references to some xed objects, for example + * XedDocument for the clipboard. So the metadata-manager should be + * shutdown after. + */ + G_APPLICATION_CLASS (xed_app_parent_class)->shutdown (app); + +#ifndef ENABLE_GVFS_METADATA + xed_metadata_manager_shutdown (); +#endif + + xed_dirs_shutdown (); +} + +static void +xed_app_class_init (XedAppClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GApplicationClass *app_class = G_APPLICATION_CLASS (klass); + + object_class->dispose = xed_app_dispose; + object_class->get_property = xed_app_get_property; + + app_class->startup = xed_app_startup; + app_class->activate = xed_app_activate; + app_class->command_line = xed_app_command_line; + app_class->handle_local_options = xed_app_handle_local_options; + app_class->open = xed_app_open; + app_class->shutdown = xed_app_shutdown; + + g_type_class_add_private (object_class, sizeof (XedAppPrivate)); +} + +static void +load_accels (void) +{ + gchar *filename; + + filename = g_build_filename (xed_dirs_get_user_config_dir (), "accels", NULL); + if (filename != NULL) + { + xed_debug_message (DEBUG_APP, "Loading keybindings from %s\n", filename); + gtk_accel_map_load (filename); + g_free (filename); + } +} + +static void +load_page_setup (XedApp *app) +{ + gchar *filename; + GError *error = NULL; + + g_return_if_fail (app->priv->page_setup == NULL); + + filename = get_page_setup_file (); + + app->priv->page_setup = gtk_page_setup_new_from_file (filename, &error); + if (error) + { + /* Ignore file not found error */ + if (error->domain != G_FILE_ERROR || error->code != G_FILE_ERROR_NOENT) + { + g_warning ("%s", error->message); + } + + g_error_free (error); + } + + g_free (filename); + + /* fall back to default settings */ + if (app->priv->page_setup == NULL) + { + app->priv->page_setup = gtk_page_setup_new (); + } +} + +static void +load_print_settings (XedApp *app) +{ + gchar *filename; + GError *error = NULL; + + g_return_if_fail (app->priv->print_settings == NULL); + + filename = get_print_settings_file (); + + app->priv->print_settings = gtk_print_settings_new_from_file (filename, &error); + if (error) + { + /* Ignore file not found error */ + if (error->domain != G_FILE_ERROR || error->code != G_FILE_ERROR_NOENT) + { + g_warning ("%s", error->message); + } + + g_error_free (error); + } + + g_free (filename); + + /* fall back to default settings */ + if (app->priv->print_settings == NULL) + { + app->priv->print_settings = gtk_print_settings_new (); + } } static void xed_app_init (XedApp *app) { - app->priv = XED_APP_GET_PRIVATE (app); + app->priv = XED_APP_GET_PRIVATE (app); - load_accels (); -} + g_set_application_name ("xed"); + gtk_window_set_default_icon_name ("accessories-text-editor"); -static void -app_weak_notify (gpointer data, - GObject *where_the_app_was) -{ - gtk_main_quit (); -} + g_application_add_main_option_entries (G_APPLICATION (app), options); -/** - * xed_app_get_default: - * - * Returns the #XedApp object. This object is a singleton and - * represents the running xed instance. - * - * Return value: the #XedApp pointer - */ -XedApp * -xed_app_get_default (void) -{ - static XedApp *app = NULL; +#ifdef ENABLE_INTROSPECTION + g_application_add_option_group (G_APPLICATION (app), g_irepository_get_option_group ()); +#endif - if (app != NULL) - return app; - - app = XED_APP (g_object_new (XED_TYPE_APP, NULL)); - - g_object_add_weak_pointer (G_OBJECT (app), - (gpointer) &app); - g_object_weak_ref (G_OBJECT (app), - app_weak_notify, - NULL); - - return app; -} - -static void -set_active_window (XedApp *app, - XedWindow *window) -{ - app->priv->active_window = window; -} - -static gboolean -window_focus_in_event (XedWindow *window, - GdkEventFocus *event, - XedApp *app) -{ - /* updates active_view and active_child when a new toplevel receives focus */ - g_return_val_if_fail (XED_IS_WINDOW (window), FALSE); - - set_active_window (app, window); - - return FALSE; + load_accels (); } static gboolean window_delete_event (XedWindow *window, - GdkEvent *event, + GdkEvent *event, XedApp *app) { - XedWindowState ws; + XedWindowState ws; - ws = xed_window_get_state (window); + ws = xed_window_get_state (window); - if (ws & - (XED_WINDOW_STATE_SAVING | - XED_WINDOW_STATE_PRINTING | - XED_WINDOW_STATE_SAVING_SESSION)) - return TRUE; + if (ws & + (XED_WINDOW_STATE_SAVING | + XED_WINDOW_STATE_PRINTING | + XED_WINDOW_STATE_SAVING_SESSION)) + { + return TRUE; + } - _xed_cmd_file_quit (NULL, window); + _xed_cmd_file_quit (NULL, window); - /* Do not destroy the window */ - return TRUE; -} - -static void -window_destroy (XedWindow *window, - XedApp *app) -{ - app->priv->windows = g_list_remove (app->priv->windows, - window); - - if (window == app->priv->active_window) - { - set_active_window (app, app->priv->windows != NULL ? app->priv->windows->data : NULL); - } - -/* CHECK: I don't think we have to disconnect this function, since windows - is being destroyed */ -/* - g_signal_handlers_disconnect_by_func (window, - G_CALLBACK (window_focus_in_event), - app); - g_signal_handlers_disconnect_by_func (window, - G_CALLBACK (window_destroy), - app); -*/ - if (app->priv->windows == NULL) - { - /* Last window is gone... save some settings and exit */ - ensure_user_config_dir (); - - save_accels (); - save_page_setup (app); - save_print_settings (app); - - g_object_unref (app); - } + /* Do not destroy the window */ + return TRUE; } /* Generates a unique string for a window role */ static gchar * gen_role (void) { - GTimeVal result; - static gint serial; + GTimeVal result; + static gint serial; - g_get_current_time (&result); + g_get_current_time (&result); - return g_strdup_printf ("xed-window-%ld-%ld-%d-%s", - result.tv_sec, - result.tv_usec, - serial++, - g_get_host_name ()); + return g_strdup_printf ("xed-window-%ld-%ld-%d-%s", + result.tv_sec, + result.tv_usec, + serial++, + g_get_host_name ()); } static XedWindow * -xed_app_create_window_real (XedApp *app, - gboolean set_geometry, - const gchar *role) +xed_app_create_window_real (XedApp *app, + gboolean set_geometry, + const gchar *role) { - XedWindow *window; + XedWindow *window; - xed_debug (DEBUG_APP); + window = g_object_new (XED_TYPE_WINDOW, "application", app, NULL); - /* - * We need to be careful here, there is a race condition: - * when another xed is launched it checks active_window, - * so we must do our best to ensure that active_window - * is never NULL when at least a window exists. - */ - if (app->priv->windows == NULL) - { - window = g_object_new (XED_TYPE_WINDOW, NULL); - set_active_window (app, window); - } - else - { - window = g_object_new (XED_TYPE_WINDOW, NULL); - } + xed_debug_message (DEBUG_APP, "Window created"); - app->priv->windows = g_list_prepend (app->priv->windows, - window); + if (role != NULL) + { + gtk_window_set_role (GTK_WINDOW (window), role); + } + else + { + gchar *newrole; - xed_debug_message (DEBUG_APP, "Window created"); + newrole = gen_role (); + gtk_window_set_role (GTK_WINDOW (window), newrole); + g_free (newrole); + } - if (role != NULL) - { - gtk_window_set_role (GTK_WINDOW (window), role); - } - else - { - gchar *newrole; + if (set_geometry) + { + GdkWindowState state; + gint w, h; - newrole = gen_role (); - gtk_window_set_role (GTK_WINDOW (window), newrole); - g_free (newrole); - } + state = g_settings_get_int (app->priv->window_settings, XED_SETTINGS_WINDOW_STATE); + g_settings_get (app->priv->window_settings, XED_SETTINGS_WINDOW_SIZE, "(ii)", &w, &h); + gtk_window_set_default_size (GTK_WINDOW (window), w, h); - if (set_geometry) - { - GdkWindowState state; - gint w, h; + if ((state & GDK_WINDOW_STATE_MAXIMIZED) != 0) + { + gtk_window_maximize (GTK_WINDOW (window)); + } + else + { + gtk_window_unmaximize (GTK_WINDOW (window)); + } - state = xed_prefs_manager_get_window_state (); + if ((state & GDK_WINDOW_STATE_STICKY ) != 0) + { + gtk_window_stick (GTK_WINDOW (window)); + } + else + { + gtk_window_unstick (GTK_WINDOW (window)); + } + } - if ((state & GDK_WINDOW_STATE_MAXIMIZED) != 0) - { - xed_prefs_manager_get_default_window_size (&w, &h); - gtk_window_set_default_size (GTK_WINDOW (window), w, h); - gtk_window_maximize (GTK_WINDOW (window)); - } - else - { - xed_prefs_manager_get_window_size (&w, &h); - gtk_window_set_default_size (GTK_WINDOW (window), w, h); - gtk_window_unmaximize (GTK_WINDOW (window)); - } + g_signal_connect (window, "delete_event", G_CALLBACK (window_delete_event), app); - if ((state & GDK_WINDOW_STATE_STICKY ) != 0) - gtk_window_stick (GTK_WINDOW (window)); - else - gtk_window_unstick (GTK_WINDOW (window)); - } - - g_signal_connect (window, - "focus_in_event", - G_CALLBACK (window_focus_in_event), - app); - g_signal_connect (window, - "delete_event", - G_CALLBACK (window_delete_event), - app); - g_signal_connect (window, - "destroy", - G_CALLBACK (window_destroy), - app); - - return window; + return window; } /** @@ -535,20 +1029,22 @@ xed_app_create_window_real (XedApp *app, * * Create a new #XedWindow part of @app. * - * Return value: the new #XedWindow + * Return value: (transfer none): the new #XedWindow */ XedWindow * -xed_app_create_window (XedApp *app, - GdkScreen *screen) +xed_app_create_window (XedApp *app, + GdkScreen *screen) { - XedWindow *window; + XedWindow *window; - window = xed_app_create_window_real (app, TRUE, NULL); + window = xed_app_create_window_real (app, TRUE, NULL); - if (screen != NULL) - gtk_window_set_screen (GTK_WINDOW (window), screen); + if (screen != NULL) + { + gtk_window_set_screen (GTK_WINDOW (window), screen); + } - return window; + return window; } /* @@ -556,160 +1052,45 @@ xed_app_create_window (XedApp *app, * The session manager takes care of it. Used in mate-session. */ XedWindow * -_xed_app_restore_window (XedApp *app, - const gchar *role) +_xed_app_restore_window (XedApp *app, + const gchar *role) { - XedWindow *window; + XedWindow *window; - window = xed_app_create_window_real (app, FALSE, role); + window = xed_app_create_window_real (app, FALSE, role); - return window; + return window; } /** - * xed_app_get_windows: - * @app: the #XedApp + * xed_app_get_main_windows: + * @app: the #GeditApp * - * Returns all the windows currently present in #XedApp. + * Returns all #XedWindows currently open in #XedApp. + * This differs from gtk_application_get_windows() since it does not + * include the preferences dialog and other auxiliary windows. * - * Return value: (transfer none): the list of #XedWindows objects. - * The list should not be freed + * Return value: (element-type Xed.Window) (transfer container): + * a newly allocated list of #XedWindow objects */ -const GList * -xed_app_get_windows (XedApp *app) +GList * +xed_app_get_main_windows (XedApp *app) { - g_return_val_if_fail (XED_IS_APP (app), NULL); + GList *res = NULL; + GList *windows, *l; - return app->priv->windows; -} + g_return_val_if_fail (XED_IS_APP (app), NULL); -/** - * xed_app_get_active_window: - * @app: the #XedApp - * - * Retrives the #XedWindow currently active. - * - * Return value: the active #XedWindow - */ -XedWindow * -xed_app_get_active_window (XedApp *app) -{ - g_return_val_if_fail (XED_IS_APP (app), NULL); + windows = gtk_application_get_windows (GTK_APPLICATION (app)); + for (l = windows; l != NULL; l = g_list_next (l)) + { + if (XED_IS_WINDOW (l->data)) + { + res = g_list_prepend (res, l->data); + } + } - /* make sure our active window is always realized: - * this is needed on startup if we launch two xed fast - * enough that the second instance comes up before the - * first one shows its window. - */ - if (!gtk_widget_get_realized (GTK_WIDGET (app->priv->active_window))) - gtk_widget_realize (GTK_WIDGET (app->priv->active_window)); - - return app->priv->active_window; -} - -static gboolean -is_in_viewport (XedWindow *window, - GdkScreen *screen, - gint workspace, - gint viewport_x, - gint viewport_y) -{ - GdkScreen *s; - GdkDisplay *display; - GdkWindow *gdkwindow; - const gchar *cur_name; - const gchar *name; - gint cur_n; - gint n; - gint ws; - gint sc_width, sc_height; - gint x, y, width, height; - gint vp_x, vp_y; - - /* Check for screen and display match */ - display = gdk_screen_get_display (screen); - cur_name = gdk_display_get_name (display); - cur_n = gdk_screen_get_number (screen); - - s = gtk_window_get_screen (GTK_WINDOW (window)); - display = gdk_screen_get_display (s); - name = gdk_display_get_name (display); - n = gdk_screen_get_number (s); - - if (strcmp (cur_name, name) != 0 || cur_n != n) - return FALSE; - - /* Check for workspace match */ - ws = xed_utils_get_window_workspace (GTK_WINDOW (window)); - if (ws != workspace && ws != XED_ALL_WORKSPACES) - return FALSE; - - /* Check for viewport match */ - gdkwindow = gtk_widget_get_window (GTK_WIDGET (window)); - gdk_window_get_position (gdkwindow, &x, &y); - - width = gdk_window_get_width(gdkwindow); - height = gdk_window_get_height(gdkwindow); - - xed_utils_get_current_viewport (screen, &vp_x, &vp_y); - x += vp_x; - y += vp_y; - - sc_width = gdk_screen_get_width (screen); - sc_height = gdk_screen_get_height (screen); - - return x + width * .25 >= viewport_x && - x + width * .75 <= viewport_x + sc_width && - y >= viewport_y && - y + height <= viewport_y + sc_height; -} - -/** - * _xed_app_get_window_in_viewport - * @app: the #XedApp - * @screen: the #GdkScreen - * @workspace: the workspace number - * @viewport_x: the viewport horizontal origin - * @viewport_y: the viewport vertical origin - * - * Since a workspace can be larger than the screen, it is divided into several - * equal parts called viewports. This function retrives the #XedWindow in - * the given viewport of the given workspace. - * - * Return value: the #XedWindow in the given viewport of the given workspace. - */ -XedWindow * -_xed_app_get_window_in_viewport (XedApp *app, - GdkScreen *screen, - gint workspace, - gint viewport_x, - gint viewport_y) -{ - XedWindow *window; - - GList *l; - - g_return_val_if_fail (XED_IS_APP (app), NULL); - - /* first try if the active window */ - window = app->priv->active_window; - - g_return_val_if_fail (XED_IS_WINDOW (window), NULL); - - if (is_in_viewport (window, screen, workspace, viewport_x, viewport_y)) - return window; - - /* otherwise try to see if there is a window on this workspace */ - for (l = app->priv->windows; l != NULL; l = l->next) - { - window = l->data; - - if (is_in_viewport (window, screen, workspace, viewport_x, viewport_y)) - return window; - } - - /* no window on this workspace... create a new one */ - return xed_app_create_window (app, screen); + return g_list_reverse (res); } /** @@ -722,24 +1103,20 @@ _xed_app_get_window_in_viewport (XedApp *app, * a newly allocated list of #XedDocument objects */ GList * -xed_app_get_documents (XedApp *app) +xed_app_get_documents (XedApp *app) { - GList *res = NULL; - GList *windows; + GList *res = NULL; + GList *windows, *l; - g_return_val_if_fail (XED_IS_APP (app), NULL); + g_return_val_if_fail (XED_IS_APP (app), NULL); - windows = app->priv->windows; + windows = gtk_application_get_windows (GTK_APPLICATION (app)); + for (l = windows; l != NULL; l = g_list_next (l)) + { + res = g_list_concat (res, xed_window_get_documents (XED_WINDOW (l->data))); + } - while (windows != NULL) - { - res = g_list_concat (res, - xed_window_get_documents (XED_WINDOW (windows->data))); - - windows = g_list_next (windows); - } - - return res; + return res; } /** @@ -754,71 +1131,151 @@ xed_app_get_documents (XedApp *app) GList * xed_app_get_views (XedApp *app) { - GList *res = NULL; - GList *windows; + GList *res = NULL; + GList *windows, *l; - g_return_val_if_fail (XED_IS_APP (app), NULL); + g_return_val_if_fail (XED_IS_APP (app), NULL); - windows = app->priv->windows; + windows = gtk_application_get_windows (GTK_APPLICATION (app)); + for (l = windows; l != NULL; l = g_list_next (l)) + { + res = g_list_concat (res, xed_window_get_views (XED_WINDOW (l->data))); + } - while (windows != NULL) - { - res = g_list_concat (res, - xed_window_get_views (XED_WINDOW (windows->data))); + return res; +} - windows = g_list_next (windows); - } +gboolean +xed_app_show_help (XedApp *app, + GtkWindow *parent, + const gchar *name, + const gchar *link_id) +{ + g_return_val_if_fail (XED_IS_APP (app), FALSE); + g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE); - return res; + GError *error = NULL; + gboolean ret; + gchar *link; + + if (name == NULL) + { + name = "xed"; + } + else if (strcmp (name, "xed.xml") == 0) + { + g_warning ("%s: Using \"xed.xml\" for the help name is deprecated, use \"xed\" or simply NULL instead", G_STRFUNC); + name = "xed"; + } + + if (link_id) + { + link = g_strdup_printf ("help:%s/%s", name, link_id); + } + else + { + link = g_strdup_printf ("help:%s", name); + } + + ret = gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (parent)), link, GDK_CURRENT_TIME, &error); + + g_free (link); + + if (error != NULL) + { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (parent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("There was an error displaying the help.")); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message); + + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (gtk_widget_destroy), NULL); + + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + + gtk_widget_show (dialog); + + g_error_free (error); + } + + return ret; +} + +void +xed_app_set_window_title (XedApp *app, + XedWindow *window, + const gchar *title) +{ + gtk_window_set_title (GTK_WINDOW (window), title); } /* Returns a copy */ GtkPageSetup * _xed_app_get_default_page_setup (XedApp *app) { - g_return_val_if_fail (XED_IS_APP (app), NULL); + g_return_val_if_fail (XED_IS_APP (app), NULL); - if (app->priv->page_setup == NULL) - load_page_setup (app); + if (app->priv->page_setup == NULL) + { + load_page_setup (app); + } - return gtk_page_setup_copy (app->priv->page_setup); + return gtk_page_setup_copy (app->priv->page_setup); } void -_xed_app_set_default_page_setup (XedApp *app, - GtkPageSetup *page_setup) +_xed_app_set_default_page_setup (XedApp *app, + GtkPageSetup *page_setup) { - g_return_if_fail (XED_IS_APP (app)); - g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup)); + g_return_if_fail (XED_IS_APP (app)); + g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup)); - if (app->priv->page_setup != NULL) - g_object_unref (app->priv->page_setup); + if (app->priv->page_setup != NULL) + { + g_object_unref (app->priv->page_setup); + } - app->priv->page_setup = g_object_ref (page_setup); + app->priv->page_setup = g_object_ref (page_setup); } /* Returns a copy */ GtkPrintSettings * _xed_app_get_default_print_settings (XedApp *app) { - g_return_val_if_fail (XED_IS_APP (app), NULL); + g_return_val_if_fail (XED_IS_APP (app), NULL); - if (app->priv->print_settings == NULL) - load_print_settings (app); + if (app->priv->print_settings == NULL) + { + load_print_settings (app); + } - return gtk_print_settings_copy (app->priv->print_settings); + return gtk_print_settings_copy (app->priv->print_settings); } void -_xed_app_set_default_print_settings (XedApp *app, - GtkPrintSettings *settings) +_xed_app_set_default_print_settings (XedApp *app, + GtkPrintSettings *settings) { - g_return_if_fail (XED_IS_APP (app)); - g_return_if_fail (GTK_IS_PRINT_SETTINGS (settings)); + g_return_if_fail (XED_IS_APP (app)); + g_return_if_fail (GTK_IS_PRINT_SETTINGS (settings)); - if (app->priv->print_settings != NULL) - g_object_unref (app->priv->print_settings); + if (app->priv->print_settings != NULL) + { + g_object_unref (app->priv->print_settings); + } - app->priv->print_settings = g_object_ref (settings); + app->priv->print_settings = g_object_ref (settings); } +GObject * +_xed_app_get_settings (XedApp *app) +{ + g_return_val_if_fail (XED_IS_APP (app), NULL); + + return app->priv->settings; +} diff --git a/xed/xed-app.h b/xed/xed-app.h index 82988c1..b9919d4 100644 --- a/xed/xed-app.h +++ b/xed/xed-app.h @@ -2,7 +2,7 @@ * xed-app.h * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -37,9 +37,6 @@ G_BEGIN_DECLS -/* - * Type checking and casting macros - */ #define XED_TYPE_APP (xed_app_get_type()) #define XED_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_APP, XedApp)) #define XED_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_APP, XedAppClass)) @@ -47,69 +44,73 @@ G_BEGIN_DECLS #define XED_IS_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_APP)) #define XED_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_APP, XedAppClass)) -/* Private structure type */ -typedef struct _XedAppPrivate XedAppPrivate; +typedef struct _XedApp XedApp; +typedef struct _XedAppPrivate XedAppPrivate; +typedef struct _XedAppClass XedAppClass; -/* - * Main object structure - */ -typedef struct _XedApp XedApp; - -struct _XedApp +struct _XedApp { - GObject object; + GtkApplication parent; - /*< private > */ - XedAppPrivate *priv; + /*< private > */ + XedAppPrivate *priv; }; -/* - * Class definition - */ -typedef struct _XedAppClass XedAppClass; - -struct _XedAppClass +struct _XedAppClass { - GObjectClass parent_class; + GtkApplicationClass parent_class; + + // gboolean (*last_window_destroyed) (XedApp *app); + + gboolean (*show_help) (XedApp *app, + GtkWindow *parent, + const gchar *name, + const gchar *link_id); + + gchar *(*help_link_id) (XedApp *app, + const gchar *name, + const gchar *link_id); + + void (*set_window_title) (XedApp *app, + XedWindow *window, + const gchar *title); }; -/* - * Public methods - */ -GType xed_app_get_type (void) G_GNUC_CONST; +/* Public methods */ +GType xed_app_get_type (void) G_GNUC_CONST; -XedApp *xed_app_get_default (void); +XedWindow *xed_app_create_window (XedApp *app, + GdkScreen *screen); -XedWindow *xed_app_create_window (XedApp *app, - GdkScreen *screen); +GList *xed_app_get_main_windows (XedApp *app); -const GList *xed_app_get_windows (XedApp *app); -XedWindow *xed_app_get_active_window (XedApp *app); - -/* Returns a newly allocated list with all the documents */ -GList *xed_app_get_documents (XedApp *app); +GList *xed_app_get_documents (XedApp *app); /* Returns a newly allocated list with all the views */ -GList *xed_app_get_views (XedApp *app); +GList *xed_app_get_views (XedApp *app); -/* - * Non exported functions - */ -XedWindow *_xed_app_restore_window (XedApp *app, - const gchar *role); -XedWindow *_xed_app_get_window_in_viewport (XedApp *app, - GdkScreen *screen, - gint workspace, - gint viewport_x, - gint viewport_y); +gboolean xed_app_show_help (XedApp *app, + GtkWindow *parent, + const gchar *name, + const gchar *link_id); + +void xed_app_set_window_title (XedApp *app, + XedWindow *window, + const gchar *title); + +/* Non exported functions */ +XedWindow *_xed_app_restore_window (XedApp *app, + const gchar *role); /* global print config */ -GtkPageSetup *_xed_app_get_default_page_setup (XedApp *app); -void _xed_app_set_default_page_setup (XedApp *app, - GtkPageSetup *page_setup); -GtkPrintSettings *_xed_app_get_default_print_settings (XedApp *app); -void _xed_app_set_default_print_settings (XedApp *app, - GtkPrintSettings *settings); +GtkPageSetup *_xed_app_get_default_page_setup (XedApp *app); +void _xed_app_set_default_page_setup (XedApp *app, + GtkPageSetup *page_setup); +GtkPrintSettings *_xed_app_get_default_print_settings (XedApp *app); +void _xed_app_set_default_print_settings (XedApp *app, + GtkPrintSettings *settings); + +GObject *_xed_app_get_settings (XedApp *app); G_END_DECLS diff --git a/xed/xed-close-confirmation-dialog.c b/xed/xed-close-confirmation-dialog.c new file mode 100755 index 0000000..e667ad5 --- /dev/null +++ b/xed/xed-close-confirmation-dialog.c @@ -0,0 +1,719 @@ +/* + * xed-close-confirmation-dialog.c + * This file is part of xed + * + * Copyright (C) 2004-2005 GNOME Foundation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* + * Modified by the xed Team, 2004-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "xed-close-confirmation-dialog.h" +#include +#include +#include + + +/* Properties */ +enum +{ + PROP_0, + PROP_UNSAVED_DOCUMENTS, + PROP_LOGOUT_MODE +}; + +/* Mode */ +enum +{ + SINGLE_DOC_MODE, + MULTIPLE_DOCS_MODE +}; + +/* Columns */ +enum +{ + SAVE_COLUMN, + NAME_COLUMN, + DOC_COLUMN, /* a handy pointer to the document */ + N_COLUMNS +}; + +struct _XedCloseConfirmationDialogPrivate +{ + gboolean logout_mode; + GList *unsaved_documents; + GList *selected_documents; + GtkTreeModel *list_store; +}; + +#define XED_CLOSE_CONFIRMATION_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + XED_TYPE_CLOSE_CONFIRMATION_DIALOG, \ + XedCloseConfirmationDialogPrivate)) + +#define GET_MODE(priv) (((priv->unsaved_documents != NULL) && \ + (priv->unsaved_documents->next == NULL)) ? \ + SINGLE_DOC_MODE : MULTIPLE_DOCS_MODE) + +G_DEFINE_TYPE(XedCloseConfirmationDialog, xed_close_confirmation_dialog, GTK_TYPE_DIALOG) + +static void set_unsaved_document (XedCloseConfirmationDialog *dlg, + const GList *list); +static GList *get_selected_docs (GtkTreeModel *store); + +/* Since we connect in the costructor we are sure this handler will be called + * before the user ones + */ +static void +response_cb (XedCloseConfirmationDialog *dlg, + gint response_id, + gpointer data) +{ + XedCloseConfirmationDialogPrivate *priv; + + g_return_if_fail (XED_IS_CLOSE_CONFIRMATION_DIALOG (dlg)); + + priv = dlg->priv; + + if (priv->selected_documents != NULL) + { + g_list_free (priv->selected_documents); + } + + if (response_id == GTK_RESPONSE_YES) + { + if (GET_MODE (priv) == SINGLE_DOC_MODE) + { + priv->selected_documents = g_list_copy (priv->unsaved_documents); + } + else + { + g_return_if_fail (priv->list_store); + + priv->selected_documents = get_selected_docs (priv->list_store); + } + } + else + priv->selected_documents = NULL; +} + +static void +set_logout_mode (XedCloseConfirmationDialog *dlg, + gboolean logout_mode) +{ + dlg->priv->logout_mode = logout_mode; + + if (logout_mode) + { + gtk_dialog_add_button (GTK_DIALOG (dlg), _("Log Out _without Saving"), GTK_RESPONSE_NO); + gtk_dialog_add_button (GTK_DIALOG (dlg), _("_Cancel Logout"), GTK_RESPONSE_CANCEL); + } + else + { + gtk_dialog_add_button (GTK_DIALOG (dlg), _("Close _without Saving"), GTK_RESPONSE_NO); + gtk_dialog_add_button (GTK_DIALOG (dlg), _("_Cancel"), GTK_RESPONSE_CANCEL); + } + + + gboolean save_as = FALSE; + + if (GET_MODE (dlg->priv) == SINGLE_DOC_MODE) + { + XedDocument *doc; + + doc = XED_DOCUMENT (dlg->priv->unsaved_documents->data); + + if (xed_document_get_readonly (doc) || xed_document_is_untitled (doc)) + { + save_as = TRUE; + } + } + + if (save_as) + { + gtk_dialog_add_button (GTK_DIALOG (dlg), _("_Save As..."), GTK_RESPONSE_YES); + } + else + { + gtk_dialog_add_button (GTK_DIALOG (dlg), _("_Save"), GTK_RESPONSE_YES); + } + + gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_YES); +} + +static void +xed_close_confirmation_dialog_init (XedCloseConfirmationDialog *dlg) +{ + AtkObject *atk_obj; + + dlg->priv = XED_CLOSE_CONFIRMATION_DIALOG_GET_PRIVATE (dlg); + + gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), 14); + gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE); + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dlg), TRUE); + + gtk_window_set_title (GTK_WINDOW (dlg), ""); + + gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); + gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE); + + atk_obj = gtk_widget_get_accessible (GTK_WIDGET (dlg)); + atk_object_set_role (atk_obj, ATK_ROLE_ALERT); + atk_object_set_name (atk_obj, _("Question")); + + g_signal_connect (dlg, "response", G_CALLBACK (response_cb), NULL); +} + +static void +xed_close_confirmation_dialog_finalize (GObject *object) +{ + XedCloseConfirmationDialogPrivate *priv; + + priv = XED_CLOSE_CONFIRMATION_DIALOG (object)->priv; + + if (priv->unsaved_documents != NULL) + { + g_list_free (priv->unsaved_documents); + } + + if (priv->selected_documents != NULL) + { + g_list_free (priv->selected_documents); + } + + /* Call the parent's destructor */ + G_OBJECT_CLASS (xed_close_confirmation_dialog_parent_class)->finalize (object); +} + +static void +xed_close_confirmation_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XedCloseConfirmationDialog *dlg; + + dlg = XED_CLOSE_CONFIRMATION_DIALOG (object); + + switch (prop_id) + { + case PROP_UNSAVED_DOCUMENTS: + set_unsaved_document (dlg, g_value_get_pointer (value)); + break; + + case PROP_LOGOUT_MODE: + set_logout_mode (dlg, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_close_confirmation_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XedCloseConfirmationDialogPrivate *priv; + + priv = XED_CLOSE_CONFIRMATION_DIALOG (object)->priv; + + switch( prop_id ) + { + case PROP_UNSAVED_DOCUMENTS: + g_value_set_pointer (value, priv->unsaved_documents); + break; + + case PROP_LOGOUT_MODE: + g_value_set_boolean (value, priv->logout_mode); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_close_confirmation_dialog_class_init (XedCloseConfirmationDialogClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = xed_close_confirmation_dialog_set_property; + gobject_class->get_property = xed_close_confirmation_dialog_get_property; + gobject_class->finalize = xed_close_confirmation_dialog_finalize; + + g_type_class_add_private (klass, sizeof (XedCloseConfirmationDialogPrivate)); + + g_object_class_install_property (gobject_class, + PROP_UNSAVED_DOCUMENTS, + g_param_spec_pointer ("unsaved_documents", + "Unsaved Documents", + "List of Unsaved Documents", + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + g_object_class_install_property (gobject_class, + PROP_LOGOUT_MODE, + g_param_spec_boolean ("logout_mode", + "Logout Mode", + "Whether the dialog is in logout mode", + FALSE, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); +} + +static GList * +get_selected_docs (GtkTreeModel *store) +{ + GList *list; + gboolean valid; + GtkTreeIter iter; + + list = NULL; + valid = gtk_tree_model_get_iter_first (store, &iter); + + while (valid) + { + gboolean to_save; + XedDocument *doc; + + gtk_tree_model_get (store, &iter, SAVE_COLUMN, &to_save, DOC_COLUMN, &doc, -1); + if (to_save) + { + list = g_list_prepend (list, doc); + } + + valid = gtk_tree_model_iter_next (store, &iter); + } + + list = g_list_reverse (list); + + return list; +} + +GList * +xed_close_confirmation_dialog_get_selected_documents (XedCloseConfirmationDialog *dlg) +{ + g_return_val_if_fail (XED_IS_CLOSE_CONFIRMATION_DIALOG (dlg), NULL); + + return g_list_copy (dlg->priv->selected_documents); +} + +GtkWidget * +xed_close_confirmation_dialog_new (GtkWindow *parent, + GList *unsaved_documents, + gboolean logout_mode) +{ + GtkWidget *dlg; + g_return_val_if_fail (unsaved_documents != NULL, NULL); + + dlg = GTK_WIDGET (g_object_new (XED_TYPE_CLOSE_CONFIRMATION_DIALOG, + "unsaved_documents", unsaved_documents, + "logout_mode", logout_mode, + NULL)); + g_return_val_if_fail (dlg != NULL, NULL); + + if (parent != NULL) + { + gtk_window_group_add_window (xed_window_get_group (XED_WINDOW (parent)), GTK_WINDOW (dlg)); + gtk_window_set_transient_for (GTK_WINDOW (dlg), parent); + } + + return dlg; +} + +GtkWidget * +xed_close_confirmation_dialog_new_single (GtkWindow *parent, + XedDocument *doc, + gboolean logout_mode) +{ + GtkWidget *dlg; + GList *unsaved_documents; + g_return_val_if_fail (doc != NULL, NULL); + + unsaved_documents = g_list_prepend (NULL, doc); + + dlg = xed_close_confirmation_dialog_new (parent, unsaved_documents, logout_mode); + + g_list_free (unsaved_documents); + + return dlg; +} + +static gchar * +get_text_secondary_label (XedDocument *doc) +{ + glong seconds; + gchar *secondary_msg; + + seconds = MAX (1, _xed_document_get_seconds_since_last_save_or_load (doc)); + + if (seconds < 55) + { + secondary_msg = g_strdup_printf (ngettext ("If you don't save, changes from the last %ld second " + "will be permanently lost.", + "If you don't save, changes from the last %ld seconds " + "will be permanently lost.", + seconds), + seconds); + } + else if (seconds < 75) /* 55 <= seconds < 75 */ + { + secondary_msg = g_strdup (_("If you don't save, changes from the last minute " + "will be permanently lost.")); + } + else if (seconds < 110) /* 75 <= seconds < 110 */ + { + secondary_msg = g_strdup_printf (ngettext ("If you don't save, changes from the last minute and %ld " + "second will be permanently lost.", + "If you don't save, changes from the last minute and %ld " + "seconds will be permanently lost.", + seconds - 60 ), + seconds - 60); + } + else if (seconds < 3600) + { + secondary_msg = g_strdup_printf (ngettext ("If you don't save, changes from the last %ld minute " + "will be permanently lost.", + "If you don't save, changes from the last %ld minutes " + "will be permanently lost.", + seconds / 60), + seconds / 60); + } + else if (seconds < 7200) + { + gint minutes; + seconds -= 3600; + + minutes = seconds / 60; + if (minutes < 5) + { + secondary_msg = g_strdup (_("If you don't save, changes from the last hour " + "will be permanently lost.")); + } + else + { + secondary_msg = g_strdup_printf (ngettext ("If you don't save, changes from the last hour and %d " + "minute will be permanently lost.", + "If you don't save, changes from the last hour and %d " + "minutes will be permanently lost.", + minutes), + minutes); + } + } + else + { + gint hours; + + hours = seconds / 3600; + + secondary_msg = g_strdup_printf (ngettext ("If you don't save, changes from the last %d hour " + "will be permanently lost.", + "If you don't save, changes from the last %d hours " + "will be permanently lost.", + hours), + hours); + } + + return secondary_msg; +} + +static void +build_single_doc_dialog (XedCloseConfirmationDialog *dlg) +{ + GtkWidget *hbox; + GtkWidget *vbox; + GtkWidget *primary_label; + GtkWidget *secondary_label; + GtkWidget *image; + XedDocument *doc; + gchar *doc_name; + gchar *str; + gchar *markup_str; + + g_return_if_fail (dlg->priv->unsaved_documents->data != NULL); + doc = XED_DOCUMENT (dlg->priv->unsaved_documents->data); + + /* Image */ + image = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_DIALOG); + gtk_widget_set_halign (image, GTK_ALIGN_START); + gtk_widget_set_valign (image, GTK_ALIGN_END); + + /* Primary label */ + primary_label = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); + gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); + gtk_widget_set_can_focus (GTK_WIDGET (primary_label), FALSE); + + doc_name = xed_document_get_short_name_for_display (doc); + + str = g_markup_printf_escaped (_("Save changes to document \"%s\" before closing?"), doc_name); + + g_free (doc_name); + + markup_str = g_strconcat ("", str, "", NULL); + g_free (str); + + gtk_label_set_markup (GTK_LABEL (primary_label), markup_str); + g_free (markup_str); + + /* Secondary label */ + str = get_text_secondary_label (doc); + secondary_label = gtk_label_new (str); + g_free (str); + gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); + gtk_widget_set_can_focus (GTK_WIDGET (secondary_label), FALSE); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), primary_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), secondary_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), hbox, FALSE, FALSE, 0); + + gtk_widget_show_all (hbox); +} + +static void +populate_model (GtkTreeModel *store, + GList *docs) +{ + GtkTreeIter iter; + + while (docs != NULL) + { + XedDocument *doc; + gchar *name; + + doc = XED_DOCUMENT (docs->data); + + name = xed_document_get_short_name_for_display (doc); + + gtk_list_store_append (GTK_LIST_STORE (store), &iter); + gtk_list_store_set (GTK_LIST_STORE (store), &iter, + SAVE_COLUMN, TRUE, + NAME_COLUMN, name, + DOC_COLUMN, doc, + -1); + + g_free (name); + + docs = g_list_next (docs); + } +} + +static void +save_toggled (GtkCellRendererToggle *renderer, + gchar *path_str, + GtkTreeModel *store) +{ + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + GtkTreeIter iter; + gboolean active; + + gtk_tree_model_get_iter (store, &iter, path); + gtk_tree_model_get (store, &iter, SAVE_COLUMN, &active, -1); + + active ^= 1; + + gtk_list_store_set (GTK_LIST_STORE (store), &iter, SAVE_COLUMN, active, -1); + + gtk_tree_path_free (path); +} + +static GtkWidget * +create_treeview (XedCloseConfirmationDialogPrivate *priv) +{ + GtkListStore *store; + GtkWidget *treeview; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + treeview = gtk_tree_view_new (); + gtk_widget_set_size_request (treeview, 260, 120); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE); + + /* Create and populate the model */ + store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER); + populate_model (GTK_TREE_MODEL (store), priv->unsaved_documents); + + /* Set model to the treeview */ + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); + g_object_unref (store); + + priv->list_store = GTK_TREE_MODEL (store); + + /* Add columns */ + + renderer = gtk_cell_renderer_toggle_new (); + g_signal_connect (renderer, "toggled", G_CALLBACK (save_toggled), store); + + column = gtk_tree_view_column_new_with_attributes ("Save?", + renderer, + "active", + SAVE_COLUMN, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Name", + renderer, + "text", + NAME_COLUMN, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + return treeview; +} + +static void +build_multiple_docs_dialog (XedCloseConfirmationDialog *dlg) +{ + XedCloseConfirmationDialogPrivate *priv; + GtkWidget *hbox; + GtkWidget *image; + GtkWidget *vbox; + GtkWidget *primary_label; + GtkWidget *vbox2; + GtkWidget *select_label; + GtkWidget *scrolledwindow; + GtkWidget *treeview; + GtkWidget *secondary_label; + gchar *str; + gchar *markup_str; + + priv = dlg->priv; + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), hbox, TRUE, TRUE, 0); + + /* Image */ + image = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_DIALOG); + gtk_widget_set_halign (image, GTK_ALIGN_CENTER); + gtk_widget_set_valign (image, GTK_ALIGN_START); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + + /* Primary label */ + primary_label = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); + gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); + gtk_widget_set_halign (GTK_WIDGET (primary_label), GTK_ALIGN_START); + gtk_widget_set_halign (primary_label, GTK_ALIGN_START); + gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); + + str = g_strdup_printf (ngettext ("There is %d document with unsaved changes. " + "Save changes before closing?", + "There are %d documents with unsaved changes. " + "Save changes before closing?", + g_list_length (priv->unsaved_documents)), + g_list_length (priv->unsaved_documents)); + + markup_str = g_strconcat ("", str, "", NULL); + g_free (str); + + gtk_label_set_markup (GTK_LABEL (primary_label), markup_str); + g_free (markup_str); + gtk_box_pack_start (GTK_BOX (vbox), primary_label, FALSE, FALSE, 0); + + vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); + gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0); + + select_label = gtk_label_new_with_mnemonic (_("S_elect the documents you want to save:")); + + gtk_box_pack_start (GTK_BOX (vbox2), select_label, FALSE, FALSE, 0); + gtk_label_set_line_wrap (GTK_LABEL (select_label), TRUE); + gtk_widget_set_halign (select_label, GTK_ALIGN_START); + + scrolledwindow = gtk_scrolled_window_new (NULL, NULL); + gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN); + gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolledwindow), 60); + + treeview = create_treeview (priv); + gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview); + + /* Secondary label */ + secondary_label = gtk_label_new (_("If you don't save, " + "all your changes will be permanently lost.")); + + gtk_box_pack_start (GTK_BOX (vbox2), secondary_label, FALSE, FALSE, 0); + gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); + + gtk_label_set_mnemonic_widget (GTK_LABEL (select_label), treeview); + + gtk_widget_show_all (hbox); +} + +static void +set_unsaved_document (XedCloseConfirmationDialog *dlg, + const GList *list) +{ + XedCloseConfirmationDialogPrivate *priv; + + g_return_if_fail (list != NULL); + + priv = dlg->priv; + g_return_if_fail (priv->unsaved_documents == NULL); + + priv->unsaved_documents = g_list_copy ((GList *)list); + + if (GET_MODE (priv) == SINGLE_DOC_MODE) + { + build_single_doc_dialog (dlg); + } + else + { + build_multiple_docs_dialog (dlg); + } +} + +const GList * +xed_close_confirmation_dialog_get_unsaved_documents (XedCloseConfirmationDialog *dlg) +{ + g_return_val_if_fail (XED_IS_CLOSE_CONFIRMATION_DIALOG (dlg), NULL); + + return dlg->priv->unsaved_documents; +} + diff --git a/xed/dialogs/xed-close-confirmation-dialog.h b/xed/xed-close-confirmation-dialog.h similarity index 100% rename from xed/dialogs/xed-close-confirmation-dialog.h rename to xed/xed-close-confirmation-dialog.h diff --git a/xed/xed-commands-edit.c b/xed/xed-commands-edit.c index 4762765..5509332 100644 --- a/xed/xed-commands-edit.c +++ b/xed/xed-commands-edit.c @@ -40,7 +40,7 @@ #include "xed-window.h" #include "xed-debug.h" #include "xed-view.h" -#include "dialogs/xed-preferences-dialog.h" +#include "xed-preferences-dialog.h" void _xed_cmd_edit_undo (GtkAction *action, diff --git a/xed/xed-commands-file.c b/xed/xed-commands-file.c index f239261..7602efe 100644 --- a/xed/xed-commands-file.c +++ b/xed/xed-commands-file.c @@ -34,8 +34,6 @@ #include #endif -#include /* For strlen and strcmp */ - #include #include #include @@ -47,333 +45,271 @@ #include "xed-debug.h" #include "xed-utils.h" #include "xed-file-chooser-dialog.h" -#include "dialogs/xed-close-confirmation-dialog.h" +#include "xed-close-confirmation-dialog.h" /* Defined constants */ -#define XED_OPEN_DIALOG_KEY "xed-open-dialog-key" -#define XED_TAB_TO_SAVE_AS "xed-tab-to-save-as" +#define XED_OPEN_DIALOG_KEY "xed-open-dialog-key" +#define XED_TAB_TO_SAVE_AS "xed-tab-to-save-as" #define XED_LIST_OF_TABS_TO_SAVE_AS "xed-list-of-tabs-to-save-as" #define XED_IS_CLOSING_ALL "xed-is-closing-all" -#define XED_IS_QUITTING "xed-is-quitting" -#define XED_IS_CLOSING_TAB "xed-is-closing-tab" -#define XED_IS_QUITTING_ALL "xed-is-quitting-all" +#define XED_IS_QUITTING "xed-is-quitting" +#define XED_IS_CLOSING_TAB "xed-is-closing-tab" +#define XED_IS_QUITTING_ALL "xed-is-quitting-all" static void tab_state_changed_while_saving (XedTab *tab, - GParamSpec *pspec, - XedWindow *window); + GParamSpec *pspec, + XedWindow *window); + +static void save_as_tab (XedTab *tab, + XedWindow *window); void _xed_cmd_file_new (GtkAction *action, - XedWindow *window) + XedWindow *window) { - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - xed_window_create_tab (window, TRUE); + xed_window_create_tab (window, TRUE); } static XedTab * -get_tab_from_file (GList *docs, GFile *file) +get_tab_from_file (GList *docs, + GFile *file) { - XedTab *tab = NULL; + XedTab *tab = NULL; - while (docs != NULL) - { - XedDocument *d; - GFile *l; + while (docs != NULL) + { + XedDocument *d; + GtkSourceFile *source_file; + GFile *l; - d = XED_DOCUMENT (docs->data); + d = XED_DOCUMENT (docs->data); + source_file = xed_document_get_file (d); - l = xed_document_get_location (d); - if (l != NULL) - { - if (g_file_equal (l, file)) - { - tab = xed_tab_get_from_document (d); - g_object_unref (l); - break; - } + l = gtk_source_file_get_location (source_file); + if (l != NULL && g_file_equal (l, file)) + { + tab = xed_tab_get_from_document (d); + break; + } - g_object_unref (l); - } + docs = g_list_next (docs); + } - docs = g_list_next (docs); - } - - return tab; + return tab; } static gboolean -is_duplicated_file (GSList *files, GFile *file) +is_duplicated_file (GSList *files, + GFile *file) { - while (files != NULL) - { - if (g_file_equal (files->data, file)) - return TRUE; + while (files != NULL) + { + if (g_file_equal (files->data, file)) + { + return TRUE; + } - files = g_slist_next (files); - } + files = g_slist_next (files); + } - return FALSE; + return FALSE; } /* File loading */ -static gint -load_file_list (XedWindow *window, - GSList *files, - const XedEncoding *encoding, - gint line_pos, - gboolean create) +static GSList * +load_file_list (XedWindow *window, + const GSList *files, + const GtkSourceEncoding *encoding, + gint line_pos, + gboolean create) { - XedTab *tab; - gint loaded_files = 0; /* Number of files to load */ - gboolean jump_to = TRUE; /* Whether to jump to the new tab */ - GList *win_docs; - GSList *files_to_load = NULL; - GSList *l; + XedTab *tab; + GSList *loaded_files = NULL; /* Number of files to load */ + gboolean jump_to = TRUE; /* Whether to jump to the new tab */ + GList *win_docs; + GSList *files_to_load = NULL; + const GSList *l; + gint num_loaded_files = 0; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - win_docs = xed_window_get_documents (window); + win_docs = xed_window_get_documents (window); - /* Remove the uris corresponding to documents already open - * in "window" and remove duplicates from "uris" list */ - for (l = files; l != NULL; l = l->next) - { - if (!is_duplicated_file (files_to_load, l->data)) - { - tab = get_tab_from_file (win_docs, l->data); - if (tab != NULL) - { - if (l == files) - { - xed_window_set_active_tab (window, tab); - jump_to = FALSE; + /* Remove the uris corresponding to documents already open + * in "window" and remove duplicates from "uris" list */ + for (l = files; l != NULL; l = l->next) + { + if (!is_duplicated_file (files_to_load, l->data)) + { + tab = get_tab_from_file (win_docs, l->data); + if (tab != NULL) + { + if (l == files) + { + XedDocument *doc; - if (line_pos > 0) - { - XedDocument *doc; - XedView *view; + xed_window_set_active_tab (window, tab); + jump_to = FALSE; + doc = xed_tab_get_document (tab); - doc = xed_tab_get_document (tab); - view = xed_tab_get_view (tab); + if (line_pos > 0) + { + xed_document_goto_line (doc, line_pos - 1); + xed_view_scroll_to_cursor (xed_tab_get_view (tab)); + } + } - /* document counts lines starting from 0 */ - xed_document_goto_line (doc, line_pos - 1); - xed_view_scroll_to_cursor (view); - } - } + ++num_loaded_files; + loaded_files = g_slist_prepend (loaded_files, xed_tab_get_document (tab)); + } + else + { + files_to_load = g_slist_prepend (files_to_load, l->data); + } + } + } - ++loaded_files; - } - else - { - files_to_load = g_slist_prepend (files_to_load, - l->data); - } - } - } + g_list_free (win_docs); - g_list_free (win_docs); + if (files_to_load == NULL) + { + return g_slist_reverse (loaded_files); + } - if (files_to_load == NULL) - return loaded_files; - - files_to_load = g_slist_reverse (files_to_load); - l = files_to_load; + files_to_load = g_slist_reverse (files_to_load); + l = files_to_load; - tab = xed_window_get_active_tab (window); - if (tab != NULL) - { - XedDocument *doc; + tab = xed_window_get_active_tab (window); + if (tab != NULL) + { + XedDocument *doc; - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); - if (xed_document_is_untouched (doc) && - (xed_tab_get_state (tab) == XED_TAB_STATE_NORMAL)) - { - gchar *uri; + if (xed_document_is_untouched (doc) && (xed_tab_get_state (tab) == XED_TAB_STATE_NORMAL)) + { + _xed_tab_load (tab, l->data, encoding, line_pos, create); - // FIXME: pass the GFile to tab when api is there - uri = g_file_get_uri (l->data); - _xed_tab_load (tab, - uri, - encoding, - line_pos, - create); - g_free (uri); + l = g_slist_next (l); + jump_to = FALSE; - l = g_slist_next (l); - jump_to = FALSE; + ++num_loaded_files; + loaded_files = g_slist_prepend (loaded_files, xed_tab_get_document (tab)); + } + } - ++loaded_files; - } - } + while (l != NULL) + { + g_return_val_if_fail (l->data != NULL, 0); - while (l != NULL) - { - gchar *uri; + tab = xed_window_create_tab_from_location (window, l->data, encoding, line_pos, create, jump_to); - g_return_val_if_fail (l->data != NULL, 0); + if (tab != NULL) + { + jump_to = FALSE; + ++num_loaded_files; + loaded_files = g_slist_prepend (loaded_files, xed_tab_get_document (tab)); + } - // FIXME: pass the GFile to tab when api is there - uri = g_file_get_uri (l->data); - tab = xed_window_create_tab_from_uri (window, - uri, - encoding, - line_pos, - create, - jump_to); - g_free (uri); + l = g_slist_next (l); + } - if (tab != NULL) - { - jump_to = FALSE; - ++loaded_files; - } + loaded_files = g_slist_reverse (loaded_files); - l = g_slist_next (l); - } + if (num_loaded_files == 1) + { + XedDocument *doc; + gchar *uri_for_display; - if (loaded_files == 1) - { - XedDocument *doc; - gchar *uri_for_display; + g_return_val_if_fail (tab != NULL, loaded_files); - g_return_val_if_fail (tab != NULL, loaded_files); + doc = xed_tab_get_document (tab); + uri_for_display = xed_document_get_uri_for_display (doc); - doc = xed_tab_get_document (tab); - uri_for_display = xed_document_get_uri_for_display (doc); + xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), + window->priv->generic_message_cid, + _("Loading file '%s'\342\200\246"), + uri_for_display); - xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), - window->priv->generic_message_cid, - _("Loading file '%s'\342\200\246"), - uri_for_display); + g_free (uri_for_display); + } + else + { + xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), + window->priv->generic_message_cid, + ngettext("Loading %d file\342\200\246", + "Loading %d files\342\200\246", + num_loaded_files), + num_loaded_files); + } - g_free (uri_for_display); - } - else - { - xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), - window->priv->generic_message_cid, - ngettext("Loading %d file\342\200\246", - "Loading %d files\342\200\246", - loaded_files), - loaded_files); - } + /* Free uris_to_load. Note that l points to the first element of uris_to_load */ + g_slist_free (files_to_load); - /* Free uris_to_load. Note that l points to the first element of uris_to_load */ - g_slist_free (files_to_load); - - return loaded_files; -} - - -// FIXME: we should expose API with GFile and just make the uri -// variants backward compat wrappers - -static gint -load_uri_list (XedWindow *window, - const GSList *uris, - const XedEncoding *encoding, - gint line_pos, - gboolean create) -{ - GSList *files = NULL; - const GSList *u; - gint ret; - - for (u = uris; u != NULL; u = u->next) - { - gchar *uri = u->data; - - if (xed_utils_is_valid_uri (uri)) - files = g_slist_prepend (files, g_file_new_for_uri (uri)); - else - g_warning ("invalid uri: %s", uri); - } - files = g_slist_reverse (files); - - ret = load_file_list (window, files, encoding, line_pos, create); - - g_slist_foreach (files, (GFunc) g_object_unref, NULL); - g_slist_free (files); - - return ret; + return loaded_files; } /** - * xed_commands_load_uri: + * xed_commands_load_location: + * @window: a #XedWindow + * @location: a #GFile to be loaded + * @encoding: (allow-none): the #GtkSourceEncoding of @location + * @line_pos: the line column to place the cursor when @location is loaded + * + * Loads @location. Ignores non-existing locations + */ +void +xed_commands_load_location (XedWindow *window, + GFile *location, + const GtkSourceEncoding *encoding, + gint line_pos) +{ + GSList *locations = NULL; + gchar *uri; + GSList *ret; + + g_return_if_fail (XED_IS_WINDOW (window)); + g_return_if_fail (G_IS_FILE (location)); + g_return_if_fail (xed_utils_is_valid_location (location)); + + uri = g_file_get_uri (location); + xed_debug_message (DEBUG_COMMANDS, "Loading URI '%s'", uri); + g_free (uri); + + locations = g_slist_prepend (locations, location); + + ret = load_file_list (window, locations, encoding, line_pos, FALSE); + g_slist_free (ret); + + g_slist_free (locations); +} + +/** + * xed_commands_load_locations: * @window: - * @uri: + * @locations: (element-type GLib.File) (transfer none): * @encoding: (allow-none): * @line_pos: * - * Do nothing if uri does not exist + * Ignore non-existing locations * - * Returns: (transfer container): + * Returns: */ -void -xed_commands_load_uri (XedWindow *window, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos) +GSList * +xed_commands_load_locations (XedWindow *window, + const GSList *locations, + const GtkSourceEncoding *encoding, + gint line_pos) { - GSList *uris = NULL; + g_return_val_if_fail (XED_IS_WINDOW (window), 0); + g_return_val_if_fail ((locations != NULL) && (locations->data != NULL), 0); - g_return_if_fail (XED_IS_WINDOW (window)); - g_return_if_fail (uri != NULL); - g_return_if_fail (xed_utils_is_valid_uri (uri)); + xed_debug (DEBUG_COMMANDS); - xed_debug_message (DEBUG_COMMANDS, "Loading URI '%s'", uri); - - uris = g_slist_prepend (uris, (gchar *)uri); - - load_uri_list (window, uris, encoding, line_pos, FALSE); - - g_slist_free (uris); -} - -/** - * xed_commands_load_uris: - * @window: - * @uris: - * @encoding: - * @line_pos: - * - * Ignore non-existing URIs - * - * Returns: (transfer container): - */ -gint -xed_commands_load_uris (XedWindow *window, - const GSList *uris, - const XedEncoding *encoding, - gint line_pos) -{ - g_return_val_if_fail (XED_IS_WINDOW (window), 0); - g_return_val_if_fail ((uris != NULL) && (uris->data != NULL), 0); - - xed_debug (DEBUG_COMMANDS); - - return load_uri_list (window, uris, encoding, line_pos, FALSE); -} - -/* - * This should become public once we convert all api to GFile: - */ -static gint -xed_commands_load_files (XedWindow *window, - GSList *files, - const XedEncoding *encoding, - gint line_pos) -{ - g_return_val_if_fail (XED_IS_WINDOW (window), 0); - g_return_val_if_fail ((files != NULL) && (files->data != NULL), 0); - - xed_debug (DEBUG_COMMANDS); - - return load_file_list (window, files, encoding, line_pos, FALSE); + return load_file_list (window, locations, encoding, line_pos, FALSE); } /* @@ -381,1321 +317,1233 @@ xed_commands_load_files (XedWindow *window, * first doc. Beside specifying a not existing uri creates a * titled document. */ -gint -_xed_cmd_load_files_from_prompt (XedWindow *window, - GSList *files, - const XedEncoding *encoding, - gint line_pos) +GSList * +_xed_cmd_load_files_from_prompt (XedWindow *window, + GSList *files, + const GtkSourceEncoding *encoding, + gint line_pos) { - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - return load_file_list (window, files, encoding, line_pos, TRUE); + return load_file_list (window, files, encoding, line_pos, TRUE); } static void open_dialog_destroyed (XedWindow *window, - XedFileChooserDialog *dialog) + XedFileChooserDialog *dialog) { - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_object_set_data (G_OBJECT (window), - XED_OPEN_DIALOG_KEY, - NULL); + g_object_set_data (G_OBJECT (window), XED_OPEN_DIALOG_KEY, NULL); } static void open_dialog_response_cb (XedFileChooserDialog *dialog, - gint response_id, + gint response_id, XedWindow *window) { - GSList *files; - const XedEncoding *encoding; + GSList *files; + const GtkSourceEncoding *encoding; + GSList *loaded; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - if (response_id != GTK_RESPONSE_OK) - { - gtk_widget_destroy (GTK_WIDGET (dialog)); + if (response_id != GTK_RESPONSE_OK) + { + gtk_widget_destroy (GTK_WIDGET (dialog)); - return; - } + return; + } - files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (dialog)); - g_return_if_fail (files != NULL); + files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (dialog)); + g_return_if_fail (files != NULL); - encoding = xed_file_chooser_dialog_get_encoding (dialog); + encoding = xed_file_chooser_dialog_get_encoding (dialog); - gtk_widget_destroy (GTK_WIDGET (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); - /* Remember the folder we navigated to */ - _xed_window_set_default_location (window, files->data); + /* Remember the folder we navigated to */ + _xed_window_set_default_location (window, files->data); - xed_commands_load_files (window, - files, - encoding, - 0); + loaded = xed_commands_load_locations (window, files, encoding, 0); - g_slist_foreach (files, (GFunc) g_object_unref, NULL); - g_slist_free (files); + g_slist_free (loaded); + + g_slist_foreach (files, (GFunc) g_object_unref, NULL); + g_slist_free (files); } void -_xed_cmd_file_open (GtkAction *action, - XedWindow *window) +_xed_cmd_file_open (GtkAction *action, + XedWindow *window) { - GtkWidget *open_dialog; - gpointer data; - XedDocument *doc; - GFile *default_path = NULL; + GtkWidget *open_dialog; + gpointer data; + XedDocument *doc; + GFile *default_path = NULL; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - data = g_object_get_data (G_OBJECT (window), XED_OPEN_DIALOG_KEY); + data = g_object_get_data (G_OBJECT (window), XED_OPEN_DIALOG_KEY); - if (data != NULL) - { - g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (data)); + if (data != NULL) + { + g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (data)); - gtk_window_present (GTK_WINDOW (data)); + gtk_window_present (GTK_WINDOW (data)); - return; - } + return; + } - /* Translators: "Open Files" is the title of the file chooser window */ - open_dialog = xed_file_chooser_dialog_new (_("Open Files"), - GTK_WINDOW (window), - GTK_FILE_CHOOSER_ACTION_OPEN, - NULL, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_OK, - NULL); + /* Translators: "Open Files" is the title of the file chooser window */ + open_dialog = xed_file_chooser_dialog_new (_("Open Files"), + GTK_WINDOW (window), + GTK_FILE_CHOOSER_ACTION_OPEN, + NULL, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Open"), GTK_RESPONSE_OK, + NULL); - g_object_set_data (G_OBJECT (window), - XED_OPEN_DIALOG_KEY, - open_dialog); + g_object_set_data (G_OBJECT (window), XED_OPEN_DIALOG_KEY, open_dialog); - g_object_weak_ref (G_OBJECT (open_dialog), - (GWeakNotify) open_dialog_destroyed, - window); + g_object_weak_ref (G_OBJECT (open_dialog), (GWeakNotify) open_dialog_destroyed, window); - /* Set the curret folder uri */ - doc = xed_window_get_active_document (window); - if (doc != NULL) - { - GFile *file; + /* Set the curret folder uri */ + doc = xed_window_get_active_document (window); + if (doc != NULL) + { + GtkSourceFile *file = xed_document_get_file (doc); + GFile *location = gtk_source_file_get_location (file); - file = xed_document_get_location (doc); + if (location != NULL) + { + default_path = g_file_get_parent (location); + } + } - if (file != NULL) - { - default_path = g_file_get_parent (file); - g_object_unref (file); - } - } + if (default_path == NULL) + { + default_path = _xed_window_get_default_location (window); + } - if (default_path == NULL) - default_path = _xed_window_get_default_location (window); + if (default_path != NULL) + { + gchar *uri; - if (default_path != NULL) - { - gchar *uri; + uri = g_file_get_uri (default_path); + gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (open_dialog), uri); - uri = g_file_get_uri (default_path); - gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (open_dialog), - uri); + g_free (uri); + g_object_unref (default_path); + } - g_free (uri); - g_object_unref (default_path); - } + g_signal_connect (open_dialog, "response", G_CALLBACK (open_dialog_response_cb), window); - g_signal_connect (open_dialog, - "response", - G_CALLBACK (open_dialog_response_cb), - window); - - gtk_widget_show (open_dialog); + gtk_widget_show (open_dialog); } -/* File saving */ -static void file_save_as (XedTab *tab, XedWindow *window); - static gboolean is_read_only (GFile *location) { - gboolean ret = TRUE; /* default to read only */ - GFileInfo *info; + gboolean ret = TRUE; /* default to read only */ + GFileInfo *info; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - info = g_file_query_info (location, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, - G_FILE_QUERY_INFO_NONE, - NULL, - NULL); + info = g_file_query_info (location, + G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); - if (info != NULL) - { - if (g_file_info_has_attribute (info, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) - { - ret = !g_file_info_get_attribute_boolean (info, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); - } + if (info != NULL) + { + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) + { + ret = !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); + } - g_object_unref (info); - } + g_object_unref (info); + } - return ret; + return ret; } /* FIXME: modify this dialog to be similar to the one provided by gtk+ for * already existing files - Paolo (Oct. 11, 2005) */ static gboolean -replace_read_only_file (GtkWindow *parent, GFile *file) +replace_read_only_file (GtkWindow *parent, + GFile *file) { - GtkWidget *dialog; - gint ret; - gchar *parse_name; - gchar *name_for_display; + GtkWidget *dialog; + gint ret; + gchar *parse_name; + gchar *name_for_display; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - parse_name = g_file_get_parse_name (file); + parse_name = g_file_get_parse_name (file); - /* Truncate the name so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the name doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - name_for_display = xed_utils_str_middle_truncate (parse_name, 50); - g_free (parse_name); + /* Truncate the name so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the name doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + name_for_display = xed_utils_str_middle_truncate (parse_name, 50); + g_free (parse_name); - dialog = gtk_message_dialog_new (parent, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("The file \"%s\" is read-only."), - name_for_display); - g_free (name_for_display); + dialog = gtk_message_dialog_new (parent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _("The file \"%s\" is read-only."), + name_for_display); + g_free (name_for_display); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - _("Do you want to try to replace it " - "with the one you are saving?")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("Do you want to try to replace it " + "with the one you are saving?")); - gtk_dialog_add_button (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Replace"), GTK_RESPONSE_YES); - xed_dialog_add_button (GTK_DIALOG (dialog), - _("_Replace"), - GTK_STOCK_SAVE_AS, - GTK_RESPONSE_YES); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), - GTK_RESPONSE_CANCEL); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + ret = gtk_dialog_run (GTK_DIALOG (dialog)); - ret = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); - gtk_widget_destroy (dialog); + return (ret == GTK_RESPONSE_YES); +} - return (ret == GTK_RESPONSE_YES); +static void +save_finish_cb (XedTab *tab, + GAsyncResult *result, + gpointer user_data) +{ + _xed_tab_save_finish (tab, result); } static void save_dialog_response_cb (XedFileChooserDialog *dialog, - gint response_id, + gint response_id, XedWindow *window) { - GFile *file; - const XedEncoding *encoding; - XedTab *tab; - gpointer data; - GSList *tabs_to_save_as; - XedDocumentNewlineType newline_type; + XedTab *tab; + gpointer data; + GSList *tabs_to_save_as; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - tab = XED_TAB (g_object_get_data (G_OBJECT (dialog), - XED_TAB_TO_SAVE_AS)); + tab = XED_TAB (g_object_get_data (G_OBJECT (dialog), XED_TAB_TO_SAVE_AS)); - if (response_id != GTK_RESPONSE_OK) - { - gtk_widget_destroy (GTK_WIDGET (dialog)); + if (response_id != GTK_RESPONSE_OK) + { + gtk_widget_destroy (GTK_WIDGET (dialog)); - goto save_next_tab; - } + goto save_next_tab; + } - file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); - g_return_if_fail (file != NULL); + if (tab != NULL) + { + GFile *location; + XedDocument *doc; + gchar *parse_name; + GtkSourceNewlineType newline_type; + const GtkSourceEncoding *encoding; - encoding = xed_file_chooser_dialog_get_encoding (dialog); - newline_type = xed_file_chooser_dialog_get_newline_type (dialog); + doc = xed_tab_get_document (tab); - gtk_widget_destroy (GTK_WIDGET (dialog)); + location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); + g_return_if_fail (location != NULL); - if (tab != NULL) - { - XedDocument *doc; - gchar *parse_name; - gchar *uri; + encoding = xed_file_chooser_dialog_get_encoding (dialog); + newline_type = xed_file_chooser_dialog_get_newline_type (dialog); - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); + gtk_widget_destroy (GTK_WIDGET (dialog)); - parse_name = g_file_get_parse_name (file); + doc = xed_tab_get_document (tab); + g_return_if_fail (XED_IS_DOCUMENT (doc)); - xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), - window->priv->generic_message_cid, - _("Saving file '%s'\342\200\246"), - parse_name); + parse_name = g_file_get_parse_name (location); - g_free (parse_name); + xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), + window->priv->generic_message_cid, + _("Saving file '%s'\342\200\246"), + parse_name); - /* let's remember the dir we navigated too, - * even if the saving fails... */ - _xed_window_set_default_location (window, file); + g_free (parse_name); - // FIXME: pass the GFile to tab when api is there - uri = g_file_get_uri (file); - _xed_tab_save_as (tab, uri, encoding, newline_type); - g_free (uri); - } + /* let's remember the dir we navigated too, + * even if the saving fails... */ + _xed_window_set_default_location (window, location); - g_object_unref (file); + _xed_tab_save_as_async (tab, + location, + encoding, + newline_type, + NULL, + (GAsyncReadyCallback) save_finish_cb, + NULL); + + g_object_unref (location); + } save_next_tab: - data = g_object_get_data (G_OBJECT (window), - XED_LIST_OF_TABS_TO_SAVE_AS); - if (data == NULL) - return; + data = g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS); + if (data == NULL) + { + return; + } - /* Save As the next tab of the list (we are Saving All files) */ - tabs_to_save_as = (GSList *)data; - g_return_if_fail (tab == XED_TAB (tabs_to_save_as->data)); + /* Save As the next tab of the list (we are Saving All files) */ + tabs_to_save_as = (GSList *)data; + g_return_if_fail (tab == XED_TAB (tabs_to_save_as->data)); - /* Remove the first item of the list */ - tabs_to_save_as = g_slist_delete_link (tabs_to_save_as, - tabs_to_save_as); + /* Remove the first item of the list */ + tabs_to_save_as = g_slist_delete_link (tabs_to_save_as, tabs_to_save_as); - g_object_set_data (G_OBJECT (window), - XED_LIST_OF_TABS_TO_SAVE_AS, - tabs_to_save_as); + g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as); - if (tabs_to_save_as != NULL) - { - tab = XED_TAB (tabs_to_save_as->data); + if (tabs_to_save_as != NULL) + { + tab = XED_TAB (tabs_to_save_as->data); - if (GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (tab), - XED_IS_CLOSING_TAB)) == TRUE) - { - g_object_set_data (G_OBJECT (tab), - XED_IS_CLOSING_TAB, - NULL); + if (GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (tab), XED_IS_CLOSING_TAB)) == TRUE) + { + g_object_set_data (G_OBJECT (tab), XED_IS_CLOSING_TAB, NULL); - /* Trace tab state changes */ - g_signal_connect (tab, - "notify::state", - G_CALLBACK (tab_state_changed_while_saving), - window); - } + /* Trace tab state changes */ + g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window); + } - xed_window_set_active_tab (window, tab); - file_save_as (tab, window); - } + xed_window_set_active_tab (window, tab); + save_as_tab (tab, window); + } } static GtkFileChooserConfirmation confirm_overwrite_callback (GtkFileChooser *dialog, - gpointer data) + gpointer data) { - gchar *uri; - GFile *file; - GtkFileChooserConfirmation res; + gchar *uri; + GFile *file; + GtkFileChooserConfirmation res; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - uri = gtk_file_chooser_get_uri (dialog); - file = g_file_new_for_uri (uri); - g_free (uri); + uri = gtk_file_chooser_get_uri (dialog); + file = g_file_new_for_uri (uri); + g_free (uri); - if (is_read_only (file)) - { - if (replace_read_only_file (GTK_WINDOW (dialog), file)) - res = GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME; - else - res = GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN; - } - else - { - /* fall back to the default confirmation dialog */ - res = GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM; - } + if (is_read_only (file)) + { + if (replace_read_only_file (GTK_WINDOW (dialog), file)) + { + res = GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME; + } + else + { + res = GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN; + } + } + else + { + /* fall back to the default confirmation dialog */ + res = GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM; + } - g_object_unref (file); + g_object_unref (file); - return res; + return res; } static void -file_save_as (XedTab *tab, - XedWindow *window) +save_as_tab (XedTab *tab, + XedWindow *window) { - GtkWidget *save_dialog; - GtkWindowGroup *wg; - XedDocument *doc; - GFile *file; - gboolean uri_set = FALSE; - const XedEncoding *encoding; - XedDocumentNewlineType newline_type; + GtkWidget *save_dialog; + GtkWindowGroup *wg; + XedDocument *doc; + GtkSourceFile *file; + GFile *location; + gboolean uri_set = FALSE; + const GtkSourceEncoding *encoding; + GtkSourceNewlineType newline_type; - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail (XED_IS_WINDOW (window)); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (XED_IS_WINDOW (window)); - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - save_dialog = xed_file_chooser_dialog_new (_("Save As\342\200\246"), - GTK_WINDOW (window), - GTK_FILE_CHOOSER_ACTION_SAVE, - NULL, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_OK, - NULL); + save_dialog = xed_file_chooser_dialog_new (_("Save As\342\200\246"), + GTK_WINDOW (window), + GTK_FILE_CHOOSER_ACTION_SAVE, + NULL, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Save"), GTK_RESPONSE_OK, + NULL); - gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (save_dialog), - TRUE); - g_signal_connect (save_dialog, - "confirm-overwrite", - G_CALLBACK (confirm_overwrite_callback), - NULL); + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (save_dialog), TRUE); + g_signal_connect (save_dialog, "confirm-overwrite", G_CALLBACK (confirm_overwrite_callback), NULL); - wg = xed_window_get_group (window); + wg = xed_window_get_group (window); - gtk_window_group_add_window (wg, - GTK_WINDOW (save_dialog)); + gtk_window_group_add_window (wg, GTK_WINDOW (save_dialog)); - /* Save As dialog is modal to its main window */ - gtk_window_set_modal (GTK_WINDOW (save_dialog), TRUE); + /* Save As dialog is modal to its main window */ + gtk_window_set_modal (GTK_WINDOW (save_dialog), TRUE); - /* Set the suggested file name */ - doc = xed_tab_get_document (tab); - file = xed_document_get_location (doc); + /* Set the suggested file name */ + doc = xed_tab_get_document (tab); + file = xed_document_get_file (doc); + location = gtk_source_file_get_location (file); - if (file != NULL) - { - uri_set = gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), - file, - NULL); - - g_object_unref (file); - } + if (location != NULL) + { + uri_set = gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), location, NULL); + } - if (!uri_set) - { - GFile *default_path; - gchar *docname; + if (!uri_set) + { + GFile *default_path; + gchar *docname; - default_path = _xed_window_get_default_location (window); - docname = xed_document_get_short_name_for_display (doc); + default_path = _xed_window_get_default_location (window); + docname = xed_document_get_short_name_for_display (doc); - if (default_path != NULL) - { - gchar *uri; + if (default_path != NULL) + { + gchar *uri; - uri = g_file_get_uri (default_path); - gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (save_dialog), - uri); + uri = g_file_get_uri (default_path); + gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (save_dialog), uri); - g_free (uri); - g_object_unref (default_path); - } + g_free (uri); + g_object_unref (default_path); + } - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (save_dialog), - docname); + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (save_dialog), docname); - g_free (docname); - } + g_free (docname); + } - /* Set suggested encoding */ - encoding = xed_document_get_encoding (doc); - g_return_if_fail (encoding != NULL); + /* Set suggested encoding */ + encoding = gtk_source_file_get_encoding (file); - newline_type = xed_document_get_newline_type (doc); + if (encoding == NULL) + { + encoding = gtk_source_encoding_get_utf8 (); + } - xed_file_chooser_dialog_set_encoding (XED_FILE_CHOOSER_DIALOG (save_dialog), - encoding); + newline_type = gtk_source_file_get_newline_type (file); - xed_file_chooser_dialog_set_newline_type (XED_FILE_CHOOSER_DIALOG (save_dialog), - newline_type); + xed_file_chooser_dialog_set_encoding (XED_FILE_CHOOSER_DIALOG (save_dialog), encoding); - g_object_set_data (G_OBJECT (save_dialog), - XED_TAB_TO_SAVE_AS, - tab); + xed_file_chooser_dialog_set_newline_type (XED_FILE_CHOOSER_DIALOG (save_dialog), newline_type); - g_signal_connect (save_dialog, - "response", - G_CALLBACK (save_dialog_response_cb), - window); + g_object_set_data (G_OBJECT (save_dialog), XED_TAB_TO_SAVE_AS, tab); - gtk_widget_show (save_dialog); + g_signal_connect (save_dialog, "response", G_CALLBACK (save_dialog_response_cb), window); + + gtk_widget_show (save_dialog); } static void -file_save (XedTab *tab, - XedWindow *window) +save_tab (XedTab *tab, + XedWindow *window) { - XedDocument *doc; - gchar *uri_for_display; + XedDocument *doc; + gchar *uri_for_display; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail (XED_IS_WINDOW (window)); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (XED_IS_WINDOW (window)); - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); + doc = xed_tab_get_document (tab); + g_return_if_fail (XED_IS_DOCUMENT (doc)); - if (xed_document_is_untitled (doc) || - xed_document_get_readonly (doc)) - { - xed_debug_message (DEBUG_COMMANDS, "Untitled or Readonly"); + if (xed_document_is_untitled (doc) || + xed_document_get_readonly (doc)) + { + xed_debug_message (DEBUG_COMMANDS, "Untitled or Readonly"); - file_save_as (tab, window); - - return; - } + save_as_tab (tab, window); - uri_for_display = xed_document_get_uri_for_display (doc); - xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), - window->priv->generic_message_cid, - _("Saving file '%s'\342\200\246"), - uri_for_display); + return; + } - g_free (uri_for_display); + uri_for_display = xed_document_get_uri_for_display (doc); + xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), + window->priv->generic_message_cid, + _("Saving file '%s'\342\200\246"), + uri_for_display); - _xed_tab_save (tab); + g_free (uri_for_display); + + _xed_tab_save_async (tab, + NULL, + (GAsyncReadyCallback) save_finish_cb, + NULL); } void -_xed_cmd_file_save (GtkAction *action, - XedWindow *window) +_xed_cmd_file_save (GtkAction *action, + XedWindow *window) { - XedTab *tab; + XedTab *tab; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - tab = xed_window_get_active_tab (window); - if (tab == NULL) - return; + tab = xed_window_get_active_tab (window); + if (tab == NULL) + { + return; + } - file_save (tab, window); + save_tab (tab, window); } void -_xed_cmd_file_save_as (GtkAction *action, - XedWindow *window) +_xed_cmd_file_save_as (GtkAction *action, + XedWindow *window) { - XedTab *tab; + XedTab *tab; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - tab = xed_window_get_active_tab (window); - if (tab == NULL) - return; + tab = xed_window_get_active_tab (window); + if (tab == NULL) + { + return; + } - file_save_as (tab, window); -} - -static gboolean -document_needs_saving (XedDocument *doc) -{ - if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc))) - return TRUE; - - /* we check if it was deleted only for local files - * since for remote files it may hang */ - if (xed_document_is_local (doc) && xed_document_get_deleted (doc)) - return TRUE; - - return FALSE; + save_as_tab (tab, window); } /* * The docs in the list must belong to the same XedWindow. */ -void -_xed_cmd_file_save_documents_list (XedWindow *window, - GList *docs) +static void +save_documents_list (XedWindow *window, + GList *docs) { - GList *l; - GSList *tabs_to_save_as = NULL; + GList *l; + GSList *tabs_to_save_as = NULL; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_if_fail (!(xed_window_get_state (window) & - (XED_WINDOW_STATE_PRINTING | - XED_WINDOW_STATE_SAVING_SESSION))); + g_return_if_fail (!(xed_window_get_state (window) & (XED_WINDOW_STATE_PRINTING | XED_WINDOW_STATE_SAVING_SESSION))); - l = docs; - while (l != NULL) - { - XedDocument *doc; - XedTab *t; - XedTabState state; + l = docs; + while (l != NULL) + { + XedDocument *doc; + XedTab *t; + XedTabState state; - g_return_if_fail (XED_IS_DOCUMENT (l->data)); - - doc = XED_DOCUMENT (l->data); - t = xed_tab_get_from_document (doc); - state = xed_tab_get_state (t); + g_return_if_fail (XED_IS_DOCUMENT (l->data)); - g_return_if_fail (state != XED_TAB_STATE_PRINTING); - g_return_if_fail (state != XED_TAB_STATE_PRINT_PREVIEWING); - g_return_if_fail (state != XED_TAB_STATE_CLOSING); + doc = XED_DOCUMENT (l->data); + t = xed_tab_get_from_document (doc); + state = xed_tab_get_state (t); - if ((state == XED_TAB_STATE_NORMAL) || - (state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) || - (state == XED_TAB_STATE_GENERIC_NOT_EDITABLE)) - { - /* FIXME: manage the case of local readonly files owned by the - user is running xed - Paolo (Dec. 8, 2005) */ - if (xed_document_is_untitled (doc) || - xed_document_get_readonly (doc)) - { - if (document_needs_saving (doc)) - { - tabs_to_save_as = g_slist_prepend (tabs_to_save_as, - t); - } - } - else - { - file_save (t, window); - } - } - else - { - /* If the state is: - - XED_TAB_STATE_LOADING: we do not save since we are sure the file is unmodified - - XED_TAB_STATE_REVERTING: we do not save since the user wants - to return back to the version of the file she previously saved - - XED_TAB_STATE_SAVING: well, we are already saving (no need to save again) - - XED_TAB_STATE_PRINTING, XED_TAB_STATE_PRINT_PREVIEWING: there is not a - real reason for not saving in this case, we do not save to avoid to run - two operations using the message area at the same time (may be we can remove - this limitation in the future). Note that SaveAll, ClosAll - and Quit are unsensitive if the window state is PRINTING. - - XED_TAB_STATE_GENERIC_ERROR: we do not save since the document contains - errors (I don't think this is a very frequent case, we should probably remove - this state) - - XED_TAB_STATE_LOADING_ERROR: there is nothing to save - - XED_TAB_STATE_REVERTING_ERROR: there is nothing to save and saving the current - document will overwrite the copy of the file the user wants to go back to - - XED_TAB_STATE_SAVING_ERROR: we do not save since we just failed to save, so there is - no reason to automatically retry... we wait for user intervention - - XED_TAB_STATE_CLOSING: this state is invalid in this case - */ + g_return_if_fail (state != XED_TAB_STATE_PRINTING); + g_return_if_fail (state != XED_TAB_STATE_PRINT_PREVIEWING); + g_return_if_fail (state != XED_TAB_STATE_CLOSING); - gchar *uri_for_display; + if ((state == XED_TAB_STATE_NORMAL) || + (state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) || + (state == XED_TAB_STATE_GENERIC_NOT_EDITABLE)) + { + /* FIXME: manage the case of local readonly files owned by the + user is running xed - Paolo (Dec. 8, 2005) */ + if (xed_document_is_untitled (doc) || xed_document_get_readonly (doc)) + { + if (_xed_document_needs_saving (doc)) + { + tabs_to_save_as = g_slist_prepend (tabs_to_save_as, t); + } + } + else + { + save_tab (t, window); + } + } + else + { + /* If the state is: + - XED_TAB_STATE_LOADING: we do not save since we are sure the file is unmodified + - XED_TAB_STATE_REVERTING: we do not save since the user wants + to return back to the version of the file she previously saved + - XED_TAB_STATE_SAVING: well, we are already saving (no need to save again) + - XED_TAB_STATE_PRINTING, XED_TAB_STATE_PRINT_PREVIEWING: there is not a + real reason for not saving in this case, we do not save to avoid to run + two operations using the message area at the same time (may be we can remove + this limitation in the future). Note that SaveAll, ClosAll + and Quit are unsensitive if the window state is PRINTING. + - XED_TAB_STATE_GENERIC_ERROR: we do not save since the document contains + errors (I don't think this is a very frequent case, we should probably remove + this state) + - XED_TAB_STATE_LOADING_ERROR: there is nothing to save + - XED_TAB_STATE_REVERTING_ERROR: there is nothing to save and saving the current + document will overwrite the copy of the file the user wants to go back to + - XED_TAB_STATE_SAVING_ERROR: we do not save since we just failed to save, so there is + no reason to automatically retry... we wait for user intervention + - XED_TAB_STATE_CLOSING: this state is invalid in this case + */ - uri_for_display = xed_document_get_uri_for_display (doc); - xed_debug_message (DEBUG_COMMANDS, - "File '%s' not saved. State: %d", - uri_for_display, - state); - g_free (uri_for_display); - } + gchar *uri_for_display; - l = g_list_next (l); - } + uri_for_display = xed_document_get_uri_for_display (doc); + xed_debug_message (DEBUG_COMMANDS, + "File '%s' not saved. State: %d", + uri_for_display, + state); + g_free (uri_for_display); + } - if (tabs_to_save_as != NULL) - { - XedTab *tab; + l = g_list_next (l); + } - tabs_to_save_as = g_slist_reverse (tabs_to_save_as ); + if (tabs_to_save_as != NULL) + { + XedTab *tab; - g_return_if_fail (g_object_get_data (G_OBJECT (window), - XED_LIST_OF_TABS_TO_SAVE_AS) == NULL); + tabs_to_save_as = g_slist_reverse (tabs_to_save_as ); - g_object_set_data (G_OBJECT (window), - XED_LIST_OF_TABS_TO_SAVE_AS, - tabs_to_save_as); + g_return_if_fail (g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS) == NULL); - tab = XED_TAB (tabs_to_save_as->data); + g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as); - xed_window_set_active_tab (window, tab); - file_save_as (tab, window); - } + tab = XED_TAB (tabs_to_save_as->data); + + xed_window_set_active_tab (window, tab); + save_as_tab (tab, window); + } } void xed_commands_save_all_documents (XedWindow *window) { - GList *docs; - - g_return_if_fail (XED_IS_WINDOW (window)); + GList *docs; - xed_debug (DEBUG_COMMANDS); + g_return_if_fail (XED_IS_WINDOW (window)); - docs = xed_window_get_documents (window); + xed_debug (DEBUG_COMMANDS); - _xed_cmd_file_save_documents_list (window, docs); + docs = xed_window_get_documents (window); - g_list_free (docs); + save_documents_list (window, docs); + + g_list_free (docs); } void -_xed_cmd_file_save_all (GtkAction *action, - XedWindow *window) +_xed_cmd_file_save_all (GtkAction *action, + XedWindow *window) { - xed_commands_save_all_documents (window); + xed_commands_save_all_documents (window); } void xed_commands_save_document (XedWindow *window, - XedDocument *document) + XedDocument *document) { - XedTab *tab; + XedTab *tab; - g_return_if_fail (XED_IS_WINDOW (window)); - g_return_if_fail (XED_IS_DOCUMENT (document)); - - xed_debug (DEBUG_COMMANDS); - - tab = xed_tab_get_from_document (document); - file_save (tab, window); + g_return_if_fail (XED_IS_WINDOW (window)); + g_return_if_fail (XED_IS_DOCUMENT (document)); + + xed_debug (DEBUG_COMMANDS); + + tab = xed_tab_get_from_document (document); + save_tab (tab, window); } /* File revert */ static void do_revert (XedWindow *window, - XedTab *tab) + XedTab *tab) { - XedDocument *doc; - gchar *docname; + XedDocument *doc; + gchar *docname; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - doc = xed_tab_get_document (tab); - docname = xed_document_get_short_name_for_display (doc); + doc = xed_tab_get_document (tab); + docname = xed_document_get_short_name_for_display (doc); - xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), - window->priv->generic_message_cid, - _("Reverting the document '%s'\342\200\246"), - docname); + xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), + window->priv->generic_message_cid, + _("Reverting the document '%s'\342\200\246"), + docname); - g_free (docname); + g_free (docname); - _xed_tab_revert (tab); + _xed_tab_revert (tab); } static void -revert_dialog_response_cb (GtkDialog *dialog, - gint response_id, - XedWindow *window) +revert_dialog_response_cb (GtkDialog *dialog, + gint response_id, + XedWindow *window) { - XedTab *tab; + XedTab *tab; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - /* FIXME: we are relying on the fact that the dialog is - modal so the active tab can't be changed... - not very nice - Paolo (Oct 11, 2005) */ - tab = xed_window_get_active_tab (window); - if (tab == NULL) - return; + /* FIXME: we are relying on the fact that the dialog is + modal so the active tab can't be changed... + not very nice - Paolo (Oct 11, 2005) */ + tab = xed_window_get_active_tab (window); + if (tab == NULL) + { + return; + } - gtk_widget_destroy (GTK_WIDGET (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); - if (response_id == GTK_RESPONSE_OK) - { - do_revert (window, tab); - } + if (response_id == GTK_RESPONSE_OK) + { + do_revert (window, tab); + } } static GtkWidget * revert_dialog (XedWindow *window, - XedDocument *doc) + XedDocument *doc) { - GtkWidget *dialog; - gchar *docname; - gchar *primary_msg; - gchar *secondary_msg; - glong seconds; + GtkWidget *dialog; + gchar *docname; + gchar *primary_msg; + gchar *secondary_msg; + glong seconds; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - docname = xed_document_get_short_name_for_display (doc); - primary_msg = g_strdup_printf (_("Revert unsaved changes to document '%s'?"), - docname); - g_free (docname); + docname = xed_document_get_short_name_for_display (doc); + primary_msg = g_strdup_printf (_("Revert unsaved changes to document '%s'?"), docname); + g_free (docname); - seconds = MAX (1, _xed_document_get_seconds_since_last_save_or_load (doc)); + seconds = MAX (1, _xed_document_get_seconds_since_last_save_or_load (doc)); - if (seconds < 55) - { - secondary_msg = g_strdup_printf ( - ngettext ("Changes made to the document in the last %ld second " - "will be permanently lost.", - "Changes made to the document in the last %ld seconds " - "will be permanently lost.", - seconds), - seconds); - } - else if (seconds < 75) /* 55 <= seconds < 75 */ - { - secondary_msg = g_strdup (_("Changes made to the document in the last minute " - "will be permanently lost.")); - } - else if (seconds < 110) /* 75 <= seconds < 110 */ - { - secondary_msg = g_strdup_printf ( - ngettext ("Changes made to the document in the last minute and " - "%ld second will be permanently lost.", - "Changes made to the document in the last minute and " - "%ld seconds will be permanently lost.", - seconds - 60 ), - seconds - 60); - } - else if (seconds < 3600) - { - secondary_msg = g_strdup_printf ( - ngettext ("Changes made to the document in the last %ld minute " - "will be permanently lost.", - "Changes made to the document in the last %ld minutes " - "will be permanently lost.", - seconds / 60), - seconds / 60); - } - else if (seconds < 7200) - { - gint minutes; - seconds -= 3600; + if (seconds < 55) + { + secondary_msg = g_strdup_printf (ngettext ("Changes made to the document in the last %ld second " + "will be permanently lost.", + "Changes made to the document in the last %ld seconds " + "will be permanently lost.", + seconds), + seconds); + } + else if (seconds < 75) /* 55 <= seconds < 75 */ + { + secondary_msg = g_strdup (_("Changes made to the document in the last minute " + "will be permanently lost.")); + } + else if (seconds < 110) /* 75 <= seconds < 110 */ + { + secondary_msg = g_strdup_printf (ngettext ("Changes made to the document in the last minute and " + "%ld second will be permanently lost.", + "Changes made to the document in the last minute and " + "%ld seconds will be permanently lost.", + seconds - 60 ), + seconds - 60); + } + else if (seconds < 3600) + { + secondary_msg = g_strdup_printf (ngettext ("Changes made to the document in the last %ld minute " + "will be permanently lost.", + "Changes made to the document in the last %ld minutes " + "will be permanently lost.", + seconds / 60), + seconds / 60); + } + else if (seconds < 7200) + { + gint minutes; + seconds -= 3600; - minutes = seconds / 60; - if (minutes < 5) - { - secondary_msg = g_strdup (_("Changes made to the document in the last hour " - "will be permanently lost.")); - } - else - { - secondary_msg = g_strdup_printf ( - ngettext ("Changes made to the document in the last hour and " - "%d minute will be permanently lost.", - "Changes made to the document in the last hour and " - "%d minutes will be permanently lost.", - minutes), - minutes); - } - } - else - { - gint hours; + minutes = seconds / 60; + if (minutes < 5) + { + secondary_msg = g_strdup (_("Changes made to the document in the last hour " + "will be permanently lost.")); + } + else + { + secondary_msg = g_strdup_printf (ngettext ("Changes made to the document in the last hour and " + "%d minute will be permanently lost.", + "Changes made to the document in the last hour and " + "%d minutes will be permanently lost.", + minutes), + minutes); + } + } + else + { + gint hours; - hours = seconds / 3600; + hours = seconds / 3600; - secondary_msg = g_strdup_printf ( - ngettext ("Changes made to the document in the last %d hour " - "will be permanently lost.", - "Changes made to the document in the last %d hours " - "will be permanently lost.", - hours), - hours); - } + secondary_msg = g_strdup_printf (ngettext ("Changes made to the document in the last %d hour " + "will be permanently lost.", + "Changes made to the document in the last %d hours " + "will be permanently lost.", + hours), + hours); + } - dialog = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - "%s", primary_msg); + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + "%s", primary_msg); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - "%s", secondary_msg); - g_free (primary_msg); - g_free (secondary_msg); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", secondary_msg); + g_free (primary_msg); + g_free (secondary_msg); - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - gtk_dialog_add_button (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Revert"), GTK_RESPONSE_OK); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); - xed_dialog_add_button (GTK_DIALOG (dialog), - _("_Revert"), - GTK_STOCK_REVERT_TO_SAVED, - GTK_RESPONSE_OK); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), - GTK_RESPONSE_CANCEL); - - return dialog; + return dialog; } void _xed_cmd_file_revert (GtkAction *action, - XedWindow *window) + XedWindow *window) { - XedTab *tab; - XedDocument *doc; - GtkWidget *dialog; - GtkWindowGroup *wg; + XedTab *tab; + XedDocument *doc; + GtkWidget *dialog; + GtkWindowGroup *wg; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - tab = xed_window_get_active_tab (window); - g_return_if_fail (tab != NULL); + tab = xed_window_get_active_tab (window); + g_return_if_fail (tab != NULL); - /* If we are already displaying a notification - * reverting will drop local modifications, do - * not bug the user further */ - if (xed_tab_get_state (tab) == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) - { - do_revert (window, tab); - return; - } + /* If we are already displaying a notification + * reverting will drop local modifications, do + * not bug the user further */ + if (xed_tab_get_state (tab) == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) + { + do_revert (window, tab); + return; + } - doc = xed_tab_get_document (tab); - g_return_if_fail (doc != NULL); - g_return_if_fail (!xed_document_is_untitled (doc)); + doc = xed_tab_get_document (tab); + g_return_if_fail (doc != NULL); + g_return_if_fail (!xed_document_is_untitled (doc)); - dialog = revert_dialog (window, doc); + dialog = revert_dialog (window, doc); - wg = xed_window_get_group (window); + wg = xed_window_get_group (window); - gtk_window_group_add_window (wg, GTK_WINDOW (dialog)); + gtk_window_group_add_window (wg, GTK_WINDOW (dialog)); - gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); - g_signal_connect (dialog, - "response", - G_CALLBACK (revert_dialog_response_cb), - window); + g_signal_connect (dialog, "response", G_CALLBACK (revert_dialog_response_cb), window); - gtk_widget_show (dialog); + gtk_widget_show (dialog); } /* Close tab */ static gboolean really_close_tab (XedTab *tab) { - GtkWidget *toplevel; - XedWindow *window; + GtkWidget *toplevel; + XedWindow *window; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_val_if_fail (xed_tab_get_state (tab) == XED_TAB_STATE_CLOSING, - FALSE); + g_return_val_if_fail (xed_tab_get_state (tab) == XED_TAB_STATE_CLOSING, FALSE); - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tab)); - g_return_val_if_fail (XED_IS_WINDOW (toplevel), FALSE); + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tab)); + g_return_val_if_fail (XED_IS_WINDOW (toplevel), FALSE); - window = XED_WINDOW (toplevel); + window = XED_WINDOW (toplevel); - xed_window_close_tab (window, tab); + xed_window_close_tab (window, tab); - if (xed_window_get_active_tab (window) == NULL) - { - gboolean is_quitting; + if (xed_window_get_active_tab (window) == NULL) + { + gboolean is_quitting; - is_quitting = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), - XED_IS_QUITTING)); + is_quitting = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_QUITTING)); - if (is_quitting) - gtk_widget_destroy (GTK_WIDGET (window)); - } + if (is_quitting) + { + gtk_widget_destroy (GTK_WIDGET (window)); + } + } - return FALSE; + return FALSE; } static void -tab_state_changed_while_saving (XedTab *tab, - GParamSpec *pspec, - XedWindow *window) +tab_state_changed_while_saving (XedTab *tab, + GParamSpec *pspec, + XedWindow *window) { - XedTabState ts; + XedTabState ts; - ts = xed_tab_get_state (tab); + ts = xed_tab_get_state (tab); - xed_debug_message (DEBUG_COMMANDS, "State while saving: %d\n", ts); + xed_debug_message (DEBUG_COMMANDS, "State while saving: %d\n", ts); - /* When the state become NORMAL, it means the saving operation is - finished */ - if (ts == XED_TAB_STATE_NORMAL) - { - XedDocument *doc; + /* When the state become NORMAL, it means the saving operation is + finished */ + if (ts == XED_TAB_STATE_NORMAL) + { + XedDocument *doc; - g_signal_handlers_disconnect_by_func (tab, - G_CALLBACK (tab_state_changed_while_saving), - window); + g_signal_handlers_disconnect_by_func (tab, G_CALLBACK (tab_state_changed_while_saving), window); - doc = xed_tab_get_document (tab); - g_return_if_fail (doc != NULL); + doc = xed_tab_get_document (tab); + g_return_if_fail (doc != NULL); - /* If the saving operation failed or was interrupted, then the - document is still "modified" -> do not close the tab */ - if (document_needs_saving (doc)) - return; + /* If the saving operation failed or was interrupted, then the + document is still "modified" -> do not close the tab */ + if (_xed_document_needs_saving (doc)) + { + return; + } - /* Close the document only if it has been succesfully saved. - Tab state is set to CLOSING (it is a state without exiting - transitions) and the tab is closed in a idle handler */ - _xed_tab_mark_for_closing (tab); + /* Close the document only if it has been succesfully saved. + Tab state is set to CLOSING (it is a state without exiting + transitions) and the tab is closed in a idle handler */ + _xed_tab_mark_for_closing (tab); - g_idle_add_full (G_PRIORITY_HIGH_IDLE, - (GSourceFunc)really_close_tab, - tab, - NULL); - } + g_idle_add_full (G_PRIORITY_HIGH_IDLE, (GSourceFunc)really_close_tab, tab, NULL); + } } static void save_and_close (XedTab *tab, - XedWindow *window) + XedWindow *window) { - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - /* Trace tab state changes */ - g_signal_connect (tab, - "notify::state", - G_CALLBACK (tab_state_changed_while_saving), - window); + /* Trace tab state changes */ + g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window); - file_save (tab, window); + save_tab (tab, window); } static void save_as_and_close (XedTab *tab, - XedWindow *window) + XedWindow *window) { - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_object_set_data (G_OBJECT (tab), - XED_IS_CLOSING_TAB, - NULL); + g_object_set_data (G_OBJECT (tab), XED_IS_CLOSING_TAB, NULL); - /* Trace tab state changes */ - g_signal_connect (tab, - "notify::state", - G_CALLBACK (tab_state_changed_while_saving), - window); + /* Trace tab state changes */ + g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window); - xed_window_set_active_tab (window, tab); - file_save_as (tab, window); + xed_window_set_active_tab (window, tab); + save_as_tab (tab, window); } static void -save_and_close_all_documents (const GList *docs, - XedWindow *window) +save_and_close_all_documents (const GList *docs, + XedWindow *window) { - GList *tabs; - GList *l; - GSList *sl; - GSList *tabs_to_save_as; - GSList *tabs_to_save_and_close; - GList *tabs_to_close; + GList *tabs; + GList *l; + GSList *sl; + GSList *tabs_to_save_as; + GSList *tabs_to_save_and_close; + GList *tabs_to_close; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_if_fail (!(xed_window_get_state (window) & XED_WINDOW_STATE_PRINTING)); + g_return_if_fail (!(xed_window_get_state (window) & XED_WINDOW_STATE_PRINTING)); - tabs = gtk_container_get_children ( - GTK_CONTAINER (_xed_window_get_notebook (window))); + tabs = gtk_container_get_children (GTK_CONTAINER (_xed_window_get_notebook (window))); - tabs_to_save_as = NULL; - tabs_to_save_and_close = NULL; - tabs_to_close = NULL; + tabs_to_save_as = NULL; + tabs_to_save_and_close = NULL; + tabs_to_close = NULL; - l = tabs; - while (l != NULL) - { - XedTab *t; - XedTabState state; - XedDocument *doc; + l = tabs; + while (l != NULL) + { + XedTab *t; + XedTabState state; + XedDocument *doc; - t = XED_TAB (l->data); + t = XED_TAB (l->data); - state = xed_tab_get_state (t); - doc = xed_tab_get_document (t); + state = xed_tab_get_state (t); + doc = xed_tab_get_document (t); - /* If the state is: ([*] invalid states) - - XED_TAB_STATE_NORMAL: close (and if needed save) - - XED_TAB_STATE_LOADING: close, we are sure the file is unmodified - - XED_TAB_STATE_REVERTING: since the user wants - to return back to the version of the file she previously saved, we can close - without saving (CHECK: are we sure this is the right behavior, suppose the case - the original file has been deleted) - - [*] XED_TAB_STATE_SAVING: invalid, ClosAll - and Quit are unsensitive if the window state is SAVING. - - [*] XED_TAB_STATE_PRINTING, XED_TAB_STATE_PRINT_PREVIEWING: there is not a - real reason for not closing in this case, we do not save to avoid to run - two operations using the message area at the same time (may be we can remove - this limitation in the future). Note that ClosAll - and Quit are unsensitive if the window state is PRINTING. - - XED_TAB_STATE_SHOWING_PRINT_PREVIEW: close (and if needed save) - - XED_TAB_STATE_LOADING_ERROR: close without saving (if the state is LOADING_ERROR then the - document is not modified) - - XED_TAB_STATE_REVERTING_ERROR: we do not close since the document contains errors - - XED_TAB_STATE_SAVING_ERROR: we do not close since the document contains errors - - XED_TAB_STATE_GENERIC_ERROR: we do not close since the document contains - errors (CHECK: we should problably remove this state) - - [*] XED_TAB_STATE_CLOSING: this state is invalid in this case - */ + /* If the state is: ([*] invalid states) + - XED_TAB_STATE_NORMAL: close (and if needed save) + - XED_TAB_STATE_LOADING: close, we are sure the file is unmodified + - XED_TAB_STATE_REVERTING: since the user wants + to return back to the version of the file she previously saved, we can close + without saving (CHECK: are we sure this is the right behavior, suppose the case + the original file has been deleted) + - [*] XED_TAB_STATE_SAVING: invalid, ClosAll + and Quit are unsensitive if the window state is SAVING. + - [*] XED_TAB_STATE_PRINTING, XED_TAB_STATE_PRINT_PREVIEWING: there is not a + real reason for not closing in this case, we do not save to avoid to run + two operations using the message area at the same time (may be we can remove + this limitation in the future). Note that ClosAll + and Quit are unsensitive if the window state is PRINTING. + - XED_TAB_STATE_SHOWING_PRINT_PREVIEW: close (and if needed save) + - XED_TAB_STATE_LOADING_ERROR: close without saving (if the state is LOADING_ERROR then the + document is not modified) + - XED_TAB_STATE_REVERTING_ERROR: we do not close since the document contains errors + - XED_TAB_STATE_SAVING_ERROR: we do not close since the document contains errors + - XED_TAB_STATE_GENERIC_ERROR: we do not close since the document contains + errors (CHECK: we should problably remove this state) + - [*] XED_TAB_STATE_CLOSING: this state is invalid in this case + */ - g_return_if_fail (state != XED_TAB_STATE_PRINTING); - g_return_if_fail (state != XED_TAB_STATE_PRINT_PREVIEWING); - g_return_if_fail (state != XED_TAB_STATE_CLOSING); - g_return_if_fail (state != XED_TAB_STATE_SAVING); + g_return_if_fail (state != XED_TAB_STATE_PRINTING); + g_return_if_fail (state != XED_TAB_STATE_PRINT_PREVIEWING); + g_return_if_fail (state != XED_TAB_STATE_CLOSING); + g_return_if_fail (state != XED_TAB_STATE_SAVING); - if ((state != XED_TAB_STATE_SAVING_ERROR) && - (state != XED_TAB_STATE_GENERIC_ERROR) && - (state != XED_TAB_STATE_REVERTING_ERROR)) - { - if ((g_list_index ((GList *)docs, doc) >= 0) && - (state != XED_TAB_STATE_LOADING) && - (state != XED_TAB_STATE_LOADING_ERROR) && - (state != XED_TAB_STATE_REVERTING)) /* CHECK: is this the right behavior with REVERTING ?*/ - { - /* The document must be saved before closing */ - g_return_if_fail (document_needs_saving (doc)); - - /* FIXME: manage the case of local readonly files owned by the - user is running xed - Paolo (Dec. 8, 2005) */ - if (xed_document_is_untitled (doc) || - xed_document_get_readonly (doc)) - { - g_object_set_data (G_OBJECT (t), - XED_IS_CLOSING_TAB, - GBOOLEAN_TO_POINTER (TRUE)); + if ((state != XED_TAB_STATE_SAVING_ERROR) && + (state != XED_TAB_STATE_GENERIC_ERROR) && + (state != XED_TAB_STATE_REVERTING_ERROR)) + { + if ((g_list_index ((GList *)docs, doc) >= 0) && + (state != XED_TAB_STATE_LOADING) && + (state != XED_TAB_STATE_LOADING_ERROR) && + (state != XED_TAB_STATE_REVERTING)) /* CHECK: is this the right behavior with REVERTING ?*/ + { + /* The document must be saved before closing */ + g_return_if_fail (_xed_document_needs_saving (doc)); - tabs_to_save_as = g_slist_prepend (tabs_to_save_as, - t); - } - else - { - tabs_to_save_and_close = g_slist_prepend (tabs_to_save_and_close, - t); - } - } - else - { - /* The document must be closed without saving */ - tabs_to_close = g_list_prepend (tabs_to_close, - t); - } - } + /* FIXME: manage the case of local readonly files owned by the + user is running xed - Paolo (Dec. 8, 2005) */ + if (xed_document_is_untitled (doc) || xed_document_get_readonly (doc)) + { + g_object_set_data (G_OBJECT (t), XED_IS_CLOSING_TAB, GBOOLEAN_TO_POINTER (TRUE)); - l = g_list_next (l); - } + tabs_to_save_as = g_slist_prepend (tabs_to_save_as, t); + } + else + { + tabs_to_save_and_close = g_slist_prepend (tabs_to_save_and_close, t); + } + } + else + { + /* The document must be closed without saving */ + tabs_to_close = g_list_prepend (tabs_to_close, t); + } + } - g_list_free (tabs); + l = g_list_next (l); + } - /* Close all tabs to close (in a sync way) */ - xed_window_close_tabs (window, tabs_to_close); - g_list_free (tabs_to_close); + g_list_free (tabs); - /* Save and close all the files in tabs_to_save_and_close */ - sl = tabs_to_save_and_close; - while (sl != NULL) - { - save_and_close (XED_TAB (sl->data), - window); - sl = g_slist_next (sl); - } - g_slist_free (tabs_to_save_and_close); + /* Close all tabs to close (in a sync way) */ + xed_window_close_tabs (window, tabs_to_close); + g_list_free (tabs_to_close); - /* Save As and close all the files in tabs_to_save_as */ - if (tabs_to_save_as != NULL) - { - XedTab *tab; + /* Save and close all the files in tabs_to_save_and_close */ + sl = tabs_to_save_and_close; + while (sl != NULL) + { + save_and_close (XED_TAB (sl->data), window); + sl = g_slist_next (sl); + } + g_slist_free (tabs_to_save_and_close); - tabs_to_save_as = g_slist_reverse (tabs_to_save_as ); + /* Save As and close all the files in tabs_to_save_as */ + if (tabs_to_save_as != NULL) + { + XedTab *tab; - g_return_if_fail (g_object_get_data (G_OBJECT (window), - XED_LIST_OF_TABS_TO_SAVE_AS) == NULL); + tabs_to_save_as = g_slist_reverse (tabs_to_save_as ); - g_object_set_data (G_OBJECT (window), - XED_LIST_OF_TABS_TO_SAVE_AS, - tabs_to_save_as); + g_return_if_fail (g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS) == NULL); - tab = XED_TAB (tabs_to_save_as->data); + g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as); - save_as_and_close (tab, window); - } + tab = XED_TAB (tabs_to_save_as->data); + + save_as_and_close (tab, window); + } } static void -save_and_close_document (const GList *docs, - XedWindow *window) +save_and_close_document (const GList *docs, + XedWindow *window) { - XedTab *tab; + XedTab *tab; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_if_fail (docs->next == NULL); + g_return_if_fail (docs->next == NULL); - tab = xed_tab_get_from_document (XED_DOCUMENT (docs->data)); - g_return_if_fail (tab != NULL); + tab = xed_tab_get_from_document (XED_DOCUMENT (docs->data)); + g_return_if_fail (tab != NULL); - save_and_close (tab, window); + save_and_close (tab, window); } static void close_all_tabs (XedWindow *window) { - gboolean is_quitting; + gboolean is_quitting; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - /* There is no document to save -> close all tabs */ - xed_window_close_all_tabs (window); + /* There is no document to save -> close all tabs */ + xed_window_close_all_tabs (window); - is_quitting = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), - XED_IS_QUITTING)); + is_quitting = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_QUITTING)); - if (is_quitting) - gtk_widget_destroy (GTK_WIDGET (window)); + if (is_quitting) + { + gtk_widget_destroy (GTK_WIDGET (window)); + } - return; + return; } static void close_document (XedWindow *window, - XedDocument *doc) + XedDocument *doc) { - XedTab *tab; + XedTab *tab; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - tab = xed_tab_get_from_document (doc); - g_return_if_fail (tab != NULL); + tab = xed_tab_get_from_document (doc); + g_return_if_fail (tab != NULL); - xed_window_close_tab (window, tab); + xed_window_close_tab (window, tab); } static void close_confirmation_dialog_response_handler (XedCloseConfirmationDialog *dlg, - gint response_id, - XedWindow *window) + gint response_id, + XedWindow *window) { - GList *selected_documents; - gboolean is_closing_all; + GList *selected_documents; + gboolean is_closing_all; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - is_closing_all = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), - XED_IS_CLOSING_ALL)); + is_closing_all = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_CLOSING_ALL)); - gtk_widget_hide (GTK_WIDGET (dlg)); + gtk_widget_hide (GTK_WIDGET (dlg)); - switch (response_id) - { - case GTK_RESPONSE_YES: /* Save and Close */ - selected_documents = xed_close_confirmation_dialog_get_selected_documents (dlg); - if (selected_documents == NULL) - { - if (is_closing_all) - { - /* There is no document to save -> close all tabs */ - /* We call gtk_widget_destroy before close_all_tabs - * because close_all_tabs could destroy the xed window */ - gtk_widget_destroy (GTK_WIDGET (dlg)); + switch (response_id) + { + case GTK_RESPONSE_YES: /* Save and Close */ + selected_documents = xed_close_confirmation_dialog_get_selected_documents (dlg); + if (selected_documents == NULL) + { + if (is_closing_all) + { + /* There is no document to save -> close all tabs */ + /* We call gtk_widget_destroy before close_all_tabs + * because close_all_tabs could destroy the xed window */ + gtk_widget_destroy (GTK_WIDGET (dlg)); - close_all_tabs (window); + close_all_tabs (window); - return; - } - else - g_return_if_reached (); - } - else - { - if (is_closing_all) - { - save_and_close_all_documents (selected_documents, - window); - } - else - { - save_and_close_document (selected_documents, - window); - } - } + return; + } + else + g_return_if_reached (); + } + else + { + if (is_closing_all) + { + save_and_close_all_documents (selected_documents, window); + } + else + { + save_and_close_document (selected_documents, window); + } + } - g_list_free (selected_documents); + g_list_free (selected_documents); - break; + break; - case GTK_RESPONSE_NO: /* Close without Saving */ - if (is_closing_all) - { - /* We call gtk_widget_destroy before close_all_tabs - * because close_all_tabs could destroy the xed window */ - gtk_widget_destroy (GTK_WIDGET (dlg)); + case GTK_RESPONSE_NO: /* Close without Saving */ + if (is_closing_all) + { + /* We call gtk_widget_destroy before close_all_tabs + * because close_all_tabs could destroy the xed window */ + gtk_widget_destroy (GTK_WIDGET (dlg)); - close_all_tabs (window); + close_all_tabs (window); - return; - } - else - { - const GList *unsaved_documents; + return; + } + else + { + const GList *unsaved_documents; - unsaved_documents = xed_close_confirmation_dialog_get_unsaved_documents (dlg); - g_return_if_fail (unsaved_documents->next == NULL); + unsaved_documents = xed_close_confirmation_dialog_get_unsaved_documents (dlg); + g_return_if_fail (unsaved_documents->next == NULL); - close_document (window, - XED_DOCUMENT (unsaved_documents->data)); - } + close_document (window, XED_DOCUMENT (unsaved_documents->data)); + } - break; - default: /* Do not close */ + break; + default: /* Do not close */ - /* Reset is_quitting flag */ - g_object_set_data (G_OBJECT (window), - XED_IS_QUITTING, - GBOOLEAN_TO_POINTER (FALSE)); + /* Reset is_quitting flag */ + g_object_set_data (G_OBJECT (window), XED_IS_QUITTING, GBOOLEAN_TO_POINTER (FALSE)); - break; - } + break; + } - gtk_widget_destroy (GTK_WIDGET (dlg)); + gtk_widget_destroy (GTK_WIDGET (dlg)); } /* Returns TRUE if the tab can be immediately closed */ static gboolean tab_can_close (XedTab *tab, - GtkWindow *window) + GtkWindow *window) { - XedDocument *doc; + XedDocument *doc; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); - if (!_xed_tab_can_close (tab)) - { - GtkWidget *dlg; + if (!_xed_tab_can_close (tab)) + { + GtkWidget *dlg; - dlg = xed_close_confirmation_dialog_new_single ( - window, - doc, - FALSE); + dlg = xed_close_confirmation_dialog_new_single (window, doc, FALSE); - g_signal_connect (dlg, - "response", - G_CALLBACK (close_confirmation_dialog_response_handler), - window); + g_signal_connect (dlg, "response", + G_CALLBACK (close_confirmation_dialog_response_handler), window); - gtk_widget_show (dlg); + gtk_widget_show (dlg); - return FALSE; - } + return FALSE; + } - return TRUE; + return TRUE; } /* CHECK: we probably need this one public for plugins... @@ -1706,142 +1554,126 @@ tab_can_close (XedTab *tab, */ void _xed_cmd_file_close_tab (XedTab *tab, - XedWindow *window) + XedWindow *window) { - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_if_fail (GTK_WIDGET (window) == gtk_widget_get_toplevel (GTK_WIDGET (tab))); + g_return_if_fail (GTK_WIDGET (window) == gtk_widget_get_toplevel (GTK_WIDGET (tab))); - g_object_set_data (G_OBJECT (window), - XED_IS_CLOSING_ALL, - GBOOLEAN_TO_POINTER (FALSE)); - - g_object_set_data (G_OBJECT (window), - XED_IS_QUITTING, - GBOOLEAN_TO_POINTER (FALSE)); - - g_object_set_data (G_OBJECT (window), - XED_IS_QUITTING_ALL, - GINT_TO_POINTER (FALSE)); + g_object_set_data (G_OBJECT (window), XED_IS_CLOSING_ALL, GBOOLEAN_TO_POINTER (FALSE)); + g_object_set_data (G_OBJECT (window), XED_IS_QUITTING, GBOOLEAN_TO_POINTER (FALSE)); + g_object_set_data (G_OBJECT (window), XED_IS_QUITTING_ALL, GINT_TO_POINTER (FALSE)); - if (tab_can_close (tab, GTK_WINDOW (window))) - xed_window_close_tab (window, tab); + if (tab_can_close (tab, GTK_WINDOW (window))) + { + xed_window_close_tab (window, tab); + } } void _xed_cmd_file_close (GtkAction *action, - XedWindow *window) + XedWindow *window) { - XedTab *active_tab; + XedTab *active_tab; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - active_tab = xed_window_get_active_tab (window); + active_tab = xed_window_get_active_tab (window); - if (active_tab == NULL) - { - return; - } + if (active_tab == NULL) + { + return; + } - _xed_cmd_file_close_tab (active_tab, window); + _xed_cmd_file_close_tab (active_tab, window); } /* Close all tabs */ static void file_close_all (XedWindow *window, - gboolean is_quitting) + gboolean is_quitting) { - GList *unsaved_docs; - GtkWidget *dlg; + GList *unsaved_docs; + GtkWidget *dlg; - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_if_fail (!(xed_window_get_state (window) & - (XED_WINDOW_STATE_SAVING | - XED_WINDOW_STATE_PRINTING | - XED_WINDOW_STATE_SAVING_SESSION))); + g_return_if_fail (!(xed_window_get_state (window) & + (XED_WINDOW_STATE_SAVING | + XED_WINDOW_STATE_PRINTING | + XED_WINDOW_STATE_SAVING_SESSION))); - g_object_set_data (G_OBJECT (window), - XED_IS_CLOSING_ALL, - GBOOLEAN_TO_POINTER (TRUE)); + g_object_set_data (G_OBJECT (window), XED_IS_CLOSING_ALL, GBOOLEAN_TO_POINTER (TRUE)); + g_object_set_data (G_OBJECT (window), XED_IS_QUITTING, GBOOLEAN_TO_POINTER (is_quitting)); - g_object_set_data (G_OBJECT (window), - XED_IS_QUITTING, - GBOOLEAN_TO_POINTER (is_quitting)); - - unsaved_docs = xed_window_get_unsaved_documents (window); + unsaved_docs = xed_window_get_unsaved_documents (window); - if (unsaved_docs == NULL) - { - /* There is no document to save -> close all tabs */ - xed_window_close_all_tabs (window); + if (unsaved_docs == NULL) + { + /* There is no document to save -> close all tabs */ + xed_window_close_all_tabs (window); - if (is_quitting) - gtk_widget_destroy (GTK_WIDGET (window)); + if (is_quitting) + { + gtk_widget_destroy (GTK_WIDGET (window)); + } - return; - } + return; + } - if (unsaved_docs->next == NULL) - { - /* There is only one unsaved document */ - XedTab *tab; - XedDocument *doc; + if (unsaved_docs->next == NULL) + { + /* There is only one unsaved document */ + XedTab *tab; + XedDocument *doc; - doc = XED_DOCUMENT (unsaved_docs->data); + doc = XED_DOCUMENT (unsaved_docs->data); - tab = xed_tab_get_from_document (doc); - g_return_if_fail (tab != NULL); + tab = xed_tab_get_from_document (doc); + g_return_if_fail (tab != NULL); - xed_window_set_active_tab (window, tab); + xed_window_set_active_tab (window, tab); - dlg = xed_close_confirmation_dialog_new_single ( - GTK_WINDOW (window), - doc, - FALSE); - } - else - { - dlg = xed_close_confirmation_dialog_new (GTK_WINDOW (window), - unsaved_docs, - FALSE); - } + dlg = xed_close_confirmation_dialog_new_single (GTK_WINDOW (window), doc, FALSE); + } + else + { + dlg = xed_close_confirmation_dialog_new (GTK_WINDOW (window), unsaved_docs, FALSE); + } - g_list_free (unsaved_docs); + g_list_free (unsaved_docs); - g_signal_connect (dlg, - "response", - G_CALLBACK (close_confirmation_dialog_response_handler), - window); + g_signal_connect (dlg, "response", + G_CALLBACK (close_confirmation_dialog_response_handler), window); - gtk_widget_show (dlg); + gtk_widget_show (dlg); } void _xed_cmd_file_close_all (GtkAction *action, - XedWindow *window) + XedWindow *window) { - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_if_fail (!(xed_window_get_state (window) & - (XED_WINDOW_STATE_SAVING | - XED_WINDOW_STATE_PRINTING | - XED_WINDOW_STATE_SAVING_SESSION))); + g_return_if_fail (!(xed_window_get_state (window) & + (XED_WINDOW_STATE_SAVING | + XED_WINDOW_STATE_PRINTING | + XED_WINDOW_STATE_SAVING_SESSION))); - file_close_all (window, FALSE); + file_close_all (window, FALSE); } void -_xed_cmd_file_quit (GtkAction *action, - XedWindow *window) +_xed_cmd_file_quit (GtkAction *action, + XedWindow *window) { - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - g_return_if_fail (!(xed_window_get_state (window) & - (XED_WINDOW_STATE_SAVING | - XED_WINDOW_STATE_PRINTING | - XED_WINDOW_STATE_SAVING_SESSION))); + g_return_if_fail (!(xed_window_get_state (window) & + (XED_WINDOW_STATE_SAVING | + XED_WINDOW_STATE_PRINTING | + XED_WINDOW_STATE_SAVING_SESSION))); - file_close_all (window, TRUE); + file_close_all (window, TRUE); } diff --git a/xed/xed-commands-help.c b/xed/xed-commands-help.c index 23e0155..b031339 100644 --- a/xed/xed-commands-help.c +++ b/xed/xed-commands-help.c @@ -32,7 +32,7 @@ */ #ifdef HAVE_CONFIG_H - #include +#include #endif #include @@ -40,28 +40,30 @@ #include "xed-commands.h" #include "xed-debug.h" -#include "xed-help.h" +#include "xed-app.h" #include "xed-dirs.h" -void _xed_cmd_help_contents(GtkAction* action, XedWindow* window) +void _xed_cmd_help_contents (GtkAction *action, + XedWindow *window) { - xed_debug(DEBUG_COMMANDS); + xed_debug(DEBUG_COMMANDS); - xed_help_display(GTK_WINDOW(window), NULL, NULL); + xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (window), NULL, NULL); } -void _xed_cmd_help_about(GtkAction* action, XedWindow* window) +void _xed_cmd_help_about (GtkAction *action, + XedWindow *window) { - static const gchar comments[] = \ - N_("A small and lightweight text editor"); + static const gchar comments[] = \ + N_("A small and lightweight text editor"); - xed_debug (DEBUG_COMMANDS); + xed_debug (DEBUG_COMMANDS); - gtk_show_about_dialog(GTK_WINDOW(window), - "program-name", "xed", - "comments", _(comments), - "logo_icon_name", "accessories-text-editor", - "version", VERSION, - "website", "http://github.com/linuxmint/xed", - NULL); + gtk_show_about_dialog (GTK_WINDOW (window), + "program-name", "xed", + "comments", _(comments), + "logo_icon_name", "accessories-text-editor", + "version", VERSION, + "website", "http://github.com/linuxmint/xed", + NULL); } diff --git a/xed/xed-commands-search.c b/xed/xed-commands-search.c index 6435389..7d32444 100644 --- a/xed/xed-commands-search.c +++ b/xed/xed-commands-search.c @@ -12,19 +12,27 @@ #include "xed-window.h" #include "xed-utils.h" #include "xed-searchbar.h" +#include "xed-view-frame.h" + +// void +// _xed_cmd_search_find (GtkAction *action, +// XedWindow *window) +// { +// xed_searchbar_show (XED_SEARCHBAR (xed_window_get_searchbar (window)), FALSE); +// } void _xed_cmd_search_find (GtkAction *action, XedWindow *window) { - xed_searchbar_show (xed_window_get_searchbar (window), FALSE); + xed_searchbar_show (XED_SEARCHBAR (xed_window_get_searchbar (window)), XED_SEARCH_MODE_SEARCH); } void _xed_cmd_search_replace (GtkAction *action, XedWindow *window) { - xed_searchbar_show (xed_window_get_searchbar (window), TRUE); + xed_searchbar_show (XED_SEARCHBAR (xed_window_get_searchbar (window)), XED_SEARCH_MODE_REPLACE); } void @@ -32,7 +40,7 @@ _xed_cmd_search_find_next (GtkAction *action, XedWindow *window) { xed_debug (DEBUG_COMMANDS); - xed_searchbar_find_again (xed_window_get_searchbar (window), FALSE); + xed_searchbar_find_again (XED_SEARCHBAR (xed_window_get_searchbar (window)), FALSE); } void @@ -40,18 +48,20 @@ _xed_cmd_search_find_prev (GtkAction *action, XedWindow *window) { xed_debug (DEBUG_COMMANDS); - xed_searchbar_find_again (xed_window_get_searchbar (window), TRUE); + xed_searchbar_find_again (XED_SEARCHBAR (xed_window_get_searchbar (window)), TRUE); } void _xed_cmd_search_clear_highlight (XedWindow *window) { XedDocument *doc; + xed_debug (DEBUG_COMMANDS); + doc = xed_window_get_active_document (window); if (doc != NULL) { - xed_document_set_search_text (XED_DOCUMENT(doc), "", XED_SEARCH_DONT_SET_FLAGS); + xed_document_set_search_context (doc, NULL); } } @@ -59,19 +69,22 @@ void _xed_cmd_search_goto_line (GtkAction *action, XedWindow *window) { - XedView *active_view; + XedTab *active_tab; + XedViewFrame *frame; + xed_debug (DEBUG_COMMANDS); - active_view = xed_window_get_active_view (window); - if (active_view == NULL) + active_tab = xed_window_get_active_tab (window); + if (active_tab == NULL) { return; } /* Focus the view if needed: we need to focus the view otherwise activating the binding for goto line has no effect */ - gtk_widget_grab_focus (GTK_WIDGET(active_view)); + // gtk_widget_grab_focus (GTK_WIDGET(active_view)); /* Goto line is builtin in XedView, just activate the corresponding binding. */ - gtk_bindings_activate (G_OBJECT(active_view), GDK_KEY_i, GDK_CONTROL_MASK); + frame = XED_VIEW_FRAME (_xed_tab_get_view_frame (active_tab)); + xed_view_frame_popup_goto_line (frame); } diff --git a/xed/xed-commands-view.c b/xed/xed-commands-view.c index 78ee31c..9df6fe2 100644 --- a/xed/xed-commands-view.c +++ b/xed/xed-commands-view.c @@ -134,6 +134,28 @@ _xed_cmd_view_toggle_fullscreen_mode (GtkAction *action, _xed_window_fullscreen (window); } +void +_xed_cmd_view_toggle_word_wrap (GtkAction *action, + XedWindow *window) +{ + XedView *view; + gboolean do_word_wrap; + + xed_debug (DEBUG_COMMANDS); + + do_word_wrap = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + view = xed_window_get_active_view (window); + + if (do_word_wrap) + { + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD); + } + else + { + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_NONE); + } +} + void _xed_cmd_view_leave_fullscreen_mode (GtkAction *action, XedWindow *window) diff --git a/xed/xed-commands.h b/xed/xed-commands.h index c053ad2..1977ddc 100644 --- a/xed/xed-commands.h +++ b/xed/xed-commands.h @@ -1,16 +1,16 @@ #ifndef __XED_COMMANDS_H__ #define __XED_COMMANDS_H__ -#include +#include #include G_BEGIN_DECLS /* Do nothing if URI does not exist */ -void xed_commands_load_uri (XedWindow *window, const gchar *uri, const XedEncoding *encoding, gint line_pos); +void xed_commands_load_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding, gint line_pos); /* Ignore non-existing URIs */ -gint xed_commands_load_uris (XedWindow *window, const GSList *uris, const XedEncoding *encoding, gint line_pos); +GSList *xed_commands_load_locations (XedWindow *window, const GSList *locations, const GtkSourceEncoding *encoding, gint line_pos); void xed_commands_save_document (XedWindow *window, XedDocument *document); void xed_commands_save_all_documents (XedWindow *window); @@ -19,14 +19,13 @@ void xed_commands_save_all_documents (XedWindow *window); */ /* Create titled documens for non-existing URIs */ -gint _xed_cmd_load_files_from_prompt (XedWindow *window, GSList *files, const XedEncoding *encoding, gint line_pos); +GSList *_xed_cmd_load_files_from_prompt (XedWindow *window, GSList *files, const GtkSourceEncoding *encoding, gint line_pos); void _xed_cmd_file_new (GtkAction *action, XedWindow *window); void _xed_cmd_file_open (GtkAction *action, XedWindow *window); void _xed_cmd_file_save (GtkAction *action, XedWindow *window); void _xed_cmd_file_save_as (GtkAction *action, XedWindow *window); void _xed_cmd_file_save_all (GtkAction *action, XedWindow *window); void _xed_cmd_file_revert (GtkAction *action, XedWindow *window); -void _xed_cmd_file_open_uri (GtkAction *action, XedWindow *window); void _xed_cmd_file_print_preview (GtkAction *action, XedWindow *window); void _xed_cmd_file_print (GtkAction *action, XedWindow *window); void _xed_cmd_file_close (GtkAction *action, XedWindow *window); @@ -47,6 +46,7 @@ void _xed_cmd_view_show_statusbar (GtkAction *action, XedWindow *window); void _xed_cmd_view_show_side_pane (GtkAction *action, XedWindow *window); void _xed_cmd_view_show_bottom_pane (GtkAction *action, XedWindow *window); void _xed_cmd_view_toggle_fullscreen_mode (GtkAction *action, XedWindow *window); +void _xed_cmd_view_toggle_word_wrap (GtkAction *action, XedWindow *window); void _xed_cmd_view_leave_fullscreen_mode (GtkAction *action, XedWindow *window); void _xed_cmd_search_find (GtkAction *action, XedWindow *window); @@ -66,8 +66,6 @@ void _xed_cmd_help_about (GtkAction *action, XedWindow *window); void _xed_cmd_file_close_tab (XedTab *tab, XedWindow *window); -void _xed_cmd_file_save_documents_list (XedWindow *window, GList *docs); - G_END_DECLS #endif /* __XED_COMMANDS_H__ */ diff --git a/xed/xed-dirs.c b/xed/xed-dirs.c index c40a88f..e2548a3 100644 --- a/xed/xed-dirs.c +++ b/xed/xed-dirs.c @@ -27,97 +27,115 @@ #include "xed-dirs.h" -gchar* xed_dirs_get_user_config_dir(void) +static gchar *user_config_dir = NULL; +static gchar *user_cache_dir = NULL; +static gchar *user_styles_dir = NULL; +static gchar *user_plugins_dir = NULL; +static gchar *xed_data_dir = NULL; +static gchar *xed_locale_dir = NULL; +static gchar *xed_lib_dir = NULL; +static gchar *xed_plugins_dir = NULL; +static gchar *xed_plugins_data_dir = NULL; + +void +xed_dirs_init () { - gchar* config_dir = NULL; + if (xed_data_dir == NULL) + { + xed_data_dir = g_build_filename (DATADIR, "xed", NULL); + xed_locale_dir = g_build_filename (DATADIR, "locale", NULL); + xed_lib_dir = g_build_filename (LIBDIR, "xed", NULL); + } - config_dir = g_build_filename(g_get_user_config_dir(), "xed", NULL); - - return config_dir; + user_cache_dir = g_build_filename (g_get_user_cache_dir (), "xed", NULL); + user_config_dir = g_build_filename (g_get_user_config_dir (), "xed", NULL); + user_styles_dir = g_build_filename (g_get_user_data_dir (), "xed", "styles", NULL); + user_plugins_dir = g_build_filename (g_get_user_data_dir (), "xed", "plugins", NULL); + xed_plugins_dir = g_build_filename (xed_lib_dir, "plugins", NULL); + xed_plugins_data_dir = g_build_filename (xed_data_dir, "plugins", NULL); } -gchar* xed_dirs_get_user_cache_dir(void) +void +xed_dirs_shutdown () { - const gchar* cache_dir; - - cache_dir = g_get_user_cache_dir(); - - return g_build_filename(cache_dir, "xed", NULL); + g_free (user_config_dir); + g_free (user_cache_dir); + g_free (user_plugins_dir); + g_free (xed_data_dir); + g_free (xed_locale_dir); + g_free (xed_lib_dir); + g_free (xed_plugins_dir); + g_free (xed_plugins_data_dir); } -gchar* xed_dirs_get_user_plugins_dir(void) +const gchar * +xed_dirs_get_user_config_dir (void) { - gchar* plugin_dir; - - plugin_dir = g_build_filename(g_get_user_data_dir(), "xed", "plugins", NULL); - - return plugin_dir; + return user_config_dir; } -gchar* xed_dirs_get_user_accels_file(void) +const gchar * +xed_dirs_get_user_cache_dir (void) { - gchar* accels = NULL; - gchar *config_dir = NULL; - - config_dir = xed_dirs_get_user_config_dir(); - accels = g_build_filename(config_dir, "accels", NULL); - - g_free(config_dir); - - return accels; + return user_cache_dir; } -gchar* xed_dirs_get_xed_data_dir(void) +const gchar * +xed_dirs_get_user_styles_dir (void) { - return g_build_filename(DATADIR, "xed", NULL); + return user_styles_dir; } -gchar* xed_dirs_get_xed_locale_dir(void) +const gchar * +xed_dirs_get_user_plugins_dir (void) { - return g_build_filename(DATADIR, "locale", NULL); + return user_plugins_dir; } -gchar* xed_dirs_get_xed_lib_dir(void) +const gchar * +xed_dirs_get_xed_data_dir (void) { - return g_build_filename(LIBDIR, "xed", NULL); + return xed_data_dir; } -gchar* xed_dirs_get_xed_plugins_dir(void) +const gchar * +xed_dirs_get_xed_locale_dir (void) { - gchar* lib_dir; - gchar* plugin_dir; - - lib_dir = xed_dirs_get_xed_lib_dir(); - - plugin_dir = g_build_filename(lib_dir, "plugins", NULL); - g_free(lib_dir); - - return plugin_dir; + return xed_locale_dir; } -gchar* xed_dirs_get_xed_plugin_loaders_dir(void) +const gchar * +xed_dirs_get_xed_lib_dir (void) { - gchar* lib_dir; - gchar* loader_dir; - - lib_dir = xed_dirs_get_xed_lib_dir(); - - loader_dir = g_build_filename(lib_dir, "plugin-loaders", NULL); - g_free(lib_dir); - - return loader_dir; + return xed_lib_dir; } -gchar* xed_dirs_get_ui_file(const gchar* file) +const gchar * +xed_dirs_get_xed_plugins_dir (void) { - gchar* datadir; - gchar* ui_file; - - g_return_val_if_fail(file != NULL, NULL); - - datadir = xed_dirs_get_xed_data_dir(); - ui_file = g_build_filename(datadir, "ui", file, NULL); - g_free(datadir); - - return ui_file; + return xed_plugins_dir; +} + +const gchar * +xed_dirs_get_xed_plugins_data_dir (void) +{ + return xed_plugins_data_dir; +} + +const gchar * +xed_dirs_get_binding_modules_dir (void) +{ + return xed_lib_dir; +} + +gchar * +xed_dirs_get_ui_file (const gchar *file) +{ + gchar *ui_file; + + g_return_val_if_fail (file != NULL, NULL); + + ui_file = g_build_filename (xed_dirs_get_xed_data_dir (), "ui", file, NULL); + + return ui_file; } diff --git a/xed/xed-dirs.h b/xed/xed-dirs.h index 3e571b9..fed863a 100644 --- a/xed/xed-dirs.h +++ b/xed/xed-dirs.h @@ -16,8 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ @@ -28,26 +28,32 @@ G_BEGIN_DECLS -gchar *xed_dirs_get_user_config_dir (void); +/* This function must be called before starting xed */ +void xed_dirs_init (void); +/* This function must be called before exiting xed */ +void xed_dirs_shutdown (void); -gchar *xed_dirs_get_user_cache_dir (void); +const gchar *xed_dirs_get_user_config_dir (void); -gchar *xed_dirs_get_user_plugins_dir (void); +const gchar *xed_dirs_get_user_cache_dir (void); -gchar *xed_dirs_get_user_accels_file (void); +const gchar *xed_dirs_get_user_styles_dir (void); -gchar *xed_dirs_get_xed_data_dir (void); +const gchar *xed_dirs_get_user_plugins_dir (void); -gchar *xed_dirs_get_xed_locale_dir (void); +const gchar *xed_dirs_get_xed_data_dir (void); -gchar *xed_dirs_get_xed_lib_dir (void); +const gchar *xed_dirs_get_xed_locale_dir (void); -gchar *xed_dirs_get_xed_plugins_dir (void); +const gchar *xed_dirs_get_xed_lib_dir (void); -gchar *xed_dirs_get_xed_plugin_loaders_dir - (void); +const gchar *xed_dirs_get_xed_plugins_dir (void); -gchar *xed_dirs_get_ui_file (const gchar *file); +const gchar *xed_dirs_get_xed_plugins_data_dir (void); + +const gchar *xed_dirs_get_binding_modules_dir (void); + +gchar *xed_dirs_get_ui_file (const gchar *file); G_END_DECLS diff --git a/xed/xed-document-input-stream.c b/xed/xed-document-input-stream.c deleted file mode 100644 index 1fc7731..0000000 --- a/xed/xed-document-input-stream.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * xed-document-input-stream.c - * This file is part of xed - * - * Copyright (C) 2010 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#include -#include -#include -#include "xed-document-input-stream.h" -#include "xed-enum-types.h" - -/* NOTE: never use async methods on this stream, the stream is just - * a wrapper around GtkTextBuffer api so that we can use GIO Stream - * methods, but the undelying code operates on a GtkTextBuffer, so - * there is no I/O involved and should be accessed only by the main - * thread */ - - -G_DEFINE_TYPE (XedDocumentInputStream, xed_document_input_stream, G_TYPE_INPUT_STREAM); - -struct _XedDocumentInputStreamPrivate -{ - GtkTextBuffer *buffer; - GtkTextMark *pos; - gint bytes_partial; - - XedDocumentNewlineType newline_type; - - guint newline_added : 1; - guint is_initialized : 1; -}; - -enum -{ - PROP_0, - PROP_BUFFER, - PROP_NEWLINE_TYPE -}; - -static gssize xed_document_input_stream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error); -static gboolean xed_document_input_stream_close (GInputStream *stream, - GCancellable *cancellable, - GError **error); - -static void -xed_document_input_stream_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedDocumentInputStream *stream = XED_DOCUMENT_INPUT_STREAM (object); - - switch (prop_id) - { - case PROP_BUFFER: - stream->priv->buffer = GTK_TEXT_BUFFER (g_value_get_object (value)); - break; - - case PROP_NEWLINE_TYPE: - stream->priv->newline_type = g_value_get_enum (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_document_input_stream_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - XedDocumentInputStream *stream = XED_DOCUMENT_INPUT_STREAM (object); - - switch (prop_id) - { - case PROP_BUFFER: - g_value_set_object (value, stream->priv->buffer); - break; - - case PROP_NEWLINE_TYPE: - g_value_set_enum (value, stream->priv->newline_type); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_document_input_stream_class_init (XedDocumentInputStreamClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass); - - g_type_class_add_private (klass, sizeof (XedDocumentInputStreamPrivate)); - - gobject_class->get_property = xed_document_input_stream_get_property; - gobject_class->set_property = xed_document_input_stream_set_property; - - stream_class->read_fn = xed_document_input_stream_read; - stream_class->close_fn = xed_document_input_stream_close; - - g_object_class_install_property (gobject_class, - PROP_BUFFER, - g_param_spec_object ("buffer", - "Buffer", - "The buffer which is read", - GTK_TYPE_TEXT_BUFFER, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - /** - * XedDocumentInputStream:newline-type: - * - * The :newline-type property determines what is considered - * as a line ending when reading complete lines from the stream. - */ - g_object_class_install_property (gobject_class, - PROP_NEWLINE_TYPE, - g_param_spec_enum ("newline-type", - "Newline type", - "The accepted types of line ending", - XED_TYPE_DOCUMENT_NEWLINE_TYPE, - XED_DOCUMENT_NEWLINE_TYPE_LF, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_BLURB | - G_PARAM_CONSTRUCT_ONLY)); -} - -static void -xed_document_input_stream_init (XedDocumentInputStream *stream) -{ - stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, - XED_TYPE_DOCUMENT_INPUT_STREAM, - XedDocumentInputStreamPrivate); -} - -static gsize -get_new_line_size (XedDocumentInputStream *stream) -{ - gsize ret; - - switch (stream->priv->newline_type) - { - case XED_DOCUMENT_NEWLINE_TYPE_CR: - case XED_DOCUMENT_NEWLINE_TYPE_LF: - ret = 1; - break; - - case XED_DOCUMENT_NEWLINE_TYPE_CR_LF: - ret = 2; - break; - - default: - g_warn_if_reached (); - ret = 1; - break; - } - - return ret; -} - -/** - * xed_document_input_stream_new: - * @buffer: a #GtkTextBuffer - * - * Reads the data from @buffer. - * - * Returns: a new #GInputStream to read @buffer - */ -GInputStream * -xed_document_input_stream_new (GtkTextBuffer *buffer, - XedDocumentNewlineType type) -{ - XedDocumentInputStream *stream; - - g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL); - - stream = g_object_new (XED_TYPE_DOCUMENT_INPUT_STREAM, - "buffer", buffer, - "newline-type", type, - NULL); - - return G_INPUT_STREAM (stream); -} - -gsize -xed_document_input_stream_get_total_size (XedDocumentInputStream *stream) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_INPUT_STREAM (stream), 0); - - return gtk_text_buffer_get_char_count (stream->priv->buffer); -} - -gsize -xed_document_input_stream_tell (XedDocumentInputStream *stream) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_INPUT_STREAM (stream), 0); - - /* FIXME: is this potentially inefficient? If yes, we could keep - track of the offset internally, assuming the mark doesn't move - during the operation */ - if (!stream->priv->is_initialized) - { - return 0; - } - else - { - GtkTextIter iter; - - gtk_text_buffer_get_iter_at_mark (stream->priv->buffer, - &iter, - stream->priv->pos); - return gtk_text_iter_get_offset (&iter); - } -} - -static const gchar * -get_new_line (XedDocumentInputStream *stream) -{ - const gchar *ret; - - switch (stream->priv->newline_type) - { - case XED_DOCUMENT_NEWLINE_TYPE_CR: - ret = "\r"; - break; - - case XED_DOCUMENT_NEWLINE_TYPE_LF: - ret = "\n"; - break; - - case XED_DOCUMENT_NEWLINE_TYPE_CR_LF: - ret = "\r\n"; - break; - - default: - g_warn_if_reached (); - ret = "\n"; - break; - } - - return ret; -} - -static gsize -read_line (XedDocumentInputStream *stream, - gchar *outbuf, - gsize space_left) -{ - GtkTextIter start, next, end; - gchar *buf; - gint bytes; /* int since it's what iter_get_offset returns */ - gsize bytes_to_write, newline_size, read; - const gchar *newline; - gboolean is_last; - - gtk_text_buffer_get_iter_at_mark (stream->priv->buffer, - &start, - stream->priv->pos); - - if (gtk_text_iter_is_end (&start)) - return 0; - - end = next = start; - newline = get_new_line (stream); - - /* Check needed for empty lines */ - if (!gtk_text_iter_ends_line (&end)) - gtk_text_iter_forward_to_line_end (&end); - - gtk_text_iter_forward_line (&next); - - buf = gtk_text_iter_get_slice (&start, &end); - - /* the bytes of a line includes also the newline, so with the - offsets we remove the newline and we add the new newline size */ - bytes = gtk_text_iter_get_bytes_in_line (&start) - stream->priv->bytes_partial; - - /* bytes_in_line includes the newlines, so we remove that assuming that - they are single byte characters */ - bytes = bytes - (gtk_text_iter_get_offset (&next) - gtk_text_iter_get_offset (&end)); - is_last = gtk_text_iter_is_end (&end); - - /* bytes_to_write contains the amount of bytes we would like to write. - This means its the amount of bytes in the line (without the newline - in the buffer) + the amount of bytes for the newline we want to - write (newline_size) */ - bytes_to_write = bytes; - - /* do not add the new newline_size for the last line */ - newline_size = get_new_line_size (stream); - if (!is_last) - bytes_to_write += newline_size; - - if (bytes_to_write > space_left) - { - gchar *ptr; - gint char_offset; - gint written; - gsize to_write; - - /* Here the line does not fit in the buffer, we thus write - the amount of bytes we can still fit, storing the position - for the next read with the mark. Do not try to write the - new newline in this case, it will be handled in the next - iteration */ - to_write = MIN (space_left, bytes); - ptr = buf; - written = 0; - char_offset = 0; - - while (written < to_write) - { - gint w; - - ptr = g_utf8_next_char (ptr); - w = (ptr - buf); - if (w > to_write) - { - break; - } - else - { - written = w; - ++char_offset; - } - } - - memcpy (outbuf, buf, written); - - /* Note: offset is one past what we wrote */ - gtk_text_iter_forward_chars (&start, char_offset); - stream->priv->bytes_partial += written; - read = written; - } - else - { - /* First just copy the bytes without the newline */ - memcpy (outbuf, buf, bytes); - - /* Then add the newline, but not for the last line */ - if (!is_last) - { - memcpy (outbuf + bytes, newline, newline_size); - } - - start = next; - stream->priv->bytes_partial = 0; - read = bytes_to_write; - } - - gtk_text_buffer_move_mark (stream->priv->buffer, - stream->priv->pos, - &start); - - g_free (buf); - return read; -} - -static gssize -xed_document_input_stream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error) -{ - XedDocumentInputStream *dstream; - GtkTextIter iter; - gssize space_left, read, n; - - dstream = XED_DOCUMENT_INPUT_STREAM (stream); - - if (count < 6) - { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, - "Not enougth space in destination"); - return -1; - } - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return -1; - - /* Initialize the mark to the first char in the text buffer */ - if (!dstream->priv->is_initialized) - { - gtk_text_buffer_get_start_iter (dstream->priv->buffer, &iter); - dstream->priv->pos = gtk_text_buffer_create_mark (dstream->priv->buffer, - NULL, - &iter, - FALSE); - - dstream->priv->is_initialized = TRUE; - } - - space_left = count; - read = 0; - - do - { - n = read_line (dstream, (void *) ((gsize) buffer + read), space_left); - read += n; - space_left -= n; - } while (space_left > 0 && n != 0 && dstream->priv->bytes_partial == 0); - - /* Make sure that non-empty files are always terminated with \n (see bug #95676). - * Note that we strip the trailing \n when loading the file */ - gtk_text_buffer_get_iter_at_mark (dstream->priv->buffer, - &iter, - dstream->priv->pos); - - if (gtk_text_iter_is_end (&iter) && - !gtk_text_iter_is_start (&iter)) - { - gssize newline_size; - - newline_size = get_new_line_size (dstream); - - if (space_left >= newline_size && - !dstream->priv->newline_added) - { - const gchar *newline; - - newline = get_new_line (dstream); - - memcpy ((void *) ((gsize) buffer + read), newline, newline_size); - - read += newline_size; - dstream->priv->newline_added = TRUE; - } - } - - return read; -} - -static gboolean -xed_document_input_stream_close (GInputStream *stream, - GCancellable *cancellable, - GError **error) -{ - XedDocumentInputStream *dstream = XED_DOCUMENT_INPUT_STREAM (stream); - - dstream->priv->newline_added = FALSE; - - if (dstream->priv->is_initialized) - { - gtk_text_buffer_delete_mark (dstream->priv->buffer, dstream->priv->pos); - } - - return TRUE; -} diff --git a/xed/xed-document-input-stream.h b/xed/xed-document-input-stream.h deleted file mode 100644 index 449c5f1..0000000 --- a/xed/xed-document-input-stream.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * xed-document-input-stream.h - * This file is part of xed - * - * Copyright (C) 2010 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#ifndef __XED_DOCUMENT_INPUT_STREAM_H__ -#define __XED_DOCUMENT_INPUT_STREAM_H__ - -#include -#include - -#include "xed-document.h" - -G_BEGIN_DECLS - -#define XED_TYPE_DOCUMENT_INPUT_STREAM (xed_document_input_stream_get_type ()) -#define XED_DOCUMENT_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_DOCUMENT_INPUT_STREAM, XedDocumentInputStream)) -#define XED_DOCUMENT_INPUT_STREAM_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_DOCUMENT_INPUT_STREAM, XedDocumentInputStream const)) -#define XED_DOCUMENT_INPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_DOCUMENT_INPUT_STREAM, XedDocumentInputStreamClass)) -#define XED_IS_DOCUMENT_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_DOCUMENT_INPUT_STREAM)) -#define XED_IS_DOCUMENT_INPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT_INPUT_STREAM)) -#define XED_DOCUMENT_INPUT_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_DOCUMENT_INPUT_STREAM, XedDocumentInputStreamClass)) - -typedef struct _XedDocumentInputStream XedDocumentInputStream; -typedef struct _XedDocumentInputStreamClass XedDocumentInputStreamClass; -typedef struct _XedDocumentInputStreamPrivate XedDocumentInputStreamPrivate; - -struct _XedDocumentInputStream -{ - GInputStream parent; - - XedDocumentInputStreamPrivate *priv; -}; - -struct _XedDocumentInputStreamClass -{ - GInputStreamClass parent_class; -}; - -GType xed_document_input_stream_get_type (void) G_GNUC_CONST; - -GInputStream *xed_document_input_stream_new (GtkTextBuffer *buffer, - XedDocumentNewlineType type); - -gsize xed_document_input_stream_get_total_size (XedDocumentInputStream *stream); - -gsize xed_document_input_stream_tell (XedDocumentInputStream *stream); - -G_END_DECLS - -#endif /* __XED_DOCUMENT_INPUT_STREAM_H__ */ diff --git a/xed/xed-document-loader.c b/xed/xed-document-loader.c deleted file mode 100644 index 921d6d6..0000000 --- a/xed/xed-document-loader.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * xed-document-loader.c - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005-2007. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "xed-document-loader.h" -#include "xed-debug.h" -#include "xed-metadata-manager.h" -#include "xed-utils.h" -#include "xed-marshal.h" -#include "xed-enum-types.h" - -/* Those are for the the xed_document_loader_new() factory */ -#include "xed-gio-document-loader.h" - -G_DEFINE_ABSTRACT_TYPE(XedDocumentLoader, xed_document_loader, G_TYPE_OBJECT) - -/* Signals */ - -enum { - LOADING, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* Properties */ - -enum -{ - PROP_0, - PROP_DOCUMENT, - PROP_URI, - PROP_ENCODING, - PROP_NEWLINE_TYPE -}; - -static void -xed_document_loader_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedDocumentLoader *loader = XED_DOCUMENT_LOADER (object); - - switch (prop_id) - { - case PROP_DOCUMENT: - g_return_if_fail (loader->document == NULL); - loader->document = g_value_get_object (value); - break; - case PROP_URI: - g_return_if_fail (loader->uri == NULL); - loader->uri = g_value_dup_string (value); - break; - case PROP_ENCODING: - g_return_if_fail (loader->encoding == NULL); - loader->encoding = g_value_get_boxed (value); - break; - case PROP_NEWLINE_TYPE: - loader->auto_detected_newline_type = g_value_get_enum (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_document_loader_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - XedDocumentLoader *loader = XED_DOCUMENT_LOADER (object); - - switch (prop_id) - { - case PROP_DOCUMENT: - g_value_set_object (value, loader->document); - break; - case PROP_URI: - g_value_set_string (value, loader->uri); - break; - case PROP_ENCODING: - g_value_set_boxed (value, xed_document_loader_get_encoding (loader)); - break; - case PROP_NEWLINE_TYPE: - g_value_set_enum (value, loader->auto_detected_newline_type); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_document_loader_finalize (GObject *object) -{ - XedDocumentLoader *loader = XED_DOCUMENT_LOADER (object); - - g_free (loader->uri); - - if (loader->info) - g_object_unref (loader->info); - - G_OBJECT_CLASS (xed_document_loader_parent_class)->finalize (object); -} - -static void -xed_document_loader_dispose (GObject *object) -{ - XedDocumentLoader *loader = XED_DOCUMENT_LOADER (object); - - if (loader->info != NULL) - { - g_object_unref (loader->info); - loader->info = NULL; - } - - G_OBJECT_CLASS (xed_document_loader_parent_class)->dispose (object); -} - -static void -xed_document_loader_class_init (XedDocumentLoaderClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_document_loader_finalize; - object_class->dispose = xed_document_loader_dispose; - object_class->get_property = xed_document_loader_get_property; - object_class->set_property = xed_document_loader_set_property; - - g_object_class_install_property (object_class, - PROP_DOCUMENT, - g_param_spec_object ("document", - "Document", - "The XedDocument this XedDocumentLoader is associated with", - XED_TYPE_DOCUMENT, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_URI, - g_param_spec_string ("uri", - "URI", - "The URI this XedDocumentLoader loads the document from", - "", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_ENCODING, - g_param_spec_boxed ("encoding", - "Encoding", - "The encoding of the saved file", - XED_TYPE_ENCODING, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_NEWLINE_TYPE, - g_param_spec_enum ("newline-type", - "Newline type", - "The accepted types of line ending", - XED_TYPE_DOCUMENT_NEWLINE_TYPE, - XED_DOCUMENT_NEWLINE_TYPE_LF, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_BLURB)); - - signals[LOADING] = - g_signal_new ("loading", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentLoaderClass, loading), - NULL, NULL, - xed_marshal_VOID__BOOLEAN_POINTER, - G_TYPE_NONE, - 2, - G_TYPE_BOOLEAN, - G_TYPE_POINTER); -} - -static void -xed_document_loader_init (XedDocumentLoader *loader) -{ - loader->used = FALSE; - loader->auto_detected_newline_type = XED_DOCUMENT_NEWLINE_TYPE_DEFAULT; -} - -void -xed_document_loader_loading (XedDocumentLoader *loader, - gboolean completed, - GError *error) -{ - /* the object will be unrefed in the callback of the loading signal - * (when completed == TRUE), so we need to prevent finalization. - */ - if (completed) - { - g_object_ref (loader); - } - - g_signal_emit (loader, signals[LOADING], 0, completed, error); - - if (completed) - { - if (error == NULL) - xed_debug_message (DEBUG_LOADER, "load completed"); - else - xed_debug_message (DEBUG_LOADER, "load failed"); - - g_object_unref (loader); - } -} - -/* This is a factory method that returns an appopriate loader - * for the given uri. - */ -XedDocumentLoader * -xed_document_loader_new (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding) -{ - XedDocumentLoader *loader; - GType loader_type; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - - /* At the moment we just use gio loader in all cases... - * In the future it would be great to have a PolicyKit - * loader to get permission to save systen files etc */ - loader_type = XED_TYPE_GIO_DOCUMENT_LOADER; - - loader = XED_DOCUMENT_LOADER (g_object_new (loader_type, - "document", doc, - "uri", uri, - "encoding", encoding, - NULL)); - - return loader; -} - -/* If enconding == NULL, the encoding will be autodetected */ -void -xed_document_loader_load (XedDocumentLoader *loader) -{ - xed_debug (DEBUG_LOADER); - - g_return_if_fail (XED_IS_DOCUMENT_LOADER (loader)); - - /* the loader can be used just once, then it must be thrown away */ - g_return_if_fail (loader->used == FALSE); - loader->used = TRUE; - - XED_DOCUMENT_LOADER_GET_CLASS (loader)->load (loader); -} - -gboolean -xed_document_loader_cancel (XedDocumentLoader *loader) -{ - xed_debug (DEBUG_LOADER); - - g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), FALSE); - - return XED_DOCUMENT_LOADER_GET_CLASS (loader)->cancel (loader); -} - -XedDocument * -xed_document_loader_get_document (XedDocumentLoader *loader) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), NULL); - - return loader->document; -} - -/* Returns STDIN_URI if loading from stdin */ -const gchar * -xed_document_loader_get_uri (XedDocumentLoader *loader) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), NULL); - - return loader->uri; -} - -goffset -xed_document_loader_get_bytes_read (XedDocumentLoader *loader) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), 0); - - return XED_DOCUMENT_LOADER_GET_CLASS (loader)->get_bytes_read (loader); -} - -const XedEncoding * -xed_document_loader_get_encoding (XedDocumentLoader *loader) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), NULL); - - if (loader->encoding != NULL) - return loader->encoding; - - g_return_val_if_fail (loader->auto_detected_encoding != NULL, - xed_encoding_get_current ()); - - return loader->auto_detected_encoding; -} - -XedDocumentNewlineType -xed_document_loader_get_newline_type (XedDocumentLoader *loader) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), - XED_DOCUMENT_NEWLINE_TYPE_LF); - - return loader->auto_detected_newline_type; -} - -GFileInfo * -xed_document_loader_get_info (XedDocumentLoader *loader) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), NULL); - - return loader->info; -} diff --git a/xed/xed-document-loader.h b/xed/xed-document-loader.h deleted file mode 100644 index ff7a8a4..0000000 --- a/xed/xed-document-loader.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * xed-document-loader.h - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005-2007. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_DOCUMENT_LOADER_H__ -#define __XED_DOCUMENT_LOADER_H__ - -#include - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_DOCUMENT_LOADER (xed_document_loader_get_type()) -#define XED_DOCUMENT_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_DOCUMENT_LOADER, XedDocumentLoader)) -#define XED_DOCUMENT_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_DOCUMENT_LOADER, XedDocumentLoaderClass)) -#define XED_IS_DOCUMENT_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_DOCUMENT_LOADER)) -#define XED_IS_DOCUMENT_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT_LOADER)) -#define XED_DOCUMENT_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_DOCUMENT_LOADER, XedDocumentLoaderClass)) - -/* Private structure type */ -typedef struct _XedDocumentLoaderPrivate XedDocumentLoaderPrivate; - -/* - * Main object structure - */ -typedef struct _XedDocumentLoader XedDocumentLoader; - -struct _XedDocumentLoader -{ - GObject object; - - XedDocument *document; - gboolean used; - - /* Info on the current file */ - GFileInfo *info; - gchar *uri; - const XedEncoding *encoding; - const XedEncoding *auto_detected_encoding; - XedDocumentNewlineType auto_detected_newline_type; -}; - -/* - * Class definition - */ -typedef struct _XedDocumentLoaderClass XedDocumentLoaderClass; - -struct _XedDocumentLoaderClass -{ - GObjectClass parent_class; - - /* Signals */ - void (* loading) (XedDocumentLoader *loader, - gboolean completed, - const GError *error); - - /* VTable */ - void (* load) (XedDocumentLoader *loader); - gboolean (* cancel) (XedDocumentLoader *loader); - goffset (* get_bytes_read) (XedDocumentLoader *loader); -}; - -/* - * Public methods - */ -GType xed_document_loader_get_type (void) G_GNUC_CONST; - -/* If enconding == NULL, the encoding will be autodetected */ -XedDocumentLoader *xed_document_loader_new (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding); - -void xed_document_loader_loading (XedDocumentLoader *loader, - gboolean completed, - GError *error); - -void xed_document_loader_load (XedDocumentLoader *loader); -#if 0 -gboolean xed_document_loader_load_from_stdin (XedDocumentLoader *loader); -#endif -gboolean xed_document_loader_cancel (XedDocumentLoader *loader); - -XedDocument *xed_document_loader_get_document (XedDocumentLoader *loader); - -/* Returns STDIN_URI if loading from stdin */ -#define STDIN_URI "stdin:" -const gchar *xed_document_loader_get_uri (XedDocumentLoader *loader); - -const XedEncoding *xed_document_loader_get_encoding (XedDocumentLoader *loader); - -XedDocumentNewlineType xed_document_loader_get_newline_type (XedDocumentLoader *loader); - -goffset xed_document_loader_get_bytes_read (XedDocumentLoader *loader); - -/* You can get from the info: content_type, time_modified, standard_size, access_can_write - and also the metadata*/ -GFileInfo *xed_document_loader_get_info (XedDocumentLoader *loader); - -G_END_DECLS - -#endif /* __XED_DOCUMENT_LOADER_H__ */ diff --git a/xed/xed-document-output-stream.c b/xed/xed-document-output-stream.c deleted file mode 100644 index 55777a5..0000000 --- a/xed/xed-document-output-stream.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * xed-document-output-stream.c - * This file is part of xed - * - * Copyright (C) 2010 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#include -#include -#include -#include -#include "xed-document-output-stream.h" - -/* NOTE: never use async methods on this stream, the stream is just - * a wrapper around GtkTextBuffer api so that we can use GIO Stream - * methods, but the undelying code operates on a GtkTextBuffer, so - * there is no I/O involved and should be accessed only by the main - * thread */ - -#define XED_DOCUMENT_OUTPUT_STREAM_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object),\ - XED_TYPE_DOCUMENT_OUTPUT_STREAM,\ - XedDocumentOutputStreamPrivate)) - -#define MAX_UNICHAR_LEN 6 - -struct _XedDocumentOutputStreamPrivate -{ - XedDocument *doc; - GtkTextIter pos; - - gchar *buffer; - gsize buflen; - - guint is_initialized : 1; - guint is_closed : 1; -}; - -enum -{ - PROP_0, - PROP_DOCUMENT -}; - -G_DEFINE_TYPE (XedDocumentOutputStream, xed_document_output_stream, G_TYPE_OUTPUT_STREAM) - -static gssize xed_document_output_stream_write (GOutputStream *stream, - const void *buffer, - gsize count, - GCancellable *cancellable, - GError **error); - -static gboolean xed_document_output_stream_flush (GOutputStream *stream, - GCancellable *cancellable, - GError **error); - -static gboolean xed_document_output_stream_close (GOutputStream *stream, - GCancellable *cancellable, - GError **error); - -static void -xed_document_output_stream_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object); - - switch (prop_id) - { - case PROP_DOCUMENT: - stream->priv->doc = XED_DOCUMENT (g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_document_output_stream_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object); - - switch (prop_id) - { - case PROP_DOCUMENT: - g_value_set_object (value, stream->priv->doc); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_document_output_stream_finalize (GObject *object) -{ - XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object); - - g_free (stream->priv->buffer); - - G_OBJECT_CLASS (xed_document_output_stream_parent_class)->finalize (object); -} - -static void -xed_document_output_stream_constructed (GObject *object) -{ - XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object); - - if (!stream->priv->doc) - { - g_critical ("This should never happen, a problem happened constructing the Document Output Stream!"); - return; - } - - /* Init the undoable action */ - gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc)); - /* clear the buffer */ - gtk_text_buffer_set_text (GTK_TEXT_BUFFER (stream->priv->doc), - "", 0); - gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc), - FALSE); - - gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc)); -} - -static void -xed_document_output_stream_class_init (XedDocumentOutputStreamClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass); - - object_class->get_property = xed_document_output_stream_get_property; - object_class->set_property = xed_document_output_stream_set_property; - object_class->finalize = xed_document_output_stream_finalize; - object_class->constructed = xed_document_output_stream_constructed; - - stream_class->write_fn = xed_document_output_stream_write; - stream_class->flush = xed_document_output_stream_flush; - stream_class->close_fn = xed_document_output_stream_close; - - g_object_class_install_property (object_class, - PROP_DOCUMENT, - g_param_spec_object ("document", - "Document", - "The document which is written", - XED_TYPE_DOCUMENT, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (object_class, sizeof (XedDocumentOutputStreamPrivate)); -} - -static void -xed_document_output_stream_init (XedDocumentOutputStream *stream) -{ - stream->priv = XED_DOCUMENT_OUTPUT_STREAM_GET_PRIVATE (stream); - - stream->priv->buffer = NULL; - stream->priv->buflen = 0; - - stream->priv->is_initialized = FALSE; - stream->priv->is_closed = FALSE; -} - -static XedDocumentNewlineType -get_newline_type (GtkTextIter *end) -{ - XedDocumentNewlineType res; - GtkTextIter copy; - gunichar c; - - copy = *end; - c = gtk_text_iter_get_char (©); - - if (g_unichar_break_type (c) == G_UNICODE_BREAK_CARRIAGE_RETURN) - { - if (gtk_text_iter_forward_char (©) && - g_unichar_break_type (gtk_text_iter_get_char (©)) == G_UNICODE_BREAK_LINE_FEED) - { - res = XED_DOCUMENT_NEWLINE_TYPE_CR_LF; - } - else - { - res = XED_DOCUMENT_NEWLINE_TYPE_CR; - } - } - else - { - res = XED_DOCUMENT_NEWLINE_TYPE_LF; - } - - return res; -} - -GOutputStream * -xed_document_output_stream_new (XedDocument *doc) -{ - return G_OUTPUT_STREAM (g_object_new (XED_TYPE_DOCUMENT_OUTPUT_STREAM, - "document", doc, NULL)); -} - -XedDocumentNewlineType -xed_document_output_stream_detect_newline_type (XedDocumentOutputStream *stream) -{ - XedDocumentNewlineType type; - GtkTextIter iter; - - g_return_val_if_fail (XED_IS_DOCUMENT_OUTPUT_STREAM (stream), - XED_DOCUMENT_NEWLINE_TYPE_DEFAULT); - - type = XED_DOCUMENT_NEWLINE_TYPE_DEFAULT; - - gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (stream->priv->doc), - &iter); - - if (gtk_text_iter_ends_line (&iter) || gtk_text_iter_forward_to_line_end (&iter)) - { - type = get_newline_type (&iter); - } - - return type; -} - -/* If the last char is a newline, remove it from the buffer (otherwise - GtkTextView shows it as an empty line). See bug #324942. */ -static void -remove_ending_newline (XedDocumentOutputStream *stream) -{ - GtkTextIter end; - GtkTextIter start; - - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (stream->priv->doc), &end); - start = end; - - gtk_text_iter_set_line_offset (&start, 0); - - if (gtk_text_iter_ends_line (&start) && - gtk_text_iter_backward_line (&start)) - { - if (!gtk_text_iter_ends_line (&start)) - { - gtk_text_iter_forward_to_line_end (&start); - } - - /* Delete the empty line which is from 'start' to 'end' */ - gtk_text_buffer_delete (GTK_TEXT_BUFFER (stream->priv->doc), - &start, - &end); - } -} - -static void -end_append_text_to_document (XedDocumentOutputStream *stream) -{ - remove_ending_newline (stream); - - gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc), - FALSE); - - gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc)); -} - -static gssize -xed_document_output_stream_write (GOutputStream *stream, - const void *buffer, - gsize count, - GCancellable *cancellable, - GError **error) -{ - XedDocumentOutputStream *ostream; - gchar *text; - gsize len; - gboolean freetext = FALSE; - const gchar *end; - gboolean valid; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return -1; - - ostream = XED_DOCUMENT_OUTPUT_STREAM (stream); - - if (!ostream->priv->is_initialized) - { - /* Init the undoable action */ - gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (ostream->priv->doc)); - - gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (ostream->priv->doc), - &ostream->priv->pos); - ostream->priv->is_initialized = TRUE; - } - - if (ostream->priv->buflen > 0) - { - len = ostream->priv->buflen + count; - text = g_new (gchar , len + 1); - memcpy (text, ostream->priv->buffer, ostream->priv->buflen); - memcpy (text + ostream->priv->buflen, buffer, count); - text[len] = '\0'; - g_free (ostream->priv->buffer); - ostream->priv->buffer = NULL; - ostream->priv->buflen = 0; - freetext = TRUE; - } - else - { - text = (gchar *) buffer; - len = count; - } - - /* validate */ - valid = g_utf8_validate (text, len, &end); - - /* Avoid keeping a CRLF across two buffers. */ - if (valid && len > 1 && end[-1] == '\r') - { - valid = FALSE; - end--; - } - - if (!valid) - { - gsize nvalid = end - text; - gsize remainder = len - nvalid; - gunichar ch; - - if ((remainder < MAX_UNICHAR_LEN) && - ((ch = g_utf8_get_char_validated (text + nvalid, remainder)) == (gunichar)-2 || - ch == (gunichar)'\r')) - { - ostream->priv->buffer = g_strndup (end, remainder); - ostream->priv->buflen = remainder; - len -= remainder; - } - else - { - /* TODO: we could escape invalid text and tag it in red - * and make the doc readonly. - */ - g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, - _("Invalid UTF-8 sequence in input")); - - if (freetext) - g_free (text); - - return -1; - } - } - - gtk_text_buffer_insert (GTK_TEXT_BUFFER (ostream->priv->doc), - &ostream->priv->pos, text, len); - - if (freetext) - g_free (text); - - return count; -} - -static gboolean -xed_document_output_stream_flush (GOutputStream *stream, - GCancellable *cancellable, - GError **error) -{ - XedDocumentOutputStream *ostream = XED_DOCUMENT_OUTPUT_STREAM (stream); - - /* Flush deferred data if some. */ - if (!ostream->priv->is_closed && ostream->priv->is_initialized && - ostream->priv->buflen > 0 && - xed_document_output_stream_write (stream, "", 0, cancellable, - error) == -1) - return FALSE; - - return TRUE; -} - -static gboolean -xed_document_output_stream_close (GOutputStream *stream, - GCancellable *cancellable, - GError **error) -{ - XedDocumentOutputStream *ostream = XED_DOCUMENT_OUTPUT_STREAM (stream); - - if (!ostream->priv->is_closed && ostream->priv->is_initialized) - { - end_append_text_to_document (ostream); - ostream->priv->is_closed = TRUE; - } - - if (ostream->priv->buflen > 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, - _("Incomplete UTF-8 sequence in input")); - return FALSE; - } - - return TRUE; -} diff --git a/xed/xed-document-output-stream.h b/xed/xed-document-output-stream.h deleted file mode 100644 index e63daeb..0000000 --- a/xed/xed-document-output-stream.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * xed-document-output-stream.h - * This file is part of xed - * - * Copyright (C) 2010 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - - -#ifndef __XED_DOCUMENT_OUTPUT_STREAM_H__ -#define __XED_DOCUMENT_OUTPUT_STREAM_H__ - -#include -#include "xed-document.h" - -G_BEGIN_DECLS - -#define XED_TYPE_DOCUMENT_OUTPUT_STREAM (xed_document_output_stream_get_type ()) -#define XED_DOCUMENT_OUTPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_DOCUMENT_OUTPUT_STREAM, XedDocumentOutputStream)) -#define XED_DOCUMENT_OUTPUT_STREAM_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_DOCUMENT_OUTPUT_STREAM, XedDocumentOutputStream const)) -#define XED_DOCUMENT_OUTPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_DOCUMENT_OUTPUT_STREAM, XedDocumentOutputStreamClass)) -#define XED_IS_DOCUMENT_OUTPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_DOCUMENT_OUTPUT_STREAM)) -#define XED_IS_DOCUMENT_OUTPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT_OUTPUT_STREAM)) -#define XED_DOCUMENT_OUTPUT_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_DOCUMENT_OUTPUT_STREAM, XedDocumentOutputStreamClass)) - -typedef struct _XedDocumentOutputStream XedDocumentOutputStream; -typedef struct _XedDocumentOutputStreamClass XedDocumentOutputStreamClass; -typedef struct _XedDocumentOutputStreamPrivate XedDocumentOutputStreamPrivate; - -struct _XedDocumentOutputStream -{ - GOutputStream parent; - - XedDocumentOutputStreamPrivate *priv; -}; - -struct _XedDocumentOutputStreamClass -{ - GOutputStreamClass parent_class; -}; - -GType xed_document_output_stream_get_type (void) G_GNUC_CONST; - -GOutputStream *xed_document_output_stream_new (XedDocument *doc); - -XedDocumentNewlineType xed_document_output_stream_detect_newline_type (XedDocumentOutputStream *stream); - -G_END_DECLS - -#endif /* __XED_DOCUMENT_OUTPUT_STREAM_H__ */ diff --git a/xed/xed-document-saver.c b/xed/xed-document-saver.c deleted file mode 100644 index 8108217..0000000 --- a/xed/xed-document-saver.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * xed-document-saver.c - * This file is part of xed - * - * Copyright (C) 2005-2006 - Paolo Borelli and Paolo Maggi - * Copyright (C) 2007 - Paolo Borelli, Paolo Maggi, Steve Frécinaux - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005-2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include - -#include "xed-document-saver.h" -#include "xed-debug.h" -#include "xed-prefs-manager.h" -#include "xed-marshal.h" -#include "xed-utils.h" -#include "xed-enum-types.h" -#include "xed-gio-document-saver.h" - -G_DEFINE_ABSTRACT_TYPE(XedDocumentSaver, xed_document_saver, G_TYPE_OBJECT) - -/* Signals */ - -enum { - SAVING, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* Properties */ - -enum { - PROP_0, - PROP_DOCUMENT, - PROP_URI, - PROP_ENCODING, - PROP_NEWLINE_TYPE, - PROP_FLAGS -}; - -static void -xed_document_saver_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedDocumentSaver *saver = XED_DOCUMENT_SAVER (object); - - switch (prop_id) - { - case PROP_DOCUMENT: - g_return_if_fail (saver->document == NULL); - saver->document = g_value_get_object (value); - break; - case PROP_URI: - g_return_if_fail (saver->uri == NULL); - saver->uri = g_value_dup_string (value); - break; - case PROP_ENCODING: - g_return_if_fail (saver->encoding == NULL); - saver->encoding = g_value_get_boxed (value); - break; - case PROP_NEWLINE_TYPE: - saver->newline_type = g_value_get_enum (value); - break; - case PROP_FLAGS: - saver->flags = g_value_get_flags (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_document_saver_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - XedDocumentSaver *saver = XED_DOCUMENT_SAVER (object); - - switch (prop_id) - { - case PROP_DOCUMENT: - g_value_set_object (value, saver->document); - break; - case PROP_URI: - g_value_set_string (value, saver->uri); - break; - case PROP_ENCODING: - g_value_set_boxed (value, saver->encoding); - break; - case PROP_NEWLINE_TYPE: - g_value_set_enum (value, saver->newline_type); - break; - case PROP_FLAGS: - g_value_set_flags (value, saver->flags); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_document_saver_finalize (GObject *object) -{ - XedDocumentSaver *saver = XED_DOCUMENT_SAVER (object); - - g_free (saver->uri); - - G_OBJECT_CLASS (xed_document_saver_parent_class)->finalize (object); -} - -static void -xed_document_saver_dispose (GObject *object) -{ - XedDocumentSaver *saver = XED_DOCUMENT_SAVER (object); - - if (saver->info != NULL) - { - g_object_unref (saver->info); - saver->info = NULL; - } - - G_OBJECT_CLASS (xed_document_saver_parent_class)->dispose (object); -} - -static void -xed_document_saver_class_init (XedDocumentSaverClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_document_saver_finalize; - object_class->dispose = xed_document_saver_dispose; - object_class->set_property = xed_document_saver_set_property; - object_class->get_property = xed_document_saver_get_property; - - g_object_class_install_property (object_class, - PROP_DOCUMENT, - g_param_spec_object ("document", - "Document", - "The XedDocument this XedDocumentSaver is associated with", - XED_TYPE_DOCUMENT, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_URI, - g_param_spec_string ("uri", - "URI", - "The URI this XedDocumentSaver saves the document to", - "", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_ENCODING, - g_param_spec_boxed ("encoding", - "URI", - "The encoding of the saved file", - XED_TYPE_ENCODING, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_NEWLINE_TYPE, - g_param_spec_enum ("newline-type", - "Newline type", - "The accepted types of line ending", - XED_TYPE_DOCUMENT_NEWLINE_TYPE, - XED_DOCUMENT_NEWLINE_TYPE_LF, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_BLURB | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_FLAGS, - g_param_spec_flags ("flags", - "Flags", - "The flags for the saving operation", - XED_TYPE_DOCUMENT_SAVE_FLAGS, - 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - signals[SAVING] = - g_signal_new ("saving", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentSaverClass, saving), - NULL, NULL, - xed_marshal_VOID__BOOLEAN_POINTER, - G_TYPE_NONE, - 2, - G_TYPE_BOOLEAN, - G_TYPE_POINTER); -} - -static void -xed_document_saver_init (XedDocumentSaver *saver) -{ - saver->used = FALSE; -} - -XedDocumentSaver * -xed_document_saver_new (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentNewlineType newline_type, - XedDocumentSaveFlags flags) -{ - XedDocumentSaver *saver; - GType saver_type; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - - saver_type = XED_TYPE_GIO_DOCUMENT_SAVER; - - if (encoding == NULL) - encoding = xed_encoding_get_utf8 (); - - saver = XED_DOCUMENT_SAVER (g_object_new (saver_type, - "document", doc, - "uri", uri, - "encoding", encoding, - "newline_type", newline_type, - "flags", flags, - NULL)); - - return saver; -} - -void -xed_document_saver_saving (XedDocumentSaver *saver, - gboolean completed, - GError *error) -{ - /* the object will be unrefed in the callback of the saving - * signal, so we need to prevent finalization. - */ - if (completed) - { - g_object_ref (saver); - } - - g_signal_emit (saver, signals[SAVING], 0, completed, error); - - if (completed) - { - if (error == NULL) - xed_debug_message (DEBUG_SAVER, "save completed"); - else - xed_debug_message (DEBUG_SAVER, "save failed"); - - g_object_unref (saver); - } -} - -void -xed_document_saver_save (XedDocumentSaver *saver, - GTimeVal *old_mtime) -{ - xed_debug (DEBUG_SAVER); - - g_return_if_fail (XED_IS_DOCUMENT_SAVER (saver)); - g_return_if_fail (saver->uri != NULL && strlen (saver->uri) > 0); - - g_return_if_fail (saver->used == FALSE); - saver->used = TRUE; - - // CHECK: - // - sanity check a max len for the uri? - // report async (in an idle handler) or sync (bool ret) - // async is extra work here, sync is special casing in the caller - - /* never keep backup of autosaves */ - if ((saver->flags & XED_DOCUMENT_SAVE_PRESERVE_BACKUP) != 0) - saver->keep_backup = FALSE; - else - saver->keep_backup = xed_prefs_manager_get_create_backup_copy (); - - XED_DOCUMENT_SAVER_GET_CLASS (saver)->save (saver, old_mtime); -} - -XedDocument * -xed_document_saver_get_document (XedDocumentSaver *saver) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_SAVER (saver), NULL); - - return saver->document; -} - -const gchar * -xed_document_saver_get_uri (XedDocumentSaver *saver) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_SAVER (saver), NULL); - - return saver->uri; -} - -/* Returns 0 if file size is unknown */ -goffset -xed_document_saver_get_file_size (XedDocumentSaver *saver) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_SAVER (saver), 0); - - return XED_DOCUMENT_SAVER_GET_CLASS (saver)->get_file_size (saver); -} - -goffset -xed_document_saver_get_bytes_written (XedDocumentSaver *saver) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_SAVER (saver), 0); - - return XED_DOCUMENT_SAVER_GET_CLASS (saver)->get_bytes_written (saver); -} - -GFileInfo * -xed_document_saver_get_info (XedDocumentSaver *saver) -{ - g_return_val_if_fail (XED_IS_DOCUMENT_SAVER (saver), NULL); - - return saver->info; -} diff --git a/xed/xed-document-saver.h b/xed/xed-document-saver.h deleted file mode 100644 index 89743b1..0000000 --- a/xed/xed-document-saver.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * xed-document-saver.h - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * Copyrhing (C) 2007 - Paolo Maggi, Steve Frécinaux - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_DOCUMENT_SAVER_H__ -#define __XED_DOCUMENT_SAVER_H__ - -#include - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_DOCUMENT_SAVER (xed_document_saver_get_type()) -#define XED_DOCUMENT_SAVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_DOCUMENT_SAVER, XedDocumentSaver)) -#define XED_DOCUMENT_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_DOCUMENT_SAVER, XedDocumentSaverClass)) -#define XED_IS_DOCUMENT_SAVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_DOCUMENT_SAVER)) -#define XED_IS_DOCUMENT_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT_SAVER)) -#define XED_DOCUMENT_SAVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_DOCUMENT_SAVER, XedDocumentSaverClass)) - -/* - * Main object structure - */ -typedef struct _XedDocumentSaver XedDocumentSaver; - -struct _XedDocumentSaver -{ - GObject object; - - /*< private >*/ - GFileInfo *info; - XedDocument *document; - gboolean used; - - gchar *uri; - const XedEncoding *encoding; - XedDocumentNewlineType newline_type; - - XedDocumentSaveFlags flags; - - gboolean keep_backup; -}; - -/* - * Class definition - */ -typedef struct _XedDocumentSaverClass XedDocumentSaverClass; - -struct _XedDocumentSaverClass -{ - GObjectClass parent_class; - - /* Signals */ - void (* saving) (XedDocumentSaver *saver, - gboolean completed, - const GError *error); - - /* VTable */ - void (* save) (XedDocumentSaver *saver, - GTimeVal *old_mtime); - goffset (* get_file_size) (XedDocumentSaver *saver); - goffset (* get_bytes_written) (XedDocumentSaver *saver); -}; - -/* - * Public methods - */ -GType xed_document_saver_get_type (void) G_GNUC_CONST; - -/* If enconding == NULL, the encoding will be autodetected */ -XedDocumentSaver *xed_document_saver_new (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentNewlineType newline_type, - XedDocumentSaveFlags flags); - -void xed_document_saver_saving (XedDocumentSaver *saver, - gboolean completed, - GError *error); -void xed_document_saver_save (XedDocumentSaver *saver, - GTimeVal *old_mtime); - -#if 0 -void xed_document_saver_cancel (XedDocumentSaver *saver); -#endif - -XedDocument *xed_document_saver_get_document (XedDocumentSaver *saver); - -const gchar *xed_document_saver_get_uri (XedDocumentSaver *saver); - -/* If backup_uri is NULL no backup will be made */ -const gchar *xed_document_saver_get_backup_uri (XedDocumentSaver *saver); -void *xed_document_saver_set_backup_uri (XedDocumentSaver *saver, - const gchar *backup_uri); - -/* Returns 0 if file size is unknown */ -goffset xed_document_saver_get_file_size (XedDocumentSaver *saver); - -goffset xed_document_saver_get_bytes_written (XedDocumentSaver *saver); - -GFileInfo *xed_document_saver_get_info (XedDocumentSaver *saver); - -G_END_DECLS - -#endif /* __XED_DOCUMENT_SAVER_H__ */ diff --git a/xed/xed-document.c b/xed/xed-document.c index d559e79..30a5fa9 100644 --- a/xed/xed-document.c +++ b/xed/xed-document.c @@ -3,8 +3,8 @@ * This file is part of xed * * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence - * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi - * Copyright (C) 2002-2005 Paolo Maggi + * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi + * Copyright (C) 2002-2005 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,14 +18,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 1998-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 1998-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -39,19 +39,13 @@ #include #include -#include -#include "xed-prefs-manager-app.h" #include "xed-document.h" +#include "xed-settings.h" #include "xed-debug.h" #include "xed-utils.h" -#include "xed-language-manager.h" -#include "xed-style-scheme-manager.h" -#include "xed-document-loader.h" -#include "xed-document-saver.h" #include "xed-marshal.h" #include "xed-enum-types.h" -#include "xedtextregion.h" #ifndef ENABLE_GVFS_METADATA #include "xed-metadata-manager.h" @@ -59,940 +53,713 @@ #define METADATA_QUERY "metadata::*" #endif -#undef ENABLE_PROFILE - -#ifdef ENABLE_PROFILE -#define PROFILE(x) x -#else -#define PROFILE(x) -#endif - -PROFILE (static GTimer *timer = NULL) - -#ifdef MAXPATHLEN -#define XED_MAX_PATH_LEN MAXPATHLEN -#elif defined (PATH_MAX) -#define XED_MAX_PATH_LEN PATH_MAX -#else -#define XED_MAX_PATH_LEN 2048 -#endif +#define NO_LANGUAGE_NAME "_NORMAL_" #define XED_DOCUMENT_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_DOCUMENT, XedDocumentPrivate)) -static void xed_document_load_real (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create); -static void xed_document_save_real (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentSaveFlags flags); -static void to_search_region_range (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end); -static void insert_text_cb (XedDocument *doc, - GtkTextIter *pos, - const gchar *text, - gint length); - -static void delete_range_cb (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end); - +static void xed_document_loaded_real (XedDocument *doc); +static void xed_document_saved_real (XedDocument *doc); + struct _XedDocumentPrivate { - gchar *uri; - gint untitled_number; - gchar *short_name; + GtkSourceFile *file; - GFileInfo *metadata_info; + GSettings *editor_settings; - const XedEncoding *encoding; + gint untitled_number; + gchar *short_name; - gchar *content_type; + GFileInfo *metadata_info; - GTimeVal mtime; - GTimeVal time_of_last_save_or_load; + gchar *content_type; - guint search_flags; - gchar *search_text; - gint num_of_lines_search_text; + GTimeVal mtime; + GTimeVal time_of_last_save_or_load; - XedDocumentNewlineType newline_type; + GtkSourceSearchContext *search_context; - /* Temp data while loading */ - XedDocumentLoader *loader; - gboolean create; /* Create file if uri points - * to a non existing file */ - const XedEncoding *requested_encoding; - gint requested_line_pos; + guint readonly : 1; + guint externally_modified : 1; + guint deleted : 1; + guint last_save_was_manually : 1; + guint language_set_by_user : 1; + guint stop_cursor_moved_emission : 1; + guint mtime_set : 1; - /* Saving stuff */ - XedDocumentSaver *saver; - - /* Search highlighting support variables */ - XedTextRegion *to_search_region; - GtkTextTag *found_tag; - - /* Mount operation factory */ - XedMountOperationFactory mount_operation_factory; - gpointer mount_operation_userdata; - - gint readonly : 1; - gint last_save_was_manually : 1; - gint language_set_by_user : 1; - gint stop_cursor_moved_emission : 1; - gint dispose_has_run : 1; + /* Create file if location points to a non existing file (for example + * when opened from the command line). + */ + guint create : 1; }; -enum { - PROP_0, - - PROP_URI, - PROP_SHORTNAME, - PROP_CONTENT_TYPE, - PROP_MIME_TYPE, - PROP_READ_ONLY, - PROP_ENCODING, - PROP_CAN_SEARCH_AGAIN, - PROP_ENABLE_SEARCH_HIGHLIGHTING, - PROP_NEWLINE_TYPE +enum +{ + PROP_0, + PROP_SHORTNAME, + PROP_CONTENT_TYPE, + PROP_MIME_TYPE, + PROP_READ_ONLY }; -enum { - CURSOR_MOVED, - LOAD, - LOADING, - LOADED, - SAVE, - SAVING, - SAVED, - SEARCH_HIGHLIGHT_UPDATED, - LAST_SIGNAL +enum +{ + CURSOR_MOVED, + LOAD, + LOADED, + SAVE, + SAVED, + LAST_SIGNAL }; static guint document_signals[LAST_SIGNAL] = { 0 }; -G_DEFINE_TYPE(XedDocument, xed_document, GTK_SOURCE_TYPE_BUFFER) - -GQuark -xed_document_error_quark (void) -{ - static GQuark quark = 0; - - if (G_UNLIKELY (quark == 0)) - quark = g_quark_from_static_string ("xed_io_load_error"); - - return quark; -} - static GHashTable *allocated_untitled_numbers = NULL; +G_DEFINE_TYPE(XedDocument, xed_document, GTK_SOURCE_TYPE_BUFFER) + static gint get_untitled_number (void) { - gint i = 1; + gint i = 1; - if (allocated_untitled_numbers == NULL) - allocated_untitled_numbers = g_hash_table_new (NULL, NULL); + if (allocated_untitled_numbers == NULL) + { + allocated_untitled_numbers = g_hash_table_new (NULL, NULL); + } - g_return_val_if_fail (allocated_untitled_numbers != NULL, -1); + g_return_val_if_fail (allocated_untitled_numbers != NULL, -1); - while (TRUE) - { - if (g_hash_table_lookup (allocated_untitled_numbers, GINT_TO_POINTER (i)) == NULL) - { - g_hash_table_insert (allocated_untitled_numbers, - GINT_TO_POINTER (i), - GINT_TO_POINTER (i)); + while (TRUE) + { + if (g_hash_table_lookup (allocated_untitled_numbers, GINT_TO_POINTER (i)) == NULL) + { + g_hash_table_insert (allocated_untitled_numbers, GINT_TO_POINTER (i), GINT_TO_POINTER (i)); - return i; - } + return i; + } - ++i; - } + ++i; + } } static void release_untitled_number (gint n) { - g_return_if_fail (allocated_untitled_numbers != NULL); + g_return_if_fail (allocated_untitled_numbers != NULL); - g_hash_table_remove (allocated_untitled_numbers, GINT_TO_POINTER (n)); + g_hash_table_remove (allocated_untitled_numbers, GINT_TO_POINTER (n)); +} + +static const gchar * +get_language_string (XedDocument *doc) +{ + GtkSourceLanguage *lang = xed_document_get_language (doc); + + return lang != NULL ? gtk_source_language_get_id (lang) : NO_LANGUAGE_NAME; +} + +static void +save_metadata (XedDocument *doc) +{ + const gchar *language = NULL; + GtkTextIter iter; + gchar *position; + + if (doc->priv->language_set_by_user) + { + language = get_language_string (doc); + } + + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), + &iter, + gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (doc))); + + position = g_strdup_printf ("%d", gtk_text_iter_get_offset (&iter)); + + if (language == NULL) + { + xed_document_set_metadata (doc, + XED_METADATA_ATTRIBUTE_POSITION, position, + NULL); + } + else + { + xed_document_set_metadata (doc, + XED_METADATA_ATTRIBUTE_POSITION, position, + XED_METADATA_ATTRIBUTE_LANGUAGE, language, + NULL); + } + + g_free (position); } static void xed_document_dispose (GObject *object) { - XedDocument *doc = XED_DOCUMENT (object); + XedDocument *doc = XED_DOCUMENT (object); - xed_debug (DEBUG_DOCUMENT); + xed_debug (DEBUG_DOCUMENT); - /* Metadata must be saved here and not in finalize - * because the language is gone by the time finalize runs. - * beside if some plugin prevents proper finalization by - * holding a ref to the doc, we still save the metadata */ - if ((!doc->priv->dispose_has_run) && (doc->priv->uri != NULL)) - { - GtkTextIter iter; - gchar *position; - const gchar *language = NULL; + /* Metadata must be saved here and not in finalize because the language + * is gone by the time finalize runs. + */ + if (doc->priv->file != NULL) + { + save_metadata (doc); - if (doc->priv->language_set_by_user) - { - GtkSourceLanguage *lang; + g_object_unref (doc->priv->file); + doc->priv->file = NULL; + } - lang = xed_document_get_language (doc); + g_clear_object (&doc->priv->editor_settings); + g_clear_object (&doc->priv->metadata_info); + g_clear_object (&doc->priv->search_context); - if (lang == NULL) - language = "_NORMAL_"; - else - language = gtk_source_language_get_id (lang); - } - - gtk_text_buffer_get_iter_at_mark ( - GTK_TEXT_BUFFER (doc), - &iter, - gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (doc))); - - position = g_strdup_printf ("%d", - gtk_text_iter_get_offset (&iter)); - - if (language == NULL) - xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_POSITION, - position, NULL); - else - xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_POSITION, - position, XED_METADATA_ATTRIBUTE_LANGUAGE, - language, NULL); - g_free (position); - } - - if (doc->priv->loader) - { - g_object_unref (doc->priv->loader); - doc->priv->loader = NULL; - } - - if (doc->priv->metadata_info != NULL) - { - g_object_unref (doc->priv->metadata_info); - doc->priv->metadata_info = NULL; - } - - doc->priv->dispose_has_run = TRUE; - - G_OBJECT_CLASS (xed_document_parent_class)->dispose (object); + G_OBJECT_CLASS (xed_document_parent_class)->dispose (object); } static void xed_document_finalize (GObject *object) { - XedDocument *doc = XED_DOCUMENT (object); + XedDocument *doc = XED_DOCUMENT (object); - xed_debug (DEBUG_DOCUMENT); + xed_debug (DEBUG_DOCUMENT); - if (doc->priv->untitled_number > 0) - { - g_return_if_fail (doc->priv->uri == NULL); - release_untitled_number (doc->priv->untitled_number); - } + if (doc->priv->untitled_number > 0) + { + release_untitled_number (doc->priv->untitled_number); + } - g_free (doc->priv->uri); - g_free (doc->priv->content_type); - g_free (doc->priv->search_text); + g_free (doc->priv->content_type); + g_free (doc->priv->short_name); - if (doc->priv->to_search_region != NULL) - { - /* we can't delete marks if we're finalizing the buffer */ - xed_text_region_destroy (doc->priv->to_search_region, FALSE); - } - - G_OBJECT_CLASS (xed_document_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_document_parent_class)->finalize (object); } static void xed_document_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedDocument *doc = XED_DOCUMENT (object); + XedDocument *doc = XED_DOCUMENT (object); - switch (prop_id) - { - case PROP_URI: - g_value_set_string (value, doc->priv->uri); - break; - case PROP_SHORTNAME: - g_value_take_string (value, xed_document_get_short_name_for_display (doc)); - break; - case PROP_CONTENT_TYPE: - g_value_take_string (value, xed_document_get_content_type (doc)); - break; - case PROP_MIME_TYPE: - g_value_take_string (value, xed_document_get_mime_type (doc)); - break; - case PROP_READ_ONLY: - g_value_set_boolean (value, doc->priv->readonly); - break; - case PROP_ENCODING: - g_value_set_boxed (value, doc->priv->encoding); - break; - case PROP_CAN_SEARCH_AGAIN: - g_value_set_boolean (value, xed_document_get_can_search_again (doc)); - break; - case PROP_ENABLE_SEARCH_HIGHLIGHTING: - g_value_set_boolean (value, xed_document_get_enable_search_highlighting (doc)); - break; - case PROP_NEWLINE_TYPE: - g_value_set_enum (value, doc->priv->newline_type); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_SHORTNAME: + g_value_take_string (value, xed_document_get_short_name_for_display (doc)); + break; + case PROP_CONTENT_TYPE: + g_value_take_string (value, xed_document_get_content_type (doc)); + break; + case PROP_MIME_TYPE: + g_value_take_string (value, xed_document_get_mime_type (doc)); + break; + case PROP_READ_ONLY: + g_value_set_boolean (value, doc->priv->readonly); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_document_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedDocument *doc = XED_DOCUMENT (object); + XedDocument *doc = XED_DOCUMENT (object); - switch (prop_id) - { - case PROP_ENABLE_SEARCH_HIGHLIGHTING: - xed_document_set_enable_search_highlighting (doc, - g_value_get_boolean (value)); - break; - case PROP_NEWLINE_TYPE: - xed_document_set_newline_type (doc, - g_value_get_enum (value)); - break; - case PROP_SHORTNAME: - xed_document_set_short_name_for_display (doc, - g_value_get_string (value)); - break; - case PROP_CONTENT_TYPE: - xed_document_set_content_type (doc, - g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_SHORTNAME: + xed_document_set_short_name_for_display (doc, g_value_get_string (value)); + break; + case PROP_CONTENT_TYPE: + xed_document_set_content_type (doc, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void emit_cursor_moved (XedDocument *doc) { - if (!doc->priv->stop_cursor_moved_emission) - { - g_signal_emit (doc, - document_signals[CURSOR_MOVED], - 0); - } + if (!doc->priv->stop_cursor_moved_emission) + { + g_signal_emit (doc, document_signals[CURSOR_MOVED], 0); + } } static void xed_document_mark_set (GtkTextBuffer *buffer, - const GtkTextIter *iter, - GtkTextMark *mark) + const GtkTextIter *iter, + GtkTextMark *mark) { - XedDocument *doc = XED_DOCUMENT (buffer); + XedDocument *doc = XED_DOCUMENT (buffer); - if (GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->mark_set) - GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->mark_set (buffer, - iter, - mark); + if (GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->mark_set != NULL) + { + GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->mark_set (buffer, iter, mark); + } - if (mark == gtk_text_buffer_get_insert (buffer)) - { - emit_cursor_moved (doc); - } + if (mark == gtk_text_buffer_get_insert (buffer)) + { + emit_cursor_moved (doc); + } } static void xed_document_changed (GtkTextBuffer *buffer) { - emit_cursor_moved (XED_DOCUMENT (buffer)); + emit_cursor_moved (XED_DOCUMENT (buffer)); - GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->changed (buffer); -} - -static void -xed_document_class_init (XedDocumentClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkTextBufferClass *buf_class = GTK_TEXT_BUFFER_CLASS (klass); - - object_class->dispose = xed_document_dispose; - object_class->finalize = xed_document_finalize; - object_class->get_property = xed_document_get_property; - object_class->set_property = xed_document_set_property; - - buf_class->mark_set = xed_document_mark_set; - buf_class->changed = xed_document_changed; - - klass->load = xed_document_load_real; - klass->save = xed_document_save_real; - - g_object_class_install_property (object_class, PROP_URI, - g_param_spec_string ("uri", - "URI", - "The document's URI", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_SHORTNAME, - g_param_spec_string ("shortname", - "Short Name", - "The document's short name", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_CONTENT_TYPE, - g_param_spec_string ("content-type", - "Content Type", - "The document's Content Type", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_MIME_TYPE, - g_param_spec_string ("mime-type", - "MIME Type", - "The document's MIME Type", - "text/plain", - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_READ_ONLY, - g_param_spec_boolean ("read-only", - "Read Only", - "Whether the document is read only or not", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_ENCODING, - g_param_spec_boxed ("encoding", - "Encoding", - "The XedEncoding used for the document", - XED_TYPE_ENCODING, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_CAN_SEARCH_AGAIN, - g_param_spec_boolean ("can-search-again", - "Can search again", - "Whether it's possible to search again in the document", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_ENABLE_SEARCH_HIGHLIGHTING, - g_param_spec_boolean ("enable-search-highlighting", - "Enable Search Highlighting", - "Whether all the occurrences of the searched string must be highlighted", - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - /** - * XedDocument:newline-type: - * - * The :newline-type property determines what is considered - * as a line ending when saving the document - */ - g_object_class_install_property (object_class, PROP_NEWLINE_TYPE, - g_param_spec_enum ("newline-type", - "Newline type", - "The accepted types of line ending", - XED_TYPE_DOCUMENT_NEWLINE_TYPE, - XED_DOCUMENT_NEWLINE_TYPE_LF, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_BLURB)); - - /* This signal is used to update the cursor position is the statusbar, - * it's emitted either when the insert mark is moved explicitely or - * when the buffer changes (insert/delete). - * We prevent the emission of the signal during replace_all to - * improve performance. - */ - document_signals[CURSOR_MOVED] = - g_signal_new ("cursor-moved", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentClass, cursor_moved), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - /** - * XedDocument::load: - * @document: the #XedDocument. - * @uri: the uri where to load the document from. - * @encoding: the #XedEncoding to encode the document. - * @line_pos: the line to show. - * @create: whether the document should be created if it doesn't exist. - * - * The "load" signal is emitted when a document is loaded. - * - * Since: 2.22 - */ - document_signals[LOAD] = - g_signal_new ("load", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentClass, load), - NULL, NULL, - xed_marshal_VOID__STRING_BOXED_INT_BOOLEAN, - G_TYPE_NONE, - 4, - G_TYPE_STRING, - /* we rely on the fact that the XedEncoding pointer stays - * the same forever */ - XED_TYPE_ENCODING | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_INT, - G_TYPE_BOOLEAN); - - - document_signals[LOADING] = - g_signal_new ("loading", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentClass, loading), - NULL, NULL, - xed_marshal_VOID__UINT64_UINT64, - G_TYPE_NONE, - 2, - G_TYPE_UINT64, - G_TYPE_UINT64); - - document_signals[LOADED] = - g_signal_new ("loaded", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentClass, loaded), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, - G_TYPE_POINTER); - - /** - * XedDocument::save: - * @document: the #XedDocument. - * @uri: the uri where the document is about to be saved. - * @encoding: the #XedEncoding used to save the document. - * @flags: the #XedDocumentSaveFlags for the save operation. - * - * The "save" signal is emitted when the document is saved. - * - * Since: 2.20 - */ - document_signals[SAVE] = - g_signal_new ("save", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentClass, save), - NULL, NULL, - xed_marshal_VOID__STRING_BOXED_FLAGS, - G_TYPE_NONE, - 3, - G_TYPE_STRING, - /* we rely on the fact that the XedEncoding pointer stays - * the same forever */ - XED_TYPE_ENCODING | G_SIGNAL_TYPE_STATIC_SCOPE, - XED_TYPE_DOCUMENT_SAVE_FLAGS); - - document_signals[SAVING] = - g_signal_new ("saving", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentClass, saving), - NULL, NULL, - xed_marshal_VOID__UINT64_UINT64, - G_TYPE_NONE, - 2, - G_TYPE_UINT64, - G_TYPE_UINT64); - - document_signals[SAVED] = - g_signal_new ("saved", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentClass, saved), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, - G_TYPE_POINTER); - - document_signals[SEARCH_HIGHLIGHT_UPDATED] = - g_signal_new ("search_highlight_updated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedDocumentClass, search_highlight_updated), - NULL, NULL, - xed_marshal_VOID__BOXED_BOXED, - G_TYPE_NONE, - 2, - GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE, - GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE); - - g_type_class_add_private (object_class, sizeof(XedDocumentPrivate)); + GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->changed (buffer); } static void -set_language (XedDocument *doc, +xed_document_constructed (GObject *object) +{ + XedDocument *doc = XED_DOCUMENT (object); + + g_settings_bind (doc->priv->editor_settings, + XED_SETTINGS_ENSURE_TRAILING_NEWLINE, + doc, + "implicit-trailing-newline", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY); + + G_OBJECT_CLASS (xed_document_parent_class)->constructed (object); +} + +static void +xed_document_class_init (XedDocumentClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkTextBufferClass *buf_class = GTK_TEXT_BUFFER_CLASS (klass); + + object_class->dispose = xed_document_dispose; + object_class->finalize = xed_document_finalize; + object_class->get_property = xed_document_get_property; + object_class->set_property = xed_document_set_property; + object_class->constructed = xed_document_constructed; + + buf_class->mark_set = xed_document_mark_set; + buf_class->changed = xed_document_changed; + + klass->loaded = xed_document_loaded_real; + klass->saved = xed_document_saved_real; + + g_object_class_install_property (object_class, PROP_SHORTNAME, + g_param_spec_string ("shortname", + "Short Name", + "The document's short name", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_CONTENT_TYPE, + g_param_spec_string ("content-type", + "Content Type", + "The document's Content Type", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_MIME_TYPE, + g_param_spec_string ("mime-type", + "MIME Type", + "The document's MIME Type", + "text/plain", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_READ_ONLY, + g_param_spec_boolean ("read-only", + "Read Only", + "Whether the document is read only or not", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* This signal is used to update the cursor position is the statusbar, + * it's emitted either when the insert mark is moved explicitely or + * when the buffer changes (insert/delete). + * We prevent the emission of the signal during replace_all to + * improve performance. + */ + document_signals[CURSOR_MOVED] = + g_signal_new ("cursor-moved", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedDocumentClass, cursor_moved), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * XedDocument::load: + * @document: the #XedDocument. + * + * The "load" signal is emitted at the beginning of file loading. + */ + document_signals[LOAD] = + g_signal_new ("load", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedDocumentClass, load), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * XedDocument::loaded: + * @document: the #XedDocument. + * + * The "loaded" signal is emitted at the end of a successful loading. + */ + document_signals[LOADED] = + g_signal_new ("loaded", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedDocumentClass, loaded), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * XedDocument::save: + * @document: the #XedDocument. + * + * The "save" signal is emitted at the beginning of file saving. + */ + document_signals[SAVE] = + g_signal_new ("save", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedDocumentClass, save), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * XedDocument::saved: + * @document: the #XedDocument. + * + * The "saved" signal is emitted at the end of a successful file saving. + */ + document_signals[SAVED] = + g_signal_new ("saved", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedDocumentClass, saved), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + g_type_class_add_private (object_class, sizeof (XedDocumentPrivate)); +} + +static void +set_language (XedDocument *doc, GtkSourceLanguage *lang, gboolean set_by_user) { - GtkSourceLanguage *old_lang; + GtkSourceLanguage *old_lang; - xed_debug (DEBUG_DOCUMENT); - - old_lang = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (doc)); - - if (old_lang == lang) - return; + xed_debug (DEBUG_DOCUMENT); - gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (doc), lang); + old_lang = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (doc)); - if (lang != NULL) - gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (doc), - xed_prefs_manager_get_enable_syntax_highlighting ()); - else - gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (doc), - FALSE); + if (old_lang == lang) + { + return; + } - if (set_by_user && (doc->priv->uri != NULL)) - { - xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_LANGUAGE, - (lang == NULL) ? "_NORMAL_" : gtk_source_language_get_id (lang), - NULL); - } + gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (doc), lang); - doc->priv->language_set_by_user = set_by_user; + if (lang != NULL) + { + gboolean syntax_hl; + + syntax_hl = g_settings_get_boolean (doc->priv->editor_settings, + XED_SETTINGS_SYNTAX_HIGHLIGHTING); + gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (doc), syntax_hl); + } + else + { + gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (doc), FALSE); + } + + if (set_by_user) + { + const gchar *language = get_language_string (doc); + + xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_LANGUAGE, language, NULL); + } + + doc->priv->language_set_by_user = set_by_user; } static void -set_encoding (XedDocument *doc, - const XedEncoding *encoding, - gboolean set_by_user) +save_encoding_metadata (XedDocument *doc) { - g_return_if_fail (encoding != NULL); + const GtkSourceEncoding *encoding; + const gchar *charset; - xed_debug (DEBUG_DOCUMENT); + xed_debug (DEBUG_DOCUMENT); - if (doc->priv->encoding == encoding) - return; + encoding = gtk_source_file_get_encoding (doc->priv->file); - doc->priv->encoding = encoding; + if (encoding == NULL) + { + encoding = gtk_source_encoding_get_utf8 (); + } - if (set_by_user) - { - const gchar *charset; + charset = gtk_source_encoding_get_charset (encoding); - charset = xed_encoding_get_charset (encoding); - - xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_ENCODING, - charset, NULL); - } - - g_object_notify (G_OBJECT (doc), "encoding"); + xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_ENCODING, charset, NULL); } static GtkSourceStyleScheme * -get_default_style_scheme (void) +get_default_style_scheme (GSettings *editor_settings) { - gchar *scheme_id; - GtkSourceStyleScheme *def_style; - GtkSourceStyleSchemeManager *manager; + GtkSourceStyleSchemeManager *manager; + gchar *scheme_id; + GtkSourceStyleScheme *def_style; - manager = xed_get_style_scheme_manager (); - scheme_id = xed_prefs_manager_get_source_style_scheme (); - def_style = gtk_source_style_scheme_manager_get_scheme (manager, - scheme_id); + manager = gtk_source_style_scheme_manager_get_default (); + scheme_id = g_settings_get_string (editor_settings, XED_SETTINGS_SCHEME); + def_style = gtk_source_style_scheme_manager_get_scheme (manager, scheme_id); - if (def_style == NULL) - { - g_warning ("Default style scheme '%s' cannot be found, falling back to 'classic' style scheme ", scheme_id); + if (def_style == NULL) + { + g_warning ("Default style scheme '%s' cannot be found, falling back to 'classic' style scheme ", scheme_id); - def_style = gtk_source_style_scheme_manager_get_scheme (manager, "classic"); - if (def_style == NULL) - { - g_warning ("Style scheme 'classic' cannot be found, check your GtkSourceView installation."); - } - } + def_style = gtk_source_style_scheme_manager_get_scheme (manager, "classic"); + if (def_style == NULL) + { + g_warning ("Style scheme 'classic' cannot be found, check your GtkSourceView installation."); + } + } - g_free (scheme_id); + g_free (scheme_id); - return def_style; -} - -static void -on_uri_changed (XedDocument *doc, - GParamSpec *pspec, - gpointer useless) -{ -#ifdef ENABLE_GVFS_METADATA - GFile *location; - - location = xed_document_get_location (doc); - - /* load metadata for this uri: we load sync since metadata is - * always local so it should be fast and we need the information - * right after the uri was set. - */ - if (location != NULL) - { - GError *error = NULL; - - if (doc->priv->metadata_info != NULL) - g_object_unref (doc->priv->metadata_info); - - doc->priv->metadata_info = g_file_query_info (location, - METADATA_QUERY, - G_FILE_QUERY_INFO_NONE, - NULL, - &error); - - if (error != NULL) - { - if (error->code != G_FILE_ERROR_ISDIR && - error->code != G_FILE_ERROR_NOTDIR && - error->code != G_FILE_ERROR_NOENT) - { - g_warning ("%s", error->message); - } - - g_error_free (error); - } - - g_object_unref (location); - } -#endif + return def_style; } static GtkSourceLanguage * -guess_language (XedDocument *doc, - const gchar *content_type) +guess_language (XedDocument *doc) { - gchar *data; - GtkSourceLanguage *language = NULL; + gchar *data; + GtkSourceLanguageManager *manager = gtk_source_language_manager_get_default (); + GtkSourceLanguage *language = NULL; - data = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_LANGUAGE); + data = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_LANGUAGE); - if (data != NULL) - { - xed_debug_message (DEBUG_DOCUMENT, "Language from metadata: %s", data); + if (data != NULL) + { + xed_debug_message (DEBUG_DOCUMENT, "Language from metadata: %s", data); - if (strcmp (data, "_NORMAL_") != 0) - { - language = gtk_source_language_manager_get_language ( - xed_get_language_manager (), - data); - } + if (!g_str_equal (data, NO_LANGUAGE_NAME)) + { + language = gtk_source_language_manager_get_language (manager, data); + } - g_free (data); - } - else - { - GFile *file; - gchar *basename = NULL; + g_free (data); + } + else + { + GFile *location; + gchar *basename = NULL; - file = xed_document_get_location (doc); - xed_debug_message (DEBUG_DOCUMENT, "Sniffing Language"); + location = gtk_source_file_get_location (doc->priv->file); + xed_debug_message (DEBUG_DOCUMENT, "Sniffing Language"); - if (file) - { - basename = g_file_get_basename (file); - } - else if (doc->priv->short_name != NULL) - { - basename = g_strdup (doc->priv->short_name); - } + if (location != NULL) + { + basename = g_file_get_basename (location); + } + else if (doc->priv->short_name != NULL) + { + basename = g_strdup (doc->priv->short_name); + } - language = gtk_source_language_manager_guess_language ( - xed_get_language_manager (), - basename, - content_type); + language = gtk_source_language_manager_guess_language (manager, basename, doc->priv->content_type); - g_free (basename); + g_free (basename); + } - if (file != NULL) - { - g_object_unref (file); - } - } - - return language; + return language; } static void on_content_type_changed (XedDocument *doc, - GParamSpec *pspec, - gpointer useless) + GParamSpec *pspec, + gpointer useless) { - if (!doc->priv->language_set_by_user) - { - GtkSourceLanguage *language; + if (!doc->priv->language_set_by_user) + { + GtkSourceLanguage *language = guess_language (doc); - language = guess_language (doc, doc->priv->content_type); + xed_debug_message (DEBUG_DOCUMENT, "Language: %s", + language != NULL ? gtk_source_language_get_name (language) : "None"); - xed_debug_message (DEBUG_DOCUMENT, "Language: %s", - language != NULL ? gtk_source_language_get_name (language) : "None"); - - set_language (doc, language, FALSE); - } + set_language (doc, language, FALSE); + } } static gchar * get_default_content_type (void) { - return g_content_type_from_mime_type ("text/plain"); + return g_content_type_from_mime_type ("text/plain"); +} + +static void +on_location_changed (GtkSourceFile *file, + GParamSpec *pspec, + XedDocument *doc) +{ + GFile *location; + + xed_debug (DEBUG_DOCUMENT); + + location = gtk_source_file_get_location (file); + + if (location != NULL && doc->priv->untitled_number > 0) + { + release_untitled_number (doc->priv->untitled_number); + doc->priv->untitled_number = 0; + } + + if (doc->priv->short_name == NULL) + { + g_object_notify (G_OBJECT (doc), "shortname"); + } + +#ifdef ENABLE_GVFS_METADATA + + /* load metadata for this location: we load sync since metadata is + * always local so it should be fast and we need the information + * right after the location was set. + */ + if (location != NULL) + { + GError *error = NULL; + + if (doc->priv->metadata_info != NULL) + { + g_object_unref (doc->priv->metadata_info); + } + + doc->priv->metadata_info = g_file_query_info (location, + METADATA_QUERY, + G_FILE_QUERY_INFO_NONE, + NULL, + &error); + + if (error != NULL) + { + /* TODO document why the warning is not displayed in + * certain cases. + */ + if (error->domain != G_FILE_ERROR || + (error->code != G_FILE_ERROR_ISDIR && + error->code != G_FILE_ERROR_NOTDIR && + error->code != G_FILE_ERROR_NOENT)) + { + g_warning ("%s", error->message); + } + + g_error_free (error); + } + } +#endif } static void xed_document_init (XedDocument *doc) { - GtkSourceStyleScheme *style_scheme; + XedDocumentPrivate *priv; + GtkSourceStyleScheme *style_scheme; - xed_debug (DEBUG_DOCUMENT); + xed_debug (DEBUG_DOCUMENT); - doc->priv = XED_DOCUMENT_GET_PRIVATE (doc); + doc->priv = XED_DOCUMENT_GET_PRIVATE (doc); + priv = doc->priv; - doc->priv->uri = NULL; - doc->priv->untitled_number = get_untitled_number (); + priv->editor_settings = g_settings_new ("org.x.editor.preferences.editor"); - doc->priv->metadata_info = NULL; + priv->untitled_number = get_untitled_number (); - doc->priv->content_type = get_default_content_type (); + priv->content_type = get_default_content_type (); - doc->priv->readonly = FALSE; + priv->readonly = FALSE; - doc->priv->stop_cursor_moved_emission = FALSE; + priv->stop_cursor_moved_emission = FALSE; - doc->priv->last_save_was_manually = TRUE; - doc->priv->language_set_by_user = FALSE; + priv->last_save_was_manually = TRUE; + priv->language_set_by_user = FALSE; - doc->priv->dispose_has_run = FALSE; + g_get_current_time (&doc->priv->time_of_last_save_or_load); - doc->priv->mtime.tv_sec = 0; - doc->priv->mtime.tv_usec = 0; + priv->file = gtk_source_file_new (); - g_get_current_time (&doc->priv->time_of_last_save_or_load); + g_signal_connect_object (priv->file, "notify::location", + G_CALLBACK (on_location_changed), doc, 0); - doc->priv->encoding = xed_encoding_get_utf8 (); + g_settings_bind (priv->editor_settings, + XED_SETTINGS_MAX_UNDO_ACTIONS, + doc, + "max-undo-levels", + G_SETTINGS_BIND_GET); - doc->priv->newline_type = XED_DOCUMENT_NEWLINE_TYPE_DEFAULT; + g_settings_bind (priv->editor_settings, + XED_SETTINGS_BRACKET_MATCHING, + doc, + "highlight-matching-brackets", + G_SETTINGS_BIND_GET); - gtk_source_buffer_set_max_undo_levels (GTK_SOURCE_BUFFER (doc), - xed_prefs_manager_get_undo_actions_limit ()); + style_scheme = get_default_style_scheme (priv->editor_settings); + if (style_scheme != NULL) + { + gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (doc), style_scheme); + } - gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (doc), - xed_prefs_manager_get_bracket_matching ()); - - xed_document_set_enable_search_highlighting (doc, - xed_prefs_manager_get_enable_search_highlighting ()); - - style_scheme = get_default_style_scheme (); - if (style_scheme != NULL) - gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (doc), - style_scheme); - - g_signal_connect_after (doc, - "insert-text", - G_CALLBACK (insert_text_cb), - NULL); - - g_signal_connect_after (doc, - "delete-range", - G_CALLBACK (delete_range_cb), - NULL); - - g_signal_connect (doc, - "notify::content-type", - G_CALLBACK (on_content_type_changed), - NULL); - - g_signal_connect (doc, - "notify::uri", - G_CALLBACK (on_uri_changed), - NULL); + g_signal_connect (doc, "notify::content-type", G_CALLBACK (on_content_type_changed), NULL); } XedDocument * xed_document_new (void) { - xed_debug (DEBUG_DOCUMENT); - - return XED_DOCUMENT (g_object_new (XED_TYPE_DOCUMENT, NULL)); + return g_object_new (XED_TYPE_DOCUMENT, NULL); } static void set_content_type_no_guess (XedDocument *doc, - const gchar *content_type) + const gchar *content_type) { - xed_debug (DEBUG_DOCUMENT); + xed_debug (DEBUG_DOCUMENT); - if (doc->priv->content_type != NULL && content_type != NULL && - (0 == strcmp (doc->priv->content_type, content_type))) - return; + if (doc->priv->content_type != NULL && + content_type != NULL && + g_str_equal (doc->priv->content_type, content_type)) + { + return; + } - g_free (doc->priv->content_type); + g_free (doc->priv->content_type); - if (content_type == NULL || g_content_type_is_unknown (content_type)) - doc->priv->content_type = get_default_content_type (); - else - doc->priv->content_type = g_strdup (content_type); + if (content_type == NULL || g_content_type_is_unknown (content_type)) + { + doc->priv->content_type = get_default_content_type (); + } + else + { + doc->priv->content_type = g_strdup (content_type); + } - g_object_notify (G_OBJECT (doc), "content-type"); -} - -static void -set_content_type (XedDocument *doc, - const gchar *content_type) -{ - xed_debug (DEBUG_DOCUMENT); - - if (content_type == NULL) - { - GFile *file; - gchar *guessed_type = NULL; - - /* If content type is null, we guess from the filename */ - file = xed_document_get_location (doc); - if (file != NULL) - { - gchar *basename; - - basename = g_file_get_basename (file); - guessed_type = g_content_type_guess (basename, NULL, 0, NULL); - - g_free (basename); - g_object_unref (file); - } - - set_content_type_no_guess (doc, guessed_type); - - g_free (guessed_type); - } - else - { - set_content_type_no_guess (doc, content_type); - } + g_object_notify (G_OBJECT (doc), "content-type"); } /** @@ -1002,69 +769,65 @@ set_content_type (XedDocument *doc, */ void xed_document_set_content_type (XedDocument *doc, - const gchar *content_type) + const gchar *content_type) { - g_return_if_fail (XED_IS_DOCUMENT (doc)); + g_return_if_fail (XED_IS_DOCUMENT (doc)); - set_content_type (doc, content_type); -} - -static void -set_uri (XedDocument *doc, - const gchar *uri) -{ - xed_debug (DEBUG_DOCUMENT); - - g_return_if_fail ((uri == NULL) || xed_utils_is_valid_uri (uri)); - - if (uri != NULL) - { - if (doc->priv->uri == uri) - return; - - g_free (doc->priv->uri); - doc->priv->uri = g_strdup (uri); - - if (doc->priv->untitled_number > 0) - { - release_untitled_number (doc->priv->untitled_number); - doc->priv->untitled_number = 0; - } - } - - g_object_notify (G_OBJECT (doc), "uri"); - - if (doc->priv->short_name == NULL) - { - g_object_notify (G_OBJECT (doc), "shortname"); - } + xed_debug (DEBUG_DOCUMENT); + + if (content_type == NULL) + { + GFile *location; + gchar *guessed_type = NULL; + + /* If content type is null, we guess from the filename */ + location = gtk_source_file_get_location (doc->priv->file); + if (location != NULL) + { + gchar *basename; + + basename = g_file_get_basename (location); + guessed_type = g_content_type_guess (basename, NULL, 0, NULL); + + g_free (basename); + } + + set_content_type_no_guess (doc, guessed_type); + g_free (guessed_type); + } + else + { + set_content_type_no_guess (doc, content_type); + } } +/** + * xed_document_get_location: + * @doc: a #XedDocument + * + * Returns: (allow-none) (transfer full): a new #GFile + */ GFile * xed_document_get_location (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + GFile *location; - return doc->priv->uri == NULL ? NULL : g_file_new_for_uri (doc->priv->uri); -} + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); -gchar * -xed_document_get_uri (XedDocument *doc) -{ - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + location = gtk_source_file_get_location (doc->priv->file); - return g_strdup (doc->priv->uri); + return location != NULL ? g_object_ref (location) : NULL; } void -xed_document_set_uri (XedDocument *doc, - const gchar *uri) +xed_document_set_location (XedDocument *doc, + GFile *location) { - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (uri != NULL); + g_return_if_fail (XED_IS_DOCUMENT (doc)); + g_return_if_fail (G_IS_FILE (location)); - set_uri (doc, uri); - set_content_type (doc, NULL); + gtk_source_file_set_location (doc->priv->file, location); + xed_document_set_content_type (doc, NULL); } /** @@ -1076,13 +839,20 @@ xed_document_set_uri (XedDocument *doc, gchar * xed_document_get_uri_for_display (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup ("")); + GFile *location; - if (doc->priv->uri == NULL) - return g_strdup_printf (_("Unsaved Document %d"), - doc->priv->untitled_number); - else - return xed_utils_uri_for_display (doc->priv->uri); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup ("")); + + location = gtk_source_file_get_location (doc->priv->file); + + if (location == NULL) + { + return g_strdup_printf (_("Unsaved Document %d"), doc->priv->untitled_number); + } + else + { + return g_file_get_parse_name (location); + } } /** @@ -1094,15 +864,24 @@ xed_document_get_uri_for_display (XedDocument *doc) gchar * xed_document_get_short_name_for_display (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup ("")); + GFile *location; - if (doc->priv->short_name != NULL) - return g_strdup (doc->priv->short_name); - else if (doc->priv->uri == NULL) - return g_strdup_printf (_("Unsaved Document %d"), - doc->priv->untitled_number); - else - return xed_utils_basename_for_display (doc->priv->uri); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup ("")); + + location = gtk_source_file_get_location (doc->priv->file); + + if (doc->priv->short_name != NULL) + { + return g_strdup (doc->priv->short_name); + } + else if (location == NULL) + { + return g_strdup_printf (_("Unsaved Document %d"), doc->priv->untitled_number); + } + else + { + return xed_utils_basename_for_display (location); + } } /** @@ -1112,22 +891,22 @@ xed_document_get_short_name_for_display (XedDocument *doc) */ void xed_document_set_short_name_for_display (XedDocument *doc, - const gchar *short_name) + const gchar *short_name) { - g_return_if_fail (XED_IS_DOCUMENT (doc)); + g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_free (doc->priv->short_name); - doc->priv->short_name = g_strdup (short_name); + g_free (doc->priv->short_name); + doc->priv->short_name = g_strdup (short_name); - g_object_notify (G_OBJECT (doc), "shortname"); + g_object_notify (G_OBJECT (doc), "shortname"); } gchar * xed_document_get_content_type (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - return g_strdup (doc->priv->content_type); + return g_strdup (doc->priv->content_type); } /** @@ -1139,544 +918,363 @@ xed_document_get_content_type (XedDocument *doc) gchar * xed_document_get_mime_type (XedDocument *doc) { - gchar *mime_type = NULL; + g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup ("text/plain")); - g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup ("text/plain")); + if (doc->priv->content_type != NULL && + !g_content_type_is_unknown (doc->priv->content_type)) + { + return g_content_type_get_mime_type (doc->priv->content_type); + } - if ((doc->priv->content_type != NULL) && - (!g_content_type_is_unknown (doc->priv->content_type))) - { - mime_type = g_content_type_get_mime_type (doc->priv->content_type); - } - - return mime_type != NULL ? mime_type : g_strdup ("text/plain"); + return g_strdup ("text/plain"); } -/* Note: do not emit the notify::read-only signal */ -static gboolean +static void set_readonly (XedDocument *doc, - gboolean readonly) + gboolean readonly) { - xed_debug (DEBUG_DOCUMENT); + xed_debug (DEBUG_DOCUMENT); - readonly = (readonly != FALSE); + g_return_if_fail (XED_IS_DOCUMENT (doc)); - if (doc->priv->readonly == readonly) - return FALSE; + readonly = readonly != FALSE; - doc->priv->readonly = readonly; - - return TRUE; -} - -/** - * xed_document_set_readonly: - * @doc: a #XedDocument - * @readonly: %TRUE to se the document as read-only - * - * If @readonly is %TRUE sets @doc as read-only. - */ -void -_xed_document_set_readonly (XedDocument *doc, - gboolean readonly) -{ - xed_debug (DEBUG_DOCUMENT); - - g_return_if_fail (XED_IS_DOCUMENT (doc)); - - if (set_readonly (doc, readonly)) - { - g_object_notify (G_OBJECT (doc), "read-only"); - } + if (doc->priv->readonly != readonly) + { + doc->priv->readonly = readonly; + g_object_notify (G_OBJECT (doc), "read-only"); + } } gboolean xed_document_get_readonly (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE); - return doc->priv->readonly; + return doc->priv->readonly; +} + +static void +loaded_query_info_cb (GFile *location, + GAsyncResult *result, + XedDocument *doc) +{ + GFileInfo *info; + GError *error = NULL; + + info = g_file_query_info_finish (location, result, &error); + + if (error != NULL) + { + /* Ignore not found error as it can happen when opening a + * non-existent file from the command line. + */ + if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_NOT_FOUND) + { + g_warning ("Document loading: query info error: %s", error->message); + } + + g_error_free (error); + error = NULL; + } + + if (info != NULL) + { + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE)) + { + const gchar *content_type; + + content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); + xed_document_set_content_type (doc, content_type); + } + + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) + { + gboolean read_only; + + read_only = !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); + set_readonly (doc, read_only); + } + + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) + { + g_file_info_get_modification_time (info, &doc->priv->mtime); + doc->priv->mtime_set = TRUE; + } + + g_object_unref (info); + } + + /* Async operation finished. */ + g_object_unref (doc); +} + +static void +xed_document_loaded_real (XedDocument *doc) +{ + GFile *location; + + if (!doc->priv->language_set_by_user) + { + GtkSourceLanguage *language = guess_language (doc); + + xed_debug_message (DEBUG_DOCUMENT, "Language: %s", + language != NULL ? gtk_source_language_get_name (language) : "None"); + + set_language (doc, language, FALSE); + } + + doc->priv->mtime_set = FALSE; + doc->priv->externally_modified = FALSE; + doc->priv->deleted = FALSE; + + g_get_current_time (&doc->priv->time_of_last_save_or_load); + + set_readonly (doc, FALSE); + + xed_document_set_content_type (doc, NULL); + + location = gtk_source_file_get_location (doc->priv->file); + + if (location != NULL) + { + /* Keep the doc alive during the async operation. */ + g_object_ref (doc); + + g_file_query_info_async (location, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," + G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "," + G_FILE_ATTRIBUTE_TIME_MODIFIED, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) loaded_query_info_cb, + doc); + } +} + +static void +saved_query_info_cb (GFile *location, + GAsyncResult *result, + XedDocument *doc) +{ + GFileInfo *info; + const gchar *content_type = NULL; + GError *error = NULL; + + info = g_file_query_info_finish (location, result, &error); + + if (error != NULL) + { + g_warning ("Document saving: query info error: %s", error->message); + g_error_free (error); + error = NULL; + } + + doc->priv->mtime_set = FALSE; + + if (info != NULL) + { + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE)) + { + content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); + } + + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) + { + g_file_info_get_modification_time (info, &doc->priv->mtime); + doc->priv->mtime_set = TRUE; + } + } + + xed_document_set_content_type (doc, content_type); + + if (info != NULL) + { + g_object_unref (info); + } + + g_get_current_time (&doc->priv->time_of_last_save_or_load); + + doc->priv->externally_modified = FALSE; + doc->priv->deleted = FALSE; + doc->priv->create = FALSE; + + set_readonly (doc, FALSE); + + gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), FALSE); + + save_encoding_metadata (doc); + + /* Async operation finished. */ + g_object_unref (doc); +} + +static void +xed_document_saved_real (XedDocument *doc) +{ + GFile *location = gtk_source_file_get_location (doc->priv->file); + + /* Keep the doc alive during the async operation. */ + g_object_ref (doc); + + g_file_query_info_async (location, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," + G_FILE_ATTRIBUTE_TIME_MODIFIED, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) saved_query_info_cb, + doc); } gboolean -_xed_document_check_externally_modified (XedDocument *doc) -{ - GFile *gfile; - GFileInfo *info; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - - if (doc->priv->uri == NULL) - { - return FALSE; - } - - gfile = g_file_new_for_uri (doc->priv->uri); - info = g_file_query_info (gfile, - G_FILE_ATTRIBUTE_TIME_MODIFIED "," \ - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, - G_FILE_QUERY_INFO_NONE, - NULL, NULL); - g_object_unref (gfile); - - if (info != NULL) - { - /* While at it also check if permissions changed */ - if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) - { - gboolean read_only; - - read_only = !g_file_info_get_attribute_boolean (info, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); - - _xed_document_set_readonly (doc, read_only); - } - - if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) - { - GTimeVal timeval; - - g_file_info_get_modification_time (info, &timeval); - g_object_unref (info); - - return (timeval.tv_sec > doc->priv->mtime.tv_sec) || - (timeval.tv_sec == doc->priv->mtime.tv_sec && - timeval.tv_usec > doc->priv->mtime.tv_usec); - } - } - - return FALSE; -} - -static void -reset_temp_loading_data (XedDocument *doc) -{ - /* the loader has been used, throw it away */ - g_object_unref (doc->priv->loader); - doc->priv->loader = NULL; - - doc->priv->requested_encoding = NULL; - doc->priv->requested_line_pos = 0; -} - -static void -document_loader_loaded (XedDocumentLoader *loader, - const GError *error, - XedDocument *doc) -{ - /* load was successful */ - if (error == NULL || - (error->domain == XED_DOCUMENT_ERROR && - error->code == XED_DOCUMENT_ERROR_CONVERSION_FALLBACK)) - { - GtkTextIter iter; - GFileInfo *info; - const gchar *content_type = NULL; - gboolean read_only = FALSE; - GTimeVal mtime = {0, 0}; - - info = xed_document_loader_get_info (loader); - - if (info) - { - if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE)) - content_type = g_file_info_get_attribute_string (info, - G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); - - if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) - g_file_info_get_modification_time (info, &mtime); - - if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) - read_only = !g_file_info_get_attribute_boolean (info, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); - } - - doc->priv->mtime = mtime; - - set_readonly (doc, read_only); - - g_get_current_time (&doc->priv->time_of_last_save_or_load); - - set_encoding (doc, - xed_document_loader_get_encoding (loader), - (doc->priv->requested_encoding != NULL)); - - set_content_type (doc, content_type); - - xed_document_set_newline_type (doc, - xed_document_loader_get_newline_type (loader)); - - /* move the cursor at the requested line if any */ - if (doc->priv->requested_line_pos > 0) - { - /* line_pos - 1 because get_iter_at_line counts from 0 */ - gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc), - &iter, - doc->priv->requested_line_pos - 1); - } - /* else, if enabled, to the position stored in the metadata */ - else if (xed_prefs_manager_get_restore_cursor_position ()) - { - gchar *pos; - gint offset; - - pos = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_POSITION); - - offset = pos ? atoi (pos) : 0; - g_free (pos); - - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), - &iter, - MAX (offset, 0)); - - /* make sure it's a valid position, if the file - * changed we may have ended up in the middle of - * a utf8 character cluster */ - if (!gtk_text_iter_is_cursor_position (&iter)) - { - gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc), - &iter); - } - } - /* otherwise to the top */ - else - { - gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc), - &iter); - } - - gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter); - } - - /* special case creating a named new doc */ - else if (doc->priv->create && - (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_FOUND) && - (xed_utils_uri_has_file_scheme (doc->priv->uri))) - { - reset_temp_loading_data (doc); - - g_signal_emit (doc, - document_signals[LOADED], - 0, - NULL); - - return; - } - - g_signal_emit (doc, - document_signals[LOADED], - 0, - error); - - reset_temp_loading_data (doc); -} - -static void -document_loader_loading (XedDocumentLoader *loader, - gboolean completed, - const GError *error, - XedDocument *doc) -{ - if (completed) - { - document_loader_loaded (loader, error, doc); - } - else - { - goffset size = 0; - goffset read; - GFileInfo *info; - - info = xed_document_loader_get_info (loader); - - if (info && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)) - size = g_file_info_get_attribute_uint64 (info, - G_FILE_ATTRIBUTE_STANDARD_SIZE); - - read = xed_document_loader_get_bytes_read (loader); - - g_signal_emit (doc, - document_signals[LOADING], - 0, - read, - size); - } -} - -static void -xed_document_load_real (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create) -{ - g_return_if_fail (doc->priv->loader == NULL); - - xed_debug_message (DEBUG_DOCUMENT, "load_real: uri = %s", uri); - - /* create a loader. It will be destroyed when loading is completed */ - doc->priv->loader = xed_document_loader_new (doc, uri, encoding); - - g_signal_connect (doc->priv->loader, - "loading", - G_CALLBACK (document_loader_loading), - doc); - - doc->priv->create = create; - doc->priv->requested_encoding = encoding; - doc->priv->requested_line_pos = line_pos; - - set_uri (doc, uri); - set_content_type (doc, NULL); - - xed_document_loader_load (doc->priv->loader); -} - -/** - * xed_document_load: - * @doc: the #XedDocument. - * @uri: the uri where to load the document from. - * @encoding: the #XedEncoding to encode the document. - * @line_pos: the line to show. - * @create: whether the document should be created if it doesn't exist. - * - * Load a document. This results in the "load" signal to be emitted. - */ -void -xed_document_load (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create) -{ - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (uri != NULL); - g_return_if_fail (xed_utils_is_valid_uri (uri)); - - g_signal_emit (doc, document_signals[LOAD], 0, uri, encoding, line_pos, create); -} - -/** - * xed_document_load_cancel: - * @doc: the #XedDocument. - * - * Cancel load of a document. - */ -gboolean -xed_document_load_cancel (XedDocument *doc) -{ - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - - if (doc->priv->loader == NULL) - return FALSE; - - return xed_document_loader_cancel (doc->priv->loader); -} - -static void -document_saver_saving (XedDocumentSaver *saver, - gboolean completed, - const GError *error, - XedDocument *doc) -{ - xed_debug (DEBUG_DOCUMENT); - - if (completed) - { - /* save was successful */ - if (error == NULL) - { - const gchar *uri; - const gchar *content_type = NULL; - GTimeVal mtime = {0, 0}; - GFileInfo *info; - - uri = xed_document_saver_get_uri (saver); - set_uri (doc, uri); - - info = xed_document_saver_get_info (saver); - - if (info != NULL) - { - if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE)) - content_type = g_file_info_get_attribute_string (info, - G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); - - if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) - g_file_info_get_modification_time (info, &mtime); - } - - set_content_type (doc, content_type); - doc->priv->mtime = mtime; - - g_get_current_time (&doc->priv->time_of_last_save_or_load); - - _xed_document_set_readonly (doc, FALSE); - - gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), - FALSE); - - set_encoding (doc, - doc->priv->requested_encoding, - TRUE); - } - - g_signal_emit (doc, - document_signals[SAVED], - 0, - error); - - /* the saver has been used, throw it away */ - g_object_unref (doc->priv->saver); - doc->priv->saver = NULL; - } - else - { - goffset size = 0; - goffset written = 0; - - size = xed_document_saver_get_file_size (saver); - written = xed_document_saver_get_bytes_written (saver); - - xed_debug_message (DEBUG_DOCUMENT, "save progress: %" G_GINT64_FORMAT " of %" G_GINT64_FORMAT, written, size); - - g_signal_emit (doc, - document_signals[SAVING], - 0, - written, - size); - } -} - -static void -xed_document_save_real (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentSaveFlags flags) -{ - g_return_if_fail (doc->priv->saver == NULL); - - /* create a saver, it will be destroyed once saving is complete */ - doc->priv->saver = xed_document_saver_new (doc, uri, encoding, - doc->priv->newline_type, - flags); - - g_signal_connect (doc->priv->saver, - "saving", - G_CALLBACK (document_saver_saving), - doc); - - doc->priv->requested_encoding = encoding; - - xed_document_saver_save (doc->priv->saver, - &doc->priv->mtime); -} - -/** - * xed_document_save: - * @doc: the #XedDocument. - * @flags: optionnal #XedDocumentSaveFlags. - * - * Save the document to its previous location. This results in the "save" - * signal to be emitted. - */ -void -xed_document_save (XedDocument *doc, - XedDocumentSaveFlags flags) -{ - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (doc->priv->uri != NULL); - - g_signal_emit (doc, - document_signals[SAVE], - 0, - doc->priv->uri, - doc->priv->encoding, - flags); -} - -/** - * xed_document_save_as: - * @doc: the #XedDocument. - * @uri: the uri where to save the document. - * @encoding: the #XedEncoding to encode the document. - * @flags: optionnal #XedDocumentSaveFlags. - * - * Save the document to a new location. This results in the "save" signal - * to be emitted. - */ -void -xed_document_save_as (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentSaveFlags flags) -{ - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (uri != NULL); - g_return_if_fail (encoding != NULL); - - /* priv->mtime refers to the the old uri (if any). Thus, it should be - * ignored when saving as. */ - g_signal_emit (doc, - document_signals[SAVE], - 0, - uri, - encoding, - flags | XED_DOCUMENT_SAVE_IGNORE_MTIME); -} - -gboolean -xed_document_insert_file (XedDocument *doc, - GtkTextIter *iter, - const gchar *uri, - const XedEncoding *encoding) -{ - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == - GTK_TEXT_BUFFER (doc), FALSE); - - /* TODO */ - - return FALSE; -} - -gboolean xed_document_is_untouched (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE); + GFile *location; - return (doc->priv->uri == NULL) && - (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc))); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE); + + location = gtk_source_file_get_location (doc->priv->file); + + return location == NULL && !gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)); } -gboolean +gboolean xed_document_is_untitled (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE); - return (doc->priv->uri == NULL); + return gtk_source_file_get_location (doc->priv->file) == NULL; } gboolean xed_document_is_local (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); + GFile *location; - if (doc->priv->uri == NULL) - { - return FALSE; - } + g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - return xed_utils_uri_has_file_scheme (doc->priv->uri); + location = gtk_source_file_get_location (doc->priv->file); + + if (location == NULL) + { + return FALSE; + } + + return g_file_has_uri_scheme (location, "file"); +} + +static void +check_file_on_disk (XedDocument *doc) +{ + GFile *location; + GFileInfo *info; + + location = gtk_source_file_get_location (doc->priv->file); + + if (location == NULL) + { + return; + } + + info = g_file_query_info (location, + G_FILE_ATTRIBUTE_TIME_MODIFIED "," \ + G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + if (info != NULL) + { + /* While at it also check if permissions changed */ + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) + { + gboolean read_only; + + read_only = !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); + + set_readonly (doc, read_only); + } + + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED) && doc->priv->mtime_set) + { + GTimeVal timeval; + + g_file_info_get_modification_time (info, &timeval); + + /* Note that mtime can even go backwards if the + * user is copying over a file with an old mtime + */ + if (timeval.tv_sec != doc->priv->mtime.tv_sec || + timeval.tv_usec != doc->priv->mtime.tv_usec) + { + doc->priv->externally_modified = TRUE; + } + } + + g_object_unref (info); + } + else + { + doc->priv->deleted = TRUE; + } +} + +gboolean +_xed_document_check_externally_modified (XedDocument *doc) +{ + g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); + + if (!doc->priv->externally_modified) + { + check_file_on_disk (doc); + } + + return doc->priv->externally_modified; } gboolean xed_document_get_deleted (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - return doc->priv->uri && !xed_utils_uri_exists (doc->priv->uri); + if (!doc->priv->deleted) + { + check_file_on_disk (doc); + } + + return doc->priv->deleted; +} + +/* + * Deletion and external modification is only checked for local files. + */ +gboolean +_xed_document_needs_saving (XedDocument *doc) +{ + g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); + + if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc))) + { + return TRUE; + } + + if (doc->priv->externally_modified || doc->priv->deleted) + { + return TRUE; + } + + if (xed_document_is_local (doc)) + { + check_file_on_disk (doc); + + if (doc->priv->externally_modified || doc->priv->deleted) + { + return TRUE; + } + } + + return FALSE; } /* @@ -1684,463 +1282,63 @@ xed_document_get_deleted (XedDocument *doc) * to the last line and FALSE is returned. */ gboolean -xed_document_goto_line (XedDocument *doc, - gint line) +xed_document_goto_line (XedDocument *doc, + gint line) { - gboolean ret = TRUE; - guint line_count; - GtkTextIter iter; + gboolean ret = TRUE; + guint line_count; + GtkTextIter iter; - xed_debug (DEBUG_DOCUMENT); + xed_debug (DEBUG_DOCUMENT); - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - g_return_val_if_fail (line >= -1, FALSE); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); + g_return_val_if_fail (line >= -1, FALSE); - line_count = gtk_text_buffer_get_line_count (GTK_TEXT_BUFFER (doc)); + line_count = gtk_text_buffer_get_line_count (GTK_TEXT_BUFFER (doc)); - if (line >= line_count) - { - ret = FALSE; - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), - &iter); - } - else - { - gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc), - &iter, - line); - } + if (line >= line_count) + { + ret = FALSE; + gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter); + } + else + { + gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc), &iter, line); + } - gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter); + gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter); - return ret; + return ret; } gboolean xed_document_goto_line_offset (XedDocument *doc, - gint line, - gint line_offset) + gint line, + gint line_offset) { - gboolean ret = TRUE; - guint offset_count; - GtkTextIter iter; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - g_return_val_if_fail (line >= -1, FALSE); - g_return_val_if_fail (line_offset >= -1, FALSE); - - gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc), - &iter, - line); + gboolean ret = TRUE; + guint offset_count; + GtkTextIter iter; - offset_count = gtk_text_iter_get_chars_in_line (&iter); - if (line_offset > offset_count) - { - ret = FALSE; - } - else - { - gtk_text_iter_set_line_offset (&iter, line_offset); - } - - gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); + g_return_val_if_fail (line >= -1, FALSE); + g_return_val_if_fail (line_offset >= -1, FALSE); - return ret; -} + gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc), &iter, line); -static gint -compute_num_of_lines (const gchar *text) -{ - const gchar *p; - gint len; - gint n = 1; + offset_count = gtk_text_iter_get_chars_in_line (&iter); + if (line_offset > offset_count) + { + ret = FALSE; + } + else + { + gtk_text_iter_set_line_offset (&iter, line_offset); + } - g_return_val_if_fail (text != NULL, 0); + gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter); - len = strlen (text); - p = text; - - while (len > 0) - { - gint del, par; - - pango_find_paragraph_boundary (p, len, &del, &par); - - if (del == par) /* not found */ - break; - - p += par; - len -= par; - ++n; - } - - return n; -} - -/** - * xed_document_set_search_text" - * @doc: - * @text: (allow-none): - * @flags: - **/ -void -xed_document_set_search_text (XedDocument *doc, - const gchar *text, - guint flags) -{ - gchar *converted_text; - gboolean notify = FALSE; - gboolean update_to_search_region = FALSE; - - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail ((text == NULL) || (doc->priv->search_text != text)); - g_return_if_fail ((text == NULL) || g_utf8_validate (text, -1, NULL)); - - xed_debug_message (DEBUG_DOCUMENT, "text = %s", text); - - if (text != NULL) - { - if (*text != '\0') - { - converted_text = xed_utils_unescape_search_text (text); - notify = !xed_document_get_can_search_again (doc); - } - else - { - converted_text = g_strdup(""); - notify = xed_document_get_can_search_again (doc); - } - - g_free (doc->priv->search_text); - - doc->priv->search_text = converted_text; - doc->priv->num_of_lines_search_text = compute_num_of_lines (doc->priv->search_text); - update_to_search_region = TRUE; - } - - if (!XED_SEARCH_IS_DONT_SET_FLAGS (flags)) - { - if (doc->priv->search_flags != flags) - update_to_search_region = TRUE; - - doc->priv->search_flags = flags; - - } - - if (update_to_search_region) - { - GtkTextIter begin; - GtkTextIter end; - - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), - &begin, - &end); - - to_search_region_range (doc, - &begin, - &end); - } - - if (notify) - g_object_notify (G_OBJECT (doc), "can-search-again"); -} - -/** - * xed_document_get_search_text: - * @doc: - * @flags: (allow-none): - */ -gchar * -xed_document_get_search_text (XedDocument *doc, - guint *flags) -{ - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - - if (flags != NULL) - *flags = doc->priv->search_flags; - - return xed_utils_escape_search_text (doc->priv->search_text); -} - -gboolean -xed_document_get_can_search_again (XedDocument *doc) -{ - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - - return ((doc->priv->search_text != NULL) && - (*doc->priv->search_text != '\0')); -} - -/** - * xed_document_search_forward: - * @doc: - * @start: (allow-none): - * @end: (allow-none): - * @match_start: (allow-none): - * @match_end: (allow=none): - **/ -gboolean -xed_document_search_forward (XedDocument *doc, - const GtkTextIter *start, - const GtkTextIter *end, - GtkTextIter *match_start, - GtkTextIter *match_end) -{ - GtkTextIter iter; - GtkTextSearchFlags search_flags; - gboolean found = FALSE; - GtkTextIter m_start; - GtkTextIter m_end; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - g_return_val_if_fail ((start == NULL) || - (gtk_text_iter_get_buffer (start) == GTK_TEXT_BUFFER (doc)), FALSE); - g_return_val_if_fail ((end == NULL) || - (gtk_text_iter_get_buffer (end) == GTK_TEXT_BUFFER (doc)), FALSE); - - if (doc->priv->search_text == NULL) - { - xed_debug_message (DEBUG_DOCUMENT, "doc->priv->search_text == NULL\n"); - return FALSE; - } - else - xed_debug_message (DEBUG_DOCUMENT, "doc->priv->search_text == \"%s\"\n", doc->priv->search_text); - - if (start == NULL) - gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc), &iter); - else - iter = *start; - - search_flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY; - - if (!XED_SEARCH_IS_CASE_SENSITIVE (doc->priv->search_flags)) - { - search_flags = search_flags | GTK_TEXT_SEARCH_CASE_INSENSITIVE; - } - - while (!found) - { - found = gtk_text_iter_forward_search (&iter, - doc->priv->search_text, - search_flags, - &m_start, - &m_end, - end); - - if (found && XED_SEARCH_IS_ENTIRE_WORD (doc->priv->search_flags)) - { - found = gtk_text_iter_starts_word (&m_start) && - gtk_text_iter_ends_word (&m_end); - - if (!found) - iter = m_end; - } - else - break; - } - - if (found && (match_start != NULL)) - *match_start = m_start; - - if (found && (match_end != NULL)) - *match_end = m_end; - - return found; -} - -/** - * xed_document_search_backward: - * @doc: - * @start: (allow-none): - * @end: (allow-none): - * @match_start: (allow-none): - * @match_end: (allow=none): - **/ -gboolean -xed_document_search_backward (XedDocument *doc, - const GtkTextIter *start, - const GtkTextIter *end, - GtkTextIter *match_start, - GtkTextIter *match_end) -{ - GtkTextIter iter; - GtkTextSearchFlags search_flags; - gboolean found = FALSE; - GtkTextIter m_start; - GtkTextIter m_end; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - g_return_val_if_fail ((start == NULL) || - (gtk_text_iter_get_buffer (start) == GTK_TEXT_BUFFER (doc)), FALSE); - g_return_val_if_fail ((end == NULL) || - (gtk_text_iter_get_buffer (end) == GTK_TEXT_BUFFER (doc)), FALSE); - - if (doc->priv->search_text == NULL) - { - xed_debug_message (DEBUG_DOCUMENT, "doc->priv->search_text == NULL\n"); - return FALSE; - } - else - xed_debug_message (DEBUG_DOCUMENT, "doc->priv->search_text == \"%s\"\n", doc->priv->search_text); - - if (end == NULL) - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter); - else - iter = *end; - - search_flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY; - - if (!XED_SEARCH_IS_CASE_SENSITIVE (doc->priv->search_flags)) - { - search_flags = search_flags | GTK_TEXT_SEARCH_CASE_INSENSITIVE; - } - - while (!found) - { - found = gtk_text_iter_backward_search (&iter, - doc->priv->search_text, - search_flags, - &m_start, - &m_end, - start); - - if (found && XED_SEARCH_IS_ENTIRE_WORD (doc->priv->search_flags)) - { - found = gtk_text_iter_starts_word (&m_start) && - gtk_text_iter_ends_word (&m_end); - - if (!found) - iter = m_start; - } - else - break; - } - - if (found && (match_start != NULL)) - *match_start = m_start; - - if (found && (match_end != NULL)) - *match_end = m_end; - - return found; -} - -/* FIXME this is an issue for introspection regardning @find */ -gint -xed_document_replace_all (XedDocument *doc, - const gchar *find, - const gchar *replace, - guint flags) -{ - GtkTextIter iter; - GtkTextIter m_start; - GtkTextIter m_end; - GtkTextSearchFlags search_flags = 0; - gboolean found = TRUE; - gint cont = 0; - gchar *search_text; - gchar *replace_text; - gint replace_text_len; - GtkTextBuffer *buffer; - gboolean brackets_highlighting; - gboolean search_highliting; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), 0); - g_return_val_if_fail (replace != NULL, 0); - g_return_val_if_fail ((find != NULL) || (doc->priv->search_text != NULL), 0); - - buffer = GTK_TEXT_BUFFER (doc); - - if (find == NULL) - search_text = g_strdup (doc->priv->search_text); - else - search_text = xed_utils_unescape_search_text (find); - - replace_text = xed_utils_unescape_search_text (replace); - - gtk_text_buffer_get_start_iter (buffer, &iter); - - search_flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY; - - if (!XED_SEARCH_IS_CASE_SENSITIVE (flags)) - { - search_flags = search_flags | GTK_TEXT_SEARCH_CASE_INSENSITIVE; - } - - replace_text_len = strlen (replace_text); - - /* disable cursor_moved emission until the end of the - * replace_all so that we don't spend all the time - * updating the position in the statusbar - */ - doc->priv->stop_cursor_moved_emission = TRUE; - - /* also avoid spending time matching brackets */ - brackets_highlighting = gtk_source_buffer_get_highlight_matching_brackets (GTK_SOURCE_BUFFER (buffer)); - gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (buffer), FALSE); - - /* and do search highliting later */ - search_highliting = xed_document_get_enable_search_highlighting (doc); - xed_document_set_enable_search_highlighting (doc, FALSE); - - gtk_text_buffer_begin_user_action (buffer); - - do - { - found = gtk_text_iter_forward_search (&iter, - search_text, - search_flags, - &m_start, - &m_end, - NULL); - - if (found && XED_SEARCH_IS_ENTIRE_WORD (flags)) - { - gboolean word; - - word = gtk_text_iter_starts_word (&m_start) && - gtk_text_iter_ends_word (&m_end); - - if (!word) - { - iter = m_end; - continue; - } - } - - if (found) - { - ++cont; - - gtk_text_buffer_delete (buffer, - &m_start, - &m_end); - gtk_text_buffer_insert (buffer, - &m_start, - replace_text, - replace_text_len); - - iter = m_start; - } - - } while (found); - - gtk_text_buffer_end_user_action (buffer); - - /* re-enable cursor_moved emission and notify - * the current position - */ - doc->priv->stop_cursor_moved_emission = FALSE; - emit_cursor_moved (doc); - - gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (buffer), - brackets_highlighting); - xed_document_set_enable_search_highlighting (doc, search_highliting); - - g_free (search_text); - g_free (replace_text); - - return cont; + return ret; } /** @@ -2149,535 +1347,109 @@ xed_document_replace_all (XedDocument *doc, * @lang: (allow-none): **/ void -xed_document_set_language (XedDocument *doc, - GtkSourceLanguage *lang) +xed_document_set_language (XedDocument *doc, + GtkSourceLanguage *lang) { - g_return_if_fail (XED_IS_DOCUMENT (doc)); + g_return_if_fail (XED_IS_DOCUMENT (doc)); - set_language (doc, lang, TRUE); + set_language (doc, lang, TRUE); } +/** + * xed_document_get_language: + * @doc: + * + * Return value: (transfer none): + */ GtkSourceLanguage * xed_document_get_language (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - return gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (doc)); + return gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (doc)); } -const XedEncoding * +const GtkSourceEncoding * xed_document_get_encoding (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - return doc->priv->encoding; + return gtk_source_file_get_encoding (doc->priv->file); } glong _xed_document_get_seconds_since_last_save_or_load (XedDocument *doc) { - GTimeVal current_time; + GTimeVal current_time; - xed_debug (DEBUG_DOCUMENT); - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), -1); + xed_debug (DEBUG_DOCUMENT); - g_get_current_time (¤t_time); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), -1); - return (current_time.tv_sec - doc->priv->time_of_last_save_or_load.tv_sec); + g_get_current_time (¤t_time); + + return (current_time.tv_sec - doc->priv->time_of_last_save_or_load.tv_sec); } -static void -get_search_match_colors (XedDocument *doc, - gboolean *foreground_set, - GdkColor *foreground, - gboolean *background_set, - GdkColor *background) -{ - GtkSourceStyleScheme *style_scheme; - GtkSourceStyle *style; - gchar *bg; - gchar *fg; - - style_scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (doc)); - if (style_scheme == NULL) - goto fallback; - - style = gtk_source_style_scheme_get_style (style_scheme, - "search-match"); - if (style == NULL) - goto fallback; - - g_object_get (style, - "foreground-set", foreground_set, - "foreground", &fg, - "background-set", background_set, - "background", &bg, - NULL); - - if (*foreground_set) - { - if (fg == NULL || - !gdk_color_parse (fg, foreground)) - { - *foreground_set = FALSE; - } - } - - if (*background_set) - { - if (bg == NULL || - !gdk_color_parse (bg, background)) - { - *background_set = FALSE; - } - } - - g_free (fg); - g_free (bg); - - return; - - fallback: - xed_debug_message (DEBUG_DOCUMENT, - "Falling back to hard-coded colors " - "for the \"found\" text tag."); - - gdk_color_parse ("#FFFF78", background); - *background_set = TRUE; - *foreground_set = FALSE; - - return; -} - -static void -sync_found_tag (XedDocument *doc, - GParamSpec *pspec, - gpointer data) -{ - GdkColor fg; - GdkColor bg; - gboolean fg_set; - gboolean bg_set; - - xed_debug (DEBUG_DOCUMENT); - - g_return_if_fail (GTK_TEXT_TAG (doc->priv->found_tag)); - - get_search_match_colors (doc, - &fg_set, &fg, - &bg_set, &bg); - - g_object_set (doc->priv->found_tag, - "foreground-gdk", fg_set ? &fg : NULL, - NULL); - g_object_set (doc->priv->found_tag, - "background-gdk", bg_set ? &bg : NULL, - NULL); -} - -static void -text_tag_set_highest_priority (GtkTextTag *tag, - GtkTextBuffer *buffer) -{ - GtkTextTagTable *table; - gint n; - - table = gtk_text_buffer_get_tag_table (buffer); - n = gtk_text_tag_table_get_size (table); - gtk_text_tag_set_priority (tag, n - 1); -} - -static void -search_region (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end) -{ - GtkTextIter iter; - GtkTextIter m_start; - GtkTextIter m_end; - GtkTextSearchFlags search_flags = 0; - gboolean found = TRUE; - - GtkTextBuffer *buffer; - - xed_debug (DEBUG_DOCUMENT); - - buffer = GTK_TEXT_BUFFER (doc); - - if (doc->priv->found_tag == NULL) - { - doc->priv->found_tag = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (doc), - "found", - NULL); - - sync_found_tag (doc, NULL, NULL); - - g_signal_connect (doc, - "notify::style-scheme", - G_CALLBACK (sync_found_tag), - NULL); - } - - /* make sure the 'found' tag has the priority over - * syntax highlighting tags */ - text_tag_set_highest_priority (doc->priv->found_tag, - GTK_TEXT_BUFFER (doc)); - - - if (doc->priv->search_text == NULL) - return; - - g_return_if_fail (doc->priv->num_of_lines_search_text > 0); - - gtk_text_iter_backward_lines (start, doc->priv->num_of_lines_search_text); - gtk_text_iter_forward_lines (end, doc->priv->num_of_lines_search_text); - - if (gtk_text_iter_has_tag (start, doc->priv->found_tag) && - !gtk_text_iter_begins_tag (start, doc->priv->found_tag)) - gtk_text_iter_backward_to_tag_toggle (start, doc->priv->found_tag); - - if (gtk_text_iter_has_tag (end, doc->priv->found_tag) && - !gtk_text_iter_ends_tag (end, doc->priv->found_tag)) - gtk_text_iter_forward_to_tag_toggle (end, doc->priv->found_tag); - - /* - g_print ("[%u (%u), %u (%u)]\n", gtk_text_iter_get_line (start), gtk_text_iter_get_offset (start), - gtk_text_iter_get_line (end), gtk_text_iter_get_offset (end)); - */ - - gtk_text_buffer_remove_tag (buffer, - doc->priv->found_tag, - start, - end); - - if (*doc->priv->search_text == '\0') - return; - - iter = *start; - - search_flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY; - - if (!XED_SEARCH_IS_CASE_SENSITIVE (doc->priv->search_flags)) - { - search_flags = search_flags | GTK_TEXT_SEARCH_CASE_INSENSITIVE; - } - - do - { - if ((end != NULL) && gtk_text_iter_is_end (end)) - end = NULL; - - found = gtk_text_iter_forward_search (&iter, - doc->priv->search_text, - search_flags, - &m_start, - &m_end, - end); - - iter = m_end; - - if (found && XED_SEARCH_IS_ENTIRE_WORD (doc->priv->search_flags)) - { - gboolean word; - - word = gtk_text_iter_starts_word (&m_start) && - gtk_text_iter_ends_word (&m_end); - - if (!word) - continue; - } - - if (found) - { - gtk_text_buffer_apply_tag (buffer, - doc->priv->found_tag, - &m_start, - &m_end); - } - - } while (found); -} - -static void -to_search_region_range (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end) -{ - xed_debug (DEBUG_DOCUMENT); - - if (doc->priv->to_search_region == NULL) - return; - - gtk_text_iter_set_line_offset (start, 0); - gtk_text_iter_forward_to_line_end (end); - - /* - g_print ("+ [%u (%u), %u (%u)]\n", gtk_text_iter_get_line (start), gtk_text_iter_get_offset (start), - gtk_text_iter_get_line (end), gtk_text_iter_get_offset (end)); - */ - - /* Add the region to the refresh region */ - xed_text_region_add (doc->priv->to_search_region, start, end); - - /* Notify views of the updated highlight region */ - gtk_text_iter_backward_lines (start, doc->priv->num_of_lines_search_text); - gtk_text_iter_forward_lines (end, doc->priv->num_of_lines_search_text); - - g_signal_emit (doc, document_signals [SEARCH_HIGHLIGHT_UPDATED], 0, start, end); -} - -void -_xed_document_search_region (XedDocument *doc, - const GtkTextIter *start, - const GtkTextIter *end) -{ - XedTextRegion *region; - - xed_debug (DEBUG_DOCUMENT); - - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (start != NULL); - g_return_if_fail (end != NULL); - - if (doc->priv->to_search_region == NULL) - return; - - /* - g_print ("U [%u (%u), %u (%u)]\n", gtk_text_iter_get_line (start), gtk_text_iter_get_offset (start), - gtk_text_iter_get_line (end), gtk_text_iter_get_offset (end)); - */ - - /* get the subregions not yet highlighted */ - region = xed_text_region_intersect (doc->priv->to_search_region, - start, - end); - if (region) - { - gint i; - GtkTextIter start_search; - GtkTextIter end_search; - - i = xed_text_region_subregions (region); - xed_text_region_nth_subregion (region, - 0, - &start_search, - NULL); - - xed_text_region_nth_subregion (region, - i - 1, - NULL, - &end_search); - - xed_text_region_destroy (region, TRUE); - - gtk_text_iter_order (&start_search, &end_search); - - search_region (doc, &start_search, &end_search); - - /* remove the just highlighted region */ - xed_text_region_subtract (doc->priv->to_search_region, - start, - end); - } -} - -static void -insert_text_cb (XedDocument *doc, - GtkTextIter *pos, - const gchar *text, - gint length) -{ - GtkTextIter start; - GtkTextIter end; - - xed_debug (DEBUG_DOCUMENT); - - start = end = *pos; - - /* - * pos is invalidated when - * insertion occurs (because the buffer contents change), but the - * default signal handler revalidates it to point to the end of the - * inserted text - */ - gtk_text_iter_backward_chars (&start, - g_utf8_strlen (text, length)); - - to_search_region_range (doc, &start, &end); -} - -static void -delete_range_cb (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end) -{ - GtkTextIter d_start; - GtkTextIter d_end; - - xed_debug (DEBUG_DOCUMENT); - - d_start = *start; - d_end = *end; - - to_search_region_range (doc, &d_start, &d_end); -} - -void -xed_document_set_enable_search_highlighting (XedDocument *doc, - gboolean enable) -{ - g_return_if_fail (XED_IS_DOCUMENT (doc)); - - enable = enable != FALSE; - - if ((doc->priv->to_search_region != NULL) == enable) - return; - - if (doc->priv->to_search_region != NULL) - { - /* Disable search highlighting */ - if (doc->priv->found_tag != NULL) - { - /* If needed remove the found_tag */ - GtkTextIter begin; - GtkTextIter end; - - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), - &begin, - &end); - - gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (doc), - doc->priv->found_tag, - &begin, - &end); - } - - xed_text_region_destroy (doc->priv->to_search_region, - TRUE); - doc->priv->to_search_region = NULL; - } - else - { - doc->priv->to_search_region = xed_text_region_new (GTK_TEXT_BUFFER (doc)); - if (xed_document_get_can_search_again (doc)) - { - /* If search_text is not empty, highligth all its occurrences */ - GtkTextIter begin; - GtkTextIter end; - - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), - &begin, - &end); - - to_search_region_range (doc, - &begin, - &end); - } - } -} - -gboolean -xed_document_get_enable_search_highlighting (XedDocument *doc) -{ - g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); - - return (doc->priv->to_search_region != NULL); -} - -void -xed_document_set_newline_type (XedDocument *doc, - XedDocumentNewlineType newline_type) -{ - g_return_if_fail (XED_IS_DOCUMENT (doc)); - - if (doc->priv->newline_type != newline_type) - { - doc->priv->newline_type = newline_type; - - g_object_notify (G_OBJECT (doc), "newline-type"); - } -} - -XedDocumentNewlineType +GtkSourceNewlineType xed_document_get_newline_type (XedDocument *doc) { - g_return_val_if_fail (XED_IS_DOCUMENT (doc), 0); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), 0); - return doc->priv->newline_type; -} - -void -_xed_document_set_mount_operation_factory (XedDocument *doc, - XedMountOperationFactory callback, - gpointer userdata) -{ - g_return_if_fail (XED_IS_DOCUMENT (doc)); - - doc->priv->mount_operation_factory = callback; - doc->priv->mount_operation_userdata = userdata; -} - -GMountOperation * -_xed_document_create_mount_operation (XedDocument *doc) -{ - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - - if (doc->priv->mount_operation_factory == NULL) - return g_mount_operation_new (); - else - return doc->priv->mount_operation_factory (doc, - doc->priv->mount_operation_userdata); + return gtk_source_file_get_newline_type (doc->priv->file); } #ifndef ENABLE_GVFS_METADATA gchar * xed_document_get_metadata (XedDocument *doc, - const gchar *key) + const gchar *key) { - gchar *value = NULL; + GFile *location; - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - g_return_val_if_fail (key != NULL, NULL); + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + g_return_val_if_fail (key != NULL, NULL); - if (!xed_document_is_untitled (doc)) - { - value = xed_metadata_manager_get (doc->priv->uri, key); - } + location = gtk_source_file_get_location (doc->priv->file); - return value; + if (location != NULL) + { + return xed_metadata_manager_get (location, key); + } + + return NULL; } void xed_document_set_metadata (XedDocument *doc, - const gchar *first_key, - ...) + const gchar *first_key, + ...) { - const gchar *key; - const gchar *value; - va_list var_args; + GFile *location; + const gchar *key; + const gchar *value; + va_list var_args; - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (first_key != NULL); + g_return_if_fail (XED_IS_DOCUMENT (doc)); + g_return_if_fail (first_key != NULL); - if (xed_document_is_untitled (doc)) - { - /* Can't set metadata for untitled documents */ - return; - } + location = gtk_source_file_get_location (doc->priv->file); - va_start (var_args, first_key); + if (location == NULL) + { + /* Can't set metadata for untitled documents */ + return; + } - for (key = first_key; key; key = va_arg (var_args, const gchar *)) - { - value = va_arg (var_args, const gchar *); - - xed_metadata_manager_set (doc->priv->uri, - key, - value); - } + va_start (var_args, first_key); - va_end (var_args); + for (key = first_key; key; key = va_arg (var_args, const gchar *)) + { + value = va_arg (var_args, const gchar *); + + xed_metadata_manager_set (location, key, value); + } + + va_end (var_args); } #else @@ -2693,32 +1465,32 @@ xed_document_set_metadata (XedDocument *doc, */ gchar * xed_document_get_metadata (XedDocument *doc, - const gchar *key) + const gchar *key) { - gchar *value = NULL; + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + g_return_val_if_fail (key != NULL, NULL); - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - g_return_val_if_fail (key != NULL, NULL); + if (doc->priv->metadata_info && g_file_info_has_attribute (doc->priv->metadata_info, key)) + { + return g_strdup (g_file_info_get_attribute_string (doc->priv->metadata_info, key)); + } - if (doc->priv->metadata_info && g_file_info_has_attribute (doc->priv->metadata_info, - key)) - { - value = g_strdup (g_file_info_get_attribute_string (doc->priv->metadata_info, - key)); - } - - return value; + return NULL; } static void -set_attributes_cb (GObject *source, - GAsyncResult *res, - gpointer useless) +set_attributes_cb (GFile *location, + GAsyncResult *result) { - g_file_set_attributes_finish (G_FILE (source), - res, - NULL, - NULL); + GError *error = NULL; + + g_file_set_attributes_finish (location, result, NULL, &error); + + if (error != NULL) + { + g_warning ("Set document metadata failed: %s", error->message); + g_error_free (error); + } } /** @@ -2732,60 +1504,138 @@ set_attributes_cb (GObject *source, */ void xed_document_set_metadata (XedDocument *doc, - const gchar *first_key, - ...) + const gchar *first_key, + ...) { - const gchar *key; - const gchar *value; - va_list var_args; - GFileInfo *info; - GFile *location; + const gchar *key; + const gchar *value; + va_list var_args; + GFileInfo *info; + GFile *location; - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (first_key != NULL); + g_return_if_fail (XED_IS_DOCUMENT (doc)); + g_return_if_fail (first_key != NULL); - info = g_file_info_new (); + info = g_file_info_new (); - va_start (var_args, first_key); + va_start (var_args, first_key); - for (key = first_key; key; key = va_arg (var_args, const gchar *)) - { - value = va_arg (var_args, const gchar *); - - if (value != NULL) - { - g_file_info_set_attribute_string (info, - key, value); - } - else - { - /* Unset the key */ - g_file_info_set_attribute (info, key, - G_FILE_ATTRIBUTE_TYPE_INVALID, - NULL); - } - } + for (key = first_key; key; key = va_arg (var_args, const gchar *)) + { + value = va_arg (var_args, const gchar *); - va_end (var_args); + if (value != NULL) + { + g_file_info_set_attribute_string (info, key, value); + } + else + { + /* Unset the key */ + g_file_info_remove_attribute (info, key); + } + } - if (doc->priv->metadata_info != NULL) - g_file_info_copy_into (info, doc->priv->metadata_info); + va_end (var_args); - location = xed_document_get_location (doc); + if (doc->priv->metadata_info != NULL) + { + g_file_info_copy_into (info, doc->priv->metadata_info); + } - if (location != NULL) - { - g_file_set_attributes_async (location, - info, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_DEFAULT, - NULL, - set_attributes_cb, - NULL); + location = gtk_source_file_get_location (doc->priv->file); - g_object_unref (location); - } - - g_object_unref (info); + if (location != NULL) + { + g_file_set_attributes_async (location, + info, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) set_attributes_cb, + NULL); + } + + g_object_unref (info); } #endif + +/** + * xed_document_set_search_context: + * @doc: a #XedDocument + * @search_context: (allow-none): the new #GtkSourceSearchContext + * + * Sets the new search context for the document. + */ +void +xed_document_set_search_context (XedDocument *doc, + GtkSourceSearchContext *search_context) +{ + g_return_if_fail (XED_IS_DOCUMENT (doc)); + + g_clear_object (&doc->priv->search_context); + doc->priv->search_context = search_context; + + if (search_context != NULL) + { + gboolean highlight = g_settings_get_boolean (doc->priv->editor_settings, XED_SETTINGS_SEARCH_HIGHLIGHTING); + + gtk_source_search_context_set_highlight (search_context, highlight); + + g_object_ref (search_context); + } +} + +/** + * xed_document_get_search_context: + * @doc: a #XedDocument + * + * Returns: the current search context of the document, + * or NULL if there is no search context + */ +GtkSourceSearchContext * +xed_document_get_search_context (XedDocument *doc) +{ + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + + return doc->priv->search_context; +} + +/** + * xed_document_get_file: + * @doc: a #XedDocument. + * + * Gets the associated #GtkSourceFile. You should use it only for reading + * purposes, not for creating a #GtkSourceFileLoader or #GtkSourceFileSaver, + * because xed does some extra work when loading or saving a file and + * maintains an internal state. If you use in a plugin a file loader or saver on + * the returned #GtkSourceFile, the internal state of xed won't be updated. + * + * If you want to save the #GeditDocument to a secondary file, you can create a + * new #GtkSourceFile and use a #GtkSourceFileSaver. + * + * Returns: (transfer none): the associated #GtkSourceFile. + */ +GtkSourceFile * +xed_document_get_file (XedDocument *doc) +{ + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + + return doc->priv->file; +} + +void +_xed_document_set_create (XedDocument *doc, + gboolean create) +{ + g_return_if_fail (XED_IS_DOCUMENT (doc)); + + doc->priv->create = create != FALSE; +} + +gboolean +_xed_document_get_create (XedDocument *doc) +{ + g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE); + + return doc->priv->create; +} diff --git a/xed/xed-document.h b/xed/xed-document.h index 79f4087..f8bb270 100644 --- a/xed/xed-document.h +++ b/xed/xed-document.h @@ -3,8 +3,8 @@ * This file is part of xed * * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence - * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi - * Copyright (C) 2002-2005 Paolo Maggi + * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi + * Copyright (C) 2002-2005 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,32 +18,25 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 1998-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 1998-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ - + #ifndef __XED_DOCUMENT_H__ #define __XED_DOCUMENT_H__ -#include -#include -#include - -#include +#include G_BEGIN_DECLS -/* - * Type checking and casting macros - */ #define XED_TYPE_DOCUMENT (xed_document_get_type()) #define XED_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_DOCUMENT, XedDocument)) #define XED_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_DOCUMENT, XedDocumentClass)) @@ -55,278 +48,113 @@ G_BEGIN_DECLS #define XED_METADATA_ATTRIBUTE_ENCODING "metadata::xed-encoding" #define XED_METADATA_ATTRIBUTE_LANGUAGE "metadata::xed-language" -typedef enum -{ - XED_DOCUMENT_NEWLINE_TYPE_LF, - XED_DOCUMENT_NEWLINE_TYPE_CR, - XED_DOCUMENT_NEWLINE_TYPE_CR_LF -} XedDocumentNewlineType; +typedef struct _XedDocument XedDocument; +typedef struct _XedDocumentPrivate XedDocumentPrivate; +typedef struct _XedDocumentClass XedDocumentClass; -#define XED_DOCUMENT_NEWLINE_TYPE_DEFAULT XED_DOCUMENT_NEWLINE_TYPE_LF - -typedef enum -{ - XED_SEARCH_DONT_SET_FLAGS = 1 << 0, - XED_SEARCH_ENTIRE_WORD = 1 << 1, - XED_SEARCH_CASE_SENSITIVE = 1 << 2, - XED_SEARCH_PARSE_ESCAPES = 1 << 3 - -} XedSearchFlags; - -/** - * XedDocumentSaveFlags: - * @XED_DOCUMENT_SAVE_IGNORE_MTIME: save file despite external modifications. - * @XED_DOCUMENT_SAVE_IGNORE_BACKUP: write the file directly without attempting to backup. - * @XED_DOCUMENT_SAVE_PRESERVE_BACKUP: preserve previous backup file, needed to support autosaving. - */ -typedef enum -{ - XED_DOCUMENT_SAVE_IGNORE_MTIME = 1 << 0, - XED_DOCUMENT_SAVE_IGNORE_BACKUP = 1 << 1, - XED_DOCUMENT_SAVE_PRESERVE_BACKUP = 1 << 2 -} XedDocumentSaveFlags; - -/* Private structure type */ -typedef struct _XedDocumentPrivate XedDocumentPrivate; - -/* - * Main object structure - */ -typedef struct _XedDocument XedDocument; - struct _XedDocument { - GtkSourceBuffer buffer; - - /*< private > */ - XedDocumentPrivate *priv; -}; + GtkSourceBuffer buffer; -/* - * Class definition - */ -typedef struct _XedDocumentClass XedDocumentClass; + /*< private > */ + XedDocumentPrivate *priv; +}; struct _XedDocumentClass { - GtkSourceBufferClass parent_class; + GtkSourceBufferClass parent_class; - /* Signals */ // CHECK: ancora da rivedere + /* Signals */ - void (* cursor_moved) (XedDocument *document); + void (* cursor_moved) (XedDocument *document); - /* Document load */ - void (* load) (XedDocument *document, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create); + void (* load) (XedDocument *document); - void (* loading) (XedDocument *document, - goffset size, - goffset total_size); + void (* loaded) (XedDocument *document); - void (* loaded) (XedDocument *document, - const GError *error); + void (* save) (XedDocument *document); - /* Document save */ - void (* save) (XedDocument *document, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentSaveFlags flags); - - void (* saving) (XedDocument *document, - goffset size, - goffset total_size); - - void (* saved) (XedDocument *document, - const GError *error); - - void (* search_highlight_updated) - (XedDocument *document, - GtkTextIter *start, - GtkTextIter *end); + void (* saved) (XedDocument *document); }; +GType xed_document_get_type (void) G_GNUC_CONST; -#define XED_DOCUMENT_ERROR xed_document_error_quark () +XedDocument *xed_document_new (void); -enum -{ - XED_DOCUMENT_ERROR_EXTERNALLY_MODIFIED, - XED_DOCUMENT_ERROR_CANT_CREATE_BACKUP, - XED_DOCUMENT_ERROR_TOO_BIG, - XED_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED, - XED_DOCUMENT_ERROR_CONVERSION_FALLBACK, - XED_DOCUMENT_NUM_ERRORS -}; +GtkSourceFile *xed_document_get_file (XedDocument *doc); -GQuark xed_document_error_quark (void); +GFile *xed_document_get_location (XedDocument *doc); -GType xed_document_get_type (void) G_GNUC_CONST; +void xed_document_set_location (XedDocument *doc, + GFile *location); -XedDocument *xed_document_new (void); +gchar *xed_document_get_uri_for_display (XedDocument *doc); -GFile *xed_document_get_location (XedDocument *doc); +gchar *xed_document_get_short_name_for_display (XedDocument *doc); -gchar *xed_document_get_uri (XedDocument *doc); -void xed_document_set_uri (XedDocument *doc, - const gchar *uri); +void xed_document_set_short_name_for_display (XedDocument *doc, + const gchar *name); -gchar *xed_document_get_uri_for_display - (XedDocument *doc); -gchar *xed_document_get_short_name_for_display - (XedDocument *doc); +gchar *xed_document_get_content_type (XedDocument *doc); -void xed_document_set_short_name_for_display - (XedDocument *doc, - const gchar *name); +void xed_document_set_content_type (XedDocument *doc, + const gchar *content_type); -gchar *xed_document_get_content_type - (XedDocument *doc); +gchar *xed_document_get_mime_type (XedDocument *doc); -void xed_document_set_content_type - (XedDocument *doc, - const gchar *content_type); +gboolean xed_document_get_readonly (XedDocument *doc); -gchar *xed_document_get_mime_type (XedDocument *doc); +gboolean xed_document_is_untouched (XedDocument *doc); +gboolean xed_document_is_untitled (XedDocument *doc); -gboolean xed_document_get_readonly (XedDocument *doc); +gboolean xed_document_is_local (XedDocument *doc); -void xed_document_load (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create); +gboolean xed_document_get_deleted (XedDocument *doc); -gboolean xed_document_insert_file (XedDocument *doc, - GtkTextIter *iter, - const gchar *uri, - const XedEncoding *encoding); +gboolean xed_document_goto_line (XedDocument *doc, + gint line); -gboolean xed_document_load_cancel (XedDocument *doc); +gboolean xed_document_goto_line_offset (XedDocument *doc, + gint line, + gint line_offset); -void xed_document_save (XedDocument *doc, - XedDocumentSaveFlags flags); +void xed_document_set_language (XedDocument *doc, + GtkSourceLanguage *lang); +GtkSourceLanguage *xed_document_get_language (XedDocument *doc); -void xed_document_save_as (XedDocument *doc, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentSaveFlags flags); +const GtkSourceEncoding *xed_document_get_encoding (XedDocument *doc); -gboolean xed_document_is_untouched (XedDocument *doc); -gboolean xed_document_is_untitled (XedDocument *doc); +GtkSourceNewlineType xed_document_get_newline_type (XedDocument *doc); -gboolean xed_document_is_local (XedDocument *doc); +gchar *xed_document_get_metadata (XedDocument *doc, + const gchar *key); -gboolean xed_document_get_deleted (XedDocument *doc); +void xed_document_set_metadata (XedDocument *doc, + const gchar *first_key, + ...); -gboolean xed_document_goto_line (XedDocument *doc, - gint line); +void xed_document_set_search_context (XedDocument *doc, + GtkSourceSearchContext *search_context); -gboolean xed_document_goto_line_offset(XedDocument *doc, - gint line, - gint line_offset); +GtkSourceSearchContext *xed_document_get_search_context (XedDocument *doc); -void xed_document_set_search_text (XedDocument *doc, - const gchar *text, - guint flags); - -gchar *xed_document_get_search_text (XedDocument *doc, - guint *flags); +/* Non exported functions */ -gboolean xed_document_get_can_search_again - (XedDocument *doc); +glong _xed_document_get_seconds_since_last_save_or_load (XedDocument *doc); -gboolean xed_document_search_forward (XedDocument *doc, - const GtkTextIter *start, - const GtkTextIter *end, - GtkTextIter *match_start, - GtkTextIter *match_end); - -gboolean xed_document_search_backward (XedDocument *doc, - const GtkTextIter *start, - const GtkTextIter *end, - GtkTextIter *match_start, - GtkTextIter *match_end); - -gint xed_document_replace_all (XedDocument *doc, - const gchar *find, - const gchar *replace, - guint flags); - -void xed_document_set_language (XedDocument *doc, - GtkSourceLanguage *lang); -GtkSourceLanguage - *xed_document_get_language (XedDocument *doc); - -const XedEncoding - *xed_document_get_encoding (XedDocument *doc); - -void xed_document_set_enable_search_highlighting - (XedDocument *doc, - gboolean enable); - -gboolean xed_document_get_enable_search_highlighting - (XedDocument *doc); - -void xed_document_set_newline_type (XedDocument *doc, - XedDocumentNewlineType newline_type); - -XedDocumentNewlineType - xed_document_get_newline_type (XedDocument *doc); - -gchar *xed_document_get_metadata (XedDocument *doc, - const gchar *key); - -void xed_document_set_metadata (XedDocument *doc, - const gchar *first_key, - ...); - -/* - * Non exported functions - */ -void _xed_document_set_readonly (XedDocument *doc, - gboolean readonly); - -glong _xed_document_get_seconds_since_last_save_or_load - (XedDocument *doc); +void _xed_document_apply_error_style (XedDocument *doc, + GtkTextIter *start, + GtkTextIter *end); /* Note: this is a sync stat: use only on local files */ -gboolean _xed_document_check_externally_modified - (XedDocument *doc); +gboolean _xed_document_check_externally_modified (XedDocument *doc); -void _xed_document_search_region (XedDocument *doc, - const GtkTextIter *start, - const GtkTextIter *end); - -/* Search macros */ -#define XED_SEARCH_IS_DONT_SET_FLAGS(sflags) ((sflags & XED_SEARCH_DONT_SET_FLAGS) != 0) -#define XED_SEARCH_SET_DONT_SET_FLAGS(sflags,state) ((state == TRUE) ? \ -(sflags |= XED_SEARCH_DONT_SET_FLAGS) : (sflags &= ~XED_SEARCH_DONT_SET_FLAGS)) +gboolean _xed_document_needs_saving (XedDocument *doc); -#define XED_SEARCH_IS_ENTIRE_WORD(sflags) ((sflags & XED_SEARCH_ENTIRE_WORD) != 0) -#define XED_SEARCH_SET_ENTIRE_WORD(sflags,state) ((state == TRUE) ? \ -(sflags |= XED_SEARCH_ENTIRE_WORD) : (sflags &= ~XED_SEARCH_ENTIRE_WORD)) +void _xed_document_set_create (XedDocument *doc, + gboolean create); -#define XED_SEARCH_IS_CASE_SENSITIVE(sflags) ((sflags & XED_SEARCH_CASE_SENSITIVE) != 0) -#define XED_SEARCH_SET_CASE_SENSITIVE(sflags,state) ((state == TRUE) ? \ -(sflags |= XED_SEARCH_CASE_SENSITIVE) : (sflags &= ~XED_SEARCH_CASE_SENSITIVE)) - -#define XED_SEARCH_IS_PARSE_ESCAPES(sflags) ((sflags & XED_SEARCH_PARSE_ESCAPES) != 0) -#define XED_SEARCH_SET_PARSE_ESCAPES(sflags,state) ((state == TRUE) ? \ -(sflags |= XED_SEARCH_PARSE_ESCAPES) : (sflags &= ~XED_SEARCH_PARSE_ESCAPES)) - -typedef GMountOperation *(*XedMountOperationFactory)(XedDocument *doc, - gpointer userdata); - -void _xed_document_set_mount_operation_factory - (XedDocument *doc, - XedMountOperationFactory callback, - gpointer userdata); -GMountOperation - *_xed_document_create_mount_operation - (XedDocument *doc); +gboolean _xed_document_get_create (XedDocument *doc); G_END_DECLS diff --git a/xed/xed-documents-panel.c b/xed/xed-documents-panel.c index c448f24..8f3aff4 100644 --- a/xed/xed-documents-panel.c +++ b/xed/xed-documents-panel.c @@ -2,7 +2,7 @@ * xed-documents-panel.c * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -39,34 +39,34 @@ #include #define XED_DOCUMENTS_PANEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_DOCUMENTS_PANEL, \ - XedDocumentsPanelPrivate)) + XED_TYPE_DOCUMENTS_PANEL, \ + XedDocumentsPanelPrivate)) struct _XedDocumentsPanelPrivate { - XedWindow *window; + XedWindow *window; - GtkWidget *treeview; - GtkTreeModel *model; + GtkWidget *treeview; + GtkTreeModel *model; - guint adding_tab : 1; - guint is_reodering : 1; + guint adding_tab : 1; + guint is_reodering : 1; }; -G_DEFINE_TYPE(XedDocumentsPanel, xed_documents_panel, GTK_TYPE_BOX) +G_DEFINE_TYPE (XedDocumentsPanel, xed_documents_panel, GTK_TYPE_BOX) enum { - PROP_0, - PROP_WINDOW + PROP_0, + PROP_WINDOW }; enum { - PIXBUF_COLUMN, - NAME_COLUMN, - TAB_COLUMN, - N_COLUMNS + PIXBUF_COLUMN, + NAME_COLUMN, + TAB_COLUMN, + N_COLUMNS }; #define MAX_DOC_NAME_LENGTH 60 @@ -74,759 +74,681 @@ enum static gchar * tab_get_name (XedTab *tab) { - XedDocument *doc; - gchar *name; - gchar *docname; - gchar *tab_name; + XedDocument *doc; + gchar *name; + gchar *docname; + gchar *tab_name; - g_return_val_if_fail (XED_IS_TAB (tab), NULL); + g_return_val_if_fail (XED_IS_TAB (tab), NULL); - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); - name = xed_document_get_short_name_for_display (doc); + name = xed_document_get_short_name_for_display (doc); - /* Truncate the name so it doesn't get insanely wide. */ - docname = xed_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH); + /* Truncate the name so it doesn't get insanely wide. */ + docname = xed_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH); - if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc))) - { - if (xed_document_get_readonly (doc)) - { - tab_name = g_markup_printf_escaped ("%s [%s]", - docname, - _("Read-Only")); - } - else - { - tab_name = g_markup_printf_escaped ("%s", - docname); - } - } - else - { - if (xed_document_get_readonly (doc)) - { - tab_name = g_markup_printf_escaped ("%s [%s]", - docname, - _("Read-Only")); - } - else - { - tab_name = g_markup_escape_text (docname, -1); - } - } + if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc))) + { + if (xed_document_get_readonly (doc)) + { + tab_name = g_markup_printf_escaped ("%s [%s]", docname, _("Read-Only")); + } + else + { + tab_name = g_markup_printf_escaped ("%s", docname); + } + } + else + { + if (xed_document_get_readonly (doc)) + { + tab_name = g_markup_printf_escaped ("%s [%s]", docname, _("Read-Only")); + } + else + { + tab_name = g_markup_escape_text (docname, -1); + } + } - g_free (docname); - g_free (name); + g_free (docname); + g_free (name); - return tab_name; + return tab_name; } static void -get_iter_from_tab (XedDocumentsPanel *panel, XedTab *tab, GtkTreeIter *iter) +get_iter_from_tab (XedDocumentsPanel *panel, + XedTab *tab, + GtkTreeIter *iter) { - gint num; - GtkWidget *nb; - GtkTreePath *path; + gint num; + GtkWidget *nb; + GtkTreePath *path; - nb = _xed_window_get_notebook (panel->priv->window); - num = gtk_notebook_page_num (GTK_NOTEBOOK (nb), - GTK_WIDGET (tab)); + nb = _xed_window_get_notebook (panel->priv->window); + num = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab)); - path = gtk_tree_path_new_from_indices (num, -1); - gtk_tree_model_get_iter (panel->priv->model, - iter, - path); - gtk_tree_path_free (path); + path = gtk_tree_path_new_from_indices (num, -1); + gtk_tree_model_get_iter (panel->priv->model, iter, path); + gtk_tree_path_free (path); } static void window_active_tab_changed (XedWindow *window, - XedTab *tab, - XedDocumentsPanel *panel) -{ - g_return_if_fail (tab != NULL); + XedTab *tab, + XedDocumentsPanel *panel) +{ + g_return_if_fail (tab != NULL); - if (!_xed_window_is_removing_tabs (window)) - { - GtkTreeIter iter; - GtkTreeSelection *selection; + if (!_xed_window_is_removing_tabs (window)) + { + GtkTreeIter iter; + GtkTreeSelection *selection; - get_iter_from_tab (panel, tab, &iter); + get_iter_from_tab (panel, tab, &iter); - if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (panel->priv->model), - &iter)) - { - selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (panel->priv->treeview)); + if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (panel->priv->model), &iter)) + { + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); - gtk_tree_selection_select_iter (selection, &iter); - } - } + gtk_tree_selection_select_iter (selection, &iter); + } + } } static void refresh_list (XedDocumentsPanel *panel) { - /* TODO: refresh the list only if the panel is visible */ + /* TODO: refresh the list only if the panel is visible */ - GList *tabs; - GList *l; - GtkWidget *nb; - GtkListStore *list_store; - XedTab *active_tab; + GList *tabs; + GList *l; + GtkWidget *nb; + GtkListStore *list_store; + XedTab *active_tab; - /* g_debug ("refresh_list"); */ - - list_store = GTK_LIST_STORE (panel->priv->model); + /* g_debug ("refresh_list"); */ - gtk_list_store_clear (list_store); + list_store = GTK_LIST_STORE (panel->priv->model); - active_tab = xed_window_get_active_tab (panel->priv->window); + gtk_list_store_clear (list_store); - nb = _xed_window_get_notebook (panel->priv->window); + active_tab = xed_window_get_active_tab (panel->priv->window); - tabs = gtk_container_get_children (GTK_CONTAINER (nb)); - l = tabs; + nb = _xed_window_get_notebook (panel->priv->window); - panel->priv->adding_tab = TRUE; - - while (l != NULL) - { - GdkPixbuf *pixbuf; - gchar *name; - GtkTreeIter iter; + tabs = gtk_container_get_children (GTK_CONTAINER (nb)); + l = tabs; - name = tab_get_name (XED_TAB (l->data)); - pixbuf = _xed_tab_get_icon (XED_TAB (l->data)); + panel->priv->adding_tab = TRUE; - /* Add a new row to the model */ - gtk_list_store_append (list_store, &iter); - gtk_list_store_set (list_store, - &iter, - PIXBUF_COLUMN, pixbuf, - NAME_COLUMN, name, - TAB_COLUMN, l->data, - -1); + while (l != NULL) + { + GdkPixbuf *pixbuf; + gchar *name; + GtkTreeIter iter; - g_free (name); - if (pixbuf != NULL) - g_object_unref (pixbuf); + name = tab_get_name (XED_TAB (l->data)); + pixbuf = _xed_tab_get_icon (XED_TAB (l->data)); - if (l->data == active_tab) - { - GtkTreeSelection *selection; + /* Add a new row to the model */ + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, + PIXBUF_COLUMN, pixbuf, + NAME_COLUMN, name, + TAB_COLUMN, l->data, + -1); - selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (panel->priv->treeview)); + g_free (name); + if (pixbuf != NULL) + { + g_object_unref (pixbuf); + } - gtk_tree_selection_select_iter (selection, &iter); - } + if (l->data == active_tab) + { + GtkTreeSelection *selection; - l = g_list_next (l); - } - - panel->priv->adding_tab = FALSE; + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); - g_list_free (tabs); + gtk_tree_selection_select_iter (selection, &iter); + } + + l = g_list_next (l); + } + + panel->priv->adding_tab = FALSE; + + g_list_free (tabs); } static void sync_name_and_icon (XedTab *tab, - GParamSpec *pspec, - XedDocumentsPanel *panel) + GParamSpec *pspec, + XedDocumentsPanel *panel) { - GdkPixbuf *pixbuf; - gchar *name; - GtkTreeIter iter; + GdkPixbuf *pixbuf; + gchar *name; + GtkTreeIter iter; - get_iter_from_tab (panel, tab, &iter); + get_iter_from_tab (panel, tab, &iter); - name = tab_get_name (tab); - pixbuf = _xed_tab_get_icon (tab); + name = tab_get_name (tab); + pixbuf = _xed_tab_get_icon (tab); - gtk_list_store_set (GTK_LIST_STORE (panel->priv->model), - &iter, - PIXBUF_COLUMN, pixbuf, - NAME_COLUMN, name, - TAB_COLUMN, tab, - -1); + gtk_list_store_set (GTK_LIST_STORE (panel->priv->model), &iter, + PIXBUF_COLUMN, pixbuf, + NAME_COLUMN, name, + TAB_COLUMN, tab, + -1); - g_free (name); - if (pixbuf != NULL) - g_object_unref (pixbuf); + g_free (name); + if (pixbuf != NULL) + { + g_object_unref (pixbuf); + } } static void window_tab_removed (XedWindow *window, - XedTab *tab, - XedDocumentsPanel *panel) + XedTab *tab, + XedDocumentsPanel *panel) { - g_signal_handlers_disconnect_by_func (tab, - G_CALLBACK (sync_name_and_icon), - panel); + g_signal_handlers_disconnect_by_func (tab, G_CALLBACK (sync_name_and_icon), panel); - if (_xed_window_is_removing_tabs (window)) - gtk_list_store_clear (GTK_LIST_STORE (panel->priv->model)); - else - refresh_list (panel); + if (_xed_window_is_removing_tabs (window)) + { + gtk_list_store_clear (GTK_LIST_STORE (panel->priv->model)); + } + else + { + refresh_list (panel); + } } static void window_tab_added (XedWindow *window, - XedTab *tab, - XedDocumentsPanel *panel) + XedTab *tab, + XedDocumentsPanel *panel) { - GtkTreeIter iter; - GtkTreeIter sibling; - GdkPixbuf *pixbuf; - gchar *name; + GtkTreeIter iter; + GtkTreeIter sibling; + GdkPixbuf *pixbuf; + gchar *name; - g_signal_connect (tab, - "notify::name", - G_CALLBACK (sync_name_and_icon), - panel); + g_signal_connect (tab, "notify::name", G_CALLBACK (sync_name_and_icon), panel); + g_signal_connect (tab, "notify::state", G_CALLBACK (sync_name_and_icon), panel); - g_signal_connect (tab, - "notify::state", - G_CALLBACK (sync_name_and_icon), - panel); + get_iter_from_tab (panel, tab, &sibling); - get_iter_from_tab (panel, tab, &sibling); + panel->priv->adding_tab = TRUE; - panel->priv->adding_tab = TRUE; - - if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (panel->priv->model), - &sibling)) - { - gtk_list_store_insert_after (GTK_LIST_STORE (panel->priv->model), - &iter, - &sibling); - } - else - { - XedTab *active_tab; + if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (panel->priv->model), &sibling)) + { + gtk_list_store_insert_after (GTK_LIST_STORE (panel->priv->model), &iter, &sibling); + } + else + { + XedTab *active_tab; - gtk_list_store_append (GTK_LIST_STORE (panel->priv->model), - &iter); + gtk_list_store_append (GTK_LIST_STORE (panel->priv->model), &iter); - active_tab = xed_window_get_active_tab (panel->priv->window); + active_tab = xed_window_get_active_tab (panel->priv->window); - if (tab == active_tab) - { - GtkTreeSelection *selection; + if (tab == active_tab) + { + GtkTreeSelection *selection; - selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (panel->priv->treeview)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); + gtk_tree_selection_select_iter (selection, &iter); + } + } - gtk_tree_selection_select_iter (selection, &iter); - } - } + name = tab_get_name (tab); + pixbuf = _xed_tab_get_icon (tab); - name = tab_get_name (tab); - pixbuf = _xed_tab_get_icon (tab); + gtk_list_store_set (GTK_LIST_STORE (panel->priv->model), &iter, + PIXBUF_COLUMN, pixbuf, + NAME_COLUMN, name, + TAB_COLUMN, tab, + -1); - gtk_list_store_set (GTK_LIST_STORE (panel->priv->model), - &iter, - PIXBUF_COLUMN, pixbuf, - NAME_COLUMN, name, - TAB_COLUMN, tab, - -1); + g_free (name); + if (pixbuf != NULL) + { + g_object_unref (pixbuf); + } - g_free (name); - if (pixbuf != NULL) - g_object_unref (pixbuf); - - panel->priv->adding_tab = FALSE; + panel->priv->adding_tab = FALSE; } static void window_tabs_reordered (XedWindow *window, - XedDocumentsPanel *panel) + XedDocumentsPanel *panel) { - if (panel->priv->is_reodering) - return; + if (panel->priv->is_reodering) + { + return; + } - refresh_list (panel); + refresh_list (panel); } static void set_window (XedDocumentsPanel *panel, - XedWindow *window) + XedWindow *window) { - g_return_if_fail (panel->priv->window == NULL); - g_return_if_fail (XED_IS_WINDOW (window)); + g_return_if_fail (panel->priv->window == NULL); + g_return_if_fail (XED_IS_WINDOW (window)); - panel->priv->window = g_object_ref (window); + panel->priv->window = g_object_ref (window); - g_signal_connect (window, - "tab_added", - G_CALLBACK (window_tab_added), - panel); - g_signal_connect (window, - "tab_removed", - G_CALLBACK (window_tab_removed), - panel); - g_signal_connect (window, - "tabs_reordered", - G_CALLBACK (window_tabs_reordered), - panel); - g_signal_connect (window, - "active_tab_changed", - G_CALLBACK (window_active_tab_changed), - panel); + g_signal_connect (window, "tab_added", G_CALLBACK (window_tab_added), panel); + g_signal_connect (window, "tab_removed", G_CALLBACK (window_tab_removed), panel); + g_signal_connect (window, "tabs_reordered", G_CALLBACK (window_tabs_reordered), panel); + g_signal_connect (window, "active_tab_changed", G_CALLBACK (window_active_tab_changed), panel); } static void -treeview_cursor_changed (GtkTreeView *view, - XedDocumentsPanel *panel) +treeview_cursor_changed (GtkTreeView *view, + XedDocumentsPanel *panel) { - GtkTreeIter iter; - GtkTreeSelection *selection; - gpointer tab; + GtkTreeIter iter; + GtkTreeSelection *selection; + gpointer tab; - selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (panel->priv->treeview)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - gtk_tree_model_get (panel->priv->model, - &iter, - TAB_COLUMN, - &tab, - -1); + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + gtk_tree_model_get (panel->priv->model, &iter, + TAB_COLUMN, &tab, + -1); - if (xed_window_get_active_tab (panel->priv->window) != tab) - { - xed_window_set_active_tab (panel->priv->window, - XED_TAB (tab)); - } - } + if (xed_window_get_active_tab (panel->priv->window) != tab) + { + xed_window_set_active_tab (panel->priv->window, XED_TAB (tab)); + } + } } static void xed_documents_panel_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedDocumentsPanel *panel = XED_DOCUMENTS_PANEL (object); + XedDocumentsPanel *panel = XED_DOCUMENTS_PANEL (object); - switch (prop_id) - { - case PROP_WINDOW: - set_window (panel, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_WINDOW: + set_window (panel, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_documents_panel_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedDocumentsPanel *panel = XED_DOCUMENTS_PANEL (object); + XedDocumentsPanel *panel = XED_DOCUMENTS_PANEL (object); - switch (prop_id) - { - case PROP_WINDOW: - g_value_set_object (value, - XED_DOCUMENTS_PANEL_GET_PRIVATE (panel)->window); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, XED_DOCUMENTS_PANEL_GET_PRIVATE (panel)->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_documents_panel_finalize (GObject *object) { - /* XedDocumentsPanel *tab = XED_DOCUMENTS_PANEL (object); */ - - /* TODO: disconnect signal with window */ + /* XedDocumentsPanel *tab = XED_DOCUMENTS_PANEL (object); */ - G_OBJECT_CLASS (xed_documents_panel_parent_class)->finalize (object); + /* TODO: disconnect signal with window */ + + G_OBJECT_CLASS (xed_documents_panel_parent_class)->finalize (object); } static void xed_documents_panel_dispose (GObject *object) { - XedDocumentsPanel *panel = XED_DOCUMENTS_PANEL (object); + XedDocumentsPanel *panel = XED_DOCUMENTS_PANEL (object); - if (panel->priv->window != NULL) - { - g_object_unref (panel->priv->window); - panel->priv->window = NULL; - } + if (panel->priv->window != NULL) + { + g_object_unref (panel->priv->window); + panel->priv->window = NULL; + } - G_OBJECT_CLASS (xed_documents_panel_parent_class)->dispose (object); + G_OBJECT_CLASS (xed_documents_panel_parent_class)->dispose (object); } -static void +static void xed_documents_panel_class_init (XedDocumentsPanelClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_documents_panel_finalize; - object_class->dispose = xed_documents_panel_dispose; - object_class->get_property = xed_documents_panel_get_property; - object_class->set_property = xed_documents_panel_set_property; + object_class->finalize = xed_documents_panel_finalize; + object_class->dispose = xed_documents_panel_dispose; + object_class->get_property = xed_documents_panel_get_property; + object_class->set_property = xed_documents_panel_set_property; - g_object_class_install_property (object_class, - PROP_WINDOW, - g_param_spec_object ("window", - "Window", - "The XedWindow this XedDocumentsPanel is associated with", - XED_TYPE_WINDOW, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_WINDOW, + g_param_spec_object ("window", + "Window", + "The XedWindow this XedDocumentsPanel is associated with", + XED_TYPE_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); - g_type_class_add_private (object_class, sizeof (XedDocumentsPanelPrivate)); + g_type_class_add_private (object_class, sizeof (XedDocumentsPanelPrivate)); } static GtkTreePath * get_current_path (XedDocumentsPanel *panel) { - gint num; - GtkWidget *nb; - GtkTreePath *path; + gint num; + GtkWidget *nb; + GtkTreePath *path; - nb = _xed_window_get_notebook (panel->priv->window); - num = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)); + nb = _xed_window_get_notebook (panel->priv->window); + num = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)); - path = gtk_tree_path_new_from_indices (num, -1); + path = gtk_tree_path_new_from_indices (num, -1); - return path; + return path; } static void -menu_position (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - XedDocumentsPanel *panel) +menu_position (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + XedDocumentsPanel *panel) { - GtkTreePath *path; - GdkRectangle rect; - gint wx, wy; - GtkAllocation allocation; - GtkRequisition requisition; - GtkWidget *w; + GtkTreePath *path; + GdkRectangle rect; + gint wy; + GtkAllocation allocation; + GtkRequisition requisition; + GtkWidget *w; - w = panel->priv->treeview; + w = panel->priv->treeview; - gtk_widget_get_allocation(w, &allocation); + gtk_widget_get_allocation(w, &allocation); - path = get_current_path (panel); + path = get_current_path (panel); - gtk_tree_view_get_cell_area (GTK_TREE_VIEW (w), - path, - NULL, - &rect); + gtk_tree_view_get_cell_area (GTK_TREE_VIEW (w), path, NULL, &rect); - wx = rect.x; - wy = rect.y; + wy = rect.y; - gdk_window_get_origin (gtk_widget_get_window (w), x, y); + gdk_window_get_origin (gtk_widget_get_window (w), x, y); - gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &requisition); + gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &requisition); - if (gtk_widget_get_direction (w) == GTK_TEXT_DIR_RTL) - { - *x += allocation.x + allocation.width - requisition.width - 10; - } - else - { - *x += allocation.x + 10; - } + if (gtk_widget_get_direction (w) == GTK_TEXT_DIR_RTL) + { + *x += allocation.x + allocation.width - requisition.width - 10; + } + else + { + *x += allocation.x + 10; + } - wy = MAX (*y + 5, *y + wy + 5); - wy = MIN (wy, *y + allocation.height - requisition.height - 5); - - *y = wy; + wy = MAX (*y + 5, *y + wy + 5); + wy = MIN (wy, *y + allocation.height - requisition.height - 5); - *push_in = TRUE; + *y = wy; + + *push_in = TRUE; } static gboolean show_popup_menu (XedDocumentsPanel *panel, - GdkEventButton *event) + GdkEventButton *event) { - GtkWidget *menu; + GtkWidget *menu; - menu = gtk_ui_manager_get_widget (xed_window_get_ui_manager (panel->priv->window), - "/NotebookPopup"); - g_return_val_if_fail (menu != NULL, FALSE); + menu = gtk_ui_manager_get_widget (xed_window_get_ui_manager (panel->priv->window), "/NotebookPopup"); + g_return_val_if_fail (menu != NULL, FALSE); - if (event != NULL) - { - gtk_menu_popup (GTK_MENU (menu), - NULL, - NULL, - NULL, - NULL, - event->button, - event->time); - } - else - { - gtk_menu_popup (GTK_MENU (menu), - NULL, - NULL, - (GtkMenuPositionFunc) menu_position, - panel, - 0, - gtk_get_current_event_time ()); + if (event != NULL) + { + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, + NULL, NULL, + event->button, event->time); + } + else + { + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, + (GtkMenuPositionFunc) menu_position, panel, + 0, gtk_get_current_event_time ()); - gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); - } + gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); + } - return TRUE; + return TRUE; } static gboolean -panel_button_press_event (GtkTreeView *treeview, - GdkEventButton *event, - XedDocumentsPanel *panel) +panel_button_press_event (GtkTreeView *treeview, + GdkEventButton *event, + XedDocumentsPanel *panel) { - if ((GDK_BUTTON_PRESS == event->type) && (3 == event->button)) - { - GtkTreePath* path = NULL; + if ((GDK_BUTTON_PRESS == event->type) && (3 == event->button)) + { + GtkTreePath* path = NULL; - if (event->window == gtk_tree_view_get_bin_window (treeview)) - { - /* Change the cursor position */ - if (gtk_tree_view_get_path_at_pos (treeview, - event->x, - event->y, - &path, - NULL, - NULL, - NULL)) - { + if (event->window == gtk_tree_view_get_bin_window (treeview)) + { + /* Change the cursor position */ + if (gtk_tree_view_get_path_at_pos (treeview, + event->x, event->y, + &path, NULL, + NULL, NULL)) + { - gtk_tree_view_set_cursor (treeview, - path, - NULL, - FALSE); + gtk_tree_view_set_cursor (treeview, path, NULL, FALSE); - gtk_tree_path_free (path); + gtk_tree_path_free (path); - /* A row exists at mouse position */ - return show_popup_menu (panel, event); - } - } - } + /* A row exists at mouse position */ + return show_popup_menu (panel, event); + } + } + } - return FALSE; + return FALSE; } static gboolean -panel_popup_menu (GtkWidget *treeview, - XedDocumentsPanel *panel) +panel_popup_menu (GtkWidget *treeview, + XedDocumentsPanel *panel) { - /* Only respond if the treeview is the actual focus */ - if (gtk_window_get_focus (GTK_WINDOW (panel->priv->window)) == treeview) - { - return show_popup_menu (panel, NULL); - } + /* Only respond if the treeview is the actual focus */ + if (gtk_window_get_focus (GTK_WINDOW (panel->priv->window)) == treeview) + { + return show_popup_menu (panel, NULL); + } - return FALSE; + return FALSE; } static gboolean treeview_query_tooltip (GtkWidget *widget, - gint x, - gint y, - gboolean keyboard_tip, - GtkTooltip *tooltip, - gpointer data) + gint x, + gint y, + gboolean keyboard_tip, + GtkTooltip *tooltip, + gpointer data) { - GtkTreeIter iter; - GtkTreeView *tree_view = GTK_TREE_VIEW (widget); - GtkTreeModel *model = gtk_tree_view_get_model (tree_view); - GtkTreePath *path = NULL; - gpointer *tab; - gchar *tip; + GtkTreeIter iter; + GtkTreeView *tree_view = GTK_TREE_VIEW (widget); + GtkTreeModel *model = gtk_tree_view_get_model (tree_view); + GtkTreePath *path = NULL; + gpointer *tab; + gchar *tip; - if (keyboard_tip) - { - gtk_tree_view_get_cursor (tree_view, &path, NULL); + if (keyboard_tip) + { + gtk_tree_view_get_cursor (tree_view, &path, NULL); - if (path == NULL) - { - return FALSE; - } - } - else - { - gint bin_x, bin_y; + if (path == NULL) + { + return FALSE; + } + } + else + { + gint bin_x, bin_y; - gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, - x, y, - &bin_x, &bin_y); + gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, &bin_x, &bin_y); - if (!gtk_tree_view_get_path_at_pos (tree_view, - bin_x, bin_y, - &path, - NULL, NULL, NULL)) - { - return FALSE; - } - } + if (!gtk_tree_view_get_path_at_pos (tree_view, + bin_x, bin_y, + &path, NULL, + NULL, NULL)) + { + return FALSE; + } + } - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, - &iter, - TAB_COLUMN, - &tab, - -1); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, TAB_COLUMN, &tab, -1); - tip = _xed_tab_get_tooltips (XED_TAB (tab)); - gtk_tooltip_set_markup (tooltip, tip); + tip = _xed_tab_get_tooltips (XED_TAB (tab)); + gtk_tooltip_set_markup (tooltip, tip); - g_free (tip); - gtk_tree_path_free (path); + g_free (tip); + gtk_tree_path_free (path); - return TRUE; + return TRUE; } static void -treeview_row_inserted (GtkTreeModel *tree_model, - GtkTreePath *path, - GtkTreeIter *iter, - XedDocumentsPanel *panel) +treeview_row_inserted (GtkTreeModel *tree_model, + GtkTreePath *path, + GtkTreeIter *iter, + XedDocumentsPanel *panel) { - XedTab *tab; - gint *indeces; - GtkWidget *nb; - gint old_position; - gint new_position; - - if (panel->priv->adding_tab) - return; - - tab = xed_window_get_active_tab (panel->priv->window); - g_return_if_fail (tab != NULL); + XedTab *tab; + gint *indeces; + GtkWidget *nb; + gint old_position; + gint new_position; - panel->priv->is_reodering = TRUE; - - indeces = gtk_tree_path_get_indices (path); - - /* g_debug ("New Index: %d (path: %s)", indeces[0], gtk_tree_path_to_string (path));*/ - - nb = _xed_window_get_notebook (panel->priv->window); + if (panel->priv->adding_tab) + { + return; + } - new_position = indeces[0]; - old_position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), - GTK_WIDGET (tab)); - if (new_position > old_position) - new_position = MAX (0, new_position - 1); - - xed_notebook_reorder_tab (XED_NOTEBOOK (nb), - tab, - new_position); + tab = xed_window_get_active_tab (panel->priv->window); + g_return_if_fail (tab != NULL); - panel->priv->is_reodering = FALSE; + panel->priv->is_reodering = TRUE; + + indeces = gtk_tree_path_get_indices (path); + + /* g_debug ("New Index: %d (path: %s)", indeces[0], gtk_tree_path_to_string (path));*/ + + nb = _xed_window_get_notebook (panel->priv->window); + + new_position = indeces[0]; + old_position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab)); + if (new_position > old_position) + { + new_position = MAX (0, new_position - 1); + } + + xed_notebook_reorder_tab (XED_NOTEBOOK (nb), tab, new_position); + + panel->priv->is_reodering = FALSE; } static void xed_documents_panel_init (XedDocumentsPanel *panel) { - GtkWidget *sw; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - GtkTreeSelection *selection; + GtkWidget *sw; + GtkTreeViewColumn *column; + GtkCellRenderer *cell; + GtkTreeSelection *selection; - panel->priv = XED_DOCUMENTS_PANEL_GET_PRIVATE (panel); - - panel->priv->adding_tab = FALSE; - panel->priv->is_reodering = FALSE; + panel->priv = XED_DOCUMENTS_PANEL_GET_PRIVATE (panel); - gtk_orientable_set_orientation (GTK_ORIENTABLE (panel), - GTK_ORIENTATION_VERTICAL); - - /* Create the scrolled window */ - sw = gtk_scrolled_window_new (NULL, NULL); - g_return_if_fail (sw != NULL); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_widget_show (sw); - gtk_box_pack_start (GTK_BOX (panel), sw, TRUE, TRUE, 0); - - /* Create the empty model */ - panel->priv->model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS, - GDK_TYPE_PIXBUF, - G_TYPE_STRING, - G_TYPE_POINTER)); + panel->priv->adding_tab = FALSE; + panel->priv->is_reodering = FALSE; - /* Create the treeview */ - panel->priv->treeview = gtk_tree_view_new_with_model (panel->priv->model); - g_object_unref (G_OBJECT (panel->priv->model)); - gtk_container_add (GTK_CONTAINER (sw), panel->priv->treeview); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (panel->priv->treeview), FALSE); - gtk_tree_view_set_reorderable (GTK_TREE_VIEW (panel->priv->treeview), TRUE); + gtk_orientable_set_orientation (GTK_ORIENTABLE (panel), GTK_ORIENTATION_VERTICAL); - g_object_set (panel->priv->treeview, "has-tooltip", TRUE, NULL); + /* Create the scrolled window */ + sw = gtk_scrolled_window_new (NULL, NULL); + g_return_if_fail (sw != NULL); - gtk_widget_show (panel->priv->treeview); - - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Documents")); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_widget_show (sw); + gtk_box_pack_start (GTK_BOX (panel), sw, TRUE, TRUE, 0); - cell = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, cell, FALSE); - gtk_tree_view_column_add_attribute (column, cell, "pixbuf", PIXBUF_COLUMN); - cell = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "markup", NAME_COLUMN); + /* Create the empty model */ + panel->priv->model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS, + GDK_TYPE_PIXBUF, + G_TYPE_STRING, + G_TYPE_POINTER)); - gtk_tree_view_append_column (GTK_TREE_VIEW (panel->priv->treeview), - column); - - selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (panel->priv->treeview)); + /* Create the treeview */ + panel->priv->treeview = gtk_tree_view_new_with_model (panel->priv->model); + g_object_unref (G_OBJECT (panel->priv->model)); + gtk_container_add (GTK_CONTAINER (sw), panel->priv->treeview); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (panel->priv->treeview), FALSE); + gtk_tree_view_set_reorderable (GTK_TREE_VIEW (panel->priv->treeview), TRUE); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - g_signal_connect (panel->priv->treeview, - "cursor_changed", - G_CALLBACK (treeview_cursor_changed), - panel); - g_signal_connect (panel->priv->treeview, - "button-press-event", - G_CALLBACK (panel_button_press_event), - panel); - g_signal_connect (panel->priv->treeview, - "popup-menu", - G_CALLBACK (panel_popup_menu), - panel); - g_signal_connect (panel->priv->treeview, - "query-tooltip", - G_CALLBACK (treeview_query_tooltip), - NULL); + g_object_set (panel->priv->treeview, "has-tooltip", TRUE, NULL); - g_signal_connect (panel->priv->model, - "row-inserted", - G_CALLBACK (treeview_row_inserted), - panel); + gtk_widget_show (panel->priv->treeview); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Documents")); + + cell = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_add_attribute (column, cell, "pixbuf", PIXBUF_COLUMN); + cell = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, cell, TRUE); + gtk_tree_view_column_add_attribute (column, cell, "markup", NAME_COLUMN); + + gtk_tree_view_append_column (GTK_TREE_VIEW (panel->priv->treeview), column); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); + + gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); + + g_signal_connect (panel->priv->treeview, "cursor_changed", G_CALLBACK (treeview_cursor_changed), panel); + g_signal_connect (panel->priv->treeview, "button-press-event", G_CALLBACK (panel_button_press_event), panel); + g_signal_connect (panel->priv->treeview, "popup-menu", G_CALLBACK (panel_popup_menu), panel); + g_signal_connect (panel->priv->treeview, "query-tooltip", G_CALLBACK (treeview_query_tooltip), NULL); + g_signal_connect (panel->priv->model, "row-inserted", G_CALLBACK (treeview_row_inserted), panel); } GtkWidget * xed_documents_panel_new (XedWindow *window) { - g_return_val_if_fail (XED_IS_WINDOW (window), NULL); + g_return_val_if_fail (XED_IS_WINDOW (window), NULL); - return GTK_WIDGET (g_object_new (XED_TYPE_DOCUMENTS_PANEL, - "window", window, - NULL)); + return GTK_WIDGET (g_object_new (XED_TYPE_DOCUMENTS_PANEL, + "window", window, + NULL)); } diff --git a/xed/xed-encodings-combo-box.c b/xed/xed-encodings-combo-box.c index 08637f3..257fc21 100644 --- a/xed/xed-encodings-combo-box.c +++ b/xed/xed-encodings-combo-box.c @@ -17,14 +17,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2003-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2003-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id: xed-encodings-combo-box.c 6112 2008-01-23 08:26:24Z sfre $ */ @@ -34,400 +34,386 @@ #endif #include -#include +#include -#include -#include -#include +#include "xed/xed-encodings-combo-box.h" +#include +#include "xed-settings.h" +#include "xed-utils.h" #define ENCODING_KEY "Enconding" -#define XED_ENCODINGS_COMBO_BOX_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_ENCODINGS_COMBO_BOX, \ - XedEncodingsComboBoxPrivate)) +#define XED_ENCODINGS_COMBO_BOX_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ + XED_TYPE_ENCODINGS_COMBO_BOX, \ + XedEncodingsComboBoxPrivate)) struct _XedEncodingsComboBoxPrivate { - GtkListStore *store; - glong changed_id; + GSettings *enc_settings; - guint activated_item; + GtkListStore *store; + glong changed_id; - guint save_mode : 1; + guint activated_item; + + guint save_mode : 1; }; enum { - NAME_COLUMN, - ENCODING_COLUMN, - ADD_COLUMN, - N_COLUMNS + NAME_COLUMN, + ENCODING_COLUMN, + ADD_COLUMN, + N_COLUMNS }; /* Properties */ enum { - PROP_0, - PROP_SAVE_MODE + PROP_0, + PROP_SAVE_MODE }; G_DEFINE_TYPE(XedEncodingsComboBox, xed_encodings_combo_box, GTK_TYPE_COMBO_BOX) -static void update_menu (XedEncodingsComboBox *combo_box); +static void update_menu (XedEncodingsComboBox *combo_box); static void xed_encodings_combo_box_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedEncodingsComboBox *combo; + XedEncodingsComboBox *combo; - combo = XED_ENCODINGS_COMBO_BOX (object); + combo = XED_ENCODINGS_COMBO_BOX (object); - switch (prop_id) - { - case PROP_SAVE_MODE: - combo->priv->save_mode = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_SAVE_MODE: + combo->priv->save_mode = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_encodings_combo_box_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedEncodingsComboBox *combo; + XedEncodingsComboBox *combo; - combo = XED_ENCODINGS_COMBO_BOX (object); + combo = XED_ENCODINGS_COMBO_BOX (object); - switch (prop_id) - { - case PROP_SAVE_MODE: - g_value_set_boolean (value, combo->priv->save_mode); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_SAVE_MODE: + g_value_set_boolean (value, combo->priv->save_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_encodings_combo_box_dispose (GObject *object) { - XedEncodingsComboBox *combo = XED_ENCODINGS_COMBO_BOX (object); + XedEncodingsComboBox *combo = XED_ENCODINGS_COMBO_BOX (object); - if (combo->priv->store != NULL) - { - g_object_unref (combo->priv->store); - combo->priv->store = NULL; - } + if (combo->priv->store != NULL) + { + g_object_unref (combo->priv->store); + combo->priv->store = NULL; + } - G_OBJECT_CLASS (xed_encodings_combo_box_parent_class)->dispose (object); + G_OBJECT_CLASS (xed_encodings_combo_box_parent_class)->dispose (object); } static void xed_encodings_combo_box_class_init (XedEncodingsComboBoxClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->set_property = xed_encodings_combo_box_set_property; - object_class->get_property = xed_encodings_combo_box_get_property; - object_class->dispose = xed_encodings_combo_box_dispose; + object_class->set_property = xed_encodings_combo_box_set_property; + object_class->get_property = xed_encodings_combo_box_get_property; + object_class->dispose = xed_encodings_combo_box_dispose; - g_object_class_install_property (object_class, - PROP_SAVE_MODE, - g_param_spec_boolean ("save-mode", - "Save Mode", - "Save Mode", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_SAVE_MODE, + g_param_spec_boolean ("save-mode", + "Save Mode", + "Save Mode", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); - g_type_class_add_private (object_class, sizeof (XedEncodingsComboBoxPrivate)); + g_type_class_add_private (object_class, sizeof (XedEncodingsComboBoxPrivate)); } static void -dialog_response_cb (GtkDialog *dialog, - gint response_id, +dialog_response_cb (GtkDialog *dialog, + gint response_id, XedEncodingsComboBox *menu) { - if (response_id == GTK_RESPONSE_OK) - { - update_menu (menu); - } + if (response_id == GTK_RESPONSE_OK) + { + update_menu (menu); + } - gtk_widget_destroy (GTK_WIDGET (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); } static void add_or_remove (XedEncodingsComboBox *menu, - GtkTreeModel *model) + GtkTreeModel *model) { - GtkTreeIter iter; - gboolean add_item = FALSE; + GtkTreeIter iter; + gboolean add_item = FALSE; - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (menu), &iter)) - { - gtk_tree_model_get (model, &iter, - ADD_COLUMN, &add_item, - -1); - } + if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (menu), &iter)) + { + gtk_tree_model_get (model, &iter, ADD_COLUMN, &add_item, -1); + } - if (!add_item) - { - menu->priv->activated_item = gtk_combo_box_get_active (GTK_COMBO_BOX (menu)); - } - else - { - GtkWidget *dialog; + if (!add_item) + { + menu->priv->activated_item = gtk_combo_box_get_active (GTK_COMBO_BOX (menu)); + } + else + { + GtkWidget *dialog; - GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (menu)); + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (menu)); - if (!gtk_widget_is_toplevel (toplevel)) - toplevel = NULL; + if (!gtk_widget_is_toplevel (toplevel)) + { + toplevel = NULL; + } - g_signal_handler_block (menu, menu->priv->changed_id); - gtk_combo_box_set_active (GTK_COMBO_BOX (menu), - menu->priv->activated_item); - g_signal_handler_unblock (menu, menu->priv->changed_id); + g_signal_handler_block (menu, menu->priv->changed_id); + gtk_combo_box_set_active (GTK_COMBO_BOX (menu), menu->priv->activated_item); + g_signal_handler_unblock (menu, menu->priv->changed_id); - dialog = xed_encodings_dialog_new(); + dialog = xed_encodings_dialog_new(); - if (toplevel != NULL) - { - GtkWindowGroup *wg; + if (toplevel != NULL) + { + GtkWindowGroup *wg; - gtk_window_set_transient_for (GTK_WINDOW (dialog), - GTK_WINDOW (toplevel)); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel)); - wg = gtk_window_get_group (GTK_WINDOW (toplevel)); - if (wg == NULL) - { - wg = gtk_window_group_new (); - gtk_window_group_add_window (wg, - GTK_WINDOW (toplevel)); - } + wg = gtk_window_get_group (GTK_WINDOW (toplevel)); + if (wg == NULL) + { + wg = gtk_window_group_new (); + gtk_window_group_add_window (wg, GTK_WINDOW (toplevel)); + } - gtk_window_group_add_window (wg, - GTK_WINDOW (dialog)); - } + gtk_window_group_add_window (wg, GTK_WINDOW (dialog)); + } - gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); - g_signal_connect (dialog, - "response", - G_CALLBACK (dialog_response_cb), - menu); + g_signal_connect (dialog, "response", G_CALLBACK (dialog_response_cb), menu); - gtk_widget_show (dialog); - } + gtk_widget_show (dialog); + } } static gboolean -separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) +separator_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) { - gchar *str; - gboolean ret; + gchar *str; + gboolean ret; - gtk_tree_model_get (model, iter, NAME_COLUMN, &str, -1); - ret = (str == NULL || *str == '\0'); - g_free (str); + gtk_tree_model_get (model, iter, NAME_COLUMN, &str, -1); + ret = (str == NULL || *str == '\0'); + g_free (str); - return ret; + return ret; } static void update_menu (XedEncodingsComboBox *menu) { - GtkListStore *store; - GtkTreeIter iter; - GSList *encodings, *l; - gchar *str; - const XedEncoding *utf8_encoding; - const XedEncoding *current_encoding; + GtkListStore *store; + GtkTreeIter iter; + GSList *encodings, *l; + gchar *str; + const GtkSourceEncoding *utf8_encoding; + const GtkSourceEncoding *current_encoding; + gchar **enc_strv; - store = menu->priv->store; + store = menu->priv->store; - /* Unset the previous model */ - g_signal_handler_block (menu, menu->priv->changed_id); - gtk_list_store_clear (store); - gtk_combo_box_set_model (GTK_COMBO_BOX (menu), - NULL); + /* Unset the previous model */ + g_signal_handler_block (menu, menu->priv->changed_id); + gtk_list_store_clear (store); + gtk_combo_box_set_model (GTK_COMBO_BOX (menu), NULL); - utf8_encoding = xed_encoding_get_utf8 (); - current_encoding = xed_encoding_get_current (); + utf8_encoding = gtk_source_encoding_get_utf8 (); + current_encoding = gtk_source_encoding_get_current (); - if (!menu->priv->save_mode) - { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - NAME_COLUMN, _("Automatically Detected"), - ENCODING_COLUMN, NULL, - ADD_COLUMN, FALSE, - -1); + if (!menu->priv->save_mode) + { + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + NAME_COLUMN, _("Automatically Detected"), + ENCODING_COLUMN, NULL, + ADD_COLUMN, FALSE, + -1); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - NAME_COLUMN, "", - ENCODING_COLUMN, NULL, - ADD_COLUMN, FALSE, - -1); - } + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + NAME_COLUMN, "", + ENCODING_COLUMN, NULL, + ADD_COLUMN, FALSE, + -1); + } - if (current_encoding != utf8_encoding) - str = xed_encoding_to_string (utf8_encoding); - else - str = g_strdup_printf (_("Current Locale (%s)"), - xed_encoding_get_charset (utf8_encoding)); + if (current_encoding != utf8_encoding) + { + str = gtk_source_encoding_to_string (utf8_encoding); + } + else + { + str = g_strdup_printf (_("Current Locale (%s)"), gtk_source_encoding_get_charset (utf8_encoding)); + } - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - NAME_COLUMN, str, - ENCODING_COLUMN, utf8_encoding, - ADD_COLUMN, FALSE, - -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + NAME_COLUMN, str, + ENCODING_COLUMN, utf8_encoding, + ADD_COLUMN, FALSE, + -1); - g_free (str); + g_free (str); - if ((utf8_encoding != current_encoding) && - (current_encoding != NULL)) - { - str = g_strdup_printf (_("Current Locale (%s)"), - xed_encoding_get_charset (current_encoding)); + if ((utf8_encoding != current_encoding) && (current_encoding != NULL)) + { + str = g_strdup_printf (_("Current Locale (%s)"), gtk_source_encoding_get_charset (current_encoding)); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - NAME_COLUMN, str, - ENCODING_COLUMN, current_encoding, - ADD_COLUMN, FALSE, - -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + NAME_COLUMN, str, + ENCODING_COLUMN, current_encoding, + ADD_COLUMN, FALSE, + -1); - g_free (str); - } + g_free (str); + } - encodings = xed_prefs_manager_get_shown_in_menu_encodings (); + enc_strv = g_settings_get_strv (menu->priv->enc_settings, XED_SETTINGS_ENCODING_SHOWN_IN_MENU); + encodings = _xed_utils_encoding_strv_to_list ((const gchar * const *)enc_strv); + g_strfreev (enc_strv); - for (l = encodings; l != NULL; l = g_slist_next (l)) - { - const XedEncoding *enc = (const XedEncoding *)l->data; + for (l = encodings; l != NULL; l = g_slist_next (l)) + { + const GtkSourceEncoding *enc = l->data; - if ((enc != current_encoding) && - (enc != utf8_encoding) && - (enc != NULL)) - { - str = xed_encoding_to_string (enc); + if ((enc != current_encoding) && (enc != utf8_encoding) && (enc != NULL)) + { + str = gtk_source_encoding_to_string (enc); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - NAME_COLUMN, str, - ENCODING_COLUMN, enc, - ADD_COLUMN, FALSE, - -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + NAME_COLUMN, str, + ENCODING_COLUMN, enc, + ADD_COLUMN, FALSE, + -1); - g_free (str); - } - } + g_free (str); + } + } - g_slist_free (encodings); + g_slist_free (encodings); - if (xed_prefs_manager_shown_in_menu_encodings_can_set ()) - { - gtk_list_store_append (store, &iter); - /* separator */ - gtk_list_store_set (store, &iter, - NAME_COLUMN, "", - ENCODING_COLUMN, NULL, - ADD_COLUMN, FALSE, - -1); + gtk_list_store_append (store, &iter); + /* Separator */ + gtk_list_store_set (store, &iter, + NAME_COLUMN, "", + ENCODING_COLUMN, NULL, + ADD_COLUMN, FALSE, + -1); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - NAME_COLUMN, _("Add or Remove..."), - ENCODING_COLUMN, NULL, - ADD_COLUMN, TRUE, - -1); - } + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + NAME_COLUMN, _("Add or Remove..."), + ENCODING_COLUMN, NULL, + ADD_COLUMN, TRUE, + -1); - /* set the model back */ - gtk_combo_box_set_model (GTK_COMBO_BOX (menu), - GTK_TREE_MODEL (menu->priv->store)); - gtk_combo_box_set_active (GTK_COMBO_BOX (menu), 0); + /* set the model back */ + gtk_combo_box_set_model (GTK_COMBO_BOX (menu), GTK_TREE_MODEL (menu->priv->store)); + gtk_combo_box_set_active (GTK_COMBO_BOX (menu), 0); - g_signal_handler_unblock (menu, menu->priv->changed_id); + g_signal_handler_unblock (menu, menu->priv->changed_id); } static void xed_encodings_combo_box_init (XedEncodingsComboBox *menu) { - GtkCellRenderer *text_renderer; + GtkCellRenderer *text_renderer; - menu->priv = XED_ENCODINGS_COMBO_BOX_GET_PRIVATE (menu); + menu->priv = XED_ENCODINGS_COMBO_BOX_GET_PRIVATE (menu); - menu->priv->store = gtk_list_store_new (N_COLUMNS, - G_TYPE_STRING, - G_TYPE_POINTER, - G_TYPE_BOOLEAN); + menu->priv->enc_settings = g_settings_new ("org.x.editor.preferences.encodings"); + menu->priv->store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN); - /* Setup up the cells */ - text_renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (menu), - text_renderer, TRUE); + /* Setup up the cells */ + text_renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (menu), text_renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (menu), - text_renderer, - "text", - NAME_COLUMN, - NULL); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (menu), + text_renderer, + "text", + NAME_COLUMN, + NULL); - gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (menu), - separator_func, NULL, - NULL); + gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (menu), separator_func, NULL, NULL); - menu->priv->changed_id = g_signal_connect (menu, "changed", - G_CALLBACK (add_or_remove), - menu->priv->store); + menu->priv->changed_id = g_signal_connect (menu, "changed", G_CALLBACK (add_or_remove), menu->priv->store); - update_menu (menu); + update_menu (menu); } GtkWidget * xed_encodings_combo_box_new (gboolean save_mode) { - return g_object_new (XED_TYPE_ENCODINGS_COMBO_BOX, - "save_mode", save_mode, - NULL); + return g_object_new (XED_TYPE_ENCODINGS_COMBO_BOX, + "save_mode", save_mode, + NULL); } -const XedEncoding * +const GtkSourceEncoding * xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu) { - GtkTreeIter iter; + GtkTreeIter iter; - g_return_val_if_fail (XED_IS_ENCODINGS_COMBO_BOX (menu), NULL); + g_return_val_if_fail (XED_IS_ENCODINGS_COMBO_BOX (menu), NULL); - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (menu), &iter)) - { - const XedEncoding *ret; - GtkTreeModel *model; + if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (menu), &iter)) + { + const GtkSourceEncoding *ret; + GtkTreeModel *model; - model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu)); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu)); - gtk_tree_model_get (model, &iter, - ENCODING_COLUMN, &ret, - -1); + gtk_tree_model_get (model, &iter, ENCODING_COLUMN, &ret, -1); - return ret; - } + return ret; + } - return NULL; + return NULL; } /** @@ -436,34 +422,31 @@ xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu) * @encoding: (allow-none): **/ void -xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu, - const XedEncoding *encoding) +xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu, + const GtkSourceEncoding *encoding) { - GtkTreeIter iter; - GtkTreeModel *model; - gboolean b; - g_return_if_fail (XED_IS_ENCODINGS_COMBO_BOX (menu)); - g_return_if_fail (GTK_IS_COMBO_BOX (menu)); + GtkTreeIter iter; + GtkTreeModel *model; + gboolean b; + g_return_if_fail (XED_IS_ENCODINGS_COMBO_BOX (menu)); + g_return_if_fail (GTK_IS_COMBO_BOX (menu)); - model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu)); - b = gtk_tree_model_get_iter_first (model, &iter); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu)); + b = gtk_tree_model_get_iter_first (model, &iter); - while (b) - { - const XedEncoding *enc; + while (b) + { + const GtkSourceEncoding *enc; - gtk_tree_model_get (model, &iter, - ENCODING_COLUMN, &enc, - -1); + gtk_tree_model_get (model, &iter, ENCODING_COLUMN, &enc, -1); - if (enc == encoding) - { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (menu), - &iter); + if (enc == encoding) + { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (menu), &iter); - return; - } + return; + } - b = gtk_tree_model_iter_next (model, &iter); - } + b = gtk_tree_model_iter_next (model, &iter); + } } diff --git a/xed/xed-encodings-combo-box.h b/xed/xed-encodings-combo-box.h index b197008..556dc44 100644 --- a/xed/xed-encodings-combo-box.h +++ b/xed/xed-encodings-combo-box.h @@ -17,14 +17,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2003-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2003-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id: xed-encodings-option-menu.h 4429 2005-12-12 17:28:04Z pborelli $ */ @@ -33,7 +33,6 @@ #define __XED_ENCODINGS_COMBO_BOX_H__ #include -#include G_BEGIN_DECLS @@ -45,31 +44,30 @@ G_BEGIN_DECLS #define XED_ENCODINGS_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_ENCODINGS_COMBO_BOX, XedEncodingsComboBoxClass)) -typedef struct _XedEncodingsComboBox XedEncodingsComboBox; -typedef struct _XedEncodingsComboBoxClass XedEncodingsComboBoxClass; - -typedef struct _XedEncodingsComboBoxPrivate XedEncodingsComboBoxPrivate; +typedef struct _XedEncodingsComboBox XedEncodingsComboBox; +typedef struct _XedEncodingsComboBoxClass XedEncodingsComboBoxClass; +typedef struct _XedEncodingsComboBoxPrivate XedEncodingsComboBoxPrivate; struct _XedEncodingsComboBox { - GtkComboBox parent; + GtkComboBox parent; - XedEncodingsComboBoxPrivate *priv; + XedEncodingsComboBoxPrivate *priv; }; struct _XedEncodingsComboBoxClass { - GtkComboBoxClass parent_class; + GtkComboBoxClass parent_class; }; -GType xed_encodings_combo_box_get_type (void) G_GNUC_CONST; +GType xed_encodings_combo_box_get_type (void) G_GNUC_CONST; /* Constructor */ -GtkWidget *xed_encodings_combo_box_new (gboolean save_mode); +GtkWidget *xed_encodings_combo_box_new (gboolean save_mode); -const XedEncoding *xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu); -void xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu, - const XedEncoding *encoding); +const GtkSourceEncoding *xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu); +void xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu, + const GtkSourceEncoding *encoding); G_END_DECLS diff --git a/xed/xed-encodings-dialog.c b/xed/xed-encodings-dialog.c new file mode 100755 index 0000000..babc2f0 --- /dev/null +++ b/xed/xed-encodings-dialog.c @@ -0,0 +1,459 @@ +/* + * xed-encodings-dialog.c + * This file is part of xed + * + * Copyright (C) 2002-2005 Paolo Maggi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* + * Modified by the xed Team, 2002-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#include "xed-encodings-dialog.h" +#include "xed-utils.h" +#include "xed-debug.h" +#include "xed-dirs.h" +#include "xed-settings.h" + +#define XED_ENCODINGS_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ + XED_TYPE_ENCODINGS_DIALOG, \ + XedEncodingsDialogPrivate)) + +struct _XedEncodingsDialogPrivate +{ + GSettings *enc_settings; + + GtkListStore *available_liststore; + GtkListStore *displayed_liststore; + + GtkWidget *available_treeview; + GtkWidget *displayed_treeview; + GtkWidget *add_button; + GtkWidget *remove_button; + + GSList *show_in_menu_list; +}; + +G_DEFINE_TYPE(XedEncodingsDialog, xed_encodings_dialog, GTK_TYPE_DIALOG) + +static void +xed_encodings_dialog_finalize (GObject *object) +{ + XedEncodingsDialogPrivate *priv = XED_ENCODINGS_DIALOG (object)->priv; + + g_slist_free (priv->show_in_menu_list); + + G_OBJECT_CLASS (xed_encodings_dialog_parent_class)->finalize (object); +} + +static void +xed_encodings_dialog_dispose (GObject *object) +{ + XedEncodingsDialogPrivate *priv = XED_ENCODINGS_DIALOG (object)->priv; + + g_clear_object (&priv->enc_settings); + + G_OBJECT_CLASS (xed_encodings_dialog_parent_class)->dispose (object); +} + +static void +xed_encodings_dialog_class_init (XedEncodingsDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = xed_encodings_dialog_finalize; + object_class->dispose = xed_encodings_dialog_dispose; + + g_type_class_add_private (object_class, sizeof (XedEncodingsDialogPrivate)); +} + +enum +{ + COLUMN_NAME, + COLUMN_CHARSET, + N_COLUMNS +}; + +static void +count_selected_items_func (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + int *count = data; + + *count += 1; +} + +static void +available_selection_changed_callback (GtkTreeSelection *selection, + XedEncodingsDialog *dialogs) +{ + int count; + + count = 0; + gtk_tree_selection_selected_foreach (selection, count_selected_items_func, &count); + + gtk_widget_set_sensitive (dialogs->priv->add_button, count > 0); +} + +static void +displayed_selection_changed_callback (GtkTreeSelection *selection, + XedEncodingsDialog *dialogs) +{ + int count; + + count = 0; + gtk_tree_selection_selected_foreach (selection, count_selected_items_func, &count); + + gtk_widget_set_sensitive (dialogs->priv->remove_button, count > 0); +} + +static void +get_selected_encodings_func (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + GSList **list = data; + gchar *charset; + const GtkSourceEncoding *enc; + + charset = NULL; + gtk_tree_model_get (model, iter, COLUMN_CHARSET, &charset, -1); + + enc = gtk_source_encoding_get_from_charset (charset); + g_free (charset); + + *list = g_slist_prepend (*list, (gpointer)enc); +} + +static void +update_shown_in_menu_tree_model (GtkListStore *store, + GSList *list) +{ + GtkTreeIter iter; + + gtk_list_store_clear (store); + + while (list != NULL) + { + const GtkSourceEncoding *enc; + + enc = list->data; + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + COLUMN_CHARSET, gtk_source_encoding_get_charset (enc), + COLUMN_NAME, gtk_source_encoding_get_name (enc), + -1); + + list = g_slist_next (list); + } +} + +static void +add_button_clicked_callback (GtkWidget *button, + XedEncodingsDialog *dialog) +{ + GtkTreeSelection *selection; + GSList *encodings; + GSList *tmp; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->available_treeview)); + + encodings = NULL; + gtk_tree_selection_selected_foreach (selection, get_selected_encodings_func, &encodings); + + tmp = encodings; + while (tmp != NULL) + { + if (g_slist_find (dialog->priv->show_in_menu_list, tmp->data) == NULL) + dialog->priv->show_in_menu_list = g_slist_prepend (dialog->priv->show_in_menu_list, tmp->data); + + tmp = g_slist_next (tmp); + } + + g_slist_free (encodings); + + update_shown_in_menu_tree_model (GTK_LIST_STORE (dialog->priv->displayed_liststore), + dialog->priv->show_in_menu_list); +} + +static void +remove_button_clicked_callback (GtkWidget *button, + XedEncodingsDialog *dialog) +{ + GtkTreeSelection *selection; + GSList *encodings; + GSList *tmp; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->displayed_treeview)); + + encodings = NULL; + gtk_tree_selection_selected_foreach (selection, get_selected_encodings_func, &encodings); + + tmp = encodings; + while (tmp != NULL) + { + dialog->priv->show_in_menu_list = g_slist_remove (dialog->priv->show_in_menu_list, tmp->data); + + tmp = g_slist_next (tmp); + } + + g_slist_free (encodings); + + update_shown_in_menu_tree_model (GTK_LIST_STORE (dialog->priv->displayed_liststore), + dialog->priv->show_in_menu_list); +} + +static void +init_shown_in_menu_tree_model (XedEncodingsDialog *dialog) +{ + GtkTreeIter iter; + gchar **enc_strv; + GSList *list, *tmp; + + /* add data to the list store */ + enc_strv = g_settings_get_strv (dialog->priv->enc_settings, XED_SETTINGS_ENCODING_SHOWN_IN_MENU); + + list = _xed_utils_encoding_strv_to_list ((const gchar * const *)enc_strv); + + for (tmp = list; tmp != NULL; tmp = g_slist_next (tmp)) + { + const GtkSourceEncoding *enc = tmp->data; + + dialog->priv->show_in_menu_list = g_slist_prepend (dialog->priv->show_in_menu_list, tmp->data); + + gtk_list_store_append (dialog->priv->displayed_liststore, &iter); + gtk_list_store_set (dialog->priv->displayed_liststore, &iter, + COLUMN_CHARSET, gtk_source_encoding_get_charset (enc), + COLUMN_NAME, gtk_source_encoding_get_name (enc), + -1); + } + + g_slist_free (list); +} + +static void +response_handler (GtkDialog *dialog, + gint response_id, + XedEncodingsDialog *dlg) +{ + if (response_id == GTK_RESPONSE_HELP) + { + xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dialog), "xed", NULL); + g_signal_stop_emission_by_name (dialog, "response"); + return; + } + + if (response_id == GTK_RESPONSE_OK) + { + gchar **encs; + + encs = _xed_utils_encoding_list_to_strv (dlg->priv->show_in_menu_list); + g_settings_set_strv (dlg->priv->enc_settings, + XED_SETTINGS_ENCODING_SHOWN_IN_MENU, + (const gchar * const *)encs); + + g_strfreev (encs); + } +} + +static void +init_liststore_available (XedEncodingsDialog *dialog) +{ + GSList *all_encodings; + GSList *l; + + all_encodings = gtk_source_encoding_get_all (); + + for (l = all_encodings; l != NULL; l = l->next) + { + const GtkSourceEncoding *encoding = l->data; + GtkTreeIter iter; + + if (encoding == gtk_source_encoding_get_utf8 ()) + { + /* The UTF-8 encoding is always added to the combobox. */ + continue; + } + + gtk_list_store_append (dialog->priv->available_liststore, &iter); + + gtk_list_store_set (dialog->priv->available_liststore, + &iter, + COLUMN_CHARSET, gtk_source_encoding_get_charset (encoding), + COLUMN_NAME, gtk_source_encoding_get_name (encoding), + -1); + } + + g_slist_free (all_encodings); +} + +static void +xed_encodings_dialog_init (XedEncodingsDialog *dlg) +{ + GtkBuilder *builder; + GtkWidget *content; + GtkCellRenderer *cell_renderer; + GtkTreeModel *sort_model; + GtkTreeViewColumn *column; + GtkTreeSelection *selection; + gchar *root_objects[] = { + "encodings-dialog-contents", + NULL + }; + + dlg->priv = XED_ENCODINGS_DIALOG_GET_PRIVATE (dlg); + dlg->priv->enc_settings = g_settings_new ("org.x.editor.preferences.encodings"); + + gtk_dialog_add_buttons (GTK_DIALOG (dlg), + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_OK"), GTK_RESPONSE_OK, + _("_Help"), GTK_RESPONSE_HELP, + NULL); + + gtk_window_set_title (GTK_WINDOW (dlg), _("Character Encodings")); + gtk_window_set_default_size (GTK_WINDOW (dlg), 650, 400); + + /* HIG defaults */ + gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), 2); /* 2 * 5 + 2 = 12 */ + + gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK); + + g_signal_connect (dlg, "response", G_CALLBACK (response_handler), dlg); + + builder = gtk_builder_new (); + gtk_builder_add_objects_from_resource (builder, "/org/x/editor/ui/xed-encodings-dialog.ui", + root_objects, NULL); + content = GTK_WIDGET (gtk_builder_get_object (builder, "encodings-dialog-contents")); + g_object_ref (content); + dlg->priv->add_button = GTK_WIDGET (gtk_builder_get_object (builder, "add-button")); + dlg->priv->remove_button = GTK_WIDGET (gtk_builder_get_object (builder, "remove-button")); + dlg->priv->available_treeview = GTK_WIDGET (gtk_builder_get_object (builder, "available-treeview")); + dlg->priv->displayed_treeview = GTK_WIDGET (gtk_builder_get_object (builder, "displayed-treeview")); + g_object_unref (builder); + + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), content, TRUE, TRUE, 0); + g_object_unref (content); + gtk_container_set_border_width (GTK_CONTAINER (content), 5); + + g_signal_connect (dlg->priv->add_button, "clicked", G_CALLBACK (add_button_clicked_callback), dlg); + g_signal_connect (dlg->priv->remove_button, "clicked", G_CALLBACK (remove_button_clicked_callback), dlg); + + /* Tree view of available encodings */ + dlg->priv->available_liststore = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING); + + cell_renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("_Description"), + cell_renderer, + "text", COLUMN_NAME, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->available_treeview), column); + gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME); + + cell_renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("_Encoding"), + cell_renderer, + "text", + COLUMN_CHARSET, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->available_treeview), column); + gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET); + + /* Add the data */ + init_liststore_available (dlg); + + /* Sort model */ + sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->available_liststore)); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), COLUMN_NAME, GTK_SORT_ASCENDING); + + gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->available_treeview), sort_model); + g_object_unref (G_OBJECT (dlg->priv->available_liststore)); + g_object_unref (G_OBJECT (sort_model)); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->available_treeview)); + gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), GTK_SELECTION_MULTIPLE); + + available_selection_changed_callback (selection, dlg); + g_signal_connect (selection, "changed", G_CALLBACK (available_selection_changed_callback), dlg); + + /* Tree view of selected encodings */ + dlg->priv->displayed_liststore = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING); + + cell_renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("_Description"), + cell_renderer, + "text", COLUMN_NAME, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->displayed_treeview), column); + gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME); + + cell_renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("_Encoding"), + cell_renderer, + "text", + COLUMN_CHARSET, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->displayed_treeview), column); + gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET); + + /* Add the data */ + init_shown_in_menu_tree_model (dlg); + + /* Sort model */ + sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->displayed_liststore)); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), COLUMN_NAME, GTK_SORT_ASCENDING); + + gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->displayed_treeview), sort_model); + g_object_unref (G_OBJECT (sort_model)); + g_object_unref (G_OBJECT (dlg->priv->displayed_liststore)); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->displayed_treeview)); + gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), GTK_SELECTION_MULTIPLE); + + displayed_selection_changed_callback (selection, dlg); + g_signal_connect (selection, "changed", G_CALLBACK (displayed_selection_changed_callback), dlg); +} + +GtkWidget * +xed_encodings_dialog_new (void) +{ + GtkWidget *dlg; + + dlg = GTK_WIDGET (g_object_new (XED_TYPE_ENCODINGS_DIALOG, NULL)); + + return dlg; +} + diff --git a/xed/dialogs/xed-encodings-dialog.h b/xed/xed-encodings-dialog.h similarity index 100% rename from xed/dialogs/xed-encodings-dialog.h rename to xed/xed-encodings-dialog.h diff --git a/xed/xed-encodings.c b/xed/xed-encodings.c deleted file mode 100644 index d829578..0000000 --- a/xed/xed-encodings.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * xed-encodings.c - * This file is part of xed - * - * Copyright (C) 2002-2005 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include "xed-encodings.h" - - -struct _XedEncoding -{ - gint index; - const gchar *charset; - const gchar *name; -}; - -/* - * The original versions of the following tables are taken from profterm - * - * Copyright (C) 2002 Red Hat, Inc. - */ - -typedef enum -{ - - XED_ENCODING_ISO_8859_1, - XED_ENCODING_ISO_8859_2, - XED_ENCODING_ISO_8859_3, - XED_ENCODING_ISO_8859_4, - XED_ENCODING_ISO_8859_5, - XED_ENCODING_ISO_8859_6, - XED_ENCODING_ISO_8859_7, - XED_ENCODING_ISO_8859_8, - XED_ENCODING_ISO_8859_9, - XED_ENCODING_ISO_8859_10, - XED_ENCODING_ISO_8859_13, - XED_ENCODING_ISO_8859_14, - XED_ENCODING_ISO_8859_15, - XED_ENCODING_ISO_8859_16, - - XED_ENCODING_UTF_7, - XED_ENCODING_UTF_16, - XED_ENCODING_UTF_16_BE, - XED_ENCODING_UTF_16_LE, - XED_ENCODING_UTF_32, - XED_ENCODING_UCS_2, - XED_ENCODING_UCS_4, - - XED_ENCODING_ARMSCII_8, - XED_ENCODING_BIG5, - XED_ENCODING_BIG5_HKSCS, - XED_ENCODING_CP_866, - - XED_ENCODING_EUC_JP, - XED_ENCODING_EUC_JP_MS, - XED_ENCODING_CP932, - XED_ENCODING_EUC_KR, - XED_ENCODING_EUC_TW, - - XED_ENCODING_GB18030, - XED_ENCODING_GB2312, - XED_ENCODING_GBK, - XED_ENCODING_GEOSTD8, - - XED_ENCODING_IBM_850, - XED_ENCODING_IBM_852, - XED_ENCODING_IBM_855, - XED_ENCODING_IBM_857, - XED_ENCODING_IBM_862, - XED_ENCODING_IBM_864, - - XED_ENCODING_ISO_2022_JP, - XED_ENCODING_ISO_2022_KR, - XED_ENCODING_ISO_IR_111, - XED_ENCODING_JOHAB, - XED_ENCODING_KOI8_R, - XED_ENCODING_KOI8__R, - XED_ENCODING_KOI8_U, - - XED_ENCODING_SHIFT_JIS, - XED_ENCODING_TCVN, - XED_ENCODING_TIS_620, - XED_ENCODING_UHC, - XED_ENCODING_VISCII, - - XED_ENCODING_WINDOWS_1250, - XED_ENCODING_WINDOWS_1251, - XED_ENCODING_WINDOWS_1252, - XED_ENCODING_WINDOWS_1253, - XED_ENCODING_WINDOWS_1254, - XED_ENCODING_WINDOWS_1255, - XED_ENCODING_WINDOWS_1256, - XED_ENCODING_WINDOWS_1257, - XED_ENCODING_WINDOWS_1258, - - XED_ENCODING_LAST, - - XED_ENCODING_UTF_8, - XED_ENCODING_UNKNOWN - -} XedEncodingIndex; - -static const XedEncoding utf8_encoding = { - XED_ENCODING_UTF_8, - "UTF-8", - N_("Unicode") -}; - -/* initialized in xed_encoding_lazy_init() */ -static XedEncoding unknown_encoding = { - XED_ENCODING_UNKNOWN, - NULL, - NULL -}; - -static const XedEncoding encodings [] = { - - { XED_ENCODING_ISO_8859_1, - "ISO-8859-1", N_("Western") }, - { XED_ENCODING_ISO_8859_2, - "ISO-8859-2", N_("Central European") }, - { XED_ENCODING_ISO_8859_3, - "ISO-8859-3", N_("South European") }, - { XED_ENCODING_ISO_8859_4, - "ISO-8859-4", N_("Baltic") }, - { XED_ENCODING_ISO_8859_5, - "ISO-8859-5", N_("Cyrillic") }, - { XED_ENCODING_ISO_8859_6, - "ISO-8859-6", N_("Arabic") }, - { XED_ENCODING_ISO_8859_7, - "ISO-8859-7", N_("Greek") }, - { XED_ENCODING_ISO_8859_8, - "ISO-8859-8", N_("Hebrew Visual") }, - { XED_ENCODING_ISO_8859_9, - "ISO-8859-9", N_("Turkish") }, - { XED_ENCODING_ISO_8859_10, - "ISO-8859-10", N_("Nordic") }, - { XED_ENCODING_ISO_8859_13, - "ISO-8859-13", N_("Baltic") }, - { XED_ENCODING_ISO_8859_14, - "ISO-8859-14", N_("Celtic") }, - { XED_ENCODING_ISO_8859_15, - "ISO-8859-15", N_("Western") }, - { XED_ENCODING_ISO_8859_16, - "ISO-8859-16", N_("Romanian") }, - - { XED_ENCODING_UTF_7, - "UTF-7", N_("Unicode") }, - { XED_ENCODING_UTF_16, - "UTF-16", N_("Unicode") }, - { XED_ENCODING_UTF_16_BE, - "UTF-16BE", N_("Unicode") }, - { XED_ENCODING_UTF_16_LE, - "UTF-16LE", N_("Unicode") }, - { XED_ENCODING_UTF_32, - "UTF-32", N_("Unicode") }, - { XED_ENCODING_UCS_2, - "UCS-2", N_("Unicode") }, - { XED_ENCODING_UCS_4, - "UCS-4", N_("Unicode") }, - - { XED_ENCODING_ARMSCII_8, - "ARMSCII-8", N_("Armenian") }, - { XED_ENCODING_BIG5, - "BIG5", N_("Chinese Traditional") }, - { XED_ENCODING_BIG5_HKSCS, - "BIG5-HKSCS", N_("Chinese Traditional") }, - { XED_ENCODING_CP_866, - "CP866", N_("Cyrillic/Russian") }, - - { XED_ENCODING_EUC_JP, - "EUC-JP", N_("Japanese") }, - { XED_ENCODING_EUC_JP_MS, - "EUC-JP-MS", N_("Japanese") }, - { XED_ENCODING_CP932, - "CP932", N_("Japanese") }, - - { XED_ENCODING_EUC_KR, - "EUC-KR", N_("Korean") }, - { XED_ENCODING_EUC_TW, - "EUC-TW", N_("Chinese Traditional") }, - - { XED_ENCODING_GB18030, - "GB18030", N_("Chinese Simplified") }, - { XED_ENCODING_GB2312, - "GB2312", N_("Chinese Simplified") }, - { XED_ENCODING_GBK, - "GBK", N_("Chinese Simplified") }, - { XED_ENCODING_GEOSTD8, - "GEORGIAN-ACADEMY", N_("Georgian") }, /* FIXME GEOSTD8 ? */ - - { XED_ENCODING_IBM_850, - "IBM850", N_("Western") }, - { XED_ENCODING_IBM_852, - "IBM852", N_("Central European") }, - { XED_ENCODING_IBM_855, - "IBM855", N_("Cyrillic") }, - { XED_ENCODING_IBM_857, - "IBM857", N_("Turkish") }, - { XED_ENCODING_IBM_862, - "IBM862", N_("Hebrew") }, - { XED_ENCODING_IBM_864, - "IBM864", N_("Arabic") }, - - { XED_ENCODING_ISO_2022_JP, - "ISO-2022-JP", N_("Japanese") }, - { XED_ENCODING_ISO_2022_KR, - "ISO-2022-KR", N_("Korean") }, - { XED_ENCODING_ISO_IR_111, - "ISO-IR-111", N_("Cyrillic") }, - { XED_ENCODING_JOHAB, - "JOHAB", N_("Korean") }, - { XED_ENCODING_KOI8_R, - "KOI8R", N_("Cyrillic") }, - { XED_ENCODING_KOI8__R, - "KOI8-R", N_("Cyrillic") }, - { XED_ENCODING_KOI8_U, - "KOI8U", N_("Cyrillic/Ukrainian") }, - - { XED_ENCODING_SHIFT_JIS, - "SHIFT_JIS", N_("Japanese") }, - { XED_ENCODING_TCVN, - "TCVN", N_("Vietnamese") }, - { XED_ENCODING_TIS_620, - "TIS-620", N_("Thai") }, - { XED_ENCODING_UHC, - "UHC", N_("Korean") }, - { XED_ENCODING_VISCII, - "VISCII", N_("Vietnamese") }, - - { XED_ENCODING_WINDOWS_1250, - "WINDOWS-1250", N_("Central European") }, - { XED_ENCODING_WINDOWS_1251, - "WINDOWS-1251", N_("Cyrillic") }, - { XED_ENCODING_WINDOWS_1252, - "WINDOWS-1252", N_("Western") }, - { XED_ENCODING_WINDOWS_1253, - "WINDOWS-1253", N_("Greek") }, - { XED_ENCODING_WINDOWS_1254, - "WINDOWS-1254", N_("Turkish") }, - { XED_ENCODING_WINDOWS_1255, - "WINDOWS-1255", N_("Hebrew") }, - { XED_ENCODING_WINDOWS_1256, - "WINDOWS-1256", N_("Arabic") }, - { XED_ENCODING_WINDOWS_1257, - "WINDOWS-1257", N_("Baltic") }, - { XED_ENCODING_WINDOWS_1258, - "WINDOWS-1258", N_("Vietnamese") } -}; - -static void -xed_encoding_lazy_init (void) -{ - static gboolean initialized = FALSE; - const gchar *locale_charset; - - if (initialized) - return; - - if (g_get_charset (&locale_charset) == FALSE) - { - unknown_encoding.charset = g_strdup (locale_charset); - } - - initialized = TRUE; -} - -const XedEncoding * -xed_encoding_get_from_charset (const gchar *charset) -{ - gint i; - - g_return_val_if_fail (charset != NULL, NULL); - - xed_encoding_lazy_init (); - - if (charset == NULL) - return NULL; - - if (g_ascii_strcasecmp (charset, "UTF-8") == 0) - return xed_encoding_get_utf8 (); - - i = 0; - while (i < XED_ENCODING_LAST) - { - if (g_ascii_strcasecmp (charset, encodings[i].charset) == 0) - return &encodings[i]; - - ++i; - } - - if (unknown_encoding.charset != NULL) - { - if (g_ascii_strcasecmp (charset, unknown_encoding.charset) == 0) - return &unknown_encoding; - } - - return NULL; -} - -const XedEncoding * -xed_encoding_get_from_index (gint idx) -{ - g_return_val_if_fail (idx >= 0, NULL); - - if (idx >= XED_ENCODING_LAST) - return NULL; - - xed_encoding_lazy_init (); - - return &encodings[idx]; -} - -const XedEncoding * -xed_encoding_get_utf8 (void) -{ - xed_encoding_lazy_init (); - - return &utf8_encoding; -} - -const XedEncoding * -xed_encoding_get_current (void) -{ - static gboolean initialized = FALSE; - static const XedEncoding *locale_encoding = NULL; - - const gchar *locale_charset; - - xed_encoding_lazy_init (); - - if (initialized != FALSE) - return locale_encoding; - - if (g_get_charset (&locale_charset) == FALSE) - { - g_return_val_if_fail (locale_charset != NULL, &utf8_encoding); - - locale_encoding = xed_encoding_get_from_charset (locale_charset); - } - else - { - locale_encoding = &utf8_encoding; - } - - if (locale_encoding == NULL) - { - locale_encoding = &unknown_encoding; - } - - g_return_val_if_fail (locale_encoding != NULL, NULL); - - initialized = TRUE; - - return locale_encoding; -} - -gchar * -xed_encoding_to_string (const XedEncoding* enc) -{ - g_return_val_if_fail (enc != NULL, NULL); - - xed_encoding_lazy_init (); - - g_return_val_if_fail (enc->charset != NULL, NULL); - - if (enc->name != NULL) - { - return g_strdup_printf ("%s (%s)", _(enc->name), enc->charset); - } - else - { - if (g_ascii_strcasecmp (enc->charset, "ANSI_X3.4-1968") == 0) - return g_strdup_printf ("US-ASCII (%s)", enc->charset); - else - return g_strdup (enc->charset); - } -} - -const gchar * -xed_encoding_get_charset (const XedEncoding* enc) -{ - g_return_val_if_fail (enc != NULL, NULL); - - xed_encoding_lazy_init (); - - g_return_val_if_fail (enc->charset != NULL, NULL); - - return enc->charset; -} - -const gchar * -xed_encoding_get_name (const XedEncoding* enc) -{ - g_return_val_if_fail (enc != NULL, NULL); - - xed_encoding_lazy_init (); - - return (enc->name == NULL) ? _("Unknown") : _(enc->name); -} - -/* These are to make language bindings happy. Since Encodings are - * const, copy() just returns the same pointer and fres() doesn't - * do nothing */ - -XedEncoding * -xed_encoding_copy (const XedEncoding *enc) -{ - g_return_val_if_fail (enc != NULL, NULL); - - return (XedEncoding *) enc; -} - -void -xed_encoding_free (XedEncoding *enc) -{ - g_return_if_fail (enc != NULL); -} - -/** - * xed_encoding_get_type: - * - * Retrieves the GType object which is associated with the - * #XedEncoding class. - * - * Return value: the GType associated with #XedEncoding. - **/ -GType -xed_encoding_get_type (void) -{ - static GType our_type = 0; - - if (!our_type) - our_type = g_boxed_type_register_static ( - "XedEncoding", - (GBoxedCopyFunc) xed_encoding_copy, - (GBoxedFreeFunc) xed_encoding_free); - - return our_type; -} - diff --git a/xed/xed-encodings.h b/xed/xed-encodings.h deleted file mode 100644 index eb890eb..0000000 --- a/xed/xed-encodings.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * xed-encodings.h - * This file is part of xed - * - * Copyright (C) 2002-2005 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_ENCODINGS_H__ -#define __XED_ENCODINGS_H__ - -#include -#include - -G_BEGIN_DECLS - -typedef struct _XedEncoding XedEncoding; - -#define XED_TYPE_ENCODING (xed_encoding_get_type ()) - -GType xed_encoding_get_type (void) G_GNUC_CONST; - -const XedEncoding *xed_encoding_get_from_charset (const gchar *charset); -const XedEncoding *xed_encoding_get_from_index (gint index); - -gchar *xed_encoding_to_string (const XedEncoding *enc); - -const gchar *xed_encoding_get_name (const XedEncoding *enc); -const gchar *xed_encoding_get_charset (const XedEncoding *enc); - -const XedEncoding *xed_encoding_get_utf8 (void); -const XedEncoding *xed_encoding_get_current (void); - -/* These should not be used, they are just to make python bindings happy */ -XedEncoding *xed_encoding_copy (const XedEncoding *enc); -void xed_encoding_free (XedEncoding *enc); - -G_END_DECLS - -#endif /* __XED_ENCODINGS_H__ */ diff --git a/xed/xed-file-chooser-dialog.c b/xed/xed-file-chooser-dialog.c index abffce8..b014d3b 100644 --- a/xed/xed-file-chooser-dialog.c +++ b/xed/xed-file-chooser-dialog.c @@ -38,414 +38,387 @@ #include #include -#include -#include #include "xed-file-chooser-dialog.h" #include "xed-encodings-combo-box.h" -#include "xed-language-manager.h" -#include "xed-prefs-manager-app.h" #include "xed-debug.h" #include "xed-enum-types.h" +#include "xed-settings.h" #define XED_FILE_CHOOSER_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_FILE_CHOOSER_DIALOG, XedFileChooserDialogPrivate)) -#define ALL_FILES _("All Files") -#define ALL_TEXT_FILES _("All Text Files") +#define ALL_FILES _("All Files") +#define ALL_TEXT_FILES _("All Text Files") struct _XedFileChooserDialogPrivate { - GtkWidget *option_menu; - GtkWidget *extra_widget; + GSettings *filter_settings; - GtkWidget *newline_label; - GtkWidget *newline_combo; - GtkListStore *newline_store; + GtkWidget *option_menu; + GtkWidget *extra_widget; + + GtkWidget *newline_label; + GtkWidget *newline_combo; + GtkListStore *newline_store; }; G_DEFINE_TYPE(XedFileChooserDialog, xed_file_chooser_dialog, GTK_TYPE_FILE_CHOOSER_DIALOG) +static void +xed_file_chooser_dialog_dispose (GObject *object) +{ + XedFileChooserDialog *dialog = XED_FILE_CHOOSER_DIALOG (object); + + g_clear_object (&dialog->priv->filter_settings); + + G_OBJECT_CLASS (xed_file_chooser_dialog_parent_class)->dispose (object); +} + static void xed_file_chooser_dialog_class_init (XedFileChooserDialogClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (object_class, sizeof(XedFileChooserDialogPrivate)); + object_class->dispose = xed_file_chooser_dialog_dispose; + + g_type_class_add_private (object_class, sizeof(XedFileChooserDialogPrivate)); } static void create_option_menu (XedFileChooserDialog *dialog) { - GtkWidget *label; - GtkWidget *menu; + GtkWidget *label; + GtkWidget *menu; - label = gtk_label_new_with_mnemonic (_("C_haracter Encoding:")); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + label = gtk_label_new_with_mnemonic (_("C_haracter Encoding:")); + gtk_widget_set_halign (label, GTK_ALIGN_START); - menu = xed_encodings_combo_box_new ( - gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE); + menu = xed_encodings_combo_box_new ( + gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), menu); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), menu); - gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget), - label, - FALSE, - TRUE, - 0); + gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget), menu, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget), - menu, - TRUE, - TRUE, - 0); + gtk_widget_show (label); + gtk_widget_show (menu); - gtk_widget_show (label); - gtk_widget_show (menu); - - dialog->priv->option_menu = menu; + dialog->priv->option_menu = menu; } static void update_newline_visibility (XedFileChooserDialog *dialog) { - if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE) - { - gtk_widget_show (dialog->priv->newline_label); - gtk_widget_show (dialog->priv->newline_combo); - } - else - { - gtk_widget_hide (dialog->priv->newline_label); - gtk_widget_hide (dialog->priv->newline_combo); - } + if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE) + { + gtk_widget_show (dialog->priv->newline_label); + gtk_widget_show (dialog->priv->newline_combo); + } + else + { + gtk_widget_hide (dialog->priv->newline_label); + gtk_widget_hide (dialog->priv->newline_combo); + } } static void -newline_combo_append (GtkComboBox *combo, - GtkListStore *store, - GtkTreeIter *iter, - const gchar *label, - XedDocumentNewlineType newline_type) +newline_combo_append (GtkComboBox *combo, + GtkListStore *store, + GtkTreeIter *iter, + const gchar *label, + GtkSourceNewlineType newline_type) { - gtk_list_store_append (store, iter); - gtk_list_store_set (store, iter, 0, label, 1, newline_type, -1); + gtk_list_store_append (store, iter); + gtk_list_store_set (store, iter, 0, label, 1, newline_type, -1); - if (newline_type == XED_DOCUMENT_NEWLINE_TYPE_DEFAULT) - { - gtk_combo_box_set_active_iter (combo, iter); - } + if (newline_type == GTK_SOURCE_NEWLINE_TYPE_DEFAULT) + { + gtk_combo_box_set_active_iter (combo, iter); + } } static void create_newline_combo (XedFileChooserDialog *dialog) { - GtkWidget *label, *combo; - GtkListStore *store; - GtkCellRenderer *renderer; - GtkTreeIter iter; + GtkWidget *label, *combo; + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeIter iter; - label = gtk_label_new_with_mnemonic (_("L_ine Ending:")); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + label = gtk_label_new_with_mnemonic (_("L_ine Ending:")); + gtk_widget_set_halign (label, GTK_ALIGN_START); - store = gtk_list_store_new (2, G_TYPE_STRING, XED_TYPE_DOCUMENT_NEWLINE_TYPE); - combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); - renderer = gtk_cell_renderer_text_new (); + store = gtk_list_store_new (2, G_TYPE_STRING, GTK_SOURCE_TYPE_NEWLINE_TYPE); + combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); + renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), - renderer, - TRUE); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); - gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), - renderer, - "text", - 0); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0); - newline_combo_append (GTK_COMBO_BOX (combo), - store, - &iter, - _("Unix/Linux"), - XED_DOCUMENT_NEWLINE_TYPE_LF); + newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Unix/Linux"), GTK_SOURCE_NEWLINE_TYPE_LF); + newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Mac OS Classic"), GTK_SOURCE_NEWLINE_TYPE_CR); + newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Windows"), GTK_SOURCE_NEWLINE_TYPE_CR_LF); - newline_combo_append (GTK_COMBO_BOX (combo), - store, - &iter, - _("Mac OS Classic"), - XED_DOCUMENT_NEWLINE_TYPE_CR); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); - newline_combo_append (GTK_COMBO_BOX (combo), - store, - &iter, - _("Windows"), - XED_DOCUMENT_NEWLINE_TYPE_CR_LF); + gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget), label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget), combo, TRUE, TRUE, 0); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); + dialog->priv->newline_combo = combo; + dialog->priv->newline_label = label; + dialog->priv->newline_store = store; - gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget), - label, - FALSE, - TRUE, - 0); - - gtk_box_pack_start (GTK_BOX (dialog->priv->extra_widget), - combo, - TRUE, - TRUE, - 0); - - dialog->priv->newline_combo = combo; - dialog->priv->newline_label = label; - dialog->priv->newline_store = store; - - update_newline_visibility (dialog); + update_newline_visibility (dialog); } static void create_extra_widget (XedFileChooserDialog *dialog) { - dialog->priv->extra_widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + dialog->priv->extra_widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_widget_show (dialog->priv->extra_widget); + gtk_widget_show (dialog->priv->extra_widget); - create_option_menu (dialog); - create_newline_combo (dialog); + create_option_menu (dialog); + create_newline_combo (dialog); - gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), - dialog->priv->extra_widget); + gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), dialog->priv->extra_widget); } static void action_changed (XedFileChooserDialog *dialog, - GParamSpec *pspec, - gpointer data) + GParamSpec *pspec, + gpointer data) { - GtkFileChooserAction action; + GtkFileChooserAction action; - action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)); + action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)); - switch (action) - { - case GTK_FILE_CHOOSER_ACTION_OPEN: - g_object_set (dialog->priv->option_menu, - "save_mode", FALSE, - NULL); - gtk_widget_show (dialog->priv->option_menu); - break; - case GTK_FILE_CHOOSER_ACTION_SAVE: - g_object_set (dialog->priv->option_menu, - "save_mode", TRUE, - NULL); - gtk_widget_show (dialog->priv->option_menu); - break; - default: - gtk_widget_hide (dialog->priv->option_menu); - } + switch (action) + { + case GTK_FILE_CHOOSER_ACTION_OPEN: + g_object_set (dialog->priv->option_menu, "save_mode", FALSE, NULL); + gtk_widget_show (dialog->priv->option_menu); + break; + case GTK_FILE_CHOOSER_ACTION_SAVE: + g_object_set (dialog->priv->option_menu, "save_mode", TRUE, NULL); + gtk_widget_show (dialog->priv->option_menu); + break; + default: + gtk_widget_hide (dialog->priv->option_menu); + } - update_newline_visibility (dialog); + update_newline_visibility (dialog); } static void filter_changed (XedFileChooserDialog *dialog, - GParamSpec *pspec, - gpointer data) + GParamSpec *pspec, + gpointer data) { - GtkFileFilter *filter; + GtkFileFilter *filter; - if (!xed_prefs_manager_active_file_filter_can_set ()) - return; + filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)); + if (filter != NULL) + { + const gchar *name; + gint id = 0; - filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)); - if (filter != NULL) - { - const gchar *name; - gint id = 0; + name = gtk_file_filter_get_name (filter); + g_return_if_fail (name != NULL); - name = gtk_file_filter_get_name (filter); - g_return_if_fail (name != NULL); + if (strcmp (name, ALL_TEXT_FILES) == 0) + { + id = 1; + } - if (strcmp (name, ALL_TEXT_FILES) == 0) - id = 1; + xed_debug_message (DEBUG_COMMANDS, "Active filter: %s (%d)", name, id); - xed_debug_message (DEBUG_COMMANDS, "Active filter: %s (%d)", name, id); - - xed_prefs_manager_set_active_file_filter (id); - } + g_settings_set_int (dialog->priv->filter_settings, XED_SETTINGS_ACTIVE_FILE_FILTER, id); + } } /* FIXME: use globs too - Paolo (Aug. 27, 2007) */ static gboolean all_text_files_filter (const GtkFileFilterInfo *filter_info, - gpointer data) + gpointer data) { - static GSList *known_mime_types = NULL; - GSList *mime_types; + static GSList *known_mime_types = NULL; + GSList *mime_types; - if (known_mime_types == NULL) - { - GtkSourceLanguageManager *lm; - const gchar * const *languages; + if (known_mime_types == NULL) + { + GtkSourceLanguageManager *lm; + const gchar * const *languages; - lm = xed_get_language_manager (); - languages = gtk_source_language_manager_get_language_ids (lm); + lm = gtk_source_language_manager_get_default (); + languages = gtk_source_language_manager_get_language_ids (lm); - while ((languages != NULL) && (*languages != NULL)) - { - gchar **mime_types; - gint i; - GtkSourceLanguage *lang; + while ((languages != NULL) && (*languages != NULL)) + { + gchar **mime_types; + gint i; + GtkSourceLanguage *lang; - lang = gtk_source_language_manager_get_language (lm, *languages); - g_return_val_if_fail (GTK_SOURCE_IS_LANGUAGE (lang), FALSE); - ++languages; + lang = gtk_source_language_manager_get_language (lm, *languages); + g_return_val_if_fail (GTK_SOURCE_IS_LANGUAGE (lang), FALSE); + ++languages; - mime_types = gtk_source_language_get_mime_types (lang); - if (mime_types == NULL) - continue; + mime_types = gtk_source_language_get_mime_types (lang); + if (mime_types == NULL) + { + continue; + } - for (i = 0; mime_types[i] != NULL; i++) - { - if (!g_content_type_is_a (mime_types[i], "text/plain")) - { - xed_debug_message (DEBUG_COMMANDS, - "Mime-type %s is not related to text/plain", - mime_types[i]); + for (i = 0; mime_types[i] != NULL; i++) + { + if (!g_content_type_is_a (mime_types[i], "text/plain")) + { + xed_debug_message (DEBUG_COMMANDS, + "Mime-type %s is not related to text/plain", + mime_types[i]); - known_mime_types = g_slist_prepend (known_mime_types, - g_strdup (mime_types[i])); - } - } + known_mime_types = g_slist_prepend (known_mime_types, g_strdup (mime_types[i])); + } + } - g_strfreev (mime_types); - } + g_strfreev (mime_types); + } - /* known_mime_types always has "text/plain" as first item" */ - known_mime_types = g_slist_prepend (known_mime_types, g_strdup ("text/plain")); - } + /* known_mime_types always has "text/plain" as first item" */ + known_mime_types = g_slist_prepend (known_mime_types, g_strdup ("text/plain")); + } - /* known mime_types contains "text/plain" and then the list of mime-types unrelated to "text/plain" - * that xed recognizes */ + /* known mime_types contains "text/plain" and then the list of mime-types unrelated to "text/plain" + * that xed recognizes */ - if (filter_info->mime_type == NULL) - return FALSE; + if (filter_info->mime_type == NULL) + { + return FALSE; + } - /* - * The filter is matching: - * - the mime-types beginning with "text/" - * - the mime-types inheriting from a known mime-type (note the text/plain is - * the first known mime-type) - */ + /* + * The filter is matching: + * - the mime-types beginning with "text/" + * - the mime-types inheriting from a known mime-type (note the text/plain is + * the first known mime-type) + */ - if (strncmp (filter_info->mime_type, "text/", 5) == 0) - return TRUE; + if (strncmp (filter_info->mime_type, "text/", 5) == 0) + { + return TRUE; + } - mime_types = known_mime_types; - while (mime_types != NULL) - { - if (g_content_type_is_a (filter_info->mime_type, (const gchar*)mime_types->data)) - return TRUE; + mime_types = known_mime_types; + while (mime_types != NULL) + { + if (g_content_type_is_a (filter_info->mime_type, (const gchar*)mime_types->data)) + { + return TRUE; + } - mime_types = g_slist_next (mime_types); - } + mime_types = g_slist_next (mime_types); + } - return FALSE; + return FALSE; } static void xed_file_chooser_dialog_init (XedFileChooserDialog *dialog) { - dialog->priv = XED_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog); + dialog->priv = XED_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog); + + dialog->priv->filter_settings = g_settings_new ("org.x.editor.state.file-filter"); } static GtkWidget * -xed_file_chooser_dialog_new_valist (const gchar *title, - GtkWindow *parent, - GtkFileChooserAction action, - const XedEncoding *encoding, - const gchar *first_button_text, - va_list varargs) +xed_file_chooser_dialog_new_valist (const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const GtkSourceEncoding *encoding, + const gchar *first_button_text, + va_list varargs) { - GtkWidget *result; - const char *button_text = first_button_text; - gint response_id; - GtkFileFilter *filter; - gint active_filter; + GtkWidget *result; + const char *button_text = first_button_text; + gint response_id; + GtkFileFilter *filter; + gint active_filter; - g_return_val_if_fail (parent != NULL, NULL); + g_return_val_if_fail (parent != NULL, NULL); - result = g_object_new (XED_TYPE_FILE_CHOOSER_DIALOG, - "title", title, - "local-only", FALSE, - "action", action, - "select-multiple", action == GTK_FILE_CHOOSER_ACTION_OPEN, - NULL); + result = g_object_new (XED_TYPE_FILE_CHOOSER_DIALOG, + "title", title, + "local-only", FALSE, + "action", action, + "select-multiple", action == GTK_FILE_CHOOSER_ACTION_OPEN, + NULL); - create_extra_widget (XED_FILE_CHOOSER_DIALOG (result)); + create_extra_widget (XED_FILE_CHOOSER_DIALOG (result)); - g_signal_connect (result, - "notify::action", - G_CALLBACK (action_changed), - NULL); + g_signal_connect (result, "notify::action", + G_CALLBACK (action_changed), NULL); - if (encoding != NULL) - xed_encodings_combo_box_set_selected_encoding ( - XED_ENCODINGS_COMBO_BOX (XED_FILE_CHOOSER_DIALOG (result)->priv->option_menu), - encoding); + if (encoding != NULL) + { + xed_encodings_combo_box_set_selected_encoding ( + XED_ENCODINGS_COMBO_BOX (XED_FILE_CHOOSER_DIALOG (result)->priv->option_menu), encoding); + } - active_filter = xed_prefs_manager_get_active_file_filter (); - xed_debug_message (DEBUG_COMMANDS, "Active filter: %d", active_filter); + active_filter = g_settings_get_int (XED_FILE_CHOOSER_DIALOG (result)->priv->filter_settings, + XED_SETTINGS_ACTIVE_FILE_FILTER); + xed_debug_message (DEBUG_COMMANDS, "Active filter: %d", active_filter); - /* Filters */ - filter = gtk_file_filter_new (); + /* Filters */ + filter = gtk_file_filter_new (); - gtk_file_filter_set_name (filter, ALL_FILES); - gtk_file_filter_add_pattern (filter, "*"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (result), filter); - gtk_file_chooser_set_action (GTK_FILE_CHOOSER (result), action); + gtk_file_filter_set_name (filter, ALL_FILES); + gtk_file_filter_add_pattern (filter, "*"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (result), filter); + gtk_file_chooser_set_action (GTK_FILE_CHOOSER (result), action); - if (active_filter != 1) - { - /* Make this filter the default */ - gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (result), filter); - } + if (active_filter != 1) + { + /* Make this filter the default */ + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (result), filter); + } - filter = gtk_file_filter_new (); - gtk_file_filter_set_name (filter, ALL_TEXT_FILES); - gtk_file_filter_add_custom (filter, - GTK_FILE_FILTER_MIME_TYPE, - all_text_files_filter, - NULL, - NULL); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (result), filter); + filter = gtk_file_filter_new (); + gtk_file_filter_set_name (filter, ALL_TEXT_FILES); + gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_MIME_TYPE, all_text_files_filter, NULL, NULL); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (result), filter); - if (active_filter == 1) - { - /* Make this filter the default */ - gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (result), filter); - } + if (active_filter == 1) + { + /* Make this filter the default */ + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (result), filter); + } - g_signal_connect (result, - "notify::filter", - G_CALLBACK (filter_changed), - NULL); + g_signal_connect (result, "notify::filter", + G_CALLBACK (filter_changed), NULL); - gtk_window_set_transient_for (GTK_WINDOW (result), parent); - gtk_window_set_destroy_with_parent (GTK_WINDOW (result), TRUE); + gtk_window_set_transient_for (GTK_WINDOW (result), parent); + gtk_window_set_destroy_with_parent (GTK_WINDOW (result), TRUE); - while (button_text) - { - response_id = va_arg (varargs, gint); + while (button_text) + { + response_id = va_arg (varargs, gint); - gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id); - if ((response_id == GTK_RESPONSE_OK) || - (response_id == GTK_RESPONSE_ACCEPT) || - (response_id == GTK_RESPONSE_YES) || - (response_id == GTK_RESPONSE_APPLY)) - gtk_dialog_set_default_response (GTK_DIALOG (result), response_id); + gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id); + if ((response_id == GTK_RESPONSE_OK) || + (response_id == GTK_RESPONSE_ACCEPT) || + (response_id == GTK_RESPONSE_YES) || + (response_id == GTK_RESPONSE_APPLY)) + { + gtk_dialog_set_default_response (GTK_DIALOG (result), response_id); + } - button_text = va_arg (varargs, const gchar *); - } + button_text = va_arg (varargs, const gchar *); + } - return result; + return result; } /** @@ -455,7 +428,7 @@ xed_file_chooser_dialog_new_valist (const gchar *title, * @action: Open or save mode for the dialog * @first_button_text: (allow-none): stock ID or text to go in * the first button, or %NULL - * @Varargs: (allow-none): response ID for the first button, then + * @...: (allow-none): response ID for the first button, then * additional (button, id) pairs, ending with %NULL * * Creates a new #XedFileChooserDialog. This function is analogous to @@ -465,99 +438,95 @@ xed_file_chooser_dialog_new_valist (const gchar *title, * **/ GtkWidget * -xed_file_chooser_dialog_new (const gchar *title, - GtkWindow *parent, - GtkFileChooserAction action, - const XedEncoding *encoding, - const gchar *first_button_text, - ...) +xed_file_chooser_dialog_new (const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const GtkSourceEncoding *encoding, + const gchar *first_button_text, + ...) { - GtkWidget *result; - va_list varargs; + GtkWidget *result; + va_list varargs; - va_start (varargs, first_button_text); - result = xed_file_chooser_dialog_new_valist (title, parent, action, - encoding, first_button_text, - varargs); - va_end (varargs); + va_start (varargs, first_button_text); + result = xed_file_chooser_dialog_new_valist (title, parent, action, encoding, first_button_text, varargs); + va_end (varargs); - return result; + return result; } void -xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog, - const XedEncoding *encoding) +xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog, + const GtkSourceEncoding *encoding) { - g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog)); - g_return_if_fail (XED_IS_ENCODINGS_COMBO_BOX (dialog->priv->option_menu)); + g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog)); + g_return_if_fail (XED_IS_ENCODINGS_COMBO_BOX (dialog->priv->option_menu)); - xed_encodings_combo_box_set_selected_encoding ( - XED_ENCODINGS_COMBO_BOX (dialog->priv->option_menu), - encoding); + xed_encodings_combo_box_set_selected_encoding (XED_ENCODINGS_COMBO_BOX (dialog->priv->option_menu), encoding); } -const XedEncoding * +const GtkSourceEncoding * xed_file_chooser_dialog_get_encoding (XedFileChooserDialog *dialog) { - g_return_val_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog), NULL); - g_return_val_if_fail (XED_IS_ENCODINGS_COMBO_BOX (dialog->priv->option_menu), NULL); - g_return_val_if_fail ((gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_OPEN || - gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE), NULL); + g_return_val_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog), NULL); + g_return_val_if_fail (XED_IS_ENCODINGS_COMBO_BOX (dialog->priv->option_menu), NULL); + g_return_val_if_fail ((gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_OPEN || + gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE), NULL); - return xed_encodings_combo_box_get_selected_encoding ( - XED_ENCODINGS_COMBO_BOX (dialog->priv->option_menu)); + return xed_encodings_combo_box_get_selected_encoding (XED_ENCODINGS_COMBO_BOX (dialog->priv->option_menu)); +} + +static void +set_enum_combo (GtkComboBox *combo, + gint value) +{ + GtkTreeIter iter; + GtkTreeModel *model; + + model = gtk_combo_box_get_model (combo); + + if (!gtk_tree_model_get_iter_first (model, &iter)) + { + return; + } + + do + { + gint nt; + + gtk_tree_model_get (model, &iter, 1, &nt, -1); + + if (value == nt) + { + gtk_combo_box_set_active_iter (combo, &iter); + break; + } + } while (gtk_tree_model_iter_next (model, &iter)); } void -xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog, - XedDocumentNewlineType newline_type) +xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog, + GtkSourceNewlineType newline_type) { - GtkTreeIter iter; - GtkTreeModel *model; + g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog)); + g_return_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE); - g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog)); - g_return_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE); - - model = GTK_TREE_MODEL (dialog->priv->newline_store); - - if (!gtk_tree_model_get_iter_first (model, &iter)) - { - return; - } - - do - { - XedDocumentNewlineType nt; - - gtk_tree_model_get (model, &iter, 1, &nt, -1); - - if (newline_type == nt) - { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->priv->newline_combo), - &iter); - break; - } - } while (gtk_tree_model_iter_next (model, &iter)); + set_enum_combo (GTK_COMBO_BOX (dialog->priv->newline_combo), newline_type); } -XedDocumentNewlineType +GtkSourceNewlineType xed_file_chooser_dialog_get_newline_type (XedFileChooserDialog *dialog) { - GtkTreeIter iter; - XedDocumentNewlineType newline_type; + GtkTreeIter iter; + GtkSourceNewlineType newline_type; - g_return_val_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog), XED_DOCUMENT_NEWLINE_TYPE_DEFAULT); - g_return_val_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE, - XED_DOCUMENT_NEWLINE_TYPE_DEFAULT); + g_return_val_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog), GTK_SOURCE_NEWLINE_TYPE_DEFAULT); + g_return_val_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_SOURCE_NEWLINE_TYPE_DEFAULT); - gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dialog->priv->newline_combo), - &iter); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dialog->priv->newline_combo), &iter); - gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->newline_store), - &iter, - 1, - &newline_type, - -1); + gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->newline_store), &iter, 1, &newline_type, -1); - return newline_type; + return newline_type; } diff --git a/xed/xed-file-chooser-dialog.h b/xed/xed-file-chooser-dialog.h index b7cc837..f2a0202 100644 --- a/xed/xed-file-chooser-dialog.h +++ b/xed/xed-file-chooser-dialog.h @@ -2,7 +2,7 @@ * xed-file-chooser-dialog.h * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -31,9 +31,8 @@ #ifndef __XED_FILE_CHOOSER_DIALOG_H__ #define __XED_FILE_CHOOSER_DIALOG_H__ -#include +#include -#include #include #include @@ -46,43 +45,40 @@ G_BEGIN_DECLS #define XED_IS_FILE_CHOOSER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_FILE_CHOOSER_DIALOG)) #define XED_FILE_CHOOSER_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_FILE_CHOOSER_DIALOG, XedFileChooserDialogClass)) -typedef struct _XedFileChooserDialog XedFileChooserDialog; -typedef struct _XedFileChooserDialogClass XedFileChooserDialogClass; - +typedef struct _XedFileChooserDialog XedFileChooserDialog; typedef struct _XedFileChooserDialogPrivate XedFileChooserDialogPrivate; - -struct _XedFileChooserDialogClass -{ - GtkFileChooserDialogClass parent_class; -}; +typedef struct _XedFileChooserDialogClass XedFileChooserDialogClass; struct _XedFileChooserDialog { - GtkFileChooserDialog parent_instance; + GtkFileChooserDialog parent_instance; - XedFileChooserDialogPrivate *priv; + XedFileChooserDialogPrivate *priv; }; -GType xed_file_chooser_dialog_get_type (void) G_GNUC_CONST; +struct _XedFileChooserDialogClass +{ + GtkFileChooserDialogClass parent_class; +}; -GtkWidget *xed_file_chooser_dialog_new (const gchar *title, - GtkWindow *parent, - GtkFileChooserAction action, - const XedEncoding *encoding, - const gchar *first_button_text, - ...); +GType xed_file_chooser_dialog_get_type (void) G_GNUC_CONST; -void xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog, - const XedEncoding *encoding); +GtkWidget *xed_file_chooser_dialog_new (const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const GtkSourceEncoding *encoding, + const gchar *first_button_text, + ...); -const XedEncoding - *xed_file_chooser_dialog_get_encoding (XedFileChooserDialog *dialog); +void xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog, + const GtkSourceEncoding *encoding); -void xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog, - XedDocumentNewlineType newline_type); +const GtkSourceEncoding *xed_file_chooser_dialog_get_encoding (XedFileChooserDialog *dialog); -XedDocumentNewlineType - xed_file_chooser_dialog_get_newline_type (XedFileChooserDialog *dialog); +void xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog, + GtkSourceNewlineType newline_type); + +GtkSourceNewlineType xed_file_chooser_dialog_get_newline_type (XedFileChooserDialog *dialog); G_END_DECLS diff --git a/xed/xed-gio-document-loader.c b/xed/xed-gio-document-loader.c deleted file mode 100644 index bbac86c..0000000 --- a/xed/xed-gio-document-loader.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - * xed-gio-document-loader.c - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005-2008. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "xed-gio-document-loader.h" -#include "xed-document-output-stream.h" -#include "xed-smart-charset-converter.h" -#include "xed-prefs-manager.h" -#include "xed-debug.h" -#include "xed-utils.h" - -#ifndef ENABLE_GVFS_METADATA -#include "xed-metadata-manager.h" -#endif - -typedef struct -{ - XedGioDocumentLoader *loader; - GCancellable *cancellable; - - gssize read; - gboolean tried_mount; -} AsyncData; - -#define READ_CHUNK_SIZE 8192 -#define REMOTE_QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \ - G_FILE_ATTRIBUTE_STANDARD_TYPE "," \ - G_FILE_ATTRIBUTE_TIME_MODIFIED "," \ - G_FILE_ATTRIBUTE_STANDARD_SIZE "," \ - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "," \ - XED_METADATA_ATTRIBUTE_ENCODING - -#define XED_GIO_DOCUMENT_LOADER_GET_PRIVATE(object) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_GIO_DOCUMENT_LOADER, \ - XedGioDocumentLoaderPrivate)) - -static void xed_gio_document_loader_load (XedDocumentLoader *loader); -static gboolean xed_gio_document_loader_cancel (XedDocumentLoader *loader); -static goffset xed_gio_document_loader_get_bytes_read (XedDocumentLoader *loader); - -static void open_async_read (AsyncData *async); - -struct _XedGioDocumentLoaderPrivate -{ - /* Info on the current file */ - GFile *gfile; - - goffset bytes_read; - - /* Handle for remote files */ - GCancellable *cancellable; - GInputStream *stream; - GOutputStream *output; - XedSmartCharsetConverter *converter; - - gchar buffer[READ_CHUNK_SIZE]; - - GError *error; -}; - -G_DEFINE_TYPE(XedGioDocumentLoader, xed_gio_document_loader, XED_TYPE_DOCUMENT_LOADER) - -static void -xed_gio_document_loader_dispose (GObject *object) -{ - XedGioDocumentLoaderPrivate *priv; - - priv = XED_GIO_DOCUMENT_LOADER (object)->priv; - - if (priv->cancellable != NULL) - { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - priv->cancellable = NULL; - } - - if (priv->stream != NULL) - { - g_object_unref (priv->stream); - priv->stream = NULL; - } - - if (priv->output != NULL) - { - g_object_unref (priv->output); - priv->output = NULL; - } - - if (priv->converter != NULL) - { - g_object_unref (priv->converter); - priv->converter = NULL; - } - - if (priv->gfile != NULL) - { - g_object_unref (priv->gfile); - priv->gfile = NULL; - } - - if (priv->error != NULL) - { - g_error_free (priv->error); - priv->error = NULL; - } - - G_OBJECT_CLASS (xed_gio_document_loader_parent_class)->dispose (object); -} - -static void -xed_gio_document_loader_class_init (XedGioDocumentLoaderClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedDocumentLoaderClass *loader_class = XED_DOCUMENT_LOADER_CLASS (klass); - - object_class->dispose = xed_gio_document_loader_dispose; - - loader_class->load = xed_gio_document_loader_load; - loader_class->cancel = xed_gio_document_loader_cancel; - loader_class->get_bytes_read = xed_gio_document_loader_get_bytes_read; - - g_type_class_add_private (object_class, sizeof(XedGioDocumentLoaderPrivate)); -} - -static void -xed_gio_document_loader_init (XedGioDocumentLoader *gvloader) -{ - gvloader->priv = XED_GIO_DOCUMENT_LOADER_GET_PRIVATE (gvloader); - - gvloader->priv->converter = NULL; - gvloader->priv->error = NULL; -} - -static AsyncData * -async_data_new (XedGioDocumentLoader *gvloader) -{ - AsyncData *async; - - async = g_slice_new (AsyncData); - async->loader = gvloader; - async->cancellable = g_object_ref (gvloader->priv->cancellable); - async->tried_mount = FALSE; - - return async; -} - -static void -async_data_free (AsyncData *async) -{ - g_object_unref (async->cancellable); - g_slice_free (AsyncData, async); -} - -static const XedEncoding * -get_metadata_encoding (XedDocumentLoader *loader) -{ - const XedEncoding *enc = NULL; - -#ifndef ENABLE_GVFS_METADATA - gchar *charset; - const gchar *uri; - - uri = xed_document_loader_get_uri (loader); - - charset = xed_metadata_manager_get (uri, "encoding"); - - if (charset == NULL) - return NULL; - - enc = xed_encoding_get_from_charset (charset); - - g_free (charset); -#else - GFileInfo *info; - - info = xed_document_loader_get_info (loader); - - /* check if the encoding was set in the metadata */ - if (g_file_info_has_attribute (info, XED_METADATA_ATTRIBUTE_ENCODING)) - { - const gchar *charset; - - charset = g_file_info_get_attribute_string (info, - XED_METADATA_ATTRIBUTE_ENCODING); - - if (charset == NULL) - return NULL; - - enc = xed_encoding_get_from_charset (charset); - } -#endif - - return enc; -} - -static void -remote_load_completed_or_failed (XedGioDocumentLoader *loader, AsyncData *async) -{ - xed_document_loader_loading (XED_DOCUMENT_LOADER (loader), - TRUE, - loader->priv->error); - - if (async) - async_data_free (async); -} - -static void -async_failed (AsyncData *async, GError *error) -{ - g_propagate_error (&async->loader->priv->error, error); - remote_load_completed_or_failed (async->loader, async); -} - -static void -close_input_stream_ready_cb (GInputStream *stream, - GAsyncResult *res, - AsyncData *async) -{ - GError *error = NULL; - - xed_debug (DEBUG_LOADER); - - /* check cancelled state manually */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - xed_debug_message (DEBUG_SAVER, "Finished closing input stream"); - - if (!g_input_stream_close_finish (stream, res, &error)) - { - xed_debug_message (DEBUG_SAVER, "Closing input stream error: %s", error->message); - - async_failed (async, error); - return; - } - - xed_debug_message (DEBUG_SAVER, "Close output stream"); - if (!g_output_stream_close (async->loader->priv->output, - async->cancellable, &error)) - { - async_failed (async, error); - return; - } - - remote_load_completed_or_failed (async->loader, async); -} - -static void -write_complete (AsyncData *async) -{ - if (async->loader->priv->stream) - g_input_stream_close_async (G_INPUT_STREAM (async->loader->priv->stream), - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback)close_input_stream_ready_cb, - async); -} - -/* prototype, because they call each other... isn't C lovely */ -static void read_file_chunk (AsyncData *async); - -static void -write_file_chunk (AsyncData *async) -{ - XedGioDocumentLoader *gvloader; - gssize bytes_written; - GError *error = NULL; - - gvloader = async->loader; - - /* we use sync methods on doc stream since it is in memory. Using async - would be racy and we can endup with invalidated iters */ - bytes_written = g_output_stream_write (G_OUTPUT_STREAM (gvloader->priv->output), - gvloader->priv->buffer, - async->read, - async->cancellable, - &error); - - xed_debug_message (DEBUG_SAVER, "Written: %" G_GSSIZE_FORMAT, bytes_written); - if (bytes_written == -1) - { - xed_debug_message (DEBUG_SAVER, "Write error: %s", error->message); - async_failed (async, error); - return; - } - - /* note that this signal blocks the read... check if it isn't - * a performance problem - */ - xed_document_loader_loading (XED_DOCUMENT_LOADER (gvloader), - FALSE, - NULL); - - read_file_chunk (async); -} - -static void -async_read_cb (GInputStream *stream, - GAsyncResult *res, - AsyncData *async) -{ - xed_debug (DEBUG_LOADER); - XedGioDocumentLoader *gvloader; - GError *error = NULL; - - xed_debug (DEBUG_LOADER); - - /* manually check cancelled state */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - gvloader = async->loader; - - async->read = g_input_stream_read_finish (stream, res, &error); - - /* error occurred */ - if (async->read == -1) - { - async_failed (async, error); - return; - } - - /* Check for the extremely unlikely case where the file size overflows. */ - if (gvloader->priv->bytes_read + async->read < gvloader->priv->bytes_read) - { - g_set_error (&gvloader->priv->error, - XED_DOCUMENT_ERROR, - XED_DOCUMENT_ERROR_TOO_BIG, - "File too big"); - - async_failed (async, gvloader->priv->error); - return; - } - - /* Bump the size. */ - gvloader->priv->bytes_read += async->read; - - /* end of the file, we are done! */ - if (async->read == 0) - { - XedDocumentLoader *loader; - - loader = XED_DOCUMENT_LOADER (gvloader); - - g_output_stream_flush (gvloader->priv->output, - NULL, - &gvloader->priv->error); - - loader->auto_detected_encoding = - xed_smart_charset_converter_get_guessed (gvloader->priv->converter); - - loader->auto_detected_newline_type = - xed_document_output_stream_detect_newline_type (XED_DOCUMENT_OUTPUT_STREAM (gvloader->priv->output)); - - /* Check if we needed some fallback char, if so, check if there was - a previous error and if not set a fallback used error */ - /* FIXME Uncomment this when we want to manage conversion fallback */ - /*if ((xed_smart_charset_converter_get_num_fallbacks (gvloader->priv->converter) != 0) && - gvloader->priv->error == NULL) - { - g_set_error_literal (&gvloader->priv->error, - XED_DOCUMENT_ERROR, - XED_DOCUMENT_ERROR_CONVERSION_FALLBACK, - "There was a conversion error and it was " - "needed to use a fallback char"); - }*/ - - write_complete (async); - - return; - } - - write_file_chunk (async); -} - -static void -read_file_chunk (AsyncData *async) -{ - XedGioDocumentLoader *gvloader; - - gvloader = async->loader; - - g_input_stream_read_async (G_INPUT_STREAM (gvloader->priv->stream), - gvloader->priv->buffer, - READ_CHUNK_SIZE, - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback) async_read_cb, - async); -} - -static GSList * -get_candidate_encodings (XedGioDocumentLoader *gvloader) -{ - const XedEncoding *metadata; - GSList *encodings = NULL; - - encodings = xed_prefs_manager_get_auto_detected_encodings (); - - metadata = get_metadata_encoding (XED_DOCUMENT_LOADER (gvloader)); - if (metadata != NULL) - { - encodings = g_slist_prepend (encodings, (gpointer)metadata); - } - - return encodings; -} - -static void -finish_query_info (AsyncData *async) -{ - XedGioDocumentLoader *gvloader; - XedDocumentLoader *loader; - GInputStream *conv_stream; - GFileInfo *info; - GSList *candidate_encodings; - - gvloader = async->loader; - loader = XED_DOCUMENT_LOADER (gvloader); - info = loader->info; - - /* if it's not a regular file, error out... */ - if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) && - g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR) - { - g_set_error (&gvloader->priv->error, - G_IO_ERROR, - G_IO_ERROR_NOT_REGULAR_FILE, - "Not a regular file"); - - remote_load_completed_or_failed (gvloader, async); - - return; - } - - /* Get the candidate encodings */ - if (loader->encoding == NULL) - { - candidate_encodings = get_candidate_encodings (gvloader); - } - else - { - candidate_encodings = g_slist_prepend (NULL, (gpointer) loader->encoding); - } - - gvloader->priv->converter = xed_smart_charset_converter_new (candidate_encodings); - g_slist_free (candidate_encodings); - - conv_stream = g_converter_input_stream_new (gvloader->priv->stream, - G_CONVERTER (gvloader->priv->converter)); - g_object_unref (gvloader->priv->stream); - - gvloader->priv->stream = conv_stream; - - /* Output stream */ - gvloader->priv->output = xed_document_output_stream_new (loader->document); - - /* start reading */ - read_file_chunk (async); -} - -static void -query_info_cb (GFile *source, - GAsyncResult *res, - AsyncData *async) -{ - XedGioDocumentLoader *gvloader; - GFileInfo *info; - GError *error = NULL; - - xed_debug (DEBUG_LOADER); - - /* manually check the cancelled state */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - gvloader = async->loader; - - /* finish the info query */ - info = g_file_query_info_finish (gvloader->priv->gfile, - res, - &error); - - if (info == NULL) - { - /* propagate the error and clean up */ - async_failed (async, error); - return; - } - - XED_DOCUMENT_LOADER (gvloader)->info = info; - - finish_query_info (async); -} - -static void -mount_ready_callback (GFile *file, - GAsyncResult *res, - AsyncData *async) -{ - GError *error = NULL; - gboolean mounted; - - xed_debug (DEBUG_LOADER); - - /* manual check for cancelled state */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - mounted = g_file_mount_enclosing_volume_finish (file, res, &error); - - if (!mounted) - { - async_failed (async, error); - } - else - { - /* try again to open the file for reading */ - open_async_read (async); - } -} - -static void -recover_not_mounted (AsyncData *async) -{ - XedDocument *doc; - GMountOperation *mount_operation; - - xed_debug (DEBUG_LOADER); - - doc = xed_document_loader_get_document (XED_DOCUMENT_LOADER (async->loader)); - mount_operation = _xed_document_create_mount_operation (doc); - - async->tried_mount = TRUE; - g_file_mount_enclosing_volume (async->loader->priv->gfile, - G_MOUNT_MOUNT_NONE, - mount_operation, - async->cancellable, - (GAsyncReadyCallback) mount_ready_callback, - async); - - g_object_unref (mount_operation); -} - -static void -async_read_ready_callback (GObject *source, - GAsyncResult *res, - AsyncData *async) -{ - GError *error = NULL; - XedGioDocumentLoader *gvloader; - - xed_debug (DEBUG_LOADER); - - /* manual check for cancelled state */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - gvloader = async->loader; - - gvloader->priv->stream = G_INPUT_STREAM (g_file_read_finish (gvloader->priv->gfile, - res, &error)); - - if (!gvloader->priv->stream) - { - if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount) - { - recover_not_mounted (async); - g_error_free (error); - return; - } - - /* Propagate error */ - g_propagate_error (&gvloader->priv->error, error); - xed_document_loader_loading (XED_DOCUMENT_LOADER (gvloader), - TRUE, - gvloader->priv->error); - - async_data_free (async); - return; - } - - /* get the file info: note we cannot use - * g_file_input_stream_query_info_async since it is not able to get the - * content type etc, beside it is not supported by gvfs. - * Using the file instead of the stream is slightly racy, but for - * loading this is not too bad... - */ - g_file_query_info_async (gvloader->priv->gfile, - REMOTE_QUERY_ATTRIBUTES, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback) query_info_cb, - async); -} - -static void -open_async_read (AsyncData *async) -{ - g_file_read_async (async->loader->priv->gfile, - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback) async_read_ready_callback, - async); -} - -static void -xed_gio_document_loader_load (XedDocumentLoader *loader) -{ - XedGioDocumentLoader *gvloader = XED_GIO_DOCUMENT_LOADER (loader); - AsyncData *async; - - xed_debug (DEBUG_LOADER); - - /* make sure no load operation is currently running */ - g_return_if_fail (gvloader->priv->cancellable == NULL); - - gvloader->priv->gfile = g_file_new_for_uri (loader->uri); - - /* loading start */ - xed_document_loader_loading (XED_DOCUMENT_LOADER (gvloader), - FALSE, - NULL); - - gvloader->priv->cancellable = g_cancellable_new (); - async = async_data_new (gvloader); - - open_async_read (async); -} - -static goffset -xed_gio_document_loader_get_bytes_read (XedDocumentLoader *loader) -{ - return XED_GIO_DOCUMENT_LOADER (loader)->priv->bytes_read; -} - -static gboolean -xed_gio_document_loader_cancel (XedDocumentLoader *loader) -{ - XedGioDocumentLoader *gvloader = XED_GIO_DOCUMENT_LOADER (loader); - - if (gvloader->priv->cancellable == NULL) - return FALSE; - - g_cancellable_cancel (gvloader->priv->cancellable); - - g_set_error (&gvloader->priv->error, - G_IO_ERROR, - G_IO_ERROR_CANCELLED, - "Operation cancelled"); - - remote_load_completed_or_failed (gvloader, NULL); - - return TRUE; -} diff --git a/xed/xed-gio-document-loader.h b/xed/xed-gio-document-loader.h deleted file mode 100644 index 90e44bb..0000000 --- a/xed/xed-gio-document-loader.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * xed-gio-document-loader.h - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005-2008. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_GIO_DOCUMENT_LOADER_H__ -#define __XED_GIO_DOCUMENT_LOADER_H__ - -#include -#include "xed-document-loader.h" - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_GIO_DOCUMENT_LOADER (xed_gio_document_loader_get_type()) -#define XED_GIO_DOCUMENT_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_GIO_DOCUMENT_LOADER, XedGioDocumentLoader)) -#define XED_GIO_DOCUMENT_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_GIO_DOCUMENT_LOADER, XedGioDocumentLoaderClass)) -#define XED_IS_GIO_DOCUMENT_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_GIO_DOCUMENT_LOADER)) -#define XED_IS_GIO_DOCUMENT_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_GIO_DOCUMENT_LOADER)) -#define XED_GIO_DOCUMENT_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_GIO_DOCUMENT_LOADER, XedGioDocumentLoaderClass)) - -/* Private structure type */ -typedef struct _XedGioDocumentLoaderPrivate XedGioDocumentLoaderPrivate; - -/* - * Main object structure - */ -typedef struct _XedGioDocumentLoader XedGioDocumentLoader; - -struct _XedGioDocumentLoader -{ - XedDocumentLoader loader; - - /*< private > */ - XedGioDocumentLoaderPrivate *priv; -}; - -/* - * Class definition - */ -typedef XedDocumentLoaderClass XedGioDocumentLoaderClass; - -/* - * Public methods - */ -GType xed_gio_document_loader_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __XED_GIO_DOCUMENT_LOADER_H__ */ diff --git a/xed/xed-gio-document-saver.c b/xed/xed-gio-document-saver.c deleted file mode 100644 index 5d73f8c..0000000 --- a/xed/xed-gio-document-saver.c +++ /dev/null @@ -1,775 +0,0 @@ -/* - * xed-gio-document-saver.c - * This file is part of xed - * - * Copyright (C) 2005-2006 - Paolo Borelli and Paolo Maggi - * Copyright (C) 2007 - Paolo Borelli, Paolo Maggi, Steve Frécinaux - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005-2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "xed-gio-document-saver.h" -#include "xed-document-input-stream.h" -#include "xed-debug.h" - -#define WRITE_CHUNK_SIZE 8192 - -typedef struct -{ - XedGioDocumentSaver *saver; - gchar buffer[WRITE_CHUNK_SIZE]; - GCancellable *cancellable; - gboolean tried_mount; - gssize written; - gssize read; - GError *error; -} AsyncData; - -#define REMOTE_QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \ - G_FILE_ATTRIBUTE_TIME_MODIFIED - -#define XED_GIO_DOCUMENT_SAVER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_GIO_DOCUMENT_SAVER, \ - XedGioDocumentSaverPrivate)) - -static void xed_gio_document_saver_save (XedDocumentSaver *saver, - GTimeVal *old_mtime); -static goffset xed_gio_document_saver_get_file_size (XedDocumentSaver *saver); -static goffset xed_gio_document_saver_get_bytes_written (XedDocumentSaver *saver); - - -static void check_modified_async (AsyncData *async); - -struct _XedGioDocumentSaverPrivate -{ - GTimeVal old_mtime; - - goffset size; - goffset bytes_written; - - GFile *gfile; - GCancellable *cancellable; - GOutputStream *stream; - GInputStream *input; - - GError *error; -}; - -G_DEFINE_TYPE(XedGioDocumentSaver, xed_gio_document_saver, XED_TYPE_DOCUMENT_SAVER) - -static void -xed_gio_document_saver_dispose (GObject *object) -{ - XedGioDocumentSaverPrivate *priv = XED_GIO_DOCUMENT_SAVER (object)->priv; - - if (priv->cancellable != NULL) - { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - priv->cancellable = NULL; - } - - if (priv->gfile != NULL) - { - g_object_unref (priv->gfile); - priv->gfile = NULL; - } - - if (priv->error != NULL) - { - g_error_free (priv->error); - priv->error = NULL; - } - - if (priv->stream != NULL) - { - g_object_unref (priv->stream); - priv->stream = NULL; - } - - if (priv->input != NULL) - { - g_object_unref (priv->input); - priv->input = NULL; - } - - G_OBJECT_CLASS (xed_gio_document_saver_parent_class)->dispose (object); -} - -static AsyncData * -async_data_new (XedGioDocumentSaver *gvsaver) -{ - AsyncData *async; - - async = g_slice_new (AsyncData); - async->saver = gvsaver; - async->cancellable = g_object_ref (gvsaver->priv->cancellable); - - async->tried_mount = FALSE; - async->written = 0; - async->read = 0; - - async->error = NULL; - - return async; -} - -static void -async_data_free (AsyncData *async) -{ - g_object_unref (async->cancellable); - - if (async->error) - { - g_error_free (async->error); - } - - g_slice_free (AsyncData, async); -} - -static void -xed_gio_document_saver_class_init (XedGioDocumentSaverClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - XedDocumentSaverClass *saver_class = XED_DOCUMENT_SAVER_CLASS (klass); - - object_class->dispose = xed_gio_document_saver_dispose; - - saver_class->save = xed_gio_document_saver_save; - saver_class->get_file_size = xed_gio_document_saver_get_file_size; - saver_class->get_bytes_written = xed_gio_document_saver_get_bytes_written; - - g_type_class_add_private (object_class, sizeof(XedGioDocumentSaverPrivate)); -} - -static void -xed_gio_document_saver_init (XedGioDocumentSaver *gvsaver) -{ - gvsaver->priv = XED_GIO_DOCUMENT_SAVER_GET_PRIVATE (gvsaver); - - gvsaver->priv->cancellable = g_cancellable_new (); - gvsaver->priv->error = NULL; -} - -static void -remote_save_completed_or_failed (XedGioDocumentSaver *gvsaver, - AsyncData *async) -{ - xed_document_saver_saving (XED_DOCUMENT_SAVER (gvsaver), - TRUE, - gvsaver->priv->error); - - if (async) - async_data_free (async); -} - -static void -async_failed (AsyncData *async, - GError *error) -{ - g_propagate_error (&async->saver->priv->error, error); - remote_save_completed_or_failed (async->saver, async); -} - -/* BEGIN NOTE: - * - * This fixes an issue in GOutputStream that applies the atomic replace - * save strategy. The stream moves the written file to the original file - * when the stream is closed. However, there is no way currently to tell - * the stream that the save should be aborted (there could be a - * conversion error). The patch explicitly closes the output stream - * in all these cases with a GCancellable in the cancelled state, causing - * the output stream to close, but not move the file. This makes use - * of an implementation detail in the local gio file stream and should be - * properly fixed by adding the appropriate API in gio. Until then, at least - * we prevent data corruption for now. - * - * Relevant bug reports: - * - * Bug 615110 - write file ignore encoding errors (xed) - * https://bugzilla.gnome.org/show_bug.cgi?id=615110 - * - * Bug 602412 - g_file_replace does not restore original file when there is - * errors while writing (glib/gio) - * https://bugzilla.gnome.org/show_bug.cgi?id=602412 - */ -static void -cancel_output_stream_ready_cb (GOutputStream *stream, - GAsyncResult *result, - AsyncData *async) -{ - GError *error; - - g_output_stream_close_finish (stream, result, NULL); - - /* check cancelled state manually */ - if (g_cancellable_is_cancelled (async->cancellable) || async->error == NULL) - { - async_data_free (async); - return; - } - - error = async->error; - async->error = NULL; - - async_failed (async, error); -} - -static void -cancel_output_stream (AsyncData *async) -{ - GCancellable *cancellable; - - xed_debug_message (DEBUG_SAVER, "Cancel output stream"); - - cancellable = g_cancellable_new (); - g_cancellable_cancel (cancellable); - - g_output_stream_close_async (async->saver->priv->stream, - G_PRIORITY_HIGH, - cancellable, - (GAsyncReadyCallback)cancel_output_stream_ready_cb, - async); - - g_object_unref (cancellable); -} - -static void -cancel_output_stream_and_fail (AsyncData *async, - GError *error) -{ - - xed_debug_message (DEBUG_SAVER, "Cancel output stream and fail"); - - g_propagate_error (&async->error, error); - cancel_output_stream (async); -} - -/* - * END NOTE - */ - -static void -remote_get_info_cb (GFile *source, - GAsyncResult *res, - AsyncData *async) -{ - XedGioDocumentSaver *saver; - GFileInfo *info; - GError *error = NULL; - - xed_debug (DEBUG_SAVER); - - /* check cancelled state manually */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - saver = async->saver; - - xed_debug_message (DEBUG_SAVER, "Finished query info on file"); - info = g_file_query_info_finish (source, res, &error); - - if (info != NULL) - { - if (XED_DOCUMENT_SAVER (saver)->info != NULL) - g_object_unref (XED_DOCUMENT_SAVER (saver)->info); - - XED_DOCUMENT_SAVER (saver)->info = info; - } - else - { - xed_debug_message (DEBUG_SAVER, "Query info failed: %s", error->message); - g_propagate_error (&saver->priv->error, error); - } - - remote_save_completed_or_failed (saver, async); -} - -static void -close_async_ready_get_info_cb (GOutputStream *stream, - GAsyncResult *res, - AsyncData *async) -{ - GError *error = NULL; - - xed_debug (DEBUG_SAVER); - - /* check cancelled state manually */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - xed_debug_message (DEBUG_SAVER, "Finished closing stream"); - - if (!g_output_stream_close_finish (stream, res, &error)) - { - xed_debug_message (DEBUG_SAVER, "Closing stream error: %s", error->message); - - async_failed (async, error); - return; - } - - /* get the file info: note we cannot use - * g_file_output_stream_query_info_async since it is not able to get the - * content type etc, beside it is not supported by gvfs. - * I'm not sure this is actually necessary, can't we just use - * g_content_type_guess (since we have the file name and the data) - */ - xed_debug_message (DEBUG_SAVER, "Query info on file"); - g_file_query_info_async (async->saver->priv->gfile, - REMOTE_QUERY_ATTRIBUTES, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback) remote_get_info_cb, - async); -} - -static void -write_complete (AsyncData *async) -{ - GError *error = NULL; - - /* first we close the input stream */ - xed_debug_message (DEBUG_SAVER, "Close input stream"); - if (!g_input_stream_close (async->saver->priv->input, - async->cancellable, &error)) - { - xed_debug_message (DEBUG_SAVER, "Closing input stream error: %s", error->message); - cancel_output_stream_and_fail (async, error); - return; - } - - /* now we close the output stream */ - xed_debug_message (DEBUG_SAVER, "Close output stream"); - g_output_stream_close_async (async->saver->priv->stream, - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback)close_async_ready_get_info_cb, - async); -} - -/* prototype, because they call each other... isn't C lovely */ -static void read_file_chunk (AsyncData *async); -static void write_file_chunk (AsyncData *async); - -static void -async_write_cb (GOutputStream *stream, - GAsyncResult *res, - AsyncData *async) -{ - XedGioDocumentSaver *gvsaver; - gssize bytes_written; - GError *error = NULL; - - xed_debug (DEBUG_SAVER); - - /* Check cancelled state manually */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - cancel_output_stream (async); - return; - } - - bytes_written = g_output_stream_write_finish (stream, res, &error); - - xed_debug_message (DEBUG_SAVER, "Written: %" G_GSSIZE_FORMAT, bytes_written); - - if (bytes_written == -1) - { - xed_debug_message (DEBUG_SAVER, "Write error: %s", error->message); - cancel_output_stream_and_fail (async, error); - return; - } - - gvsaver = async->saver; - async->written += bytes_written; - - /* write again */ - if (async->written != async->read) - { - write_file_chunk (async); - return; - } - - /* note that this signal blocks the write... check if it isn't - * a performance problem - */ - xed_document_saver_saving (XED_DOCUMENT_SAVER (gvsaver), - FALSE, - NULL); - - read_file_chunk (async); -} - -static void -write_file_chunk (AsyncData *async) -{ - XedGioDocumentSaver *gvsaver; - - xed_debug (DEBUG_SAVER); - - gvsaver = async->saver; - - g_output_stream_write_async (G_OUTPUT_STREAM (gvsaver->priv->stream), - async->buffer + async->written, - async->read - async->written, - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback) async_write_cb, - async); -} - -static void -read_file_chunk (AsyncData *async) -{ - XedGioDocumentSaver *gvsaver; - XedDocumentInputStream *dstream; - GError *error = NULL; - - xed_debug (DEBUG_SAVER); - - gvsaver = async->saver; - async->written = 0; - - /* we use sync methods on doc stream since it is in memory. Using async - would be racy and we can endup with invalidated iters */ - async->read = g_input_stream_read (gvsaver->priv->input, - async->buffer, - WRITE_CHUNK_SIZE, - async->cancellable, - &error); - - if (error != NULL) - { - cancel_output_stream_and_fail (async, error); - return; - } - - /* Check if we finished reading and writing */ - if (async->read == 0) - { - write_complete (async); - return; - } - - /* Get how many chars have been read */ - dstream = XED_DOCUMENT_INPUT_STREAM (gvsaver->priv->input); - gvsaver->priv->bytes_written = xed_document_input_stream_tell (dstream); - - write_file_chunk (async); -} - -static void -async_replace_ready_callback (GFile *source, - GAsyncResult *res, - AsyncData *async) -{ - XedGioDocumentSaver *gvsaver; - XedDocumentSaver *saver; - GCharsetConverter *converter; - GFileOutputStream *file_stream; - GError *error = NULL; - - xed_debug (DEBUG_SAVER); - - /* Check cancelled state manually */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - gvsaver = async->saver; - saver = XED_DOCUMENT_SAVER (gvsaver); - file_stream = g_file_replace_finish (source, res, &error); - - /* handle any error that might occur */ - if (!file_stream) - { - xed_debug_message (DEBUG_SAVER, "Opening file failed: %s", error->message); - async_failed (async, error); - return; - } - - /* FIXME: manage converter error? */ - xed_debug_message (DEBUG_SAVER, "Encoding charset: %s", - xed_encoding_get_charset (saver->encoding)); - - if (saver->encoding != xed_encoding_get_utf8 ()) - { - converter = g_charset_converter_new (xed_encoding_get_charset (saver->encoding), - "UTF-8", - NULL); - gvsaver->priv->stream = g_converter_output_stream_new (G_OUTPUT_STREAM (file_stream), - G_CONVERTER (converter)); - - g_object_unref (file_stream); - g_object_unref (converter); - } - else - { - gvsaver->priv->stream = G_OUTPUT_STREAM (file_stream); - } - - gvsaver->priv->input = xed_document_input_stream_new (GTK_TEXT_BUFFER (saver->document), - saver->newline_type); - - gvsaver->priv->size = xed_document_input_stream_get_total_size (XED_DOCUMENT_INPUT_STREAM (gvsaver->priv->input)); - - read_file_chunk (async); -} - -static void -begin_write (AsyncData *async) -{ - XedGioDocumentSaver *gvsaver; - XedDocumentSaver *saver; - gboolean backup; - - xed_debug_message (DEBUG_SAVER, "Start replacing file contents"); - - /* For remote files we simply use g_file_replace_async. There is no - * backup as of yet - */ - gvsaver = async->saver; - saver = XED_DOCUMENT_SAVER (gvsaver); - - /* Do not make backups for remote files so they do not clutter remote systems */ - backup = (saver->keep_backup && xed_document_is_local (saver->document)); - - xed_debug_message (DEBUG_SAVER, "File contents size: %" G_GINT64_FORMAT, gvsaver->priv->size); - xed_debug_message (DEBUG_SAVER, "Calling replace_async"); - xed_debug_message (DEBUG_SAVER, backup ? "Keep backup" : "Discard backup"); - - g_file_replace_async (gvsaver->priv->gfile, - NULL, - backup, - G_FILE_CREATE_NONE, - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback) async_replace_ready_callback, - async); -} - -static void -mount_ready_callback (GFile *file, - GAsyncResult *res, - AsyncData *async) -{ - GError *error = NULL; - gboolean mounted; - - xed_debug (DEBUG_SAVER); - - /* manual check for cancelled state */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - mounted = g_file_mount_enclosing_volume_finish (file, res, &error); - - if (!mounted) - { - async_failed (async, error); - } - else - { - /* try again to get the modified state */ - check_modified_async (async); - } -} - -static void -recover_not_mounted (AsyncData *async) -{ - XedDocument *doc; - GMountOperation *mount_operation; - - xed_debug (DEBUG_LOADER); - - doc = xed_document_saver_get_document (XED_DOCUMENT_SAVER (async->saver)); - mount_operation = _xed_document_create_mount_operation (doc); - - async->tried_mount = TRUE; - g_file_mount_enclosing_volume (async->saver->priv->gfile, - G_MOUNT_MOUNT_NONE, - mount_operation, - async->cancellable, - (GAsyncReadyCallback) mount_ready_callback, - async); - - g_object_unref (mount_operation); -} - -static void -check_modification_callback (GFile *source, - GAsyncResult *res, - AsyncData *async) -{ - XedGioDocumentSaver *gvsaver; - GError *error = NULL; - GFileInfo *info; - - xed_debug (DEBUG_SAVER); - - /* manually check cancelled state */ - if (g_cancellable_is_cancelled (async->cancellable)) - { - async_data_free (async); - return; - } - - gvsaver = async->saver; - info = g_file_query_info_finish (source, res, &error); - if (info == NULL) - { - if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount) - { - recover_not_mounted (async); - g_error_free (error); - return; - } - - /* it's perfectly fine if the file doesn't exist yet */ - if (error->code != G_IO_ERROR_NOT_FOUND) - { - xed_debug_message (DEBUG_SAVER, "Error getting modification: %s", error->message); - - async_failed (async, error); - return; - } - } - - /* check if the mtime is > what we know about it (if we have it) */ - if (info != NULL && g_file_info_has_attribute (info, - G_FILE_ATTRIBUTE_TIME_MODIFIED)) - { - GTimeVal mtime; - GTimeVal old_mtime; - - g_file_info_get_modification_time (info, &mtime); - old_mtime = gvsaver->priv->old_mtime; - - if ((old_mtime.tv_sec > 0 || old_mtime.tv_usec > 0) && - (mtime.tv_sec != old_mtime.tv_sec || mtime.tv_usec != old_mtime.tv_usec) && - (XED_DOCUMENT_SAVER (gvsaver)->flags & XED_DOCUMENT_SAVE_IGNORE_MTIME) == 0) - { - xed_debug_message (DEBUG_SAVER, "File is externally modified"); - g_set_error (&gvsaver->priv->error, - XED_DOCUMENT_ERROR, - XED_DOCUMENT_ERROR_EXTERNALLY_MODIFIED, - "Externally modified"); - - remote_save_completed_or_failed (gvsaver, async); - g_object_unref (info); - - return; - } - } - - if (info != NULL) - g_object_unref (info); - - /* modification check passed, start write */ - begin_write (async); -} - -static void -check_modified_async (AsyncData *async) -{ - xed_debug_message (DEBUG_SAVER, "Check externally modified"); - - g_file_query_info_async (async->saver->priv->gfile, - G_FILE_ATTRIBUTE_TIME_MODIFIED, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_HIGH, - async->cancellable, - (GAsyncReadyCallback) check_modification_callback, - async); -} - -static gboolean -save_remote_file_real (XedGioDocumentSaver *gvsaver) -{ - AsyncData *async; - - xed_debug_message (DEBUG_SAVER, "Starting gio save"); - - /* First find out if the file is modified externally. This requires - * a stat, but I don't think we can do this any other way - */ - async = async_data_new (gvsaver); - - check_modified_async (async); - - /* return false to stop timeout */ - return FALSE; -} - -static void -xed_gio_document_saver_save (XedDocumentSaver *saver, - GTimeVal *old_mtime) -{ - XedGioDocumentSaver *gvsaver = XED_GIO_DOCUMENT_SAVER (saver); - - gvsaver->priv->old_mtime = *old_mtime; - gvsaver->priv->gfile = g_file_new_for_uri (saver->uri); - - /* saving start */ - xed_document_saver_saving (saver, FALSE, NULL); - - g_timeout_add_full (G_PRIORITY_HIGH, - 0, - (GSourceFunc) save_remote_file_real, - gvsaver, - NULL); -} - -static goffset -xed_gio_document_saver_get_file_size (XedDocumentSaver *saver) -{ - return XED_GIO_DOCUMENT_SAVER (saver)->priv->size; -} - -static goffset -xed_gio_document_saver_get_bytes_written (XedDocumentSaver *saver) -{ - return XED_GIO_DOCUMENT_SAVER (saver)->priv->bytes_written; -} diff --git a/xed/xed-gio-document-saver.h b/xed/xed-gio-document-saver.h deleted file mode 100644 index be18442..0000000 --- a/xed/xed-gio-document-saver.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * xed-gio-document-saver.h - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * Copyrhing (C) 2007 - Paolo Maggi, Steve Frécinaux - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005-2007. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifndef __XED_GIO_DOCUMENT_SAVER_H__ -#define __XED_GIO_DOCUMENT_SAVER_H__ - -#include - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_GIO_DOCUMENT_SAVER (xed_gio_document_saver_get_type()) -#define XED_GIO_DOCUMENT_SAVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_GIO_DOCUMENT_SAVER, XedGioDocumentSaver)) -#define XED_GIO_DOCUMENT_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_GIO_DOCUMENT_SAVER, XedGioDocumentSaverClass)) -#define XED_IS_GIO_DOCUMENT_SAVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_GIO_DOCUMENT_SAVER)) -#define XED_IS_GIO_DOCUMENT_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_GIO_DOCUMENT_SAVER)) -#define XED_GIO_DOCUMENT_SAVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_GIO_DOCUMENT_SAVER, XedGioDocumentSaverClass)) - -/* Private structure type */ -typedef struct _XedGioDocumentSaverPrivate XedGioDocumentSaverPrivate; - -/* - * Main object structure - */ -typedef struct _XedGioDocumentSaver XedGioDocumentSaver; - -struct _XedGioDocumentSaver -{ - XedDocumentSaver saver; - - /*< private > */ - XedGioDocumentSaverPrivate *priv; -}; - -/* - * Class definition - */ -typedef XedDocumentSaverClass XedGioDocumentSaverClass; - -/* - * Public methods - */ -GType xed_gio_document_saver_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __XED_GIO_DOCUMENT_SAVER_H__ */ diff --git a/xed/xed-help.c b/xed/xed-help.c deleted file mode 100644 index a904910..0000000 --- a/xed/xed-help.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * xed-help.c - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "xed-help.h" - -#include -#include -#include - -gboolean -xed_help_display (GtkWindow *parent, - const gchar *name, /* "xed" if NULL */ - const gchar *link_id) -{ - GError *error = NULL; - gboolean ret; - gchar *link; - - g_return_val_if_fail ((parent == NULL) || GTK_IS_WINDOW (parent), FALSE); - - if (name == NULL) - name = "xed"; - else if (strcmp (name, "xed.xml") == 0) - { - g_warning ("%s: Using \"xed.xml\" for the help name is deprecated, use \"xed\" or simply NULL instead", G_STRFUNC); - - name = "xed"; - } - - if (link_id) - link = g_strdup_printf ("help:%s/%s", name, link_id); - else - link = g_strdup_printf ("help:%s", name); - - ret = gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (parent)), - link, - GDK_CURRENT_TIME, - &error); - - g_free (link); - - if (error != NULL) - { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (parent, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _("There was an error displaying the help.")); - - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - "%s", error->message); - - g_signal_connect (G_OBJECT (dialog), - "response", - G_CALLBACK (gtk_widget_destroy), - NULL); - - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - - gtk_widget_show (dialog); - - g_error_free (error); - } - - return ret; -} diff --git a/xed/xed-help.h b/xed/xed-help.h deleted file mode 100644 index 2325589..0000000 --- a/xed/xed-help.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * xed-help.h - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_HELP_H__ -#define __XED_HELP_H__ - -#include - -G_BEGIN_DECLS - -gboolean xed_help_display (GtkWindow *parent, - const gchar *name, /* "xed" if NULL */ - const gchar *link_id); - -G_END_DECLS - -#endif /* __XED_HELP_H__ */ diff --git a/xed/xed-history-entry.c b/xed/xed-history-entry.c index 2e23d9b..7497faa 100644 --- a/xed/xed-history-entry.c +++ b/xed/xed-history-entry.c @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2006. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -38,12 +38,12 @@ #include #include "xed-history-entry.h" -#include "xed-prefs-manager.h" -enum { - PROP_0, - PROP_HISTORY_ID, - PROP_HISTORY_LENGTH +enum +{ + PROP_0, + PROP_HISTORY_ID, + PROP_HISTORY_LENGTH }; #define MIN_ITEM_LEN 3 @@ -51,494 +51,460 @@ enum { #define XED_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT 10 #define XED_HISTORY_ENTRY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_HISTORY_ENTRY, \ - XedHistoryEntryPrivate)) + XED_TYPE_HISTORY_ENTRY, \ + XedHistoryEntryPrivate)) struct _XedHistoryEntryPrivate { - gchar *history_id; - guint history_length; - - GtkEntryCompletion *completion; - - GSettings *settings; + gchar *history_id; + guint history_length; + GtkEntryCompletion *completion; + GSettings *settings; }; G_DEFINE_TYPE(XedHistoryEntry, xed_history_entry, GTK_TYPE_COMBO_BOX_TEXT) static void xed_history_entry_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *spec) + guint prop_id, + const GValue *value, + GParamSpec *spec) { - XedHistoryEntry *entry; + XedHistoryEntry *entry; - g_return_if_fail (XED_IS_HISTORY_ENTRY (object)); + g_return_if_fail (XED_IS_HISTORY_ENTRY (object)); - entry = XED_HISTORY_ENTRY (object); + entry = XED_HISTORY_ENTRY (object); - switch (prop_id) { - case PROP_HISTORY_ID: - entry->priv->history_id = g_value_dup_string (value); - break; - case PROP_HISTORY_LENGTH: - xed_history_entry_set_history_length (entry, - g_value_get_uint (value)); - break; - default: - break; - } + switch (prop_id) + { + case PROP_HISTORY_ID: + entry->priv->history_id = g_value_dup_string (value); + break; + case PROP_HISTORY_LENGTH: + xed_history_entry_set_history_length (entry, g_value_get_uint (value)); + break; + default: + break; + } } static void xed_history_entry_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *spec) + guint prop_id, + GValue *value, + GParamSpec *spec) { - XedHistoryEntryPrivate *priv; + XedHistoryEntryPrivate *priv; - g_return_if_fail (XED_IS_HISTORY_ENTRY (object)); + g_return_if_fail (XED_IS_HISTORY_ENTRY (object)); - priv = XED_HISTORY_ENTRY (object)->priv; + priv = XED_HISTORY_ENTRY (object)->priv; - switch (prop_id) { - case PROP_HISTORY_ID: - g_value_set_string (value, priv->history_id); - break; - case PROP_HISTORY_LENGTH: - g_value_set_uint (value, priv->history_length); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec); - } + switch (prop_id) + { + case PROP_HISTORY_ID: + g_value_set_string (value, priv->history_id); + break; + case PROP_HISTORY_LENGTH: + g_value_set_uint (value, priv->history_length); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec); + } } static void xed_history_entry_dispose (GObject *object) { - xed_history_entry_set_enable_completion (XED_HISTORY_ENTRY (object), - FALSE); + XedHistoryEntryPrivate *priv; - G_OBJECT_CLASS (xed_history_entry_parent_class)->dispose (object); + priv = XED_HISTORY_ENTRY (object)->priv; + xed_history_entry_set_enable_completion (XED_HISTORY_ENTRY (object), FALSE); + + g_clear_object (&priv->settings); + + G_OBJECT_CLASS (xed_history_entry_parent_class)->dispose (object); } static void xed_history_entry_finalize (GObject *object) { - XedHistoryEntryPrivate *priv; + XedHistoryEntryPrivate *priv; - priv = XED_HISTORY_ENTRY (object)->priv; - - g_free (priv->history_id); + priv = XED_HISTORY_ENTRY (object)->priv; - if (priv->settings != NULL) - { - g_object_unref (G_OBJECT (priv->settings)); - priv->settings = NULL; - } + g_free (priv->history_id); - G_OBJECT_CLASS (xed_history_entry_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_history_entry_parent_class)->finalize (object); } -static void +static void xed_history_entry_class_init (XedHistoryEntryClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = xed_history_entry_set_property; - object_class->get_property = xed_history_entry_get_property; - object_class->finalize = xed_history_entry_finalize; - object_class->dispose = xed_history_entry_dispose; - - g_object_class_install_property (object_class, - PROP_HISTORY_ID, - g_param_spec_string ("history-id", - "History ID", - "History ID", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_object_class_install_property (object_class, - PROP_HISTORY_LENGTH, - g_param_spec_uint ("history-length", - "Max History Length", - "Max History Length", - 0, - G_MAXUINT, - XED_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); + object_class->set_property = xed_history_entry_set_property; + object_class->get_property = xed_history_entry_get_property; + object_class->finalize = xed_history_entry_finalize; + object_class->dispose = xed_history_entry_dispose; - /* TODO: Add enable-completion property */ + g_object_class_install_property (object_class, + PROP_HISTORY_ID, + g_param_spec_string ("history-id", + "History ID", + "History ID", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); - g_type_class_add_private (object_class, sizeof(XedHistoryEntryPrivate)); + g_object_class_install_property (object_class, + PROP_HISTORY_LENGTH, + g_param_spec_uint ("history-length", + "Max History Length", + "Max History Length", + 0, + G_MAXUINT, + XED_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /* TODO: Add enable-completion property */ + + g_type_class_add_private (object_class, sizeof(XedHistoryEntryPrivate)); } static GtkListStore * get_history_store (XedHistoryEntry *entry) { - GtkTreeModel *store; + GtkTreeModel *store; - store = gtk_combo_box_get_model (GTK_COMBO_BOX (entry)); - g_return_val_if_fail (GTK_IS_LIST_STORE (store), NULL); + store = gtk_combo_box_get_model (GTK_COMBO_BOX (entry)); + g_return_val_if_fail (GTK_IS_LIST_STORE (store), NULL); - return (GtkListStore *) store; + return (GtkListStore *) store; } -static GSList * -get_history_list (XedHistoryEntry *entry) +static gchar ** +get_history_items (XedHistoryEntry *entry) { - GtkListStore *store; - GtkTreeIter iter; - gboolean valid; - GSList *list = NULL; + GtkListStore *store; + GtkTreeIter iter; + GPtrArray *array; + gboolean valid; + gint n_children; + gint text_column; - store = get_history_store (entry); + store = get_history_store (entry); + text_column = gtk_combo_box_get_entry_text_column (GTK_COMBO_BOX (entry)); + valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter); + n_children = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL); + array = g_ptr_array_sized_new (n_children + 1); - valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), - &iter); + while (valid) + { + gchar *str; - while (valid) - { - gchar *str; + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, text_column, &str, -1); - gtk_tree_model_get (GTK_TREE_MODEL (store), - &iter, - 0, &str, - -1); + g_ptr_array_add (array, str); + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); + } - list = g_slist_prepend (list, str); + g_ptr_array_add (array, NULL); - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), - &iter); - } - - return g_slist_reverse (list); + return (gchar **)g_ptr_array_free (array, FALSE); } static void xed_history_entry_save_history (XedHistoryEntry *entry) { - GSList *settings_items; + gchar **items; - g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); + g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - settings_items = get_history_list (entry); + items = get_history_items (entry); - xed_prefs_manager_set_gslist (entry->priv->settings, - entry->priv->history_id, - settings_items); + g_settings_set_strv (entry->priv->settings, entry->priv->history_id, (const gchar * const *)items); - g_slist_foreach (settings_items, (GFunc) g_free, NULL); - g_slist_free (settings_items); + g_strfreev (items); } static gboolean -remove_item (GtkListStore *store, - const gchar *text) +remove_item (XedHistoryEntry *entry, + const gchar *text) { - GtkTreeIter iter; + GtkListStore *store; + GtkTreeIter iter; + gint text_column; - g_return_val_if_fail (text != NULL, FALSE); + g_return_val_if_fail (text != NULL, FALSE); - if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) - return FALSE; + store = get_history_store (entry); + text_column = gtk_combo_box_get_entry_text_column (GTK_COMBO_BOX (entry)); - do - { - gchar *item_text; + if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) + { + return FALSE; + } - gtk_tree_model_get (GTK_TREE_MODEL (store), - &iter, - 0, - &item_text, - -1); + do + { + gchar *item_text; - if (item_text != NULL && - strcmp (item_text, text) == 0) - { - gtk_list_store_remove (store, &iter); - g_free (item_text); - return TRUE; - } + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, text_column, &item_text, -1); - g_free (item_text); + if (item_text != NULL && strcmp (item_text, text) == 0) + { + gtk_list_store_remove (store, &iter); + g_free (item_text); + return TRUE; + } - } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)); + g_free (item_text); - return FALSE; + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)); + + return FALSE; } static void clamp_list_store (GtkListStore *store, - guint max) + guint max) { - GtkTreePath *path; - GtkTreeIter iter; + GtkTreePath *path; + GtkTreeIter iter; - /* -1 because TreePath counts from 0 */ - path = gtk_tree_path_new_from_indices (max - 1, -1); + /* -1 because TreePath counts from 0 */ + path = gtk_tree_path_new_from_indices (max - 1, -1); - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) - { - while (1) - { - if (!gtk_list_store_remove (store, &iter)) - break; - } - } + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) + { + while (1) + { + if (!gtk_list_store_remove (store, &iter)) + { + break; + } + } + } - gtk_tree_path_free (path); + gtk_tree_path_free (path); } static void insert_history_item (XedHistoryEntry *entry, - const gchar *text, - gboolean prepend) + const gchar *text, + gboolean prepend) { - GtkListStore *store; - GtkTreeIter iter; + GtkListStore *store; - if (g_utf8_strlen (text, -1) <= MIN_ITEM_LEN) - return; - - store = get_history_store (entry); + if (g_utf8_strlen (text, -1) <= MIN_ITEM_LEN) + { + return; + } - /* remove the text from the store if it was already - * present. If it wasn't, clamp to max history - 1 - * before inserting the new row, otherwise appending - * would not work */ + store = get_history_store (entry); - if (!remove_item (store, text)) - clamp_list_store (store, - entry->priv->history_length - 1); + /* remove the text from the store if it was already + * present. If it wasn't, clamp to max history - 1 + * before inserting the new row, otherwise appending + * would not work */ - if (prepend) - gtk_list_store_insert (store, &iter, 0); - else - gtk_list_store_append (store, &iter); + if (!remove_item (entry, text)) + { + clamp_list_store (store, entry->priv->history_length - 1); + } - gtk_list_store_set (store, - &iter, - 0, - text, - -1); + if (prepend) + { + gtk_combo_box_text_prepend_text (GTK_COMBO_BOX_TEXT (entry), text); + } + else + { + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (entry), text); + } - xed_history_entry_save_history (entry); + xed_history_entry_save_history (entry); } void xed_history_entry_prepend_text (XedHistoryEntry *entry, - const gchar *text) + const gchar *text) { - g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - g_return_if_fail (text != NULL); + g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); + g_return_if_fail (text != NULL); - insert_history_item (entry, text, TRUE); + insert_history_item (entry, text, TRUE); } void xed_history_entry_append_text (XedHistoryEntry *entry, - const gchar *text) + const gchar *text) { - g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - g_return_if_fail (text != NULL); + g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); + g_return_if_fail (text != NULL); - insert_history_item (entry, text, FALSE); + insert_history_item (entry, text, FALSE); } static void xed_history_entry_load_history (XedHistoryEntry *entry) { - GSList *settings_items, *l; - GtkListStore *store; - GtkTreeIter iter; - guint i; + gchar **items; + gsize i; - g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); + g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - store = get_history_store (entry); + items = g_settings_get_strv (entry->priv->settings, entry->priv->history_id); + i = 0; - settings_items = xed_prefs_manager_get_gslist (entry->priv->settings, - entry->priv->history_id); + gtk_combo_box_text_remove_all (GTK_COMBO_BOX_TEXT (entry)); - gtk_list_store_clear (store); + /* Now the default value is an empty string so we have to take care of it to not + add the empty string in the search list */ + while (items[i] != NULL && *items[i] != '\0' && i < entry->priv->history_length) + { + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (entry), items[i]); + i++; + } - for (l = settings_items, i = 0; - l != NULL && i < entry->priv->history_length; - l = l->next, i++) - { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, - &iter, - 0, - l->data, - -1); - } - - g_slist_foreach (settings_items, (GFunc) g_free, NULL); - g_slist_free (settings_items); + g_strfreev (items); } void xed_history_entry_clear (XedHistoryEntry *entry) { - GtkListStore *store; + g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); + gtk_combo_box_text_remove_all (GTK_COMBO_BOX_TEXT (entry)); - store = get_history_store (entry); - gtk_list_store_clear (store); - - xed_history_entry_save_history (entry); + xed_history_entry_save_history (entry); } static void xed_history_entry_init (XedHistoryEntry *entry) { - XedHistoryEntryPrivate *priv; + XedHistoryEntryPrivate *priv; - priv = XED_HISTORY_ENTRY_GET_PRIVATE (entry); - entry->priv = priv; + priv = XED_HISTORY_ENTRY_GET_PRIVATE (entry); + entry->priv = priv; - priv->history_id = NULL; - priv->history_length = XED_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT; + priv->history_id = NULL; + priv->history_length = XED_HISTORY_ENTRY_HISTORY_LENGTH_DEFAULT; - priv->completion = NULL; + priv->completion = NULL; - priv->settings = g_settings_new (XED_SCHEMA); + priv->settings = g_settings_new ("org.x.editor.state.history-entry"); } void xed_history_entry_set_history_length (XedHistoryEntry *entry, - guint history_length) + guint history_length) { - g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - g_return_if_fail (history_length > 0); + g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); + g_return_if_fail (history_length > 0); - entry->priv->history_length = history_length; + entry->priv->history_length = history_length; - /* TODO: update if we currently have more items than max */ + /* TODO: update if we currently have more items than max */ } guint xed_history_entry_get_history_length (XedHistoryEntry *entry) { - g_return_val_if_fail (XED_IS_HISTORY_ENTRY (entry), 0); + g_return_val_if_fail (XED_IS_HISTORY_ENTRY (entry), 0); - return entry->priv->history_length; -} - -gchar * -xed_history_entry_get_history_id (XedHistoryEntry *entry) -{ - g_return_val_if_fail (XED_IS_HISTORY_ENTRY (entry), NULL); - - return g_strdup (entry->priv->history_id); + return entry->priv->history_length; } void xed_history_entry_set_enable_completion (XedHistoryEntry *entry, - gboolean enable) + gboolean enable) { - g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - - if (enable) - { - if (entry->priv->completion != NULL) - return; - - entry->priv->completion = gtk_entry_completion_new (); - gtk_entry_completion_set_model (entry->priv->completion, - GTK_TREE_MODEL (get_history_store (entry))); - - /* Use model column 0 as the text column */ - gtk_entry_completion_set_text_column (entry->priv->completion, 0); + g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - gtk_entry_completion_set_minimum_key_length (entry->priv->completion, - MIN_ITEM_LEN); + if (enable) + { + if (entry->priv->completion != NULL) + { + return; + } - gtk_entry_completion_set_popup_completion (entry->priv->completion, FALSE); - gtk_entry_completion_set_inline_completion (entry->priv->completion, TRUE); - - /* Assign the completion to the entry */ - gtk_entry_set_completion (GTK_ENTRY (xed_history_entry_get_entry(entry)), - entry->priv->completion); - } - else - { - if (entry->priv->completion == NULL) - return; + entry->priv->completion = gtk_entry_completion_new (); + gtk_entry_completion_set_model (entry->priv->completion, GTK_TREE_MODEL (get_history_store (entry))); - gtk_entry_set_completion (GTK_ENTRY (xed_history_entry_get_entry (entry)), - NULL); - - g_object_unref (entry->priv->completion); - - entry->priv->completion = NULL; - } + /* Use model column 0 as the text column */ + gtk_entry_completion_set_text_column (entry->priv->completion, 0); + + gtk_entry_completion_set_minimum_key_length (entry->priv->completion, MIN_ITEM_LEN); + + gtk_entry_completion_set_popup_completion (entry->priv->completion, FALSE); + gtk_entry_completion_set_inline_completion (entry->priv->completion, TRUE); + + /* Assign the completion to the entry */ + gtk_entry_set_completion (GTK_ENTRY (xed_history_entry_get_entry(entry)), entry->priv->completion); + } + else + { + if (entry->priv->completion == NULL) + { + return; + } + + gtk_entry_set_completion (GTK_ENTRY (xed_history_entry_get_entry (entry)), NULL); + + g_object_unref (entry->priv->completion); + + entry->priv->completion = NULL; + } } - + gboolean xed_history_entry_get_enable_completion (XedHistoryEntry *entry) { - g_return_val_if_fail (XED_IS_HISTORY_ENTRY (entry), FALSE); - - return entry->priv->completion != NULL; + g_return_val_if_fail (XED_IS_HISTORY_ENTRY (entry), FALSE); + + return entry->priv->completion != NULL; } GtkWidget * xed_history_entry_new (const gchar *history_id, - gboolean enable_completion) + gboolean enable_completion) { - GtkWidget *ret; - GtkListStore *store; + GtkWidget *ret; - g_return_val_if_fail (history_id != NULL, NULL); + g_return_val_if_fail (history_id != NULL, NULL); - /* Note that we are setting the model, so - * user must be careful to always manipulate - * data in the history through xed_history_entry_ - * functions. - */ + ret = g_object_new (XED_TYPE_HISTORY_ENTRY, + "has-entry", TRUE, + "entry-text-column", 0, + "id-column", 1, + "history-id", history_id, + NULL); - store = gtk_list_store_new (1, G_TYPE_STRING); + /* loading has to happen after the model + * has been set. However the model is not a + * G_PARAM_CONSTRUCT property of GtkComboBox + * so we cannot do this in the constructor. + * For now we simply do here since this widget is + * not bound to other programming languages. + * A maybe better alternative is to override the + * model property of combobox and mark CONTRUCT_ONLY. + * This would also ensure that the model cannot be + * set explicitely at a later time. + */ + xed_history_entry_load_history (XED_HISTORY_ENTRY (ret)); - ret = g_object_new (XED_TYPE_HISTORY_ENTRY, - "history-id", history_id, - "model", store, - "has-entry", TRUE, - "entry-text-column", 0, - NULL); + xed_history_entry_set_enable_completion (XED_HISTORY_ENTRY (ret), enable_completion); - g_object_unref (store); - - /* loading has to happen after the model - * has been set. However the model is not a - * G_PARAM_CONSTRUCT property of GtkComboBox - * so we cannot do this in the constructor. - * For now we simply do here since this widget is - * not bound to other programming languages. - * A maybe better alternative is to override the - * model property of combobox and mark CONTRUCT_ONLY. - * This would also ensure that the model cannot be - * set explicitely at a later time. - */ - xed_history_entry_load_history (XED_HISTORY_ENTRY (ret)); - - xed_history_entry_set_enable_completion (XED_HISTORY_ENTRY (ret), - enable_completion); - - return ret; + return ret; } /* * Utility function to get the editable text entry internal widget. - * I would prefer to not expose this implementation detail and - * simply make the XedHistoryEntry widget implement the + * I would prefer to not expose this implementation detail and + * simply make the XedHistoryEntry widget implement the * GtkEditable interface. Unfortunately both GtkEditable and * GtkComboBox have a "changed" signal and I am not sure how to * handle the conflict. @@ -546,54 +512,7 @@ xed_history_entry_new (const gchar *history_id, GtkWidget * xed_history_entry_get_entry (XedHistoryEntry *entry) { - g_return_val_if_fail (XED_IS_HISTORY_ENTRY (entry), NULL); + g_return_val_if_fail (XED_IS_HISTORY_ENTRY (entry), NULL); - return gtk_bin_get_child (GTK_BIN (entry)); -} - -static void -escape_cell_data_func (GtkTreeViewColumn *col, - GtkCellRenderer *renderer, - GtkTreeModel *model, - GtkTreeIter *iter, - XedHistoryEntryEscapeFunc escape_func) -{ - gchar *str; - gchar *escaped; - - gtk_tree_model_get (model, iter, 0, &str, -1); - escaped = escape_func (str); - g_object_set (renderer, "text", escaped, NULL); - - g_free (str); - g_free (escaped); -} - -void -xed_history_entry_set_escape_func (XedHistoryEntry *entry, - XedHistoryEntryEscapeFunc escape_func) -{ - GList *cells; - - g_return_if_fail (XED_IS_HISTORY_ENTRY (entry)); - - cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (entry)); - - /* We only have one cell renderer */ - g_return_if_fail (cells->data != NULL && cells->next == NULL); - - if (escape_func != NULL) - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry), - GTK_CELL_RENDERER (cells->data), - (GtkCellLayoutDataFunc) escape_cell_data_func, - escape_func, - NULL); - else - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry), - GTK_CELL_RENDERER (cells->data), - NULL, - NULL, - NULL); - - g_list_free (cells); + return gtk_bin_get_child (GTK_BIN (entry)); } diff --git a/xed/xed-history-entry.h b/xed/xed-history-entry.h index 0fa844c..4ebe92b 100644 --- a/xed/xed-history-entry.h +++ b/xed/xed-history-entry.h @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2006. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -48,48 +48,37 @@ typedef struct _XedHistoryEntryPrivate XedHistoryEntryPrivate; struct _XedHistoryEntryClass { - GtkComboBoxTextClass parent_class; + GtkComboBoxTextClass parent_class; }; struct _XedHistoryEntry { - GtkComboBoxText parent_instance; + GtkComboBoxText parent_instance; - XedHistoryEntryPrivate *priv; + XedHistoryEntryPrivate *priv; }; -GType xed_history_entry_get_type (void) G_GNUC_CONST; +GType xed_history_entry_get_type (void) G_GNUC_CONST; -GtkWidget *xed_history_entry_new (const gchar *history_id, - gboolean enable_completion); +GtkWidget *xed_history_entry_new (const gchar *history_id, + gboolean enable_completion); -void xed_history_entry_prepend_text (XedHistoryEntry *entry, - const gchar *text); +void xed_history_entry_prepend_text (XedHistoryEntry *entry, + const gchar *text); +void xed_history_entry_append_text (XedHistoryEntry *entry, + const gchar *text); -void xed_history_entry_append_text (XedHistoryEntry *entry, - const gchar *text); +void xed_history_entry_clear (XedHistoryEntry *entry); -void xed_history_entry_clear (XedHistoryEntry *entry); +void xed_history_entry_set_history_length (XedHistoryEntry *entry, + guint max_saved); +guint xed_history_entry_get_history_length (XedHistoryEntry *gentry); -void xed_history_entry_set_history_length (XedHistoryEntry *entry, - guint max_saved); +void xed_history_entry_set_enable_completion (XedHistoryEntry *entry, + gboolean enable); +gboolean xed_history_entry_get_enable_completion (XedHistoryEntry *entry); -guint xed_history_entry_get_history_length (XedHistoryEntry *gentry); - -gchar *xed_history_entry_get_history_id (XedHistoryEntry *entry); - -void xed_history_entry_set_enable_completion - (XedHistoryEntry *entry, - gboolean enable); - -gboolean xed_history_entry_get_enable_completion - (XedHistoryEntry *entry); - -GtkWidget *xed_history_entry_get_entry (XedHistoryEntry *entry); - -typedef gchar * (* XedHistoryEntryEscapeFunc) (const gchar *str); -void xed_history_entry_set_escape_func (XedHistoryEntry *entry, - XedHistoryEntryEscapeFunc escape_func); +GtkWidget *xed_history_entry_get_entry (XedHistoryEntry *entry); G_END_DECLS diff --git a/xed/xed-io-error-info-bar.c b/xed/xed-io-error-info-bar.c new file mode 100644 index 0000000..682d7a3 --- /dev/null +++ b/xed/xed-io-error-info-bar.c @@ -0,0 +1,1142 @@ +/* + * xed-io-error-info-bar.c + * This file is part of xed + * + * Copyright (C) 2005 - Paolo Maggi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. + * + * $Id$ + */ + +/* + * Verbose error reporting for file I/O operations (load, save, revert, create) + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include + +#include "xed-settings.h" +#include "xed-utils.h" +#include "xed-document.h" +#include "xed-io-error-info-bar.h" +#include + +#define MAX_URI_IN_DIALOG_LENGTH 50 + +static gboolean +is_recoverable_error (const GError *error) +{ + gboolean is_recoverable = FALSE; + + if (error->domain == G_IO_ERROR) + { + switch (error->code) + { + case G_IO_ERROR_PERMISSION_DENIED: + case G_IO_ERROR_NOT_FOUND: + case G_IO_ERROR_HOST_NOT_FOUND: + case G_IO_ERROR_TIMED_OUT: + case G_IO_ERROR_NOT_MOUNTABLE_FILE: + case G_IO_ERROR_NOT_MOUNTED: + case G_IO_ERROR_BUSY: + is_recoverable = TRUE; + } + } + + return is_recoverable; +} + +static gboolean +is_gio_error (const GError *error, + gint code) +{ + return error->domain == G_IO_ERROR && error->code == code; +} + +static void +set_contents (GtkWidget *area, + GtkWidget *contents) +{ + GtkWidget *content_area; + + content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (area)); + gtk_container_add (GTK_CONTAINER (content_area), contents); +} + +static void +set_info_bar_text_and_icon (GtkWidget *info_bar, + const gchar *icon_name, + const gchar *primary_text, + const gchar *secondary_text) +{ + GtkWidget *hbox_content; + GtkWidget *image; + GtkWidget *vbox; + gchar *primary_markup; + gchar *secondary_markup; + GtkWidget *primary_label; + GtkWidget *secondary_label; + + hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); + + image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG); + gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); + gtk_widget_set_halign (image, GTK_ALIGN_CENTER); + gtk_widget_set_valign (image, GTK_ALIGN_START); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); + + primary_markup = g_strdup_printf ("%s", primary_text); + primary_label = gtk_label_new (primary_markup); + g_free (primary_markup); + gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); + gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); + gtk_widget_set_halign (primary_label, GTK_ALIGN_START); + gtk_widget_set_can_focus (primary_label, TRUE); + gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); + + if (secondary_text != NULL) + { + secondary_markup = g_strdup_printf ("%s", secondary_text); + secondary_label = gtk_label_new (secondary_markup); + g_free (secondary_markup); + gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); + gtk_widget_set_can_focus (secondary_label, TRUE); + gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); + gtk_widget_set_halign (secondary_label, GTK_ALIGN_START); + } + + gtk_widget_show_all (hbox_content); + set_contents (info_bar, hbox_content); +} + +static GtkWidget * +create_io_loading_error_info_bar (const gchar *primary_text, + const gchar *secondary_text, + gboolean recoverable_error) +{ + GtkWidget *info_bar; + + info_bar = gtk_info_bar_new_with_buttons (_("_Cancel"), GTK_RESPONSE_CANCEL, NULL); + gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_ERROR); + + set_info_bar_text_and_icon (info_bar, "dialog-error-symbolic", primary_text, secondary_text); + + if (recoverable_error) + { + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("_Retry"), GTK_RESPONSE_OK); + } + + return info_bar; +} + +static gboolean +parse_gio_error (gint code, + gchar **error_message, + gchar **message_details, + GFile *location, + const gchar *uri_for_display) +{ + gboolean ret = TRUE; + + switch (code) + { + case G_IO_ERROR_NOT_FOUND: + case G_IO_ERROR_NOT_DIRECTORY: + *error_message = g_strdup_printf (_("Could not find the file %s."), uri_for_display); + *message_details = g_strdup (_("Please check that you typed the " + "location correctly and try again.")); + break; + case G_IO_ERROR_NOT_SUPPORTED: + { + gchar *scheme_string; + gchar *scheme_markup; + + scheme_string = g_file_get_uri_scheme (location); + + if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL)) + { + scheme_markup = g_markup_printf_escaped ("%s:", scheme_string); + + /* Translators: %s is a URI scheme (like for example http:, ftp:, etc.) */ + *message_details = g_strdup_printf (_("xed cannot handle %s locations."), scheme_markup); + g_free (scheme_markup); + } + else + { + *message_details = g_strdup (_("xed cannot handle this location.")); + } + + g_free (scheme_string); + } + break; + case G_IO_ERROR_NOT_MOUNTABLE_FILE: + *message_details = g_strdup (_("The location of the file cannot be mounted.")); + break; + case G_IO_ERROR_NOT_MOUNTED: + *message_details = g_strdup( _("The location of the file cannot be accessed because it is not mounted.")); + break; + case G_IO_ERROR_IS_DIRECTORY: + *error_message = g_strdup_printf (_("%s is a directory."), uri_for_display); + *message_details = g_strdup (_("Please check that you typed the " + "location correctly and try again.")); + break; + case G_IO_ERROR_INVALID_FILENAME: + *error_message = g_strdup_printf (_("%s is not a valid location."), uri_for_display); + *message_details = g_strdup (_("Please check that you typed the " + "location correctly and try again.")); + break; + case G_IO_ERROR_HOST_NOT_FOUND: + /* This case can be hit for user-typed strings like "foo" due to + * the code that guesses web addresses when there's no initial "/". + * But this case is also hit for legitimate web addresses when + * the proxy is set up wrong. + */ + { + gchar *hn = NULL; + gchar *uri; + + uri = g_file_get_uri (location); + + if (uri && xed_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL)) + { + if (hn != NULL) + { + gchar *host_markup; + gchar *host_name; + + host_name = xed_utils_make_valid_utf8 (hn); + g_free (hn); + + host_markup = g_markup_printf_escaped ("%s", host_name); + g_free (host_name); + + /* Translators: %s is a host name */ + *message_details = g_strdup_printf (_("Host %s could not be found. " + "Please check that your proxy settings " + "are correct and try again."), + host_markup); + + g_free (host_markup); + } + } + + g_free (uri); + + if (!*message_details) + { + /* use the same string as INVALID_HOST */ + *message_details = g_strdup_printf (_("Hostname was invalid. " + "Please check that you typed the location " + "correctly and try again.")); + } + } + break; + case G_IO_ERROR_NOT_REGULAR_FILE: + *message_details = g_strdup_printf (_("%s is not a regular file."), uri_for_display); + break; + case G_IO_ERROR_TIMED_OUT: + *message_details = g_strdup (_("Connection timed out. Please try again.")); + break; + default: + ret = FALSE; + break; + } + + return ret; +} + +static void +parse_error (const GError *error, + gchar **error_message, + gchar **message_details, + GFile *location, + const gchar *uri_for_display) +{ + gboolean ret = FALSE; + + if (error->domain == G_IO_ERROR) + { + ret = parse_gio_error (error->code, error_message, message_details, location, uri_for_display); + } + + if (!ret) + { + g_warning ("Hit unhandled case %d (%s) in %s.", error->code, error->message, G_STRFUNC); + *message_details = g_strdup_printf (_("Unexpected error: %s"), error->message); + } +} + +GtkWidget * +xed_unrecoverable_reverting_error_info_bar_new (GFile *location, + const GError *error) +{ + gchar *error_message = NULL; + gchar *message_details = NULL; + gchar *full_formatted_uri; + gchar *uri_for_display; + gchar *temp_uri_for_display; + GtkWidget *info_bar; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail ((error->domain == GTK_SOURCE_FILE_LOADER_ERROR) || error->domain == G_IO_ERROR, NULL); + + full_formatted_uri = g_file_get_parse_name (location); + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + if (is_gio_error (error, G_IO_ERROR_NOT_FOUND)) + { + message_details = g_strdup (_("xed cannot find the file. " + "Perhaps it has recently been deleted.")); + } + else + { + parse_error (error, &error_message, &message_details, location, uri_for_display); + } + + if (error_message == NULL) + { + error_message = g_strdup_printf (_("Could not revert the file %s."), uri_for_display); + } + + info_bar = create_io_loading_error_info_bar (error_message, message_details, FALSE); + + g_free (uri_for_display); + g_free (error_message); + g_free (message_details); + + return info_bar; +} + +static void +create_combo_box (GtkWidget *info_bar, + GtkWidget *vbox) +{ + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *menu; + gchar *label_markup; + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + + label_markup = g_strdup_printf ("%s", _("Ch_aracter Encoding:")); + label = gtk_label_new_with_mnemonic (label_markup); + g_free (label_markup); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + menu = xed_encodings_combo_box_new (TRUE); + g_object_set_data (G_OBJECT (info_bar), "xed-info-bar-encoding-menu", menu); + + gtk_label_set_mnemonic_widget (GTK_LABEL (label), menu); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), menu, FALSE, FALSE, 0); + + gtk_widget_show_all (hbox); + gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); +} + +static GtkWidget * +create_conversion_error_info_bar (const gchar *primary_text, + const gchar *secondary_text, + gboolean edit_anyway) +{ + GtkWidget *info_bar; + GtkWidget *hbox_content; + GtkWidget *image; + GtkWidget *vbox; + gchar *primary_markup; + gchar *secondary_markup; + GtkWidget *primary_label; + GtkWidget *secondary_label; + + info_bar = gtk_info_bar_new (); + + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("_Retry"), GTK_RESPONSE_OK); + + if (edit_anyway) + { + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), + /* Translators: the access key chosen for this string should be + different from other main menu access keys (Open, Edit, View...) */ + _("Edit Any_way"), + GTK_RESPONSE_YES); + gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_WARNING); + } + else + { + gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_ERROR); + } + + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("_Cancel"), GTK_RESPONSE_CANCEL); + + hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); + + image = gtk_image_new_from_icon_name ("dialog-error-symbolic", GTK_ICON_SIZE_DIALOG); + gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); + gtk_widget_set_halign (image, GTK_ALIGN_CENTER); + gtk_widget_set_valign (image, GTK_ALIGN_START); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); + + primary_markup = g_strdup_printf ("%s", primary_text); + primary_label = gtk_label_new (primary_markup); + g_free (primary_markup); + gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); + gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); + gtk_widget_set_halign (primary_label, GTK_ALIGN_START); + gtk_widget_set_can_focus (primary_label, TRUE); + gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); + + if (secondary_text != NULL) + { + secondary_markup = g_strdup_printf ("%s", secondary_text); + secondary_label = gtk_label_new (secondary_markup); + g_free (secondary_markup); + gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); + gtk_widget_set_can_focus (secondary_label, TRUE); + gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); + gtk_widget_set_halign (secondary_label, GTK_ALIGN_START); + } + + create_combo_box (info_bar, vbox); + gtk_widget_show_all (hbox_content); + set_contents (info_bar, hbox_content); + + return info_bar; +} + +GtkWidget * +xed_io_loading_error_info_bar_new (GFile *location, + const GtkSourceEncoding *encoding, + const GError *error) +{ + gchar *error_message = NULL; + gchar *message_details = NULL; + gchar *full_formatted_uri; + gchar *uri_for_display; + gchar *temp_uri_for_display; + GtkWidget *info_bar; + gboolean edit_anyway = FALSE; + gboolean convert_error = FALSE; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_LOADER_ERROR || + error->domain == G_IO_ERROR || + error->domain == G_CONVERT_ERROR, NULL); + + if (location != NULL) + { + full_formatted_uri = g_file_get_parse_name (location); + } + else + { + full_formatted_uri = g_strdup ("stdin"); + } + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + if (is_gio_error (error, G_IO_ERROR_TOO_MANY_LINKS)) + { + message_details = g_strdup (_("The number of followed links is limited and the actual file could not be found within this limit.")); + } + else if (is_gio_error (error, G_IO_ERROR_PERMISSION_DENIED)) + { + message_details = g_strdup (_("You do not have the permissions necessary to open the file.")); + } + else if ((is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding == NULL) || + (error->domain == GTK_SOURCE_FILE_LOADER_ERROR && + error->code == GTK_SOURCE_FILE_LOADER_ERROR_ENCODING_AUTO_DETECTION_FAILED)) + { + message_details = g_strconcat (_("xed has not been able to detect " + "the character encoding."), "\n", + _("Please check that you are not trying to open a binary file."), "\n", + _("Select a character encoding from the menu and try again."), NULL); + convert_error = TRUE; + } + else if (error->domain == GTK_SOURCE_FILE_LOADER_ERROR && + error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK) + { + error_message = g_strdup_printf (_("There was a problem opening the file %s."), uri_for_display); + message_details = g_strconcat (_("The file you opened has some invalid characters. " + "If you continue editing this file you could corrupt this " + "document."), "\n", + _("You can also choose another character encoding and try again."), + NULL); + edit_anyway = TRUE; + convert_error = TRUE; + } + else if (is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding != NULL) + { + gchar *encoding_name = gtk_source_encoding_to_string (encoding); + + error_message = g_strdup_printf (_("Could not open the file %s using the %s character encoding."), + uri_for_display, + encoding_name); + message_details = g_strconcat (_("Please check that you are not trying to open a binary file."), "\n", + _("Select a different character encoding from the menu and try again."), NULL); + convert_error = TRUE; + + g_free (encoding_name); + } + else + { + parse_error (error, &error_message, &message_details, location, uri_for_display); + } + + if (error_message == NULL) + { + error_message = g_strdup_printf (_("Could not open the file %s."), uri_for_display); + } + + if (convert_error) + { + info_bar = create_conversion_error_info_bar (error_message, message_details, edit_anyway); + } + else + { + info_bar = create_io_loading_error_info_bar (error_message, message_details, is_recoverable_error (error)); + } + + g_free (uri_for_display); + g_free (error_message); + g_free (message_details); + + return info_bar; +} + +GtkWidget * +xed_conversion_error_while_saving_info_bar_new (GFile *location, + const GtkSourceEncoding *encoding, + const GError *error) +{ + gchar *error_message = NULL; + gchar *message_details = NULL; + gchar *full_formatted_uri; + gchar *encoding_name; + gchar *uri_for_display; + gchar *temp_uri_for_display; + GtkWidget *info_bar; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (error->domain == G_CONVERT_ERROR || + error->domain == G_IO_ERROR, NULL); + g_return_val_if_fail (encoding != NULL, NULL); + + full_formatted_uri = g_file_get_parse_name (location); + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + encoding_name = gtk_source_encoding_to_string (encoding); + + error_message = g_strdup_printf (_("Could not save the file %s using the %s character encoding."), + uri_for_display, + encoding_name); + message_details = g_strconcat (_("The document contains one or more characters that cannot be encoded " + "using the specified character encoding."), "\n", + _("Select a different character encoding from the menu and try again."), NULL); + + info_bar = create_conversion_error_info_bar (error_message, message_details, FALSE); + + g_free (uri_for_display); + g_free (encoding_name); + g_free (error_message); + g_free (message_details); + + return info_bar; +} + +const GtkSourceEncoding * +xed_conversion_error_info_bar_get_encoding (GtkWidget *info_bar) +{ + gpointer menu; + + g_return_val_if_fail (GTK_IS_INFO_BAR (info_bar), NULL); + + menu = g_object_get_data (G_OBJECT (info_bar), "xed-info-bar-encoding-menu"); + g_return_val_if_fail (menu, NULL); + + return xed_encodings_combo_box_get_selected_encoding (XED_ENCODINGS_COMBO_BOX (menu)); +} + +GtkWidget * +xed_file_already_open_warning_info_bar_new (GFile *location) +{ + GtkWidget *info_bar; + GtkWidget *hbox_content; + GtkWidget *image; + GtkWidget *vbox; + gchar *primary_markup; + gchar *secondary_markup; + GtkWidget *primary_label; + GtkWidget *secondary_label; + gchar *primary_text; + const gchar *secondary_text; + gchar *full_formatted_uri; + gchar *uri_for_display; + gchar *temp_uri_for_display; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + + full_formatted_uri = g_file_get_parse_name (location); + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + info_bar = gtk_info_bar_new (); + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), + /* Translators: the access key chosen for this string should be + different from other main menu access keys (Open, Edit, View...) */ + _("Edit Any_way"), + GTK_RESPONSE_YES); + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), + /* Translators: the access key chosen for this string should be + different from other main menu access keys (Open, Edit, View...) */ + _("D_on't Edit"), + GTK_RESPONSE_CANCEL); + gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_WARNING); + + hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); + + image = gtk_image_new_from_icon_name ("dialog-warning-symbolic", GTK_ICON_SIZE_DIALOG); + gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); + gtk_widget_set_halign (image, GTK_ALIGN_CENTER); + gtk_widget_set_valign (image, GTK_ALIGN_START); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); + + primary_text = g_strdup_printf (_("This file (%s) is already open in another xed window."), uri_for_display); + g_free (uri_for_display); + + primary_markup = g_strdup_printf ("%s", primary_text); + g_free (primary_text); + primary_label = gtk_label_new (primary_markup); + g_free (primary_markup); + gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); + gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); + gtk_widget_set_halign (primary_label, GTK_ALIGN_START); + gtk_widget_set_can_focus (primary_label, TRUE); + gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); + + secondary_text = _("xed opened this instance of the file in a non-editable way. " + "Do you want to edit it anyway?"); + secondary_markup = g_strdup_printf ("%s", secondary_text); + secondary_label = gtk_label_new (secondary_markup); + g_free (secondary_markup); + gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); + gtk_widget_set_can_focus (secondary_label, TRUE); + gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); + gtk_widget_set_halign (secondary_label, GTK_ALIGN_START); + + gtk_widget_show_all (hbox_content); + set_contents (info_bar, hbox_content); + + return info_bar; +} + +GtkWidget * +xed_externally_modified_saving_error_info_bar_new (GFile *location, + const GError *error) +{ + GtkWidget *info_bar; + GtkWidget *hbox_content; + GtkWidget *image; + GtkWidget *vbox; + gchar *primary_markup; + gchar *secondary_markup; + GtkWidget *primary_label; + GtkWidget *secondary_label; + gchar *primary_text; + const gchar *secondary_text; + gchar *full_formatted_uri; + gchar *uri_for_display; + gchar *temp_uri_for_display; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_SAVER_ERROR, NULL); + g_return_val_if_fail (error->code == GTK_SOURCE_FILE_SAVER_ERROR_EXTERNALLY_MODIFIED, NULL); + + full_formatted_uri = g_file_get_parse_name (location); + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + info_bar = gtk_info_bar_new (); + + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("S_ave Anyway"), GTK_RESPONSE_YES); + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("D_on't Save"), GTK_RESPONSE_CANCEL); + gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_WARNING); + + hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); + + image = gtk_image_new_from_icon_name ("dialog-warning-symbolic", GTK_ICON_SIZE_DIALOG); + gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); + gtk_widget_set_halign (image, GTK_ALIGN_CENTER); + gtk_widget_set_valign (image, GTK_ALIGN_START); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); + + /* FIXME: review this message, it's not clear since for the user the "modification" + * could be interpreted as the changes he made in the document. beside "reading" is + * not accurate (since last load/save) + */ + primary_text = g_strdup_printf (_("The file %s has been modified since reading it."), uri_for_display); + g_free (uri_for_display); + + primary_markup = g_strdup_printf ("%s", primary_text); + g_free (primary_text); + primary_label = gtk_label_new (primary_markup); + g_free (primary_markup); + gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); + gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); + gtk_widget_set_halign (primary_label, GTK_ALIGN_START); + gtk_widget_set_can_focus (primary_label, TRUE); + gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); + + secondary_text = _("If you save it, all the external changes could be lost. Save it anyway?"); + secondary_markup = g_strdup_printf ("%s", secondary_text); + secondary_label = gtk_label_new (secondary_markup); + g_free (secondary_markup); + gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); + gtk_widget_set_can_focus (secondary_label, TRUE); + gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); + gtk_widget_set_halign (secondary_label, GTK_ALIGN_START); + + gtk_widget_show_all (hbox_content); + set_contents (info_bar, hbox_content); + + return info_bar; +} + +GtkWidget * +xed_no_backup_saving_error_info_bar_new (GFile *location, + const GError *error) +{ + GtkWidget *info_bar; + GtkWidget *hbox_content; + GtkWidget *image; + GtkWidget *vbox; + gchar *primary_markup; + gchar *secondary_markup; + GtkWidget *primary_label; + GtkWidget *secondary_label; + gchar *primary_text; + const gchar *secondary_text; + gchar *full_formatted_uri; + gchar *uri_for_display; + gchar *temp_uri_for_display; + gboolean create_backup_copy; + GSettings *editor_settings; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (error->domain == G_IO_ERROR && + error->code == G_IO_ERROR_CANT_CREATE_BACKUP, NULL); + + full_formatted_uri = g_file_get_parse_name (location); + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + info_bar = gtk_info_bar_new (); + + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("S_ave Anyway"), GTK_RESPONSE_YES); + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("D_on't Save"), GTK_RESPONSE_CANCEL); + gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_WARNING); + + hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); + + image = gtk_image_new_from_icon_name ("dialog-warning-symbolic", GTK_ICON_SIZE_DIALOG); + gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); + gtk_widget_set_halign (image, GTK_ALIGN_CENTER); + gtk_widget_set_valign (image, GTK_ALIGN_START); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); + + editor_settings = g_settings_new ("org.x.editor.preferences.editor"); + create_backup_copy = g_settings_get_boolean (editor_settings, XED_SETTINGS_CREATE_BACKUP_COPY); + g_object_unref (editor_settings); + + // FIXME: review this messages + if (create_backup_copy) + { + primary_text = g_strdup_printf (_("Could not create a backup file while saving %s"), uri_for_display); + } + else + { + primary_text = g_strdup_printf (_("Could not create a temporary backup file while saving %s"), uri_for_display); + } + + g_free (uri_for_display); + + primary_markup = g_strdup_printf ("%s", primary_text); + g_free (primary_text); + primary_label = gtk_label_new (primary_markup); + g_free (primary_markup); + gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); + gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); + gtk_widget_set_halign (primary_label, GTK_ALIGN_START); + gtk_widget_set_can_focus (primary_label, TRUE); + gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); + + secondary_text = _("xed could not back up the old copy of the file before saving the new one. " + "You can ignore this warning and save the file anyway, but if an error " + "occurs while saving, you could lose the old copy of the file. Save anyway?"); + secondary_markup = g_strdup_printf ("%s", secondary_text); + secondary_label = gtk_label_new (secondary_markup); + g_free (secondary_markup); + gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); + gtk_widget_set_can_focus (secondary_label, TRUE); + gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); + gtk_widget_set_halign (secondary_label, GTK_ALIGN_START); + + gtk_widget_show_all (hbox_content); + set_contents (info_bar, hbox_content); + + return info_bar; +} + +GtkWidget * +xed_unrecoverable_saving_error_info_bar_new (GFile *location, + const GError *error) +{ + gchar *error_message = NULL; + gchar *message_details = NULL; + gchar *full_formatted_uri; + gchar *scheme_string; + gchar *scheme_markup; + gchar *uri_for_display; + gchar *temp_uri_for_display; + GtkWidget *info_bar; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_SAVER_ERROR || error->domain == G_IO_ERROR, NULL); + + full_formatted_uri = g_file_get_parse_name (location); + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + if (is_gio_error (error, G_IO_ERROR_NOT_SUPPORTED)) + { + scheme_string = g_file_get_uri_scheme (location); + + if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL)) + { + scheme_markup = g_markup_printf_escaped ("%s:", scheme_string); + + /* Translators: %s is a URI scheme (like for example http:, ftp:, etc.) */ + message_details = g_strdup_printf (_("xed cannot handle %s locations in write mode. " + "Please check that you typed the " + "location correctly and try again."), + scheme_markup); + g_free (scheme_markup); + } + else + { + message_details = g_strdup (_("xed cannot handle this location in write mode. " + "Please check that you typed the " + "location correctly and try again.")); + } + + g_free (scheme_string); + } + else if (is_gio_error (error, G_IO_ERROR_INVALID_FILENAME)) + { + message_details = g_strdup (_("%s is not a valid location. " + "Please check that you typed the " + "location correctly and try again.")); + } + else if (is_gio_error (error, G_IO_ERROR_PERMISSION_DENIED)) + { + message_details = g_strdup (_("You do not have the permissions necessary to save the file. " + "Please check that you typed the " + "location correctly and try again.")); + } + else if (is_gio_error (error, G_IO_ERROR_NO_SPACE)) + { + message_details = g_strdup (_("There is not enough disk space to save the file. " + "Please free some disk space and try again.")); + } + else if (is_gio_error (error, G_IO_ERROR_READ_ONLY)) + { + message_details = g_strdup (_("You are trying to save the file on a read-only disk. " + "Please check that you typed the location " + "correctly and try again.")); + } + else if (is_gio_error (error, G_IO_ERROR_EXISTS)) + { + message_details = g_strdup (_("A file with the same name already exists. " + "Please use a different name.")); + } + else if (is_gio_error (error, G_IO_ERROR_FILENAME_TOO_LONG)) + { + message_details = g_strdup (_("The disk where you are trying to save the file has " + "a limitation on length of the file names. " + "Please use a shorter name.")); + } +#if 0 + /* FIXME this error can not occur for a file saving. Either remove the + * code here, or improve the GtkSourceFileSaver so this error can occur. + */ + else if (error->domain == XED_DOCUMENT_ERROR && error->code == XED_DOCUMENT_ERROR_TOO_BIG) + { + message_details = g_strdup (_("The disk where you are trying to save the file has " + "a limitation on file sizes. Please try saving " + "a smaller file or saving it to a disk that does not " + "have this limitation.")); + } +#endif + else + { + parse_error (error, &error_message, &message_details, location, uri_for_display); + } + + if (error_message == NULL) + { + error_message = g_strdup_printf (_("Could not save the file %s."), uri_for_display); + } + + info_bar = create_io_loading_error_info_bar (error_message, message_details, FALSE); + + g_free (uri_for_display); + g_free (error_message); + g_free (message_details); + + return info_bar; +} + +GtkWidget * +xed_externally_modified_info_bar_new (GFile *location, + gboolean document_modified) +{ + gchar *full_formatted_uri; + gchar *uri_for_display; + gchar *temp_uri_for_display; + const gchar *primary_text; + const gchar *secondary_text; + GtkWidget *info_bar; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + + full_formatted_uri = g_file_get_parse_name (location); + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + // FIXME: review this message, it's not clear since for the user the "modification" + // could be interpreted as the changes he made in the document. beside "reading" is + // not accurate (since last load/save) + primary_text = g_strdup_printf (_("The file %s changed on disk."), uri_for_display); + g_free (uri_for_display); + + if (document_modified) + { + secondary_text = _("Do you want to drop your changes and reload the file?"); + } + else + { + secondary_text = _("Do you want to reload the file?"); + } + + info_bar = gtk_info_bar_new (); + + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("_Reload"), GTK_RESPONSE_OK); + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("_Cancel"), GTK_RESPONSE_CANCEL); + gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_WARNING); + + set_info_bar_text_and_icon (info_bar, "dialog-warning-symbolic", primary_text, secondary_text); + + return info_bar; +} + +GtkWidget * +xed_invalid_character_info_bar_new (GFile *location) +{ + GtkWidget *info_bar; + GtkWidget *hbox_content; + GtkWidget *image; + GtkWidget *vbox; + GtkWidget *primary_label; + GtkWidget *secondary_label; + gchar *primary_markup; + gchar *secondary_markup; + gchar *primary_text; + gchar *full_formatted_uri; + gchar *uri_for_display; + gchar *temp_uri_for_display; + const gchar *secondary_text; + + g_return_val_if_fail (G_IS_FILE (location), NULL); + + full_formatted_uri = g_file_get_parse_name (location); + + /* Truncate the URI so it doesn't get insanely wide. Note that even + * though the dialog uses wrapped text, if the URI doesn't contain + * white space then the text-wrapping code is too stupid to wrap it. + */ + temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, MAX_URI_IN_DIALOG_LENGTH); + g_free (full_formatted_uri); + + uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); + g_free (temp_uri_for_display); + + info_bar = gtk_info_bar_new (); + + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), _("S_ave Anyway"), GTK_RESPONSE_YES); + gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), + _("D_on't Save"), + GTK_RESPONSE_CANCEL); + gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_WARNING); + + hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); + + image = gtk_image_new_from_icon_name ("dialog-warning-symbolic", GTK_ICON_SIZE_DIALOG); + gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); + gtk_widget_set_valign (image, GTK_ALIGN_START); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); + + primary_text = g_strdup_printf (_("Some invalid chars have been detected while saving %s"), uri_for_display); + + g_free (uri_for_display); + + primary_markup = g_strdup_printf ("%s", primary_text); + g_free (primary_text); + primary_label = gtk_label_new (primary_markup); + g_free (primary_markup); + gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); + gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); + gtk_widget_set_halign (primary_label, GTK_ALIGN_START); + gtk_widget_set_can_focus (primary_label, TRUE); + gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); + + secondary_text = _("If you continue saving this file you can corrupt the document. " + " Save anyway?"); + secondary_markup = g_strdup_printf ("%s", secondary_text); + secondary_label = gtk_label_new (secondary_markup); + g_free (secondary_markup); + gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); + gtk_widget_set_can_focus (secondary_label, TRUE); + gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); + gtk_widget_set_halign (secondary_label, GTK_ALIGN_START); + + gtk_widget_show_all (hbox_content); + set_contents (info_bar, hbox_content); + + return info_bar; +} diff --git a/xed/xed-io-error-info-bar.h b/xed/xed-io-error-info-bar.h new file mode 100644 index 0000000..3bf7ea4 --- /dev/null +++ b/xed/xed-io-error-info-bar.h @@ -0,0 +1,69 @@ +/* + * xed-io-error-info-bar.h + * This file is part of xed + * + * Copyright (C) 2005 - Paolo Maggi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. + * + * $Id$ + */ + +#ifndef __XED_IO_ERROR_INFO_BAR_H__ +#define __XED_IO_ERROR_INFO_BAR_H__ + +#include + +G_BEGIN_DECLS + +GtkWidget *xed_io_loading_error_info_bar_new (GFile *location, + const GtkSourceEncoding *encoding, + const GError *error); + +GtkWidget *xed_unrecoverable_reverting_error_info_bar_new (GFile *location, + const GError *error); + +GtkWidget *xed_conversion_error_while_saving_info_bar_new (GFile *location, + const GtkSourceEncoding *encoding, + const GError *error); + +const GtkSourceEncoding *xed_conversion_error_info_bar_get_encoding (GtkWidget *info_bar); + +GtkWidget *xed_file_already_open_warning_info_bar_new (GFile *location); + +GtkWidget *xed_externally_modified_saving_error_info_bar_new (GFile *location, + const GError *error); + +GtkWidget *xed_no_backup_saving_error_info_bar_new (GFile *location, + const GError *error); + +GtkWidget *xed_unrecoverable_saving_error_info_bar_new (GFile *location, + const GError *error); + +GtkWidget *xed_externally_modified_info_bar_new (GFile *location, + gboolean document_modified); + +GtkWidget *xed_invalid_character_info_bar_new (GFile *location); + +G_END_DECLS + +#endif /* __XED_IO_ERROR_INFO_BAR_H__ */ diff --git a/xed/xed-io-error-message-area.c b/xed/xed-io-error-message-area.c deleted file mode 100644 index bfa7500..0000000 --- a/xed/xed-io-error-message-area.c +++ /dev/null @@ -1,1195 +0,0 @@ -/* - * xed-io-error-message-area.c - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -/* - * Verbose error reporting for file I/O operations (load, save, revert, create) - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include -#include - -#include "xed-utils.h" -#include "xed-document.h" -#include "xed-io-error-message-area.h" -#include "xed-prefs-manager.h" -#include - -#define MAX_URI_IN_DIALOG_LENGTH 50 - -static gboolean -is_recoverable_error (const GError *error) -{ - gboolean is_recoverable = FALSE; - - if (error->domain == G_IO_ERROR) - { - switch (error->code) { - case G_IO_ERROR_PERMISSION_DENIED: - case G_IO_ERROR_NOT_FOUND: - case G_IO_ERROR_HOST_NOT_FOUND: - case G_IO_ERROR_TIMED_OUT: - case G_IO_ERROR_NOT_MOUNTABLE_FILE: - case G_IO_ERROR_NOT_MOUNTED: - case G_IO_ERROR_BUSY: - is_recoverable = TRUE; - } - } - - return is_recoverable; -} - -static gboolean -is_gio_error (const GError *error, - gint code) -{ - return error->domain == G_IO_ERROR && error->code == code; -} - -static void -set_contents (GtkWidget *area, - GtkWidget *contents) -{ - GtkWidget *content_area; - - content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (area)); - gtk_container_add (GTK_CONTAINER (content_area), contents); -} - -static void -info_bar_add_stock_button_with_text (GtkInfoBar *infobar, - const gchar *text, - const gchar *stock_id, - gint response_id) -{ - GtkWidget *button; - GtkWidget *image; - - button = gtk_info_bar_add_button (infobar, text, response_id); - image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON); - gtk_button_set_image (GTK_BUTTON (button), image); -} - -static void -set_message_area_text_and_icon (GtkWidget *message_area, - const gchar *icon_stock_id, - const gchar *primary_text, - const gchar *secondary_text) -{ - GtkWidget *hbox_content; - GtkWidget *image; - GtkWidget *vbox; - gchar *primary_markup; - gchar *secondary_markup; - GtkWidget *primary_label; - GtkWidget *secondary_label; - - hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); - - image = gtk_image_new_from_stock (icon_stock_id, GTK_ICON_SIZE_DIALOG); - gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); - gtk_widget_set_halign (image, GTK_ALIGN_CENTER); - gtk_widget_set_valign (image, GTK_ALIGN_START); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); - - primary_markup = g_strdup_printf ("%s", primary_text); - primary_label = gtk_label_new (primary_markup); - g_free (primary_markup); - gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); - gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5); - gtk_widget_set_can_focus (primary_label, TRUE); - gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); - - if (secondary_text != NULL) - { - secondary_markup = g_strdup_printf ("%s", - secondary_text); - secondary_label = gtk_label_new (secondary_markup); - g_free (secondary_markup); - gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); - gtk_widget_set_can_focus (secondary_label, TRUE); - gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5); - } - - gtk_widget_show_all (hbox_content); - set_contents (message_area, hbox_content); -} - -static GtkWidget * -create_io_loading_error_message_area (const gchar *primary_text, - const gchar *secondary_text, - gboolean recoverable_error) -{ - GtkWidget *message_area; - - message_area = gtk_info_bar_new_with_buttons ( - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - NULL); - gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area), - GTK_MESSAGE_ERROR); - - set_message_area_text_and_icon (message_area, - "gtk-dialog-error", - primary_text, - secondary_text); - - if (recoverable_error) - { - info_bar_add_stock_button_with_text (GTK_INFO_BAR (message_area), - _("_Retry"), - GTK_STOCK_REFRESH, - GTK_RESPONSE_OK); - } - - return message_area; -} - -static gboolean -parse_gio_error (gint code, - gchar **error_message, - gchar **message_details, - const gchar *uri, - const gchar *uri_for_display) -{ - gboolean ret = TRUE; - - switch (code) - { - case G_IO_ERROR_NOT_FOUND: - case G_IO_ERROR_NOT_DIRECTORY: - *error_message = g_strdup_printf (_("Could not find the file %s."), - uri_for_display); - *message_details = g_strdup (_("Please check that you typed the " - "location correctly and try again.")); - break; - case G_IO_ERROR_NOT_SUPPORTED: - { - gchar *scheme_string; - gchar *scheme_markup; - - scheme_string = g_uri_parse_scheme (uri); - - if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL)) - { - scheme_markup = g_markup_printf_escaped ("%s:", scheme_string); - - /* Translators: %s is a URI scheme (like for example http:, ftp:, etc.) */ - *message_details = g_strdup_printf (_("xed cannot handle %s locations."), - scheme_markup); - g_free (scheme_markup); - } - else - { - *message_details = g_strdup (_("xed cannot handle this location.")); - } - - g_free (scheme_string); - } - break; - - case G_IO_ERROR_NOT_MOUNTABLE_FILE: - *message_details = g_strdup (_("The location of the file cannot be mounted.")); - break; - - case G_IO_ERROR_NOT_MOUNTED: - *message_details = g_strdup( _("The location of the file cannot be accessed because it is not mounted.")); - - break; - case G_IO_ERROR_IS_DIRECTORY: - *error_message = g_strdup_printf (_("%s is a directory."), - uri_for_display); - *message_details = g_strdup (_("Please check that you typed the " - "location correctly and try again.")); - break; - - case G_IO_ERROR_INVALID_FILENAME: - *error_message = g_strdup_printf (_("%s is not a valid location."), - uri_for_display); - *message_details = g_strdup (_("Please check that you typed the " - "location correctly and try again.")); - break; - - case G_IO_ERROR_HOST_NOT_FOUND: - /* This case can be hit for user-typed strings like "foo" due to - * the code that guesses web addresses when there's no initial "/". - * But this case is also hit for legitimate web addresses when - * the proxy is set up wrong. - */ - { - gchar *hn = NULL; - - if (xed_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL)) - { - if (hn != NULL) - { - gchar *host_markup; - gchar *host_name; - - host_name = xed_utils_make_valid_utf8 (hn); - g_free (hn); - - host_markup = g_markup_printf_escaped ("%s", host_name); - g_free (host_name); - - /* Translators: %s is a host name */ - *message_details = g_strdup_printf ( - _("Host %s could not be found. " - "Please check that your proxy settings " - "are correct and try again."), - host_markup); - - g_free (host_markup); - } - } - - if (!*message_details) - { - /* use the same string as INVALID_HOST */ - *message_details = g_strdup_printf ( - _("Hostname was invalid. " - "Please check that you typed the location " - "correctly and try again.")); - } - } - break; - - case G_IO_ERROR_NOT_REGULAR_FILE: - *message_details = g_strdup_printf (_("%s is not a regular file."), - uri_for_display); - break; - - case G_IO_ERROR_TIMED_OUT: - *message_details = g_strdup (_("Connection timed out. Please try again.")); - break; - - default: - ret = FALSE; - break; - } - - return ret; -} - -static gboolean -parse_xed_error (gint code, - gchar **error_message, - gchar **message_details, - const gchar *uri, - const gchar *uri_for_display) -{ - gboolean ret = TRUE; - - switch (code) - { - case XED_DOCUMENT_ERROR_TOO_BIG: - *message_details = g_strdup (_("The file is too big.")); - break; - - default: - ret = FALSE; - break; - } - - return ret; -} - -static void -parse_error (const GError *error, - gchar **error_message, - gchar **message_details, - const gchar *uri, - const gchar *uri_for_display) -{ - gboolean ret = FALSE; - - if (error->domain == G_IO_ERROR) - { - ret = parse_gio_error (error->code, - error_message, - message_details, - uri, - uri_for_display); - } - else if (error->domain == XED_DOCUMENT_ERROR) - { - ret = parse_xed_error (error->code, - error_message, - message_details, - uri, - uri_for_display); - } - - if (!ret) - { - g_warning ("Hit unhandled case %d (%s) in %s.", - error->code, error->message, G_STRFUNC); - *message_details = g_strdup_printf (_("Unexpected error: %s"), - error->message); - } -} - -GtkWidget * -xed_unrecoverable_reverting_error_message_area_new (const gchar *uri, - const GError *error) -{ - gchar *error_message = NULL; - gchar *message_details = NULL; - gchar *full_formatted_uri; - gchar *uri_for_display; - gchar *temp_uri_for_display; - GtkWidget *message_area; - - g_return_val_if_fail (uri != NULL, NULL); - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail ((error->domain == XED_DOCUMENT_ERROR) || - (error->domain == G_IO_ERROR), NULL); - - full_formatted_uri = xed_utils_uri_for_display (uri); - - /* Truncate the URI so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the URI doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, - MAX_URI_IN_DIALOG_LENGTH); - g_free (full_formatted_uri); - - uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); - g_free (temp_uri_for_display); - - if (is_gio_error (error, G_IO_ERROR_NOT_FOUND)) - { - message_details = g_strdup (_("xed cannot find the file. " - "Perhaps it has recently been deleted.")); - } - else - { - parse_error (error, &error_message, &message_details, uri, uri_for_display); - } - - if (error_message == NULL) - { - error_message = g_strdup_printf (_("Could not revert the file %s."), - uri_for_display); - } - - message_area = create_io_loading_error_message_area (error_message, - message_details, - FALSE); - - g_free (uri_for_display); - g_free (error_message); - g_free (message_details); - - return message_area; -} - -static void -create_combo_box (GtkWidget *message_area, GtkWidget *vbox) -{ - GtkWidget *hbox; - GtkWidget *label; - GtkWidget *menu; - gchar *label_markup; - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - - label_markup = g_strdup_printf ("%s", - _("Ch_aracter Encoding:")); - label = gtk_label_new_with_mnemonic (label_markup); - g_free (label_markup); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - menu = xed_encodings_combo_box_new (TRUE); - g_object_set_data (G_OBJECT (message_area), - "xed-message-area-encoding-menu", - menu); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), menu); - gtk_box_pack_start (GTK_BOX (hbox), - label, - FALSE, - FALSE, - 0); - - gtk_box_pack_start (GTK_BOX (hbox), - menu, - FALSE, - FALSE, - 0); - - gtk_widget_show_all (hbox); - gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); -} - -static GtkWidget * -create_conversion_error_message_area (const gchar *primary_text, - const gchar *secondary_text, - gboolean edit_anyway) -{ - GtkWidget *message_area; - GtkWidget *hbox_content; - GtkWidget *image; - GtkWidget *vbox; - gchar *primary_markup; - gchar *secondary_markup; - GtkWidget *primary_label; - GtkWidget *secondary_label; - - message_area = gtk_info_bar_new (); - - info_bar_add_stock_button_with_text (GTK_INFO_BAR (message_area), - _("_Retry"), - GTK_STOCK_REDO, - GTK_RESPONSE_OK); - - if (edit_anyway) - { - gtk_info_bar_add_button (GTK_INFO_BAR (message_area), - /* Translators: the access key chosen for this string should be - different from other main menu access keys (Open, Edit, View...) */ - _("Edit Any_way"), - GTK_RESPONSE_YES); - gtk_info_bar_add_button (GTK_INFO_BAR (message_area), - /* Translators: the access key chosen for this string should be - different from other main menu access keys (Open, Edit, View...) */ - _("D_on't Edit"), - GTK_RESPONSE_NO); - gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area), - GTK_MESSAGE_WARNING); - } - else - { - gtk_info_bar_add_button (GTK_INFO_BAR (message_area), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL); - gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area), - GTK_MESSAGE_ERROR); - } - - hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); - - image = gtk_image_new_from_stock ("gtk-dialog-error", GTK_ICON_SIZE_DIALOG); - gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); - gtk_widget_set_halign (image, GTK_ALIGN_CENTER); - gtk_widget_set_valign (image, GTK_ALIGN_START); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); - - primary_markup = g_strdup_printf ("%s", primary_text); - primary_label = gtk_label_new (primary_markup); - g_free (primary_markup); - gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); - gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5); - gtk_widget_set_can_focus (primary_label, TRUE); - gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); - - if (secondary_text != NULL) - { - secondary_markup = g_strdup_printf ("%s", - secondary_text); - secondary_label = gtk_label_new (secondary_markup); - g_free (secondary_markup); - gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); - gtk_widget_set_can_focus (secondary_label, TRUE); - gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5); - } - - create_combo_box (message_area, vbox); - gtk_widget_show_all (hbox_content); - set_contents (message_area, hbox_content); - - return message_area; -} - -GtkWidget * -xed_io_loading_error_message_area_new (const gchar *uri, - const XedEncoding *encoding, - const GError *error) -{ - gchar *error_message = NULL; - gchar *message_details = NULL; - gchar *full_formatted_uri; - gchar *encoding_name; - gchar *uri_for_display; - gchar *temp_uri_for_display; - GtkWidget *message_area; - gboolean edit_anyway = FALSE; - gboolean convert_error = FALSE; - - g_return_val_if_fail (uri != NULL, NULL); - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail ((error->domain == G_CONVERT_ERROR) || - (error->domain == XED_DOCUMENT_ERROR) || - (error->domain == G_IO_ERROR), NULL); - - full_formatted_uri = xed_utils_uri_for_display (uri); - - /* Truncate the URI so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the URI doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, - MAX_URI_IN_DIALOG_LENGTH); - g_free (full_formatted_uri); - - uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); - g_free (temp_uri_for_display); - - if (encoding != NULL) - encoding_name = xed_encoding_to_string (encoding); - else - encoding_name = g_strdup ("UTF-8"); - - if (is_gio_error (error, G_IO_ERROR_TOO_MANY_LINKS)) - { - message_details = g_strdup (_("The number of followed links is limited and the actual file could not be found within this limit.")); - } - else if (is_gio_error (error, G_IO_ERROR_PERMISSION_DENIED)) - { - message_details = g_strdup (_("You do not have the permissions necessary to open the file.")); - } - else if ((is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding == NULL) || - (error->domain == XED_DOCUMENT_ERROR && - error->code == XED_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED)) - { - message_details = g_strconcat (_("xed has not been able to detect " - "the character encoding."), "\n", - _("Please check that you are not trying to open a binary file."), "\n", - _("Select a character encoding from the menu and try again."), NULL); - convert_error = TRUE; - } - else if (error->domain == XED_DOCUMENT_ERROR && - error->code == XED_DOCUMENT_ERROR_CONVERSION_FALLBACK) - { - error_message = g_strdup_printf (_("There was a problem opening the file %s."), - uri_for_display); - message_details = g_strconcat (_("The file you opened has some invalid characters. " - "If you continue editing this file you could make this " - "document useless."), "\n", - _("You can also choose another character encoding and try again."), - NULL); - edit_anyway = TRUE; - convert_error = TRUE; - } - else if (is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding != NULL) - { - error_message = g_strdup_printf (_("Could not open the file %s using the %s character encoding."), - uri_for_display, - encoding_name); - message_details = g_strconcat (_("Please check that you are not trying to open a binary file."), "\n", - _("Select a different character encoding from the menu and try again."), NULL); - convert_error = TRUE; - } - else - { - parse_error (error, &error_message, &message_details, uri, uri_for_display); - } - - if (error_message == NULL) - { - error_message = g_strdup_printf (_("Could not open the file %s."), - uri_for_display); - } - - if (convert_error) - { - message_area = create_conversion_error_message_area (error_message, - message_details, - edit_anyway); - } - else - { - message_area = create_io_loading_error_message_area (error_message, - message_details, - is_recoverable_error (error)); - } - - g_free (uri_for_display); - g_free (encoding_name); - g_free (error_message); - g_free (message_details); - - return message_area; -} - -GtkWidget * -xed_conversion_error_while_saving_message_area_new ( - const gchar *uri, - const XedEncoding *encoding, - const GError *error) -{ - gchar *error_message = NULL; - gchar *message_details = NULL; - gchar *full_formatted_uri; - gchar *encoding_name; - gchar *uri_for_display; - gchar *temp_uri_for_display; - GtkWidget *message_area; - - g_return_val_if_fail (uri != NULL, NULL); - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail (error->domain == G_CONVERT_ERROR || - error->domain == G_IO_ERROR, NULL); - g_return_val_if_fail (encoding != NULL, NULL); - - full_formatted_uri = xed_utils_uri_for_display (uri); - - /* Truncate the URI so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the URI doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, - MAX_URI_IN_DIALOG_LENGTH); - g_free (full_formatted_uri); - - uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); - g_free (temp_uri_for_display); - - encoding_name = xed_encoding_to_string (encoding); - - error_message = g_strdup_printf (_("Could not save the file %s using the %s character encoding."), - uri_for_display, - encoding_name); - message_details = g_strconcat (_("The document contains one or more characters that cannot be encoded " - "using the specified character encoding."), "\n", - _("Select a different character encoding from the menu and try again."), NULL); - - message_area = create_conversion_error_message_area ( - error_message, - message_details, - FALSE); - - g_free (uri_for_display); - g_free (encoding_name); - g_free (error_message); - g_free (message_details); - - return message_area; -} - -const XedEncoding * -xed_conversion_error_message_area_get_encoding (GtkWidget *message_area) -{ - gpointer menu; - - g_return_val_if_fail (GTK_IS_INFO_BAR (message_area), NULL); - - menu = g_object_get_data (G_OBJECT (message_area), - "xed-message-area-encoding-menu"); - g_return_val_if_fail (menu, NULL); - - return xed_encodings_combo_box_get_selected_encoding - (XED_ENCODINGS_COMBO_BOX (menu)); -} - -GtkWidget * -xed_file_already_open_warning_message_area_new (const gchar *uri) -{ - GtkWidget *message_area; - GtkWidget *hbox_content; - GtkWidget *image; - GtkWidget *vbox; - gchar *primary_markup; - gchar *secondary_markup; - GtkWidget *primary_label; - GtkWidget *secondary_label; - gchar *primary_text; - const gchar *secondary_text; - gchar *full_formatted_uri; - gchar *uri_for_display; - gchar *temp_uri_for_display; - - full_formatted_uri = xed_utils_uri_for_display (uri); - - /* Truncate the URI so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the URI doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, - MAX_URI_IN_DIALOG_LENGTH); - g_free (full_formatted_uri); - - uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); - g_free (temp_uri_for_display); - - message_area = gtk_info_bar_new (); - gtk_info_bar_add_button (GTK_INFO_BAR (message_area), - /* Translators: the access key chosen for this string should be - different from other main menu access keys (Open, Edit, View...) */ - _("Edit Any_way"), - GTK_RESPONSE_YES); - gtk_info_bar_add_button (GTK_INFO_BAR (message_area), - /* Translators: the access key chosen for this string should be - different from other main menu access keys (Open, Edit, View...) */ - _("D_on't Edit"), - GTK_RESPONSE_CANCEL); - gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area), - GTK_MESSAGE_WARNING); - - hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); - - image = gtk_image_new_from_stock ("gtk-dialog-warning", GTK_ICON_SIZE_DIALOG); - gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); - gtk_widget_set_halign (image, GTK_ALIGN_CENTER); - gtk_widget_set_valign (image, GTK_ALIGN_START); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); - - primary_text = g_strdup_printf (_("This file (%s) is already open in another xed window."), uri_for_display); - g_free (uri_for_display); - - primary_markup = g_strdup_printf ("%s", primary_text); - g_free (primary_text); - primary_label = gtk_label_new (primary_markup); - g_free (primary_markup); - gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); - gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5); - gtk_widget_set_can_focus (primary_label, TRUE); - gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); - - secondary_text = _("xed opened this instance of the file in a non-editable way. " - "Do you want to edit it anyway?"); - secondary_markup = g_strdup_printf ("%s", - secondary_text); - secondary_label = gtk_label_new (secondary_markup); - g_free (secondary_markup); - gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); - gtk_widget_set_can_focus (secondary_label, TRUE); - gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5); - - gtk_widget_show_all (hbox_content); - set_contents (message_area, hbox_content); - - return message_area; -} - -GtkWidget * -xed_externally_modified_saving_error_message_area_new ( - const gchar *uri, - const GError *error) -{ - GtkWidget *message_area; - GtkWidget *hbox_content; - GtkWidget *image; - GtkWidget *vbox; - gchar *primary_markup; - gchar *secondary_markup; - GtkWidget *primary_label; - GtkWidget *secondary_label; - gchar *primary_text; - const gchar *secondary_text; - gchar *full_formatted_uri; - gchar *uri_for_display; - gchar *temp_uri_for_display; - - g_return_val_if_fail (uri != NULL, NULL); - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail (error->domain == XED_DOCUMENT_ERROR, NULL); - g_return_val_if_fail (error->code == XED_DOCUMENT_ERROR_EXTERNALLY_MODIFIED, NULL); - - full_formatted_uri = xed_utils_uri_for_display (uri); - - /* Truncate the URI so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the URI doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, - MAX_URI_IN_DIALOG_LENGTH); - g_free (full_formatted_uri); - - uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); - g_free (temp_uri_for_display); - - message_area = gtk_info_bar_new (); - - info_bar_add_stock_button_with_text (GTK_INFO_BAR (message_area), - _("S_ave Anyway"), - GTK_STOCK_SAVE, - GTK_RESPONSE_YES); - gtk_info_bar_add_button (GTK_INFO_BAR (message_area), - _("D_on't Save"), - GTK_RESPONSE_CANCEL); - gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area), - GTK_MESSAGE_WARNING); - - hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); - - image = gtk_image_new_from_stock ("gtk-dialog-warning", GTK_ICON_SIZE_DIALOG); - gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); - gtk_widget_set_halign (image, GTK_ALIGN_CENTER); - gtk_widget_set_valign (image, GTK_ALIGN_START); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); - - // FIXME: review this message, it's not clear since for the user the "modification" - // could be interpreted as the changes he made in the document. beside "reading" is - // not accurate (since last load/save) - primary_text = g_strdup_printf (_("The file %s has been modified since reading it."), - uri_for_display); - g_free (uri_for_display); - - primary_markup = g_strdup_printf ("%s", primary_text); - g_free (primary_text); - primary_label = gtk_label_new (primary_markup); - g_free (primary_markup); - gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); - gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5); - gtk_widget_set_can_focus (primary_label, TRUE); - gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); - - secondary_text = _("If you save it, all the external changes could be lost. Save it anyway?"); - secondary_markup = g_strdup_printf ("%s", - secondary_text); - secondary_label = gtk_label_new (secondary_markup); - g_free (secondary_markup); - gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); - gtk_widget_set_can_focus (secondary_label, TRUE); - gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5); - - gtk_widget_show_all (hbox_content); - set_contents (message_area, hbox_content); - - return message_area; -} - -GtkWidget * -xed_no_backup_saving_error_message_area_new (const gchar *uri, - const GError *error) -{ - GtkWidget *message_area; - GtkWidget *hbox_content; - GtkWidget *image; - GtkWidget *vbox; - gchar *primary_markup; - gchar *secondary_markup; - GtkWidget *primary_label; - GtkWidget *secondary_label; - gchar *primary_text; - const gchar *secondary_text; - gchar *full_formatted_uri; - gchar *uri_for_display; - gchar *temp_uri_for_display; - - g_return_val_if_fail (uri != NULL, NULL); - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail (((error->domain == XED_DOCUMENT_ERROR && - error->code == XED_DOCUMENT_ERROR_CANT_CREATE_BACKUP) || - (error->domain == G_IO_ERROR && - error->code == G_IO_ERROR_CANT_CREATE_BACKUP)), NULL); - - full_formatted_uri = xed_utils_uri_for_display (uri); - - /* Truncate the URI so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the URI doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, - MAX_URI_IN_DIALOG_LENGTH); - g_free (full_formatted_uri); - - uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); - g_free (temp_uri_for_display); - - message_area = gtk_info_bar_new (); - - info_bar_add_stock_button_with_text (GTK_INFO_BAR (message_area), - _("S_ave Anyway"), - GTK_STOCK_SAVE, - GTK_RESPONSE_YES); - gtk_info_bar_add_button (GTK_INFO_BAR (message_area), - _("D_on't Save"), - GTK_RESPONSE_CANCEL); - gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area), - GTK_MESSAGE_WARNING); - - hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); - - image = gtk_image_new_from_stock ("gtk-dialog-warning", GTK_ICON_SIZE_DIALOG); - gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); - gtk_widget_set_halign (image, GTK_ALIGN_CENTER); - gtk_widget_set_valign (image, GTK_ALIGN_START); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0); - - // FIXME: review this messages - - if (xed_prefs_manager_get_create_backup_copy ()) - primary_text = g_strdup_printf (_("Could not create a backup file while saving %s"), - uri_for_display); - else - primary_text = g_strdup_printf (_("Could not create a temporary backup file while saving %s"), - uri_for_display); - - g_free (uri_for_display); - - primary_markup = g_strdup_printf ("%s", primary_text); - g_free (primary_text); - primary_label = gtk_label_new (primary_markup); - g_free (primary_markup); - gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); - gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5); - gtk_widget_set_can_focus (primary_label, TRUE); - gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE); - - secondary_text = _("xed could not back up the old copy of the file before saving the new one. " - "You can ignore this warning and save the file anyway, but if an error " - "occurs while saving, you could lose the old copy of the file. Save anyway?"); - secondary_markup = g_strdup_printf ("%s", - secondary_text); - secondary_label = gtk_label_new (secondary_markup); - g_free (secondary_markup); - gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); - gtk_widget_set_can_focus (secondary_label, TRUE); - gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); - gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5); - - gtk_widget_show_all (hbox_content); - set_contents (message_area, hbox_content); - - return message_area; -} - -GtkWidget * -xed_unrecoverable_saving_error_message_area_new (const gchar *uri, - const GError *error) -{ - gchar *error_message = NULL; - gchar *message_details = NULL; - gchar *full_formatted_uri; - gchar *scheme_string; - gchar *scheme_markup; - gchar *uri_for_display; - gchar *temp_uri_for_display; - GtkWidget *message_area; - - g_return_val_if_fail (uri != NULL, NULL); - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail ((error->domain == XED_DOCUMENT_ERROR) || - (error->domain == G_IO_ERROR), NULL); - - full_formatted_uri = xed_utils_uri_for_display (uri); - - /* Truncate the URI so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the URI doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, - MAX_URI_IN_DIALOG_LENGTH); - g_free (full_formatted_uri); - - uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); - g_free (temp_uri_for_display); - - if (is_gio_error (error, G_IO_ERROR_NOT_SUPPORTED)) - { - scheme_string = g_uri_parse_scheme (uri); - - if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL)) - { - scheme_markup = g_markup_printf_escaped ("%s:", scheme_string); - - /* Translators: %s is a URI scheme (like for example http:, ftp:, etc.) */ - message_details = g_strdup_printf (_("xed cannot handle %s locations in write mode. " - "Please check that you typed the " - "location correctly and try again."), - scheme_markup); - g_free (scheme_markup); - } - else - { - message_details = g_strdup (_("xed cannot handle this location in write mode. " - "Please check that you typed the " - "location correctly and try again.")); - } - - g_free (scheme_string); - } - else if (is_gio_error (error, G_IO_ERROR_INVALID_FILENAME)) - { - message_details = g_strdup (_("%s is not a valid location. " - "Please check that you typed the " - "location correctly and try again.")); - } - else if (is_gio_error (error, G_IO_ERROR_PERMISSION_DENIED)) - { - message_details = g_strdup (_("You do not have the permissions necessary to save the file. " - "Please check that you typed the " - "location correctly and try again.")); - } - else if (is_gio_error (error, G_IO_ERROR_NO_SPACE)) - { - message_details = g_strdup (_("There is not enough disk space to save the file. " - "Please free some disk space and try again.")); - } - else if (is_gio_error (error, G_IO_ERROR_READ_ONLY)) - { - message_details = g_strdup (_("You are trying to save the file on a read-only disk. " - "Please check that you typed the location " - "correctly and try again.")); - } - else if (is_gio_error (error, G_IO_ERROR_EXISTS)) - { - message_details = g_strdup (_("A file with the same name already exists. " - "Please use a different name.")); - } - else if (is_gio_error (error, G_IO_ERROR_FILENAME_TOO_LONG)) - { - message_details = g_strdup (_("The disk where you are trying to save the file has " - "a limitation on length of the file names. " - "Please use a shorter name.")); - } - else if (error->domain == XED_DOCUMENT_ERROR && - error->code == XED_DOCUMENT_ERROR_TOO_BIG) - { - message_details = g_strdup (_("The disk where you are trying to save the file has " - "a limitation on file sizes. Please try saving " - "a smaller file or saving it to a disk that does not " - "have this limitation.")); - } - else - { - parse_error (error, - &error_message, - &message_details, - uri, - uri_for_display); - } - - if (error_message == NULL) - { - error_message = g_strdup_printf (_("Could not save the file %s."), - uri_for_display); - } - - message_area = create_io_loading_error_message_area (error_message, - message_details, - FALSE); - - g_free (uri_for_display); - g_free (error_message); - g_free (message_details); - - return message_area; -} - -GtkWidget * -xed_externally_modified_message_area_new (const gchar *uri, - gboolean document_modified) -{ - gchar *full_formatted_uri; - gchar *uri_for_display; - gchar *temp_uri_for_display; - const gchar *primary_text; - const gchar *secondary_text; - GtkWidget *message_area; - - g_return_val_if_fail (uri != NULL, NULL); - - full_formatted_uri = xed_utils_uri_for_display (uri); - - /* Truncate the URI so it doesn't get insanely wide. Note that even - * though the dialog uses wrapped text, if the URI doesn't contain - * white space then the text-wrapping code is too stupid to wrap it. - */ - temp_uri_for_display = xed_utils_str_middle_truncate (full_formatted_uri, - MAX_URI_IN_DIALOG_LENGTH); - g_free (full_formatted_uri); - - uri_for_display = g_markup_printf_escaped ("%s", temp_uri_for_display); - g_free (temp_uri_for_display); - - // FIXME: review this message, it's not clear since for the user the "modification" - // could be interpreted as the changes he made in the document. beside "reading" is - // not accurate (since last load/save) - primary_text = g_strdup_printf (_("The file %s changed on disk."), - uri_for_display); - g_free (uri_for_display); - - if (document_modified) - secondary_text = _("Do you want to drop your changes and reload the file?"); - else - secondary_text = _("Do you want to reload the file?"); - - message_area = gtk_info_bar_new (); - - info_bar_add_stock_button_with_text (GTK_INFO_BAR (message_area), - _("_Reload"), - GTK_STOCK_REFRESH, - GTK_RESPONSE_OK); - gtk_info_bar_add_button (GTK_INFO_BAR (message_area), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL); - gtk_info_bar_set_message_type (GTK_INFO_BAR (message_area), - GTK_MESSAGE_WARNING); - - set_message_area_text_and_icon (message_area, - "gtk-dialog-warning", - primary_text, - secondary_text); - - return message_area; -} - diff --git a/xed/xed-io-error-message-area.h b/xed/xed-io-error-message-area.h deleted file mode 100644 index 607bc8c..0000000 --- a/xed/xed-io-error-message-area.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * xed-io-error-message-area.h - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_IO_ERROR_MESSAGE_AREA_H__ -#define __XED_IO_ERROR_MESSAGE_AREA_H__ - -#include - -G_BEGIN_DECLS - -GtkWidget *xed_io_loading_error_message_area_new (const gchar *uri, - const XedEncoding *encoding, - const GError *error); - -GtkWidget *xed_unrecoverable_reverting_error_message_area_new (const gchar *uri, - const GError *error); - -GtkWidget *xed_conversion_error_while_saving_message_area_new (const gchar *uri, - const XedEncoding *encoding, - const GError *error); - -const XedEncoding - *xed_conversion_error_message_area_get_encoding (GtkWidget *message_area); - -GtkWidget *xed_file_already_open_warning_message_area_new (const gchar *uri); - -GtkWidget *xed_externally_modified_saving_error_message_area_new (const gchar *uri, - const GError *error); - -GtkWidget *xed_no_backup_saving_error_message_area_new (const gchar *uri, - const GError *error); - -GtkWidget *xed_unrecoverable_saving_error_message_area_new (const gchar *uri, - const GError *error); - -GtkWidget *xed_externally_modified_message_area_new (const gchar *uri, - gboolean document_modified); - -G_END_DECLS - -#endif /* __XED_IO_ERROR_MESSAGE_AREA_H__ */ diff --git a/xed/xed-language-manager.c b/xed/xed-language-manager.c deleted file mode 100644 index 0871708..0000000 --- a/xed/xed-language-manager.c +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-languages-manager.c - * This file is part of xed - * - * Copyright (C) 2003-2006 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2003-2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#include -#include -#include -#include "xed-language-manager.h" -#include "xed-prefs-manager.h" -#include "xed-utils.h" -#include "xed-debug.h" - -static GtkSourceLanguageManager *language_manager = NULL; - -GtkSourceLanguageManager * -xed_get_language_manager (void) -{ - if (language_manager == NULL) - { - language_manager = gtk_source_language_manager_new (); - } - - return language_manager; -} - -static gint -language_compare (gconstpointer a, gconstpointer b) -{ - GtkSourceLanguage *lang_a = (GtkSourceLanguage *)a; - GtkSourceLanguage *lang_b = (GtkSourceLanguage *)b; - const gchar *name_a = gtk_source_language_get_name (lang_a); - const gchar *name_b = gtk_source_language_get_name (lang_b); - - return g_utf8_collate (name_a, name_b); -} - -GSList * -xed_language_manager_list_languages_sorted (GtkSourceLanguageManager *lm, - gboolean include_hidden) -{ - GSList *languages = NULL; - const gchar * const *ids; - - ids = gtk_source_language_manager_get_language_ids (lm); - if (ids == NULL) - return NULL; - - while (*ids != NULL) - { - GtkSourceLanguage *lang; - - lang = gtk_source_language_manager_get_language (lm, *ids); - g_return_val_if_fail (GTK_SOURCE_IS_LANGUAGE (lang), NULL); - ++ids; - - if (include_hidden || !gtk_source_language_get_hidden (lang)) - { - languages = g_slist_prepend (languages, lang); - } - } - - return g_slist_sort (languages, (GCompareFunc)language_compare); -} - diff --git a/xed/xed-language-manager.h b/xed/xed-language-manager.h deleted file mode 100644 index 9c48bae..0000000 --- a/xed/xed-language-manager.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-languages-manager.h - * This file is part of xed - * - * Copyright (C) 2003-2005 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2003-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_LANGUAGES_MANAGER_H__ -#define __XED_LANGUAGES_MANAGER_H__ - -#include -#include - -G_BEGIN_DECLS - -GtkSourceLanguageManager *xed_get_language_manager (void); - -GSList *xed_language_manager_list_languages_sorted - (GtkSourceLanguageManager *lm, - gboolean include_hidden); - -G_END_DECLS - -#endif /* __XED_LANGUAGES_MANAGER_H__ */ diff --git a/xed/xed-marshal.list b/xed/xed-marshal.list index d288294..03d7c9e 100644 --- a/xed/xed-marshal.list +++ b/xed/xed-marshal.list @@ -5,8 +5,8 @@ VOID:BOOLEAN,POINTER VOID:BOXED,BOXED VOID:OBJECT VOID:POINTER -VOID:STRING,BOXED,FLAGS -VOID:STRING,BOXED,INT,BOOLEAN +VOID:OBJECT,BOXED,FLAGS +VOID:OBJECT,BOXED,INT,BOOLEAN VOID:UINT,POINTER VOID:UINT64,UINT64 VOID:VOID diff --git a/xed/xed-message-bus.c b/xed/xed-message-bus.c index aa35631..9a5be47 100644 --- a/xed/xed-message-bus.c +++ b/xed/xed-message-bus.c @@ -46,8 +46,8 @@ * * // Register 'method' at '/plugins/example' with one required * // string argument 'arg1' - * XedMessageType *message_type = xed_message_bus_register ("/plugins/example", "method", - * 0, + * XedMessageType *message_type = xed_message_bus_register ("/plugins/example", "method", + * 0, * "arg1", G_TYPE_STRING, * NULL); * @@ -60,21 +60,21 @@ * XedMessage *message, * gpointer userdata) * { - * gchar *arg1 = NULL; - * - * xed_message_get (message, "arg1", &arg1, NULL); - * g_message ("Evoked /plugins/example.method with: %s", arg1); - * g_free (arg1); + * gchar *arg1 = NULL; + * + * xed_message_get (message, "arg1", &arg1, NULL); + * g_message ("Evoked /plugins/example.method with: %s", arg1); + * g_free (arg1); * } * * XedMessageBus *bus = xed_message_bus_get_default (); - * - * guint id = xed_message_bus_connect (bus, + * + * guint id = xed_message_bus_connect (bus, * "/plugins/example", "method", * example_method_cb, * NULL, * NULL); - * + * * * * @@ -82,440 +82,446 @@ * * XedMessageBus *bus = xed_message_bus_get_default (); * - * xed_message_bus_send (bus, - * "/plugins/example", "method", - * "arg1", "Hello World", + * xed_message_bus_send (bus, + * "/plugins/example", "method", + * "arg1", "Hello World", * NULL); * * - * - * Since: 2.25.3 - * */ - + #define XED_MESSAGE_BUS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_MESSAGE_BUS, XedMessageBusPrivate)) typedef struct { - gchar *object_path; - gchar *method; + gchar *object_path; + gchar *method; - GList *listeners; + GList *listeners; } Message; typedef struct { - guint id; - gboolean blocked; + guint id; + gboolean blocked; - GDestroyNotify destroy_data; - XedMessageCallback callback; - gpointer userdata; + GDestroyNotify destroy_data; + XedMessageCallback callback; + gpointer userdata; } Listener; typedef struct { - Message *message; - GList *listener; + Message *message; + GList *listener; } IdMap; struct _XedMessageBusPrivate { - GHashTable *messages; - GHashTable *idmap; + GHashTable *messages; + GHashTable *idmap; - GList *message_queue; - guint idle_id; + GList *message_queue; + guint idle_id; - guint next_id; - - GHashTable *types; /* mapping from identifier to XedMessageType */ + guint next_id; + + GHashTable *types; /* mapping from identifier to XedMessageType */ }; /* signals */ enum { - DISPATCH, - REGISTERED, - UNREGISTERED, - LAST_SIGNAL + DISPATCH, + REGISTERED, + UNREGISTERED, + LAST_SIGNAL }; static guint message_bus_signals[LAST_SIGNAL] = { 0 }; static void xed_message_bus_dispatch_real (XedMessageBus *bus, - XedMessage *message); + XedMessage *message); -G_DEFINE_TYPE(XedMessageBus, xed_message_bus, G_TYPE_OBJECT) +G_DEFINE_TYPE (XedMessageBus, xed_message_bus, G_TYPE_OBJECT) static void listener_free (Listener *listener) { - if (listener->destroy_data) - listener->destroy_data (listener->userdata); + if (listener->destroy_data) + { + listener->destroy_data (listener->userdata); + } - g_free (listener); + g_free (listener); } static void message_free (Message *message) { - g_free (message->method); - g_free (message->object_path); - - g_list_foreach (message->listeners, (GFunc)listener_free, NULL); - g_list_free (message->listeners); - - g_free (message); + g_free (message->method); + g_free (message->object_path); + + g_list_foreach (message->listeners, (GFunc)listener_free, NULL); + g_list_free (message->listeners); + + g_free (message); } static void message_queue_free (GList *queue) { - g_list_foreach (queue, (GFunc)g_object_unref, NULL); - g_list_free (queue); + g_list_foreach (queue, (GFunc)g_object_unref, NULL); + g_list_free (queue); } static void xed_message_bus_finalize (GObject *object) { - XedMessageBus *bus = XED_MESSAGE_BUS (object); - - if (bus->priv->idle_id != 0) - g_source_remove (bus->priv->idle_id); - - message_queue_free (bus->priv->message_queue); + XedMessageBus *bus = XED_MESSAGE_BUS (object); - g_hash_table_destroy (bus->priv->messages); - g_hash_table_destroy (bus->priv->idmap); - g_hash_table_destroy (bus->priv->types); - - G_OBJECT_CLASS (xed_message_bus_parent_class)->finalize (object); + if (bus->priv->idle_id != 0) + { + g_source_remove (bus->priv->idle_id); + } + + message_queue_free (bus->priv->message_queue); + + g_hash_table_destroy (bus->priv->messages); + g_hash_table_destroy (bus->priv->idmap); + g_hash_table_destroy (bus->priv->types); + + G_OBJECT_CLASS (xed_message_bus_parent_class)->finalize (object); } static void xed_message_bus_class_init (XedMessageBusClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_message_bus_finalize; - - klass->dispatch = xed_message_bus_dispatch_real; + GObjectClass *object_class = G_OBJECT_CLASS (klass); - /** - * XedMessageBus::dispatch: - * @bus: a #XedMessageBus - * @message: the #XedMessage to dispatch - * - * The "dispatch" signal is emitted when a message is to be dispatched. - * The message is dispatched in the default handler of this signal. - * Primary use of this signal is to customize the dispatch of a message - * (for instance to automatically dispatch all messages over DBus). - *2 - */ - message_bus_signals[DISPATCH] = - g_signal_new ("dispatch", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedMessageBusClass, dispatch), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - XED_TYPE_MESSAGE); + object_class->finalize = xed_message_bus_finalize; - /** - * XedMessageBus::registered: - * @bus: a #XedMessageBus - * @message_type: the registered #XedMessageType - * - * The "registered" signal is emitted when a message has been registered - * on the bus. - * - */ - message_bus_signals[REGISTERED] = - g_signal_new ("registered", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedMessageBusClass, registered), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, - 1, - XED_TYPE_MESSAGE_TYPE); + klass->dispatch = xed_message_bus_dispatch_real; - /** - * XedMessageBus::unregistered: - * @bus: a #XedMessageBus - * @message_type: the unregistered #XedMessageType - * - * The "unregistered" signal is emitted when a message has been - * unregistered from the bus. - * - */ - message_bus_signals[UNREGISTERED] = - g_signal_new ("unregistered", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedMessageBusClass, unregistered), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, - 1, - XED_TYPE_MESSAGE_TYPE); + /** + * XedMessageBus::dispatch: + * @bus: a #XedMessageBus + * @message: the #XedMessage to dispatch + * + * The "dispatch" signal is emitted when a message is to be dispatched. + * The message is dispatched in the default handler of this signal. + * Primary use of this signal is to customize the dispatch of a message + * (for instance to automatically dispatch all messages over DBus). + *2 + */ + message_bus_signals[DISPATCH] = + g_signal_new ("dispatch", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedMessageBusClass, dispatch), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + XED_TYPE_MESSAGE); - g_type_class_add_private (object_class, sizeof(XedMessageBusPrivate)); + /** + * XedMessageBus::registered: + * @bus: a #XedMessageBus + * @message_type: the registered #XedMessageType + * + * The "registered" signal is emitted when a message has been registered + * on the bus. + * + */ + message_bus_signals[REGISTERED] = + g_signal_new ("registered", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedMessageBusClass, registered), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + 1, + XED_TYPE_MESSAGE_TYPE); + + /** + * XedMessageBus::unregistered: + * @bus: a #XedMessageBus + * @message_type: the unregistered #XedMessageType + * + * The "unregistered" signal is emitted when a message has been + * unregistered from the bus. + * + */ + message_bus_signals[UNREGISTERED] = + g_signal_new ("unregistered", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedMessageBusClass, unregistered), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + 1, + XED_TYPE_MESSAGE_TYPE); + + g_type_class_add_private (object_class, sizeof(XedMessageBusPrivate)); } static Message * message_new (XedMessageBus *bus, - const gchar *object_path, - const gchar *method) + const gchar *object_path, + const gchar *method) { - Message *message = g_new (Message, 1); - - message->object_path = g_strdup (object_path); - message->method = g_strdup (method); - message->listeners = NULL; + Message *message = g_new (Message, 1); - g_hash_table_insert (bus->priv->messages, - xed_message_type_identifier (object_path, method), - message); - return message; + message->object_path = g_strdup (object_path); + message->method = g_strdup (method); + message->listeners = NULL; + + g_hash_table_insert (bus->priv->messages, xed_message_type_identifier (object_path, method), message); + return message; } static Message * lookup_message (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - gboolean create) + const gchar *object_path, + const gchar *method, + gboolean create) { - gchar *identifier; - Message *message; - - identifier = xed_message_type_identifier (object_path, method); - message = (Message *)g_hash_table_lookup (bus->priv->messages, identifier); - g_free (identifier); + gchar *identifier; + Message *message; - if (!message && !create) - return NULL; - - if (!message) - message = message_new (bus, object_path, method); - - return message; + identifier = xed_message_type_identifier (object_path, method); + message = (Message *)g_hash_table_lookup (bus->priv->messages, identifier); + g_free (identifier); + + if (!message && !create) + { + return NULL; + } + + if (!message) + { + message = message_new (bus, object_path, method); + } + + return message; } static guint add_listener (XedMessageBus *bus, - Message *message, - XedMessageCallback callback, - gpointer userdata, - GDestroyNotify destroy_data) + Message *message, + XedMessageCallback callback, + gpointer userdata, + GDestroyNotify destroy_data) { - Listener *listener; - IdMap *idmap; - - listener = g_new (Listener, 1); - listener->id = ++bus->priv->next_id; - listener->callback = callback; - listener->userdata = userdata; - listener->blocked = FALSE; - listener->destroy_data = destroy_data; + Listener *listener; + IdMap *idmap; - message->listeners = g_list_append (message->listeners, listener); - - idmap = g_new (IdMap, 1); - idmap->message = message; - idmap->listener = g_list_last (message->listeners); + listener = g_new (Listener, 1); + listener->id = ++bus->priv->next_id; + listener->callback = callback; + listener->userdata = userdata; + listener->blocked = FALSE; + listener->destroy_data = destroy_data; - g_hash_table_insert (bus->priv->idmap, GINT_TO_POINTER (listener->id), idmap); - return listener->id; + message->listeners = g_list_append (message->listeners, listener); + + idmap = g_new (IdMap, 1); + idmap->message = message; + idmap->listener = g_list_last (message->listeners); + + g_hash_table_insert (bus->priv->idmap, GINT_TO_POINTER (listener->id), idmap); + return listener->id; } static void remove_listener (XedMessageBus *bus, - Message *message, - GList *listener) + Message *message, + GList *listener) { - Listener *lst; - - lst = (Listener *)listener->data; - - /* remove from idmap */ - g_hash_table_remove (bus->priv->idmap, GINT_TO_POINTER (lst->id)); - listener_free (lst); + Listener *lst; - /* remove from list of listeners */ - message->listeners = g_list_delete_link (message->listeners, listener); - - if (!message->listeners) - { - /* remove message because it does not have any listeners */ - g_hash_table_remove (bus->priv->messages, message); - } + lst = (Listener *)listener->data; + + /* remove from idmap */ + g_hash_table_remove (bus->priv->idmap, GINT_TO_POINTER (lst->id)); + listener_free (lst); + + /* remove from list of listeners */ + message->listeners = g_list_delete_link (message->listeners, listener); + + if (!message->listeners) + { + /* remove message because it does not have any listeners */ + g_hash_table_remove (bus->priv->messages, message); + } } static void block_listener (XedMessageBus *bus, - Message *message, - GList *listener) + Message *message, + GList *listener) { - Listener *lst; - - lst = (Listener *)listener->data; - lst->blocked = TRUE; + Listener *lst; + + lst = (Listener *)listener->data; + lst->blocked = TRUE; } static void unblock_listener (XedMessageBus *bus, - Message *message, - GList *listener) + Message *message, + GList *listener) { - Listener *lst; - - lst = (Listener *)listener->data; - lst->blocked = FALSE; + Listener *lst; + + lst = (Listener *)listener->data; + lst->blocked = FALSE; } static void dispatch_message_real (XedMessageBus *bus, - Message *msg, - XedMessage *message) + Message *msg, + XedMessage *message) { - GList *item; - - for (item = msg->listeners; item; item = item->next) - { - Listener *listener = (Listener *)item->data; - - if (!listener->blocked) - listener->callback (bus, message, listener->userdata); - } + GList *item; + + for (item = msg->listeners; item; item = item->next) + { + Listener *listener = (Listener *)item->data; + + if (!listener->blocked) + { + listener->callback (bus, message, listener->userdata); + } + } } static void xed_message_bus_dispatch_real (XedMessageBus *bus, - XedMessage *message) + XedMessage *message) { - const gchar *object_path; - const gchar *method; - Message *msg; - - object_path = xed_message_get_object_path (message); - method = xed_message_get_method (message); + const gchar *object_path; + const gchar *method; + Message *msg; - msg = lookup_message (bus, object_path, method, FALSE); - - if (msg) - dispatch_message_real (bus, msg, message); + object_path = xed_message_get_object_path (message); + method = xed_message_get_method (message); + + msg = lookup_message (bus, object_path, method, FALSE); + + if (msg) + { + dispatch_message_real (bus, msg, message); + } } static void dispatch_message (XedMessageBus *bus, - XedMessage *message) + XedMessage *message) { - g_signal_emit (bus, message_bus_signals[DISPATCH], 0, message); + g_signal_emit (bus, message_bus_signals[DISPATCH], 0, message); } static gboolean idle_dispatch (XedMessageBus *bus) { - GList *list; - GList *item; - - /* make sure to set idle_id to 0 first so that any new async messages - will be queued properly */ - bus->priv->idle_id = 0; + GList *list; + GList *item; - /* reverse queue to get correct delivery order */ - list = g_list_reverse (bus->priv->message_queue); - bus->priv->message_queue = NULL; - - for (item = list; item; item = item->next) - { - XedMessage *msg = XED_MESSAGE (item->data); - - dispatch_message (bus, msg); - } - - message_queue_free (list); - return FALSE; + /* make sure to set idle_id to 0 first so that any new async messages + will be queued properly */ + bus->priv->idle_id = 0; + + /* reverse queue to get correct delivery order */ + list = g_list_reverse (bus->priv->message_queue); + bus->priv->message_queue = NULL; + + for (item = list; item; item = item->next) + { + XedMessage *msg = XED_MESSAGE (item->data); + + dispatch_message (bus, msg); + } + + message_queue_free (list); + return FALSE; } typedef void (*MatchCallback) (XedMessageBus *, Message *, GList *); static void -process_by_id (XedMessageBus *bus, - guint id, - MatchCallback processor) +process_by_id (XedMessageBus *bus, + guint id, + MatchCallback processor) { - IdMap *idmap; - - idmap = (IdMap *)g_hash_table_lookup (bus->priv->idmap, GINT_TO_POINTER (id)); - - if (idmap == NULL) - { - g_warning ("No handler registered with id `%d'", id); - return; - } - - processor (bus, idmap->message, idmap->listener); + IdMap *idmap; + + idmap = (IdMap *)g_hash_table_lookup (bus->priv->idmap, GINT_TO_POINTER (id)); + + if (idmap == NULL) + { + g_warning ("No handler registered with id `%d'", id); + return; + } + + processor (bus, idmap->message, idmap->listener); } static void process_by_match (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - XedMessageCallback callback, - gpointer userdata, - MatchCallback processor) + const gchar *object_path, + const gchar *method, + XedMessageCallback callback, + gpointer userdata, + MatchCallback processor) { - Message *message; - GList *item; - - message = lookup_message (bus, object_path, method, FALSE); - - if (!message) - { - g_warning ("No such handler registered for %s.%s", object_path, method); - return; - } - - for (item = message->listeners; item; item = item->next) - { - Listener *listener = (Listener *)item->data; - - if (listener->callback == callback && - listener->userdata == userdata) - { - processor (bus, message, item); - return; - } - } - - g_warning ("No such handler registered for %s.%s", object_path, method); + Message *message; + GList *item; + + message = lookup_message (bus, object_path, method, FALSE); + + if (!message) + { + g_warning ("No such handler registered for %s.%s", object_path, method); + return; + } + + for (item = message->listeners; item; item = item->next) + { + Listener *listener = (Listener *)item->data; + + if (listener->callback == callback && listener->userdata == userdata) + { + processor (bus, message, item); + return; + } + } + + g_warning ("No such handler registered for %s.%s", object_path, method); } static void xed_message_bus_init (XedMessageBus *self) { - self->priv = XED_MESSAGE_BUS_GET_PRIVATE (self); - - self->priv->messages = g_hash_table_new_full (g_str_hash, - g_str_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)message_free); + self->priv = XED_MESSAGE_BUS_GET_PRIVATE (self); - self->priv->idmap = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)g_free); - - self->priv->types = g_hash_table_new_full (g_str_hash, - g_str_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)xed_message_type_unref); + self->priv->messages = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)message_free); + + self->priv->idmap = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify)g_free); + + self->priv->types = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)xed_message_type_unref); } /** @@ -523,27 +529,26 @@ xed_message_bus_init (XedMessageBus *self) * * Get the default application #XedMessageBus. * - * Return value: the default #XedMessageBus + * Return value: (transfer none): the default #XedMessageBus * */ XedMessageBus * xed_message_bus_get_default (void) { - static XedMessageBus *default_bus = NULL; - - if (G_UNLIKELY (default_bus == NULL)) - { - default_bus = g_object_new (XED_TYPE_MESSAGE_BUS, NULL); - g_object_add_weak_pointer (G_OBJECT (default_bus), - (gpointer) &default_bus); - } - - return default_bus; + static XedMessageBus *default_bus = NULL; + + if (G_UNLIKELY (default_bus == NULL)) + { + default_bus = g_object_new (XED_TYPE_MESSAGE_BUS, NULL); + g_object_add_weak_pointer (G_OBJECT (default_bus), (gpointer) &default_bus); + } + + return default_bus; } /** * xed_message_bus_new: - * + * * Create a new message bus. Use xed_message_bus_get_default() to get the * default, application wide, message bus. Creating a new bus is useful for * associating a specific bus with for instance a #XedWindow. @@ -554,7 +559,7 @@ xed_message_bus_get_default (void) XedMessageBus * xed_message_bus_new (void) { - return XED_MESSAGE_BUS (g_object_new (XED_TYPE_MESSAGE_BUS, NULL)); + return XED_MESSAGE_BUS (g_object_new (XED_TYPE_MESSAGE_BUS, NULL)); } /** @@ -563,7 +568,7 @@ xed_message_bus_new (void) * @object_path: the object path * @method: the method * - * Get the registered #XedMessageType for @method at @object_path. The + * Get the registered #XedMessageType for @method at @object_path. The * returned #XedMessageType is owned by the bus and should not be unreffed. * * Return value: the registered #XedMessageType or %NULL if no message type @@ -572,21 +577,21 @@ xed_message_bus_new (void) */ XedMessageType * xed_message_bus_lookup (XedMessageBus *bus, - const gchar *object_path, - const gchar *method) + const gchar *object_path, + const gchar *method) { - gchar *identifier; - XedMessageType *message_type; - - g_return_val_if_fail (XED_IS_MESSAGE_BUS (bus), NULL); - g_return_val_if_fail (object_path != NULL, NULL); - g_return_val_if_fail (method != NULL, NULL); + gchar *identifier; + XedMessageType *message_type; - identifier = xed_message_type_identifier (object_path, method); - message_type = XED_MESSAGE_TYPE (g_hash_table_lookup (bus->priv->types, identifier)); - - g_free (identifier); - return message_type; + g_return_val_if_fail (XED_IS_MESSAGE_BUS (bus), NULL); + g_return_val_if_fail (object_path != NULL, NULL); + g_return_val_if_fail (method != NULL, NULL); + + identifier = xed_message_type_identifier (object_path, method); + message_type = XED_MESSAGE_TYPE (g_hash_table_lookup (bus->priv->types, identifier)); + + g_free (identifier); + return message_type; } /** @@ -598,9 +603,9 @@ xed_message_bus_lookup (XedMessageBus *bus, * @...: NULL terminated list of key/gtype method argument pairs * * Register a message on the bus. A message must be registered on the bus before - * it can be send. This function registers the type arguments for @method at - * @object_path. The arguments are specified with the variable arguments which - * should contain pairs of const gchar *key and GType terminated by %NULL. The + * it can be send. This function registers the type arguments for @method at + * @object_path. The arguments are specified with the variable arguments which + * should contain pairs of const gchar *key and GType terminated by %NULL. The * last @num_optional arguments are registered as optional (and are thus not * required when sending a message). * @@ -613,68 +618,65 @@ xed_message_bus_lookup (XedMessageBus *bus, */ XedMessageType * xed_message_bus_register (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - guint num_optional, - ...) + const gchar *object_path, + const gchar *method, + guint num_optional, + ...) { - gchar *identifier; - gpointer data; - va_list var_args; - XedMessageType *message_type; + gchar *identifier; + va_list var_args; + XedMessageType *message_type; - g_return_val_if_fail (XED_IS_MESSAGE_BUS (bus), NULL); - g_return_val_if_fail (xed_message_type_is_valid_object_path (object_path), NULL); - - if (xed_message_bus_is_registered (bus, object_path, method)) - { - g_warning ("Message type for '%s.%s' is already registered", object_path, method); - return NULL; - } + g_return_val_if_fail (XED_IS_MESSAGE_BUS (bus), NULL); + g_return_val_if_fail (xed_message_type_is_valid_object_path (object_path), NULL); - identifier = xed_message_type_identifier (object_path, method); - data = g_hash_table_lookup (bus->priv->types, identifier); - - va_start (var_args, num_optional); - message_type = xed_message_type_new_valist (object_path, - method, - num_optional, - var_args); - va_end (var_args); - - if (message_type) - { - g_hash_table_insert (bus->priv->types, identifier, message_type); - g_signal_emit (bus, message_bus_signals[REGISTERED], 0, message_type); - } - else - { - g_free (identifier); - } - - return message_type; + if (xed_message_bus_is_registered (bus, object_path, method)) + { + g_warning ("Message type for '%s.%s' is already registered", object_path, method); + return NULL; + } + + identifier = xed_message_type_identifier (object_path, method); + + va_start (var_args, num_optional); + message_type = xed_message_type_new_valist (object_path, method, num_optional, var_args); + va_end (var_args); + + if (message_type) + { + g_hash_table_insert (bus->priv->types, identifier, message_type); + g_signal_emit (bus, message_bus_signals[REGISTERED], 0, message_type); + } + else + { + g_free (identifier); + } + + return message_type; } static void xed_message_bus_unregister_real (XedMessageBus *bus, - XedMessageType *message_type, - gboolean remove_from_store) + XedMessageType *message_type, + gboolean remove_from_store) { - gchar *identifier; - - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + gchar *identifier; - identifier = xed_message_type_identifier (xed_message_type_get_object_path (message_type), - xed_message_type_get_method (message_type)); - - /* Keep message type alive for signal emission */ - xed_message_type_ref (message_type); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - if (!remove_from_store || g_hash_table_remove (bus->priv->types, identifier)) - g_signal_emit (bus, message_bus_signals[UNREGISTERED], 0, message_type); - - xed_message_type_unref (message_type); - g_free (identifier); + identifier = xed_message_type_identifier (xed_message_type_get_object_path (message_type), + xed_message_type_get_method (message_type)); + + /* Keep message type alive for signal emission */ + xed_message_type_ref (message_type); + + if (!remove_from_store || g_hash_table_remove (bus->priv->types, identifier)) + { + g_signal_emit (bus, message_bus_signals[UNREGISTERED], 0, message_type); + } + + xed_message_type_unref (message_type); + g_free (identifier); } /** @@ -682,7 +684,7 @@ xed_message_bus_unregister_real (XedMessageBus *bus, * @bus: a #XedMessageBus * @message_type: the #XedMessageType to unregister * - * Unregisters a previously registered message type. This is especially useful + * Unregisters a previously registered message type. This is especially useful * for plugins which should unregister message types when they are deactivated. * * This function emits the #XedMessageBus::unregistered signal. @@ -690,31 +692,31 @@ xed_message_bus_unregister_real (XedMessageBus *bus, */ void xed_message_bus_unregister (XedMessageBus *bus, - XedMessageType *message_type) + XedMessageType *message_type) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - xed_message_bus_unregister_real (bus, message_type, TRUE); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + xed_message_bus_unregister_real (bus, message_type, TRUE); } -typedef struct +typedef struct { - XedMessageBus *bus; - const gchar *object_path; + XedMessageBus *bus; + const gchar *object_path; } UnregisterInfo; static gboolean -unregister_each (const gchar *identifier, - XedMessageType *message_type, - UnregisterInfo *info) +unregister_each (const gchar *identifier, + XedMessageType *message_type, + UnregisterInfo *info) { - if (strcmp (xed_message_type_get_object_path (message_type), - info->object_path) == 0) - { - xed_message_bus_unregister_real (info->bus, message_type, FALSE); - return TRUE; - } - - return FALSE; + if (strcmp (xed_message_type_get_object_path (message_type), + info->object_path) == 0) + { + xed_message_bus_unregister_real (info->bus, message_type, FALSE); + return TRUE; + } + + return FALSE; } /** @@ -731,16 +733,14 @@ unregister_each (const gchar *identifier, */ void xed_message_bus_unregister_all (XedMessageBus *bus, - const gchar *object_path) + const gchar *object_path) { - UnregisterInfo info = {bus, object_path}; + UnregisterInfo info = {bus, object_path}; - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - g_return_if_fail (object_path != NULL); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + g_return_if_fail (object_path != NULL); - g_hash_table_foreach_remove (bus->priv->types, - (GHRFunc)unregister_each, - &info); + g_hash_table_foreach_remove (bus->priv->types, (GHRFunc)unregister_each, &info); } /** @@ -749,68 +749,68 @@ xed_message_bus_unregister_all (XedMessageBus *bus, * @object_path: the object path * @method: the method * - * Check whether a message type @method at @object_path is registered on the + * Check whether a message type @method at @object_path is registered on the * bus. * - * Return value: %TRUE if the @method at @object_path is a registered message + * Return value: %TRUE if the @method at @object_path is a registered message * type on the bus * */ gboolean -xed_message_bus_is_registered (XedMessageBus *bus, - const gchar *object_path, - const gchar *method) +xed_message_bus_is_registered (XedMessageBus *bus, + const gchar *object_path, + const gchar *method) { - gchar *identifier; - gboolean ret; - - g_return_val_if_fail (XED_IS_MESSAGE_BUS (bus), FALSE); - g_return_val_if_fail (object_path != NULL, FALSE); - g_return_val_if_fail (method != NULL, FALSE); + gchar *identifier; + gboolean ret; - identifier = xed_message_type_identifier (object_path, method); - ret = g_hash_table_lookup (bus->priv->types, identifier) != NULL; - - g_free(identifier); - return ret; + g_return_val_if_fail (XED_IS_MESSAGE_BUS (bus), FALSE); + g_return_val_if_fail (object_path != NULL, FALSE); + g_return_val_if_fail (method != NULL, FALSE); + + identifier = xed_message_type_identifier (object_path, method); + ret = g_hash_table_lookup (bus->priv->types, identifier) != NULL; + + g_free(identifier); + return ret; } typedef struct { - XedMessageBusForeach func; - gpointer userdata; + XedMessageBusForeach func; + gpointer userdata; } ForeachInfo; static void -foreach_type (const gchar *key, - XedMessageType *message_type, - ForeachInfo *info) +foreach_type (const gchar *key, + XedMessageType *message_type, + ForeachInfo *info) { - xed_message_type_ref (message_type); - info->func (message_type, info->userdata); - xed_message_type_unref (message_type); + xed_message_type_ref (message_type); + info->func (message_type, info->userdata); + xed_message_type_unref (message_type); } /** * xed_message_bus_foreach: * @bus: the #XedMessagebus - * @func: the callback function + * @func: (scope call): the callback function * @userdata: the user data to supply to the callback function * * Calls @func for each message type registered on the bus * */ -void +void xed_message_bus_foreach (XedMessageBus *bus, - XedMessageBusForeach func, - gpointer userdata) + XedMessageBusForeach func, + gpointer userdata) { - ForeachInfo info = {func, userdata}; - - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - g_return_if_fail (func != NULL); + ForeachInfo info = {func, userdata}; - g_hash_table_foreach (bus->priv->types, (GHFunc)foreach_type, &info); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + g_return_if_fail (func != NULL); + + g_hash_table_foreach (bus->priv->types, (GHFunc)foreach_type, &info); } /** @@ -830,24 +830,24 @@ xed_message_bus_foreach (XedMessageBus *bus, * */ guint -xed_message_bus_connect (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - XedMessageCallback callback, - gpointer userdata, - GDestroyNotify destroy_data) +xed_message_bus_connect (XedMessageBus *bus, + const gchar *object_path, + const gchar *method, + XedMessageCallback callback, + gpointer userdata, + GDestroyNotify destroy_data) { - Message *message; + Message *message; - g_return_val_if_fail (XED_IS_MESSAGE_BUS (bus), 0); - g_return_val_if_fail (object_path != NULL, 0); - g_return_val_if_fail (method != NULL, 0); - g_return_val_if_fail (callback != NULL, 0); - - /* lookup the message and create if it does not exist yet */ - message = lookup_message (bus, object_path, method, TRUE); - - return add_listener (bus, message, callback, userdata, destroy_data); + g_return_val_if_fail (XED_IS_MESSAGE_BUS (bus), 0); + g_return_val_if_fail (object_path != NULL, 0); + g_return_val_if_fail (method != NULL, 0); + g_return_val_if_fail (callback != NULL, 0); + + /* lookup the message and create if it does not exist yet */ + message = lookup_message (bus, object_path, method, TRUE); + + return add_listener (bus, message, callback, userdata, destroy_data); } /** @@ -860,11 +860,11 @@ xed_message_bus_connect (XedMessageBus *bus, */ void xed_message_bus_disconnect (XedMessageBus *bus, - guint id) + guint id) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - - process_by_id (bus, id, remove_listener); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + + process_by_id (bus, id, remove_listener); } /** @@ -872,24 +872,24 @@ xed_message_bus_disconnect (XedMessageBus *bus, * @bus: a #XedMessageBus * @object_path: the object path * @method: the method - * @callback: the connected callback + * @callback: (scope call): the connected callback * @userdata: the userdata with which the callback was connected * - * Disconnects a previously connected message callback by matching the - * provided callback function and userdata. See also + * Disconnects a previously connected message callback by matching the + * provided callback function and userdata. See also * xed_message_bus_disconnect(). * */ void xed_message_bus_disconnect_by_func (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - XedMessageCallback callback, - gpointer userdata) + const gchar *object_path, + const gchar *method, + XedMessageCallback callback, + gpointer userdata) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - - process_by_match (bus, object_path, method, callback, userdata, remove_listener); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + + process_by_match (bus, object_path, method, callback, userdata, remove_listener); } /** @@ -903,11 +903,11 @@ xed_message_bus_disconnect_by_func (XedMessageBus *bus, */ void xed_message_bus_block (XedMessageBus *bus, - guint id) + guint id) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - - process_by_id (bus, id, block_listener); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + + process_by_id (bus, id, block_listener); } /** @@ -915,7 +915,7 @@ xed_message_bus_block (XedMessageBus *bus, * @bus: a #XedMessageBus * @object_path: the object path * @method: the method - * @callback: the callback to block + * @callback: (scope call): the callback to block * @userdata: the userdata with which the callback was connected * * Blocks evoking the callback that matches provided @callback and @userdata. @@ -924,14 +924,14 @@ xed_message_bus_block (XedMessageBus *bus, */ void xed_message_bus_block_by_func (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - XedMessageCallback callback, - gpointer userdata) + const gchar *object_path, + const gchar *method, + XedMessageCallback callback, + gpointer userdata) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - - process_by_match (bus, object_path, method, callback, userdata, block_listener); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + + process_by_match (bus, object_path, method, callback, userdata, block_listener); } /** @@ -944,11 +944,11 @@ xed_message_bus_block_by_func (XedMessageBus *bus, */ void xed_message_bus_unblock (XedMessageBus *bus, - guint id) + guint id) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - - process_by_id (bus, id, unblock_listener); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + + process_by_id (bus, id, unblock_listener); } /** @@ -956,7 +956,7 @@ xed_message_bus_unblock (XedMessageBus *bus, * @bus: a #XedMessageBus * @object_path: the object path * @method: the method - * @callback: the callback to block + * @callback: (scope call): the callback to block * @userdata: the userdata with which the callback was connected * * Unblocks the callback that matches provided @callback and @userdata. @@ -964,46 +964,47 @@ xed_message_bus_unblock (XedMessageBus *bus, */ void xed_message_bus_unblock_by_func (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - XedMessageCallback callback, - gpointer userdata) + const gchar *object_path, + const gchar *method, + XedMessageCallback callback, + gpointer userdata) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - - process_by_match (bus, object_path, method, callback, userdata, unblock_listener); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + + process_by_match (bus, object_path, method, callback, userdata, unblock_listener); } static gboolean validate_message (XedMessage *message) { - if (!xed_message_validate (message)) - { - g_warning ("Message '%s.%s' is invalid", xed_message_get_object_path (message), - xed_message_get_method (message)); - return FALSE; - } - - return TRUE; + if (!xed_message_validate (message)) + { + g_warning ("Message '%s.%s' is invalid", xed_message_get_object_path (message), + xed_message_get_method (message)); + return FALSE; + } + + return TRUE; } static void send_message_real (XedMessageBus *bus, - XedMessage *message) + XedMessage *message) { - if (!validate_message (message)) - { - return; - } - - bus->priv->message_queue = g_list_prepend (bus->priv->message_queue, - g_object_ref (message)); + if (!validate_message (message)) + { + return; + } - if (bus->priv->idle_id == 0) - bus->priv->idle_id = g_idle_add_full (G_PRIORITY_HIGH, - (GSourceFunc)idle_dispatch, - bus, - NULL); + bus->priv->message_queue = g_list_prepend (bus->priv->message_queue, g_object_ref (message)); + + if (bus->priv->idle_id == 0) + { + bus->priv->idle_id = g_idle_add_full (G_PRIORITY_HIGH, + (GSourceFunc)idle_dispatch, + bus, + NULL); + } } /** @@ -1012,31 +1013,31 @@ send_message_real (XedMessageBus *bus, * @message: the message to send * * This sends the provided @message asynchronously over the bus. To send - * a message synchronously, use xed_message_bus_send_message_sync(). The + * a message synchronously, use xed_message_bus_send_message_sync(). The * convenience function xed_message_bus_send() can be used to easily send * a message without constructing the message object explicitly first. * */ void xed_message_bus_send_message (XedMessageBus *bus, - XedMessage *message) + XedMessage *message) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - g_return_if_fail (XED_IS_MESSAGE (message)); - - send_message_real (bus, message); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + g_return_if_fail (XED_IS_MESSAGE (message)); + + send_message_real (bus, message); } static void send_message_sync_real (XedMessageBus *bus, XedMessage *message) { - if (!validate_message (message)) - { - return; - } - - dispatch_message (bus, message); + if (!validate_message (message)) + { + return; + } + + dispatch_message (bus, message); } /** @@ -1045,39 +1046,38 @@ send_message_sync_real (XedMessageBus *bus, * @message: the message to send * * This sends the provided @message synchronously over the bus. To send - * a message asynchronously, use xed_message_bus_send_message(). The + * a message asynchronously, use xed_message_bus_send_message(). The * convenience function xed_message_bus_send_sync() can be used to easily send * a message without constructing the message object explicitly first. * */ void xed_message_bus_send_message_sync (XedMessageBus *bus, - XedMessage *message) + XedMessage *message) { - g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); - g_return_if_fail (XED_IS_MESSAGE (message)); + g_return_if_fail (XED_IS_MESSAGE_BUS (bus)); + g_return_if_fail (XED_IS_MESSAGE (message)); - send_message_sync_real (bus, message); + send_message_sync_real (bus, message); } static XedMessage * create_message (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - va_list var_args) + const gchar *object_path, + const gchar *method, + va_list var_args) { - XedMessageType *message_type; - - message_type = xed_message_bus_lookup (bus, object_path, method); - - if (!message_type) - { - g_warning ("Could not find message type for '%s.%s'", object_path, method); - return NULL; - } + XedMessageType *message_type; - return xed_message_type_instantiate_valist (message_type, - var_args); + message_type = xed_message_bus_lookup (bus, object_path, method); + + if (!message_type) + { + g_warning ("Could not find message type for '%s.%s'", object_path, method); + return NULL; + } + + return xed_message_type_instantiate_valist (message_type, var_args); } /** @@ -1087,36 +1087,36 @@ create_message (XedMessageBus *bus, * @method: the method * @...: NULL terminated list of key/value pairs * - * This provides a convenient way to quickly send a message @method at - * @object_path asynchronously over the bus. The variable argument list - * specifies key (string) value pairs used to construct the message arguments. + * This provides a convenient way to quickly send a message @method at + * @object_path asynchronously over the bus. The variable argument list + * specifies key (string) value pairs used to construct the message arguments. * To send a message synchronously use xed_message_bus_send_sync(). * */ void xed_message_bus_send (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - ...) + const gchar *object_path, + const gchar *method, + ...) { - va_list var_args; - XedMessage *message; - - va_start (var_args, method); + va_list var_args; + XedMessage *message; - message = create_message (bus, object_path, method, var_args); - - if (message) - { - send_message_real (bus, message); - g_object_unref (message); - } - else - { - g_warning ("Could not instantiate message"); - } + va_start (var_args, method); - va_end (var_args); + message = create_message (bus, object_path, method, var_args); + + if (message) + { + send_message_real (bus, message); + g_object_unref (message); + } + else + { + g_warning ("Could not instantiate message"); + } + + va_end (var_args); } /** @@ -1126,33 +1126,33 @@ xed_message_bus_send (XedMessageBus *bus, * @method: the method * @...: NULL terminated list of key/value pairs * - * This provides a convenient way to quickly send a message @method at - * @object_path synchronously over the bus. The variable argument list - * specifies key (string) value pairs used to construct the message + * This provides a convenient way to quickly send a message @method at + * @object_path synchronously over the bus. The variable argument list + * specifies key (string) value pairs used to construct the message * arguments. To send a message asynchronously use xed_message_bus_send(). * - * Return value: the constructed #XedMessage. The caller owns a reference + * Return value: (transfer full): the constructed #XedMessage. The caller owns a reference * to the #XedMessage and should call g_object_unref() when * it is no longer needed */ XedMessage * xed_message_bus_send_sync (XedMessageBus *bus, - const gchar *object_path, - const gchar *method, - ...) + const gchar *object_path, + const gchar *method, + ...) { - va_list var_args; - XedMessage *message; - - va_start (var_args, method); - message = create_message (bus, object_path, method, var_args); - - if (message) - send_message_sync_real (bus, message); + va_list var_args; + XedMessage *message; - va_end (var_args); - - return message; + va_start (var_args, method); + message = create_message (bus, object_path, method, var_args); + + if (message) + send_message_sync_real (bus, message); + + va_end (var_args); + + return message; } // ex:ts=8:noet: diff --git a/xed/xed-message-type.c b/xed/xed-message-type.c index 1ab1aa5..236f5b8 100644 --- a/xed/xed-message-type.c +++ b/xed/xed-message-type.c @@ -10,12 +10,12 @@ * the Object Path, Method and Arguments of the message. * * A message type can contain any number of required and optional arguments. - * To instantiate a #XedMessage from a #XedMessageType, use + * To instantiate a #XedMessage from a #XedMessageType, use * xed_message_type_instantiate(). * * Registering a new message type on a #XedMessageBus with * xed_message_bus_register() internally creates a new #XedMessageType. When - * then using xed_message_bus_send(), an actual instantiation of the + * then using xed_message_bus_send(), an actual instantiation of the * registered type is internally created and send over the bus. * * @@ -33,9 +33,6 @@ * NULL); * * - * - * Since: 2.25.3 - * */ typedef struct { @@ -50,10 +47,10 @@ struct _XedMessageType gchar *object_path; gchar *method; - + guint num_arguments; guint num_required; - + GHashTable *arguments; // mapping of key -> ArgumentInfo }; @@ -71,7 +68,7 @@ xed_message_type_ref (XedMessageType *message_type) { g_return_val_if_fail (message_type != NULL, NULL); g_atomic_int_inc (&message_type->ref_count); - + return message_type; } @@ -83,30 +80,30 @@ xed_message_type_ref (XedMessageType *message_type) * drops to 0, @message_type is destroyed. * */ -void +void xed_message_type_unref (XedMessageType *message_type) { g_return_if_fail (message_type != NULL); if (!g_atomic_int_dec_and_test (&message_type->ref_count)) return; - + g_free (message_type->object_path); g_free (message_type->method); - + g_hash_table_destroy (message_type->arguments); g_free (message_type); } /** * xed_message_type_get_type: - * + * * Retrieves the GType object which is associated with the * #XedMessageType class. - * + * * Return value: the GType associated with #XedMessageType. **/ -GType +GType xed_message_type_get_type (void) { static GType our_type = 0; @@ -151,17 +148,17 @@ xed_message_type_is_valid_object_path (const gchar *object_path) { if (!object_path) return FALSE; - + /* needs to start with / */ if (*object_path != '/') return FALSE; - + while (*object_path) { if (*object_path == '/') { ++object_path; - + if (!*object_path || !(g_ascii_isalpha (*object_path) || *object_path == '_')) return FALSE; } @@ -169,10 +166,10 @@ xed_message_type_is_valid_object_path (const gchar *object_path) { return FALSE; } - + ++object_path; } - + return TRUE; } @@ -189,7 +186,7 @@ gboolean xed_message_type_is_supported (GType type) { gint i = 0; - + static const GType type_list[] = { G_TYPE_BOOLEAN, @@ -252,7 +249,7 @@ xed_message_type_new_valist (const gchar *object_path, g_return_val_if_fail (xed_message_type_is_valid_object_path (object_path), NULL); message_type = g_new0(XedMessageType, 1); - + message_type->ref_count = 1; message_type->object_path = g_strdup(object_path); message_type->method = g_strdup(method); @@ -288,11 +285,11 @@ xed_message_type_new (const gchar *object_path, { XedMessageType *message_type; va_list var_args; - + va_start(var_args, num_optional); message_type = xed_message_type_new_valist (object_path, method, num_optional, var_args); va_end(var_args); - + return message_type; } @@ -313,7 +310,7 @@ xed_message_type_set (XedMessageType *message_type, ...) { va_list va_args; - + va_start (va_args, num_optional); xed_message_type_set_valist (message_type, num_optional, va_args); va_end (va_args); @@ -326,11 +323,11 @@ xed_message_type_set (XedMessageType *message_type, * @var_args: key/gtype pair variable argument list * * Sets argument names/types supplied by the NULL terminated variable - * argument list @var_args. The last @num_optional provided arguments are + * argument list @var_args. The last @num_optional provided arguments are * considered optional. * */ -void +void xed_message_type_set_valist (XedMessageType *message_type, guint num_optional, va_list var_args) @@ -346,35 +343,35 @@ xed_message_type_set_valist (XedMessageType *message_type, // get corresponding GType GType gtype = va_arg (var_args, GType); ArgumentInfo *info; - + if (!xed_message_type_is_supported (gtype)) { g_error ("Message type '%s' is not supported", g_type_name (gtype)); xed_message_type_unref (message_type); g_free (optional); - + return; } - + info = g_new(ArgumentInfo, 1); info->type = gtype; info->required = TRUE; g_hash_table_insert (message_type->arguments, g_strdup (key), info); - + ++message_type->num_arguments; ++added; - + if (num_optional > 0) { for (i = num_optional - 1; i > 0; --i) optional[i] = optional[i - 1]; - + *optional = info; } } - + message_type->num_required += added; // set required for last num_optional arguments @@ -386,7 +383,7 @@ xed_message_type_set_valist (XedMessageType *message_type, --message_type->num_required; } } - + g_free (optional); } @@ -398,7 +395,7 @@ xed_message_type_set_valist (XedMessageType *message_type, * Instantiate a new message from the message type with specific values * for the message arguments. * - * Return value: the newly created message + * Return value: (transfer full): the newly created message * */ XedMessage * @@ -406,12 +403,12 @@ xed_message_type_instantiate_valist (XedMessageType *message_type, va_list va_args) { XedMessage *message; - + g_return_val_if_fail (message_type != NULL, NULL); - + message = XED_MESSAGE (g_object_new (XED_TYPE_MESSAGE, "type", message_type, NULL)); xed_message_set_valist (message, va_args); - + return message; } @@ -423,7 +420,7 @@ xed_message_type_instantiate_valist (XedMessageType *message_type, * Instantiate a new message from the message type with specific values * for the message arguments. * - * Return value: the newly created message + * Return value: (transfer full): the newly created message * */ XedMessage * @@ -432,11 +429,11 @@ xed_message_type_instantiate (XedMessageType *message_type, { XedMessage *message; va_list va_args; - + va_start (va_args, message_type); message = xed_message_type_instantiate_valist (message_type, va_args); va_end (va_args); - + return message; } @@ -485,10 +482,10 @@ xed_message_type_lookup (XedMessageType *message_type, const gchar *key) { ArgumentInfo *info = g_hash_table_lookup (message_type->arguments, key); - + if (!info) return G_TYPE_INVALID; - + return info->type; } @@ -509,13 +506,13 @@ foreach_gtype (const gchar *key, /** * xed_message_type_foreach: * @message_type: the #XedMessageType - * @func: the callback function + * @func: (scope call): the callback function * @user_data: user data supplied to the callback function * * Calls @func for each argument in the message type. * */ -void +void xed_message_type_foreach (XedMessageType *message_type, XedMessageTypeForeach func, gpointer user_data) diff --git a/xed/xed-message.c b/xed/xed-message.c index 13dd947..ed7c7c5 100644 --- a/xed/xed-message.c +++ b/xed/xed-message.c @@ -17,9 +17,6 @@ * A message can be seen as a method call, or signal emission depending on * who is the sender and who is the receiver. There is no explicit distinction * between methods and signals. - * - * Since: 2.25.3 - * */ #define XED_MESSAGE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_MESSAGE, XedMessagePrivate)) @@ -45,7 +42,7 @@ static void xed_message_finalize (GObject *object) { XedMessage *message = XED_MESSAGE (object); - + xed_message_type_unref (message->priv->type); g_hash_table_destroy (message->priv->values); @@ -102,16 +99,16 @@ add_value (XedMessage *message, { GValue *value; GType type = xed_message_type_lookup (message->priv->type, key); - + if (type == G_TYPE_INVALID) return NULL; - + value = g_new0 (GValue, 1); g_value_init (value, type); g_value_reset (value); g_hash_table_insert (message->priv->values, g_strdup (key), value); - + return value; } @@ -119,11 +116,11 @@ static void xed_message_class_init (XedMessageClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); - + object_class->finalize = xed_message_finalize; object_class->get_property = xed_message_get_property; object_class->set_property = xed_message_set_property; - + /** * XedMessage:object_path: * @@ -151,7 +148,7 @@ xed_message_class_init (XedMessageClass *klass) NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - + /** * XedMEssage:type: * @@ -189,17 +186,17 @@ xed_message_init (XedMessage *self) } static gboolean -set_value_real (GValue *to, +set_value_real (GValue *to, const GValue *from) { GType from_type; GType to_type; - + from_type = G_VALUE_TYPE (from); to_type = G_VALUE_TYPE (to); if (!g_type_is_a (from_type, to_type)) - { + { if (!g_value_transform (from, to)) { g_warning ("%s: Unable to make conversion from %s to %s", @@ -208,10 +205,10 @@ set_value_real (GValue *to, g_type_name (to_type)); return FALSE; } - + return TRUE; } - + g_value_copy (from, to); return TRUE; } @@ -222,10 +219,10 @@ value_lookup (XedMessage *message, gboolean create) { GValue *ret = (GValue *)g_hash_table_lookup (message->priv->values, key); - + if (!ret && create) ret = add_value (message, key); - + return ret; } @@ -242,7 +239,7 @@ const gchar * xed_message_get_method (XedMessage *message) { g_return_val_if_fail (XED_IS_MESSAGE (message), NULL); - + return xed_message_type_get_method (message->priv->type); } @@ -259,7 +256,7 @@ const gchar * xed_message_get_object_path (XedMessage *message) { g_return_val_if_fail (XED_IS_MESSAGE (message), NULL); - + return xed_message_type_get_object_path (message->priv->type); } @@ -308,21 +305,21 @@ xed_message_set_valist (XedMessage *message, GValue *container = value_lookup (message, key, TRUE); GValue value = {0,}; gchar *error = NULL; - + if (!container) { - g_warning ("%s: Cannot set value for %s, does not exist", + g_warning ("%s: Cannot set value for %s, does not exist", G_STRLOC, key); - + /* skip value */ va_arg (var_args, gpointer); continue; } - + g_value_init (&value, G_VALUE_TYPE (container)); G_VALUE_COLLECT (&value, var_args, 0, &error); - + if (error) { g_warning ("%s: %s", G_STRLOC, error); @@ -350,25 +347,25 @@ xed_message_set_value (XedMessage *message, { GValue *container; g_return_if_fail (XED_IS_MESSAGE (message)); - + container = value_lookup (message, key, TRUE); - + if (!container) { - g_warning ("%s: Cannot set value for %s, does not exist", - G_STRLOC, + g_warning ("%s: Cannot set value for %s, does not exist", + G_STRLOC, key); return; } - + set_value_real (container, value); } /** * xed_message_set_valuesv: * @message: the #XedMessage - * @keys: (array-length=n_values): keys to set values for - * @values: (array-length=n_values): values to set + * @keys: (array length=n_values): keys to set values for + * @values: (array length=n_values): values to set * @n_values: number of arguments to set values for * * Set message argument values. @@ -381,9 +378,9 @@ xed_message_set_valuesv (XedMessage *message, gint n_values) { gint i; - + g_return_if_fail (XED_IS_MESSAGE (message)); - + for (i = 0; i < n_values; i++) { xed_message_set_value (message, keys[i], &values[i]); @@ -401,14 +398,14 @@ xed_message_set_valuesv (XedMessage *message, * value for the specified key. * */ -void +void xed_message_get (XedMessage *message, ...) { va_list ap; g_return_if_fail (XED_IS_MESSAGE (message)); - + va_start (ap, message); xed_message_get_valist (message, ap); va_end (ap); @@ -431,7 +428,7 @@ xed_message_get_valist (XedMessage *message, const gchar *key; g_return_if_fail (XED_IS_MESSAGE (message)); - + while ((key = va_arg (var_args, const gchar *)) != NULL) { GValue *container; @@ -439,30 +436,30 @@ xed_message_get_valist (XedMessage *message, gchar *error = NULL; container = value_lookup (message, key, FALSE); - + if (!container) - { + { /* skip value */ va_arg (var_args, gpointer); continue; } - + /* copy the value here, to be sure it isn't tainted */ g_value_init (©, G_VALUE_TYPE (container)); g_value_copy (container, ©); - + G_VALUE_LCOPY (©, var_args, 0, &error); - + if (error) { g_warning ("%s: %s", G_STRLOC, error); g_free (error); - + /* purposely leak the value here, because it might be in a bad state */ continue; } - + g_value_unset (©); } } @@ -477,17 +474,17 @@ xed_message_get_valist (XedMessage *message, * with the correct type. * */ -void +void xed_message_get_value (XedMessage *message, const gchar *key, GValue *value) { GValue *container; - + g_return_if_fail (XED_IS_MESSAGE (message)); - + container = value_lookup (message, key, FALSE); - + if (!container) { g_warning ("%s: Invalid key `%s'", @@ -495,7 +492,7 @@ xed_message_get_value (XedMessage *message, key); return; } - + g_value_init (value, G_VALUE_TYPE (container)); set_value_real (value, container); } @@ -510,7 +507,7 @@ xed_message_get_value (XedMessage *message, * Return value: the type of @key * */ -GType +GType xed_message_get_key_type (XedMessage *message, const gchar *key) { @@ -535,14 +532,14 @@ xed_message_has_key (XedMessage *message, const gchar *key) { g_return_val_if_fail (XED_IS_MESSAGE (message), FALSE); - + return value_lookup (message, key, FALSE) != NULL; } typedef struct { XedMessage *message; - gboolean valid; + gboolean valid; } ValidateInfo; static void @@ -552,12 +549,12 @@ validate_key (const gchar *key, ValidateInfo *info) { GValue *value; - + if (!info->valid || !required) return; - + value = value_lookup (info->message, key, FALSE); - + if (!value) info->valid = FALSE; } @@ -578,16 +575,16 @@ xed_message_validate (XedMessage *message) g_return_val_if_fail (XED_IS_MESSAGE (message), FALSE); g_return_val_if_fail (message->priv->type != NULL, FALSE); - + if (!message->priv->valid) { - xed_message_type_foreach (message->priv->type, + xed_message_type_foreach (message->priv->type, (XedMessageTypeForeach)validate_key, &info); message->priv->valid = info.valid; } - + return message->priv->valid; } diff --git a/xed/xed-metadata-manager.c b/xed/xed-metadata-manager.c index a656d70..01d491e 100644 --- a/xed/xed-metadata-manager.c +++ b/xed/xed-metadata-manager.c @@ -3,7 +3,7 @@ * xed-metadata-manager.c * This file is part of xed * - * Copyright (C) 2003-2007 Paolo Maggi + * Copyright (C) 2003-2007 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,33 +17,26 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2003-2007. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif +/* + * Modified by the xed Team, 2003-2007. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. + */ #include #include #include #include "xed-metadata-manager.h" #include "xed-debug.h" -#include "xed-dirs.h" /* #define XED_METADATA_VERBOSE_DEBUG 1 */ -#define METADATA_FILE "xed-metadata.xml" - #define MAX_ITEMS 50 typedef struct _XedMetadataManager XedMetadataManager; @@ -56,15 +49,17 @@ struct _Item GHashTable *values; }; - + struct _XedMetadataManager { - gboolean values_loaded; /* It is true if the file + gboolean values_loaded; /* It is true if the file has been read */ guint timeout_id; GHashTable *items; + + gchar *metadata_filename; }; static gboolean xed_metadata_manager_save (gpointer data); @@ -76,7 +71,7 @@ static void item_free (gpointer data) { Item *item; - + g_return_if_fail (data != NULL); #ifdef XED_METADATA_VERBOSE_DEBUG @@ -96,7 +91,7 @@ xed_metadata_manager_arm_timeout (void) { if (xed_metadata_manager->timeout_id == 0) { - xed_metadata_manager->timeout_id = + xed_metadata_manager->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE, 2, (GSourceFunc)xed_metadata_manager_save, @@ -105,28 +100,42 @@ xed_metadata_manager_arm_timeout (void) } } -static gboolean -xed_metadata_manager_init (void) +/** + * xed_metadata_manager_init: + * @metadata_filename: the filename where the metadata is. + * + * This function initializes the metadata manager. + * See also xed_metadata_manager_shutdown(). + */ +void +xed_metadata_manager_init (const gchar *metadata_filename) { xed_debug (DEBUG_METADATA); if (xed_metadata_manager != NULL) - return TRUE; + return; xed_metadata_manager = g_new0 (XedMetadataManager, 1); xed_metadata_manager->values_loaded = FALSE; - xed_metadata_manager->items = - g_hash_table_new_full (g_str_hash, - g_str_equal, + xed_metadata_manager->items = + g_hash_table_new_full (g_str_hash, + g_str_equal, g_free, item_free); - return TRUE; + xed_metadata_manager->metadata_filename = g_strdup (metadata_filename); + + return; } -/* This function must be called before exiting xed */ +/** + * xed_metadata_manager_shutdown: + * + * This function frees the internal data of the metadata manager. + * See also xed_metadata_manager_init(). + */ void xed_metadata_manager_shutdown (void) { @@ -145,6 +154,7 @@ xed_metadata_manager_shutdown (void) if (xed_metadata_manager->items != NULL) g_hash_table_destroy (xed_metadata_manager->items); + g_free (gedit_metadata_manager->metadata_filename); g_free (xed_metadata_manager); xed_metadata_manager = NULL; } @@ -153,13 +163,13 @@ static void parseItem (xmlDocPtr doc, xmlNodePtr cur) { Item *item; - + xmlChar *uri; xmlChar *atime; - + #ifdef XED_METADATA_VERBOSE_DEBUG xed_debug (DEBUG_METADATA); -#endif +#endif if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0) return; @@ -167,7 +177,7 @@ parseItem (xmlDocPtr doc, xmlNodePtr cur) uri = xmlGetProp (cur, (const xmlChar *)"uri"); if (uri == NULL) return; - + atime = xmlGetProp (cur, (const xmlChar *)"atime"); if (atime == NULL) { @@ -179,9 +189,9 @@ parseItem (xmlDocPtr doc, xmlNodePtr cur) item->atime = g_ascii_strtoull ((char *)atime, NULL, 0); - item->values = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, + item->values = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, g_free); cur = cur->xmlChildrenNode; @@ -198,7 +208,7 @@ parseItem (xmlDocPtr doc, xmlNodePtr cur) if ((key != NULL) && (value != NULL)) g_hash_table_insert (item->values, - g_strdup ((gchar *)key), + g_strdup ((gchar *)key), g_strdup ((gchar *)value)); if (key != NULL) @@ -218,29 +228,11 @@ parseItem (xmlDocPtr doc, xmlNodePtr cur) xmlFree (atime); } -static gchar * -get_metadata_filename (void) -{ - gchar *cache_dir; - gchar *metadata; - - cache_dir = xed_dirs_get_user_cache_dir (); - - metadata = g_build_filename (cache_dir, - METADATA_FILE, - NULL); - - g_free (cache_dir); - - return metadata; -} - static gboolean load_values (void) { xmlDocPtr doc; xmlNodePtr cur; - gchar *file_name; xed_debug (DEBUG_METADATA); @@ -248,20 +240,17 @@ load_values (void) g_return_val_if_fail (xed_metadata_manager->values_loaded == FALSE, FALSE); xed_metadata_manager->values_loaded = TRUE; - + xmlKeepBlanksDefault (0); /* FIXME: file locking - Paolo */ - file_name = get_metadata_filename (); - if ((file_name == NULL) || - (!g_file_test (file_name, G_FILE_TEST_EXISTS))) + if ((xed_metadata_manager->metadata_filename == NULL) || + (!g_file_test (xed_metadata_manager->metadata_filename, G_FILE_TEST_EXISTS))) { - g_free (file_name); return FALSE; } - doc = xmlParseFile (file_name); - g_free (file_name); + doc = xmlParseFile (xed_metadata_manager->metadata_filename); if (doc == NULL) { @@ -269,25 +258,25 @@ load_values (void) } cur = xmlDocGetRootElement (doc); - if (cur == NULL) + if (cur == NULL) { - g_message ("The metadata file '%s' is empty", METADATA_FILE); + g_message ("The metadata file '%s' is empty", g_path_get_basename (xed_metadata_manager->metadata_filename)); xmlFreeDoc (doc); - + return FALSE; } - if (xmlStrcmp (cur->name, (const xmlChar *) "metadata")) + if (xmlStrcmp (cur->name, (const xmlChar *) "metadata")) { - g_message ("File '%s' is of the wrong type", METADATA_FILE); + g_message ("File '%s' is of the wrong type", g_path_get_basename (xed_metadata_manager->metadata_filename)); xmlFreeDoc (doc); - + return FALSE; } cur = xmlDocGetRootElement (doc); cur = cur->xmlChildrenNode; - + while (cur != NULL) { parseItem (doc, cur); @@ -300,19 +289,27 @@ load_values (void) return TRUE; } +/** + * xed_metadata_manager_get: + * @location: a #GFile. + * @key: a key. + * + * Gets the value associated with the specified @key for the file @location. + */ gchar * -xed_metadata_manager_get (const gchar *uri, +xed_metadata_manager_get (GFile *location, const gchar *key) { Item *item; gchar *value; + gchar *uri; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (G_IS_FILE (location), NULL); g_return_val_if_fail (key != NULL, NULL); - xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key ); + uri = g_file_get_uri (location); - xed_metadata_manager_init (); + xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key ); if (!xed_metadata_manager->values_loaded) { @@ -327,11 +324,13 @@ xed_metadata_manager_get (const gchar *uri, item = (Item *)g_hash_table_lookup (xed_metadata_manager->items, uri); + g_free (uri); + if (item == NULL) return NULL; item->atime = time (NULL); - + if (item->values == NULL) return NULL; @@ -343,19 +342,28 @@ xed_metadata_manager_get (const gchar *uri, return g_strdup (value); } +/** + * xed_metadata_manager_set: + * @location: a #GFile. + * @key: a key. + * @value: the value associated with the @key. + * + * Sets the @key to contain the given @value for the file @location. + */ void -xed_metadata_manager_set (const gchar *uri, +xed_metadata_manager_set (GFile *location, const gchar *key, const gchar *value) { Item *item; + gchar *uri; - g_return_if_fail (uri != NULL); + g_return_if_fail (G_IS_FILE (location)); g_return_if_fail (key != NULL); + uri = g_file_get_uri (location); + xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value); - - xed_metadata_manager_init (); if (!xed_metadata_manager->values_loaded) { @@ -378,11 +386,11 @@ xed_metadata_manager_set (const gchar *uri, g_strdup (uri), item); } - + if (item->values == NULL) - item->values = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, + item->values = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, g_free); if (value != NULL) g_hash_table_insert (item->values, @@ -394,6 +402,8 @@ xed_metadata_manager_set (const gchar *uri, item->atime = time (NULL); + g_free (uri); + xed_metadata_manager_arm_timeout (); } @@ -404,13 +414,13 @@ save_values (const gchar *key, const gchar *value, xmlNodePtr parent) #ifdef XED_METADATA_VERBOSE_DEBUG xed_debug (DEBUG_METADATA); -#endif +#endif g_return_if_fail (key != NULL); - + if (value == NULL) return; - + xml_node = xmlNewChild (parent, NULL, (const xmlChar *)"entry", @@ -425,7 +435,7 @@ save_values (const gchar *key, const gchar *value, xmlNodePtr parent) #ifdef XED_METADATA_VERBOSE_DEBUG xed_debug_message (DEBUG_METADATA, "entry: %s = %s", key, value); -#endif +#endif } static void @@ -450,14 +460,14 @@ save_item (const gchar *key, const gpointer *data, xmlNodePtr parent) #ifdef XED_METADATA_VERBOSE_DEBUG xed_debug_message (DEBUG_METADATA, "uri: %s", key); -#endif +#endif atime = g_strdup_printf ("%ld", item->atime); - xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime); + xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime); #ifdef XED_METADATA_VERBOSE_DEBUG xed_debug_message (DEBUG_METADATA, "atime: %s", atime); -#endif +#endif g_free (atime); @@ -477,7 +487,7 @@ get_oldest (const gchar *key, const gpointer value, const gchar ** key_to_remove } else { - const Item *item_to_remove = + const Item *item_to_remove = g_hash_table_lookup (xed_metadata_manager->items, *key_to_remove); @@ -487,7 +497,7 @@ get_oldest (const gchar *key, const gpointer value, const gchar ** key_to_remove { *key_to_remove = key; } - } + } } static void @@ -502,7 +512,7 @@ resize_items (void) &key_to_remove); g_return_if_fail (key_to_remove != NULL); - + g_hash_table_remove (xed_metadata_manager->items, key_to_remove); } @@ -510,17 +520,16 @@ resize_items (void) static gboolean xed_metadata_manager_save (gpointer data) -{ +{ xmlDocPtr doc; xmlNodePtr root; - gchar *file_name; xed_debug (DEBUG_METADATA); xed_metadata_manager->timeout_id = 0; resize_items (); - + xmlIndentTreeOutput = TRUE; doc = xmlNewDoc ((const xmlChar *)"1.0"); @@ -533,28 +542,26 @@ xed_metadata_manager_save (gpointer data) g_hash_table_foreach (xed_metadata_manager->items, (GHFunc)save_item, - root); + root); /* FIXME: lock file - Paolo */ - file_name = get_metadata_filename (); - if (file_name != NULL) + if (xed_metadata_manager->metadata_filename != NULL) { gchar *cache_dir; int res; /* make sure the cache dir exists */ - cache_dir = xed_dirs_get_user_cache_dir (); + cache_dir = g_path_get_dirname (xed_metadata_manager->metadata_filename); res = g_mkdir_with_parents (cache_dir, 0755); if (res != -1) { - xmlSaveFormatFile (file_name, doc, 1); + xmlSaveFormatFile (xed_metadata_manager->metadata_filename, doc, 1); } g_free (cache_dir); - g_free (file_name); } - xmlFreeDoc (doc); + xmlFreeDoc (doc); xed_debug_message (DEBUG_METADATA, "DONE"); diff --git a/xed/xed-metadata-manager.h b/xed/xed-metadata-manager.h index 5f26bbe..dd682f7 100644 --- a/xed/xed-metadata-manager.h +++ b/xed/xed-metadata-manager.h @@ -3,7 +3,7 @@ * xed-metadata-manager.h * This file is part of xed * - * Copyright (C) 2003 Paolo Maggi + * Copyright (C) 2003 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,14 +17,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2003. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2003. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ #ifndef __XED_METADATA_MANAGER_H__ @@ -34,16 +34,17 @@ G_BEGIN_DECLS +void xed_metadata_manager_init (const gchar *metadata_filename); /* This function must be called before exiting xed */ -void xed_metadata_manager_shutdown (void); +void xed_metadata_manager_shutdown (void); +gchar *xed_metadata_manager_get (GFile *location, + const gchar *key); -gchar *xed_metadata_manager_get (const gchar *uri, - const gchar *key); -void xed_metadata_manager_set (const gchar *uri, - const gchar *key, - const gchar *value); +void xed_metadata_manager_set (GFile *location, + const gchar *key, + const gchar *value); G_END_DECLS diff --git a/xed/xed-notebook.c b/xed/xed-notebook.c index 46b9589..b0ee7c1 100644 --- a/xed/xed-notebook.c +++ b/xed/xed-notebook.c @@ -2,7 +2,7 @@ * xed-notebook.c * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ /* This file is a modified version of the epiphany file ephy-notebook.c @@ -56,15 +56,16 @@ struct _XedNotebookPrivate { - GList *focused_pages; - gulong motion_notify_handler_id; - gint x_start; - gint y_start; - gint drag_in_progress : 1; - gint always_show_tabs : 1; - gint close_buttons_sensitive : 1; - gint tab_drag_and_drop_enabled : 1; - guint destroy_has_run : 1; + GSettings *ui_settings; + GList *focused_pages; + gulong motion_notify_handler_id; + gint x_start; + gint y_start; + gint drag_in_progress : 1; + gint close_buttons_sensitive : 1; + gint tab_drag_and_drop_enabled : 1; + gint tab_scrolling_enabled : 1; + guint destroy_has_run : 1; }; G_DEFINE_TYPE(XedNotebook, xed_notebook, GTK_TYPE_NOTEBOOK) @@ -72,12 +73,12 @@ G_DEFINE_TYPE(XedNotebook, xed_notebook, GTK_TYPE_NOTEBOOK) static void xed_notebook_finalize (GObject *object); static gboolean xed_notebook_change_current_page (GtkNotebook *notebook, - gint offset); + gint offset); -static void move_current_tab_to_another_notebook (XedNotebook *src, - XedNotebook *dest, - GdkEventMotion *event, - gint dest_position); +static void move_current_tab_to_another_notebook (XedNotebook *src, + XedNotebook *dest, + GdkEventMotion *event, + gint dest_position); /* Local variables */ static GdkCursor *cursor = NULL; @@ -85,12 +86,12 @@ static GdkCursor *cursor = NULL; /* Signals */ enum { - TAB_ADDED, - TAB_REMOVED, - TABS_REORDERED, - TAB_DETACHED, - TAB_CLOSE_REQUEST, - LAST_SIGNAL + TAB_ADDED, + TAB_REMOVED, + TABS_REORDERED, + TAB_DETACHED, + TAB_CLOSE_REQUEST, + LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -98,178 +99,177 @@ static guint signals[LAST_SIGNAL] = { 0 }; static void xed_notebook_dispose (GObject *object) { - XedNotebook *notebook = XED_NOTEBOOK (object); + XedNotebook *notebook = XED_NOTEBOOK (object); - if (!notebook->priv->destroy_has_run) - { - GList *children, *l; + if (!notebook->priv->destroy_has_run) + { + GList *children, *l; - children = gtk_container_get_children (GTK_CONTAINER (notebook)); + children = gtk_container_get_children (GTK_CONTAINER (notebook)); - for (l = children; l != NULL; l = g_list_next (l)) - { - xed_notebook_remove_tab (notebook, - XED_TAB (l->data)); - } + for (l = children; l != NULL; l = g_list_next (l)) + { + xed_notebook_remove_tab (notebook, XED_TAB (l->data)); + } - g_list_free (children); - notebook->priv->destroy_has_run = TRUE; - } + g_list_free (children); + notebook->priv->destroy_has_run = TRUE; + } - G_OBJECT_CLASS (xed_notebook_parent_class)->dispose (object); + g_clear_object (¬ebook->priv->ui_settings); + + G_OBJECT_CLASS (xed_notebook_parent_class)->dispose (object); } static void xed_notebook_class_init (XedNotebookClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass); - object_class->finalize = xed_notebook_finalize; - object_class->dispose = xed_notebook_dispose; + object_class->finalize = xed_notebook_finalize; + object_class->dispose = xed_notebook_dispose; - notebook_class->change_current_page = xed_notebook_change_current_page; + notebook_class->change_current_page = xed_notebook_change_current_page; - signals[TAB_ADDED] = - g_signal_new ("tab_added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (XedNotebookClass, tab_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - XED_TYPE_TAB); - signals[TAB_REMOVED] = - g_signal_new ("tab_removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (XedNotebookClass, tab_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - XED_TYPE_TAB); - signals[TAB_DETACHED] = - g_signal_new ("tab_detached", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (XedNotebookClass, tab_detached), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - XED_TYPE_TAB); - signals[TABS_REORDERED] = - g_signal_new ("tabs_reordered", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (XedNotebookClass, tabs_reordered), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - signals[TAB_CLOSE_REQUEST] = - g_signal_new ("tab-close-request", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedNotebookClass, tab_close_request), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - XED_TYPE_TAB); + signals[TAB_ADDED] = + g_signal_new ("tab_added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (XedNotebookClass, tab_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + XED_TYPE_TAB); + signals[TAB_REMOVED] = + g_signal_new ("tab_removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (XedNotebookClass, tab_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + XED_TYPE_TAB); + signals[TAB_DETACHED] = + g_signal_new ("tab_detached", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (XedNotebookClass, tab_detached), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + XED_TYPE_TAB); + signals[TABS_REORDERED] = + g_signal_new ("tabs_reordered", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (XedNotebookClass, tabs_reordered), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + signals[TAB_CLOSE_REQUEST] = + g_signal_new ("tab-close-request", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedNotebookClass, tab_close_request), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + XED_TYPE_TAB); - g_type_class_add_private (object_class, sizeof(XedNotebookPrivate)); + g_type_class_add_private (object_class, sizeof(XedNotebookPrivate)); } static XedNotebook * -find_notebook_at_pointer (gint abs_x, gint abs_y) +find_notebook_at_pointer (gint abs_x, + gint abs_y) { - GdkWindow *win_at_pointer; - GdkWindow *toplevel_win; - gpointer toplevel = NULL; - gint x, y; + GdkWindow *win_at_pointer; + GdkWindow *toplevel_win; + gpointer toplevel = NULL; + gint x, y; - /* FIXME multi-head */ - win_at_pointer = gdk_window_at_pointer (&x, &y); - if (win_at_pointer == NULL) - { - /* We are outside all windows of the same application */ - return NULL; - } + /* FIXME multi-head */ + win_at_pointer = gdk_window_at_pointer (&x, &y); + if (win_at_pointer == NULL) + { + /* We are outside all windows of the same application */ + return NULL; + } - toplevel_win = gdk_window_get_toplevel (win_at_pointer); + toplevel_win = gdk_window_get_toplevel (win_at_pointer); - /* get the GtkWidget which owns the toplevel GdkWindow */ - gdk_window_get_user_data (toplevel_win, &toplevel); + /* get the GtkWidget which owns the toplevel GdkWindow */ + gdk_window_get_user_data (toplevel_win, &toplevel); - /* toplevel should be an XedWindow */ - if ((toplevel != NULL) && - XED_IS_WINDOW (toplevel)) - { - return XED_NOTEBOOK (_xed_window_get_notebook - (XED_WINDOW (toplevel))); - } + /* toplevel should be an XedWindow */ + if ((toplevel != NULL) && XED_IS_WINDOW (toplevel)) + { + return XED_NOTEBOOK (_xed_window_get_notebook (XED_WINDOW (toplevel))); + } - /* We are outside all windows containing a notebook */ - return NULL; + /* We are outside all windows containing a notebook */ + return NULL; } static gboolean is_in_notebook_window (XedNotebook *notebook, - gint abs_x, - gint abs_y) + gint abs_x, + gint abs_y) { - XedNotebook *nb_at_pointer; + XedNotebook *nb_at_pointer; - g_return_val_if_fail (notebook != NULL, FALSE); + g_return_val_if_fail (notebook != NULL, FALSE); - nb_at_pointer = find_notebook_at_pointer (abs_x, abs_y); + nb_at_pointer = find_notebook_at_pointer (abs_x, abs_y); - return (nb_at_pointer == notebook); + return (nb_at_pointer == notebook); } static gint -find_tab_num_at_pos (XedNotebook *notebook, - gint abs_x, - gint abs_y) +find_tab_num_at_pos (XedNotebook *notebook, + gint abs_x, + gint abs_y) { - GtkPositionType tab_pos; - int page_num = 0; - GtkNotebook *nb = GTK_NOTEBOOK (notebook); - GtkWidget *page; + GtkPositionType tab_pos; + int page_num = 0; + GtkNotebook *nb = GTK_NOTEBOOK (notebook); + GtkWidget *page; - tab_pos = gtk_notebook_get_tab_pos (GTK_NOTEBOOK (notebook)); + tab_pos = gtk_notebook_get_tab_pos (GTK_NOTEBOOK (notebook)); - /* For some reason unfullscreen + quick click can - cause a wrong click event to be reported to the tab */ - if (!is_in_notebook_window (notebook, abs_x, abs_y)) - { - return NOT_IN_APP_WINDOWS; - } + /* For some reason unfullscreen + quick click can + cause a wrong click event to be reported to the tab */ + if (!is_in_notebook_window (notebook, abs_x, abs_y)) + { + return NOT_IN_APP_WINDOWS; + } - while ((page = gtk_notebook_get_nth_page (nb, page_num)) != NULL) - { - GtkAllocation allocation; - GtkWidget *tab; + while ((page = gtk_notebook_get_nth_page (nb, page_num)) != NULL) + { + GtkAllocation allocation; + GtkWidget *tab; gint min_x, min_y; - gint max_x, max_y; - gint x_root, y_root; + gint max_x, max_y; + gint x_root, y_root; - tab = gtk_notebook_get_tab_label (nb, page); - g_return_val_if_fail (tab != NULL, AFTER_ALL_TABS); + tab = gtk_notebook_get_tab_label (nb, page); + g_return_val_if_fail (tab != NULL, AFTER_ALL_TABS); - if (!gtk_widget_get_mapped (tab)) - { - ++page_num; - continue; - } + if (!gtk_widget_get_mapped (tab)) + { + ++page_num; + continue; + } - gdk_window_get_origin (GDK_WINDOW (gtk_widget_get_window (tab)), - &x_root, &y_root); + gdk_window_get_origin (GDK_WINDOW (gtk_widget_get_window (tab)), &x_root, &y_root); - gtk_widget_get_allocation(tab, &allocation); + gtk_widget_get_allocation(tab, &allocation); min_x = x_root + allocation.x; max_x = x_root + allocation.x + allocation.width; @@ -293,34 +293,34 @@ find_tab_num_at_pos (XedNotebook *notebook, return page_num; } - ++page_num; - } - - return AFTER_ALL_TABS; + ++page_num; + } + + return AFTER_ALL_TABS; } -static gint -find_notebook_and_tab_at_pos (gint abs_x, - gint abs_y, - XedNotebook **notebook, - gint *page_num) +static gint +find_notebook_and_tab_at_pos (gint abs_x, + gint abs_y, + XedNotebook **notebook, + gint *page_num) { - *notebook = find_notebook_at_pointer (abs_x, abs_y); - if (*notebook == NULL) - { - return NOT_IN_APP_WINDOWS; - } - - *page_num = find_tab_num_at_pos (*notebook, abs_x, abs_y); + *notebook = find_notebook_at_pointer (abs_x, abs_y); + if (*notebook == NULL) + { + return NOT_IN_APP_WINDOWS; + } - if (*page_num < 0) - { - return *page_num; - } - else - { - return 0; - } + *page_num = find_tab_num_at_pos (*notebook, abs_x, abs_y); + + if (*page_num < 0) + { + return *page_num; + } + else + { + return 0; + } } /** @@ -331,26 +331,26 @@ find_notebook_and_tab_at_pos (gint abs_x, * @dest_position: the position for @tab * * Moves @tab from @src to @dest. - * If dest_position is greater than or equal to the number of tabs - * of the destination nootebook or negative, tab will be moved to the + * If dest_position is greater than or equal to the number of tabs + * of the destination nootebook or negative, tab will be moved to the * end of the tabs. */ void xed_notebook_move_tab (XedNotebook *src, - XedNotebook *dest, - XedTab *tab, - gint dest_position) + XedNotebook *dest, + XedTab *tab, + gint dest_position) { - g_return_if_fail (XED_IS_NOTEBOOK (src)); - g_return_if_fail (XED_IS_NOTEBOOK (dest)); - g_return_if_fail (src != dest); - g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (XED_IS_NOTEBOOK (src)); + g_return_if_fail (XED_IS_NOTEBOOK (dest)); + g_return_if_fail (src != dest); + g_return_if_fail (XED_IS_TAB (tab)); - /* make sure the tab isn't destroyed while we move it */ - g_object_ref (tab); - xed_notebook_remove_tab (src, tab); - xed_notebook_add_tab (dest, tab, dest_position, TRUE); - g_object_unref (tab); + /* make sure the tab isn't destroyed while we move it */ + g_object_ref (tab); + xed_notebook_remove_tab (src, tab); + xed_notebook_add_tab (dest, tab, dest_position, TRUE); + g_object_unref (tab); } /** @@ -360,81 +360,77 @@ xed_notebook_move_tab (XedNotebook *src, * @dest_position: the position for @tab * * Reorders the page containing @tab, so that it appears in @dest_position position. - * If dest_position is greater than or equal to the number of tabs - * of the destination notebook or negative, tab will be moved to the + * If dest_position is greater than or equal to the number of tabs + * of the destination notebook or negative, tab will be moved to the * end of the tabs. */ void xed_notebook_reorder_tab (XedNotebook *src, - XedTab *tab, - gint dest_position) + XedTab *tab, + gint dest_position) { - gint old_position; - - g_return_if_fail (XED_IS_NOTEBOOK (src)); - g_return_if_fail (XED_IS_TAB (tab)); + gint old_position; - old_position = gtk_notebook_page_num (GTK_NOTEBOOK (src), - GTK_WIDGET (tab)); - - if (old_position == dest_position) - return; + g_return_if_fail (XED_IS_NOTEBOOK (src)); + g_return_if_fail (XED_IS_TAB (tab)); - gtk_notebook_reorder_child (GTK_NOTEBOOK (src), - GTK_WIDGET (tab), - dest_position); - - if (!src->priv->drag_in_progress) - { - g_signal_emit (G_OBJECT (src), - signals[TABS_REORDERED], - 0); - } + old_position = gtk_notebook_page_num (GTK_NOTEBOOK (src), GTK_WIDGET (tab)); + + if (old_position == dest_position) + { + return; + } + + gtk_notebook_reorder_child (GTK_NOTEBOOK (src), GTK_WIDGET (tab), dest_position); + + if (!src->priv->drag_in_progress) + { + g_signal_emit (G_OBJECT (src), signals[TABS_REORDERED], 0); + } } static void drag_start (XedNotebook *notebook, - guint32 time) + guint32 time) { - notebook->priv->drag_in_progress = TRUE; + notebook->priv->drag_in_progress = TRUE; - /* get a new cursor, if necessary */ - /* FIXME multi-head */ - if (cursor == NULL) - cursor = gdk_cursor_new (GDK_FLEUR); + /* get a new cursor, if necessary */ + /* FIXME multi-head */ + if (cursor == NULL) + { + cursor = gdk_cursor_new (GDK_FLEUR); + } - /* grab the pointer */ - gtk_grab_add (GTK_WIDGET (notebook)); + /* grab the pointer */ + gtk_grab_add (GTK_WIDGET (notebook)); - /* FIXME multi-head */ - if (!gdk_pointer_is_grabbed ()) - { - gdk_pointer_grab (gtk_widget_get_window (GTK_WIDGET (notebook)), - FALSE, - GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, - NULL, - cursor, - time); - } + /* FIXME multi-head */ + if (!gdk_pointer_is_grabbed ()) + { + gdk_pointer_grab (gtk_widget_get_window (GTK_WIDGET (notebook)), + FALSE, + GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, + NULL, + cursor, + time); + } } static void drag_stop (XedNotebook *notebook) { - if (notebook->priv->drag_in_progress) - { - g_signal_emit (G_OBJECT (notebook), - signals[TABS_REORDERED], - 0); - } + if (notebook->priv->drag_in_progress) + { + g_signal_emit (G_OBJECT (notebook), signals[TABS_REORDERED], 0); + } - notebook->priv->drag_in_progress = FALSE; - if (notebook->priv->motion_notify_handler_id != 0) - { - g_signal_handler_disconnect (G_OBJECT (notebook), - notebook->priv->motion_notify_handler_id); - notebook->priv->motion_notify_handler_id = 0; - } + notebook->priv->drag_in_progress = FALSE; + if (notebook->priv->motion_notify_handler_id != 0) + { + g_signal_handler_disconnect (G_OBJECT (notebook), notebook->priv->motion_notify_handler_id); + notebook->priv->motion_notify_handler_id = 0; + } } /* This function is only called during dnd, we don't need to emit TABS_REORDERED @@ -442,205 +438,218 @@ drag_stop (XedNotebook *notebook) */ static void move_current_tab (XedNotebook *notebook, - gint dest_position) + gint dest_position) { - gint cur_page_num; + gint cur_page_num; - cur_page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); + cur_page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); - if (dest_position != cur_page_num) - { - GtkWidget *cur_tab; - - cur_tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), - cur_page_num); - - xed_notebook_reorder_tab (XED_NOTEBOOK (notebook), - XED_TAB (cur_tab), - dest_position); - } + if (dest_position != cur_page_num) + { + GtkWidget *cur_tab; + + cur_tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), cur_page_num); + xed_notebook_reorder_tab (XED_NOTEBOOK (notebook), XED_TAB (cur_tab), dest_position); + } } static gboolean -motion_notify_cb (XedNotebook *notebook, - GdkEventMotion *event, - gpointer data) +motion_notify_cb (XedNotebook *notebook, + GdkEventMotion *event, + gpointer data) { - XedNotebook *dest; - gint page_num; - gint result; + XedNotebook *dest; + gint page_num; + gint result; - if (notebook->priv->drag_in_progress == FALSE) - { - if (notebook->priv->tab_drag_and_drop_enabled == FALSE) - return FALSE; - - if (gtk_drag_check_threshold (GTK_WIDGET (notebook), - notebook->priv->x_start, - notebook->priv->y_start, - event->x_root, - event->y_root)) - { - drag_start (notebook, event->time); - return TRUE; - } + if (notebook->priv->drag_in_progress == FALSE) + { + if (notebook->priv->tab_drag_and_drop_enabled == FALSE) + { + return FALSE; + } - return FALSE; - } + if (gtk_drag_check_threshold (GTK_WIDGET (notebook), + notebook->priv->x_start, + notebook->priv->y_start, + event->x_root, + event->y_root)) + { + drag_start (notebook, event->time); + return TRUE; + } - result = find_notebook_and_tab_at_pos ((gint)event->x_root, - (gint)event->y_root, - &dest, - &page_num); + return FALSE; + } - if (result != NOT_IN_APP_WINDOWS) - { - if (dest != notebook) - { - move_current_tab_to_another_notebook (notebook, - dest, - event, - page_num); - } - else - { - g_return_val_if_fail (page_num >= -1, FALSE); - move_current_tab (notebook, page_num); - } - } + result = find_notebook_and_tab_at_pos ((gint)event->x_root, (gint)event->y_root, &dest, &page_num); - return FALSE; + if (result != NOT_IN_APP_WINDOWS) + { + if (dest != notebook) + { + move_current_tab_to_another_notebook (notebook, dest, event, page_num); + } + else + { + g_return_val_if_fail (page_num >= -1, FALSE); + move_current_tab (notebook, page_num); + } + } + + return FALSE; } static void -move_current_tab_to_another_notebook (XedNotebook *src, - XedNotebook *dest, - GdkEventMotion *event, - gint dest_position) +move_current_tab_to_another_notebook (XedNotebook *src, + XedNotebook *dest, + GdkEventMotion *event, + gint dest_position) { - XedTab *tab; - gint cur_page; + XedTab *tab; + gint cur_page; - /* This is getting tricky, the tab was dragged in a notebook - * in another window of the same app, we move the tab - * to that new notebook, and let this notebook handle the - * drag - */ - g_return_if_fail (XED_IS_NOTEBOOK (dest)); - g_return_if_fail (dest != src); + /* This is getting tricky, the tab was dragged in a notebook + * in another window of the same app, we move the tab + * to that new notebook, and let this notebook handle the + * drag + */ + g_return_if_fail (XED_IS_NOTEBOOK (dest)); + g_return_if_fail (dest != src); - cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (src)); - tab = XED_TAB (gtk_notebook_get_nth_page (GTK_NOTEBOOK (src), - cur_page)); + cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (src)); + tab = XED_TAB (gtk_notebook_get_nth_page (GTK_NOTEBOOK (src), cur_page)); - /* stop drag in origin window */ - /* ungrab the pointer if it's grabbed */ - drag_stop (src); - if (gdk_pointer_is_grabbed ()) - { - gdk_pointer_ungrab (event->time); - } - gtk_grab_remove (GTK_WIDGET (src)); + /* stop drag in origin window */ + /* ungrab the pointer if it's grabbed */ + drag_stop (src); + if (gdk_pointer_is_grabbed ()) + { + gdk_pointer_ungrab (event->time); + } + gtk_grab_remove (GTK_WIDGET (src)); - xed_notebook_move_tab (src, dest, tab, dest_position); + xed_notebook_move_tab (src, dest, tab, dest_position); - /* start drag handling in dest notebook */ - dest->priv->motion_notify_handler_id = - g_signal_connect (G_OBJECT (dest), - "motion-notify-event", - G_CALLBACK (motion_notify_cb), - NULL); + /* start drag handling in dest notebook */ + dest->priv->motion_notify_handler_id = g_signal_connect (G_OBJECT (dest), "motion-notify-event", + G_CALLBACK (motion_notify_cb), NULL); - drag_start (dest, event->time); + drag_start (dest, event->time); } static gboolean -button_release_cb (XedNotebook *notebook, - GdkEventButton *event, - gpointer data) +button_release_cb (XedNotebook *notebook, + GdkEventButton *event, + gpointer data) { - if (notebook->priv->drag_in_progress) - { - gint cur_page_num; - GtkWidget *cur_page; + if (notebook->priv->drag_in_progress) + { + gint cur_page_num; + GtkWidget *cur_page; - cur_page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); - cur_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), - cur_page_num); + cur_page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); + cur_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), cur_page_num); - /* CHECK: I don't follow the code here -- Paolo */ - if (!is_in_notebook_window (notebook, event->x_root, event->y_root) && - (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) > 1)) - { - /* Tab was detached */ - g_signal_emit (G_OBJECT (notebook), - signals[TAB_DETACHED], - 0, - cur_page); - } + /* CHECK: I don't follow the code here -- Paolo */ + if (!is_in_notebook_window (notebook, event->x_root, event->y_root) && + (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) > 1)) + { + /* Tab was detached */ + g_signal_emit (G_OBJECT (notebook), signals[TAB_DETACHED], 0, cur_page); + } - /* ungrab the pointer if it's grabbed */ - if (gdk_pointer_is_grabbed ()) - { - gdk_pointer_ungrab (event->time); - } - gtk_grab_remove (GTK_WIDGET (notebook)); - } + /* ungrab the pointer if it's grabbed */ + if (gdk_pointer_is_grabbed ()) + { + gdk_pointer_ungrab (event->time); + } + gtk_grab_remove (GTK_WIDGET (notebook)); + } - /* This must be called even if a drag isn't happening */ - drag_stop (notebook); + /* This must be called even if a drag isn't happening */ + drag_stop (notebook); - return FALSE; + return FALSE; } static gboolean -button_press_cb (XedNotebook *notebook, - GdkEventButton *event, - gpointer data) +button_press_cb (XedNotebook *notebook, + GdkEventButton *event, + gpointer data) { - gint tab_clicked; + gint tab_clicked; - if (notebook->priv->drag_in_progress) - return TRUE; + if (notebook->priv->drag_in_progress) + { + return TRUE; + } - tab_clicked = find_tab_num_at_pos (notebook, - event->x_root, - event->y_root); - - if ((event->button == 1) && - (event->type == GDK_BUTTON_PRESS) && - (tab_clicked >= 0)) - { - notebook->priv->x_start = event->x_root; - notebook->priv->y_start = event->y_root; - - notebook->priv->motion_notify_handler_id = - g_signal_connect (G_OBJECT (notebook), - "motion-notify-event", - G_CALLBACK (motion_notify_cb), - NULL); - } - else if ((event->type == GDK_BUTTON_PRESS) && - (event->button == 3 || event->button == 2)) - { - if (tab_clicked == -1) - { - // CHECK: do we really need it? - - /* consume event, so that we don't pop up the context menu when - * the mouse if not over a tab label - */ - return TRUE; - } - else - { - /* Switch to the page the mouse is over, but don't consume the event */ - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), - tab_clicked); - } - } + tab_clicked = find_tab_num_at_pos (notebook, event->x_root, event->y_root); - return FALSE; + if ((event->button == 1) && (event->type == GDK_BUTTON_PRESS) && (tab_clicked >= 0)) + { + notebook->priv->x_start = event->x_root; + notebook->priv->y_start = event->y_root; + + notebook->priv->motion_notify_handler_id = g_signal_connect (G_OBJECT (notebook), "motion-notify-event", + G_CALLBACK (motion_notify_cb), NULL); + } + else if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3 || event->button == 2)) + { + if (tab_clicked == -1) + { + // CHECK: do we really need it? + + /* consume event, so that we don't pop up the context menu when + * the mouse if not over a tab label + */ + return TRUE; + } + else + { + /* Switch to the page the mouse is over, but don't consume the event */ + gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), tab_clicked); + } + } + + return FALSE; +} + +static gboolean +notebook_scroll_event_cb (XedNotebook *notebook, + GdkEventScroll *event, + gpointer data) +{ + GtkWidget *event_widget; + + if (!notebook->priv->tab_scrolling_enabled) + { + return TRUE; + } + + event_widget = gtk_get_event_widget ((GdkEvent *) event); + + if (event_widget == NULL) + { + return FALSE; + } + + switch (event->direction) + { + case GDK_SCROLL_DOWN: + case GDK_SCROLL_RIGHT: + gtk_notebook_next_page (GTK_NOTEBOOK (notebook)); + break; + case GDK_SCROLL_UP: + case GDK_SCROLL_LEFT: + gtk_notebook_prev_page (GTK_NOTEBOOK (notebook)); + break; + default: + break; + } + + return TRUE; } /** @@ -653,96 +662,83 @@ button_press_cb (XedNotebook *notebook, GtkWidget * xed_notebook_new (void) { - return GTK_WIDGET (g_object_new (XED_TYPE_NOTEBOOK, NULL)); + return GTK_WIDGET (g_object_new (XED_TYPE_NOTEBOOK, NULL)); } static void -xed_notebook_switch_page_cb (GtkNotebook *notebook, - GtkWidget *page, - guint page_num, - gpointer data) +xed_notebook_switch_page_cb (GtkNotebook *notebook, + GtkWidget *page, + guint page_num, + gpointer data) { - XedNotebook *nb = XED_NOTEBOOK (notebook); - GtkWidget *child; - XedView *view; + XedNotebook *nb = XED_NOTEBOOK (notebook); + GtkWidget *child; + XedView *view; - child = gtk_notebook_get_nth_page (notebook, page_num); + child = gtk_notebook_get_nth_page (notebook, page_num); - /* Remove the old page, we dont want to grow unnecessarily - * the list */ - if (nb->priv->focused_pages) - { - nb->priv->focused_pages = - g_list_remove (nb->priv->focused_pages, child); - } + /* Remove the old page, we dont want to grow unnecessarily + * the list */ + if (nb->priv->focused_pages) + { + nb->priv->focused_pages = g_list_remove (nb->priv->focused_pages, child); + } - nb->priv->focused_pages = g_list_append (nb->priv->focused_pages, - child); + nb->priv->focused_pages = g_list_append (nb->priv->focused_pages, child); - /* give focus to the view */ - view = xed_tab_get_view (XED_TAB (child)); - gtk_widget_grab_focus (GTK_WIDGET (view)); + /* give focus to the view */ + view = xed_tab_get_view (XED_TAB (child)); + gtk_widget_grab_focus (GTK_WIDGET (view)); } /* * update_tabs_visibility: Hide tabs if there is only one tab - * and the pref is not set. */ static void -update_tabs_visibility (XedNotebook *nb, - gboolean before_inserting) +update_tabs_visibility (XedNotebook *notebook) { - gboolean show_tabs; - guint num; + gboolean show_tabs; - num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)); - - if (before_inserting) num++; - - show_tabs = (nb->priv->always_show_tabs || num > 1); - - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nb), show_tabs); + show_tabs = (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) > 1); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), show_tabs); } static void xed_notebook_init (XedNotebook *notebook) { - notebook->priv = XED_NOTEBOOK_GET_PRIVATE (notebook); + notebook->priv = XED_NOTEBOOK_GET_PRIVATE (notebook); - notebook->priv->close_buttons_sensitive = TRUE; - notebook->priv->tab_drag_and_drop_enabled = TRUE; - - gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE); + notebook->priv->close_buttons_sensitive = TRUE; + notebook->priv->tab_drag_and_drop_enabled = TRUE; + notebook->priv->ui_settings = g_settings_new ("org.x.editor.preferences.ui"); + notebook->priv->tab_scrolling_enabled = g_settings_get_boolean (notebook->priv->ui_settings, "enable-tab-scrolling"); - notebook->priv->always_show_tabs = TRUE; + gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE); + // gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE); - g_signal_connect (notebook, - "button-press-event", - (GCallback)button_press_cb, - NULL); - g_signal_connect (notebook, - "button-release-event", - (GCallback)button_release_cb, - NULL); - gtk_widget_add_events (GTK_WIDGET (notebook), - GDK_BUTTON1_MOTION_MASK); + g_signal_connect (notebook, "button-press-event", + (GCallback)button_press_cb, NULL); + g_signal_connect (notebook, "button-release-event", + (GCallback)button_release_cb, NULL); + gtk_widget_add_events (GTK_WIDGET (notebook), GDK_BUTTON1_MOTION_MASK); - g_signal_connect_after (G_OBJECT (notebook), - "switch_page", - G_CALLBACK (xed_notebook_switch_page_cb), - NULL); + g_signal_connect_after (G_OBJECT (notebook), "switch_page", + G_CALLBACK (xed_notebook_switch_page_cb), NULL); + + gtk_widget_add_events (GTK_WIDGET (notebook), GDK_SCROLL_MASK); + g_signal_connect (notebook, "scroll-event", + G_CALLBACK (notebook_scroll_event_cb), NULL); } static void xed_notebook_finalize (GObject *object) { - XedNotebook *notebook = XED_NOTEBOOK (object); + XedNotebook *notebook = XED_NOTEBOOK (object); - g_list_free (notebook->priv->focused_pages); + g_list_free (notebook->priv->focused_pages); - G_OBJECT_CLASS (xed_notebook_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_notebook_parent_class)->finalize (object); } /* @@ -751,112 +747,90 @@ xed_notebook_finalize (GObject *object) */ static gboolean xed_notebook_change_current_page (GtkNotebook *notebook, - gint offset) + gint offset) { - gboolean wrap_around; - gint current; - - current = gtk_notebook_get_current_page (notebook); + gboolean wrap_around; + gint current; - if (current != -1) - { - current = current + offset; - - g_object_get (gtk_widget_get_settings (GTK_WIDGET (notebook)), - "gtk-keynav-wrap-around", &wrap_around, - NULL); - - if (wrap_around) - { - if (current < 0) - { - current = gtk_notebook_get_n_pages (notebook) - 1; - } - else if (current >= gtk_notebook_get_n_pages (notebook)) - { - current = 0; - } - } - - gtk_notebook_set_current_page (notebook, current); - } - else - { - gtk_widget_error_bell (GTK_WIDGET (notebook)); - } + current = gtk_notebook_get_current_page (notebook); - return TRUE; + if (current != -1) + { + current = current + offset; + + g_object_get (gtk_widget_get_settings (GTK_WIDGET (notebook)), + "gtk-keynav-wrap-around", &wrap_around, NULL); + + if (wrap_around) + { + if (current < 0) + { + current = gtk_notebook_get_n_pages (notebook) - 1; + } + else if (current >= gtk_notebook_get_n_pages (notebook)) + { + current = 0; + } + } + + gtk_notebook_set_current_page (notebook, current); + } + else + { + gtk_widget_error_bell (GTK_WIDGET (notebook)); + } + + return TRUE; } static void -close_button_clicked_cb (XedTabLabel *tab_label, XedNotebook *notebook) +close_button_clicked_cb (XedTabLabel *tab_label, + XedNotebook *notebook) { - XedTab *tab; + XedTab *tab; - tab = xed_tab_label_get_tab (tab_label); - g_signal_emit (notebook, signals[TAB_CLOSE_REQUEST], 0, tab); + tab = xed_tab_label_get_tab (tab_label); + g_signal_emit (notebook, signals[TAB_CLOSE_REQUEST], 0, tab); } static GtkWidget * create_tab_label (XedNotebook *nb, - XedTab *tab) + XedTab *tab) { - GtkWidget *tab_label; + GtkWidget *tab_label; - tab_label = xed_tab_label_new (tab); + tab_label = xed_tab_label_new (tab); - g_signal_connect (tab_label, - "close-clicked", - G_CALLBACK (close_button_clicked_cb), - nb); + g_signal_connect (tab_label, "close-clicked", + G_CALLBACK (close_button_clicked_cb), nb); - g_object_set_data (G_OBJECT (tab), "tab-label", tab_label); + g_object_set_data (G_OBJECT (tab), "tab-label", tab_label); - return tab_label; + return tab_label; } static GtkWidget * get_tab_label (XedTab *tab) { - GtkWidget *tab_label; + GtkWidget *tab_label; - tab_label = GTK_WIDGET (g_object_get_data (G_OBJECT (tab), "tab-label")); - g_return_val_if_fail (tab_label != NULL, NULL); + tab_label = GTK_WIDGET (g_object_get_data (G_OBJECT (tab), "tab-label")); + g_return_val_if_fail (tab_label != NULL, NULL); - return tab_label; + return tab_label; } static void remove_tab_label (XedNotebook *nb, - XedTab *tab) + XedTab *tab) { - GtkWidget *tab_label; + GtkWidget *tab_label; - tab_label = get_tab_label (tab); + tab_label = get_tab_label (tab); - g_signal_handlers_disconnect_by_func (tab_label, - G_CALLBACK (close_button_clicked_cb), - nb); + g_signal_handlers_disconnect_by_func (tab_label, G_CALLBACK (close_button_clicked_cb), nb); - g_object_set_data (G_OBJECT (tab), "tab-label", NULL); -} - -/** - * xed_notebook_set_always_show_tabs: - * @nb: a #XedNotebook - * @show_tabs: %TRUE to always show the tabs - * - * Sets the visibility of the tabs in the @nb. - */ -void -xed_notebook_set_always_show_tabs (XedNotebook *nb, - gboolean show_tabs) -{ - g_return_if_fail (XED_IS_NOTEBOOK (nb)); - - nb->priv->always_show_tabs = (show_tabs != FALSE); - - update_tabs_visibility (nb, FALSE); + g_object_set_data (G_OBJECT (tab), "tab-label", NULL); } /** @@ -870,91 +844,82 @@ xed_notebook_set_always_show_tabs (XedNotebook *nb, */ void xed_notebook_add_tab (XedNotebook *nb, - XedTab *tab, - gint position, - gboolean jump_to) + XedTab *tab, + gint position, + gboolean jump_to) { - GtkWidget *tab_label; + GtkWidget *tab_label; - g_return_if_fail (XED_IS_NOTEBOOK (nb)); - g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (XED_IS_NOTEBOOK (nb)); + g_return_if_fail (XED_IS_TAB (tab)); - tab_label = create_tab_label (nb, tab); - gtk_notebook_insert_page (GTK_NOTEBOOK (nb), - GTK_WIDGET (tab), - tab_label, - position); - update_tabs_visibility (nb, TRUE); + tab_label = create_tab_label (nb, tab); + gtk_notebook_insert_page (GTK_NOTEBOOK (nb), GTK_WIDGET (tab), tab_label, position); + update_tabs_visibility (nb); - g_signal_emit (G_OBJECT (nb), signals[TAB_ADDED], 0, tab); + g_signal_emit (G_OBJECT (nb), signals[TAB_ADDED], 0, tab); - /* The signal handler may have reordered the tabs */ - position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), - GTK_WIDGET (tab)); + /* The signal handler may have reordered the tabs */ + position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab)); - if (jump_to) - { - XedView *view; - - gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), position); - g_object_set_data (G_OBJECT (tab), - "jump_to", - GINT_TO_POINTER (jump_to)); - view = xed_tab_get_view (tab); - - gtk_widget_grab_focus (GTK_WIDGET (view)); - } + if (jump_to) + { + XedView *view; + + gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), position); + g_object_set_data (G_OBJECT (tab), "jump_to", GINT_TO_POINTER (jump_to)); + view = xed_tab_get_view (tab); + + gtk_widget_grab_focus (GTK_WIDGET (view)); + } } static void smart_tab_switching_on_closure (XedNotebook *nb, - XedTab *tab) + XedTab *tab) { - gboolean jump_to; + gboolean jump_to; - jump_to = GPOINTER_TO_INT (g_object_get_data - (G_OBJECT (tab), "jump_to")); + jump_to = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tab), "jump_to")); - if (!jump_to || !nb->priv->focused_pages) - { - gtk_notebook_next_page (GTK_NOTEBOOK (nb)); - } - else - { - GList *l; - GtkWidget *child; - int page_num; + if (!jump_to || !nb->priv->focused_pages) + { + gtk_notebook_next_page (GTK_NOTEBOOK (nb)); + } + else + { + GList *l; + GtkWidget *child; + int page_num; - /* activate the last focused tab */ - l = g_list_last (nb->priv->focused_pages); - child = GTK_WIDGET (l->data); - page_num = gtk_notebook_page_num (GTK_NOTEBOOK (nb), - child); - gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), - page_num); - } + /* activate the last focused tab */ + l = g_list_last (nb->priv->focused_pages); + child = GTK_WIDGET (l->data); + page_num = gtk_notebook_page_num (GTK_NOTEBOOK (nb), child); + gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), page_num); + } } static void remove_tab (XedTab *tab, - XedNotebook *nb) + XedNotebook *nb) { - gint position; + gint position; - position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab)); + position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab)); - /* we ref the tab so that it's still alive while the tabs_removed - * signal is processed. - */ - g_object_ref (tab); + /* we ref the tab so that it's still alive while the tabs_removed + * signal is processed. + */ + g_object_ref (tab); - remove_tab_label (nb, tab); - gtk_notebook_remove_page (GTK_NOTEBOOK (nb), position); - update_tabs_visibility (nb, FALSE); + remove_tab_label (nb, tab); + gtk_notebook_remove_page (GTK_NOTEBOOK (nb), position); + update_tabs_visibility (nb); - g_signal_emit (G_OBJECT (nb), signals[TAB_REMOVED], 0, tab); + g_signal_emit (G_OBJECT (nb), signals[TAB_REMOVED], 0, tab); - g_object_unref (tab); + g_object_unref (tab); } /** @@ -966,26 +931,25 @@ remove_tab (XedTab *tab, */ void xed_notebook_remove_tab (XedNotebook *nb, - XedTab *tab) + XedTab *tab) { - gint position, curr; + gint position, curr; - g_return_if_fail (XED_IS_NOTEBOOK (nb)); - g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (XED_IS_NOTEBOOK (nb)); + g_return_if_fail (XED_IS_TAB (tab)); - /* Remove the page from the focused pages list */ - nb->priv->focused_pages = g_list_remove (nb->priv->focused_pages, - tab); + /* Remove the page from the focused pages list */ + nb->priv->focused_pages = g_list_remove (nb->priv->focused_pages, tab); - position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab)); - curr = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)); + position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab)); + curr = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)); - if (position == curr) - { - smart_tab_switching_on_closure (nb, tab); - } + if (position == curr) + { + smart_tab_switching_on_closure (nb, tab); + } - remove_tab (tab, nb); + remove_tab (tab, nb); } /** @@ -996,27 +960,24 @@ xed_notebook_remove_tab (XedNotebook *nb, */ void xed_notebook_remove_all_tabs (XedNotebook *nb) -{ - g_return_if_fail (XED_IS_NOTEBOOK (nb)); - - g_list_free (nb->priv->focused_pages); - nb->priv->focused_pages = NULL; +{ + g_return_if_fail (XED_IS_NOTEBOOK (nb)); - gtk_container_foreach (GTK_CONTAINER (nb), - (GtkCallback)remove_tab, - nb); + g_list_free (nb->priv->focused_pages); + nb->priv->focused_pages = NULL; + + gtk_container_foreach (GTK_CONTAINER (nb), (GtkCallback)remove_tab, nb); } static void set_close_buttons_sensitivity (XedTab *tab, XedNotebook *nb) { - GtkWidget *tab_label; + GtkWidget *tab_label; - tab_label = get_tab_label (tab); + tab_label = get_tab_label (tab); - xed_tab_label_set_close_button_sensitive (XED_TAB_LABEL (tab_label), - nb->priv->close_buttons_sensitive); + xed_tab_label_set_close_button_sensitive (XED_TAB_LABEL (tab_label), nb->priv->close_buttons_sensitive); } /** @@ -1028,20 +989,20 @@ set_close_buttons_sensitivity (XedTab *tab, */ void xed_notebook_set_close_buttons_sensitive (XedNotebook *nb, - gboolean sensitive) + gboolean sensitive) { - g_return_if_fail (XED_IS_NOTEBOOK (nb)); + g_return_if_fail (XED_IS_NOTEBOOK (nb)); - sensitive = (sensitive != FALSE); + sensitive = (sensitive != FALSE); - if (sensitive == nb->priv->close_buttons_sensitive) - return; + if (sensitive == nb->priv->close_buttons_sensitive) + { + return; + } - nb->priv->close_buttons_sensitive = sensitive; + nb->priv->close_buttons_sensitive = sensitive; - gtk_container_foreach (GTK_CONTAINER (nb), - (GtkCallback)set_close_buttons_sensitivity, - nb); + gtk_container_foreach (GTK_CONTAINER (nb), (GtkCallback)set_close_buttons_sensitivity, nb); } /** @@ -1055,9 +1016,9 @@ xed_notebook_set_close_buttons_sensitive (XedNotebook *nb, gboolean xed_notebook_get_close_buttons_sensitive (XedNotebook *nb) { - g_return_val_if_fail (XED_IS_NOTEBOOK (nb), TRUE); + g_return_val_if_fail (XED_IS_NOTEBOOK (nb), TRUE); - return nb->priv->close_buttons_sensitive; + return nb->priv->close_buttons_sensitive; } /** @@ -1069,16 +1030,18 @@ xed_notebook_get_close_buttons_sensitive (XedNotebook *nb) */ void xed_notebook_set_tab_drag_and_drop_enabled (XedNotebook *nb, - gboolean enable) + gboolean enable) { - g_return_if_fail (XED_IS_NOTEBOOK (nb)); - - enable = (enable != FALSE); - - if (enable == nb->priv->tab_drag_and_drop_enabled) - return; - - nb->priv->tab_drag_and_drop_enabled = enable; + g_return_if_fail (XED_IS_NOTEBOOK (nb)); + + enable = (enable != FALSE); + + if (enable == nb->priv->tab_drag_and_drop_enabled) + { + return; + } + + nb->priv->tab_drag_and_drop_enabled = enable; } /** @@ -1089,11 +1052,49 @@ xed_notebook_set_tab_drag_and_drop_enabled (XedNotebook *nb, * * Returns: %TRUE if the drag and drop is enabled. */ -gboolean +gboolean xed_notebook_get_tab_drag_and_drop_enabled (XedNotebook *nb) { - g_return_val_if_fail (XED_IS_NOTEBOOK (nb), TRUE); - - return nb->priv->tab_drag_and_drop_enabled; + g_return_val_if_fail (XED_IS_NOTEBOOK (nb), TRUE); + + return nb->priv->tab_drag_and_drop_enabled; } +/** + * xed_notebook_set_tab_scrolling_enabled: + * @nb: a #XedNotebook + * @enable: %TRUE to enable tab scrolling + * + * Sets whether tab scrolling in the @nb is enabled. + */ +void +xed_notebook_set_tab_scrolling_enabled (XedNotebook *nb, + gboolean enable) +{ + g_return_if_fail (XED_IS_NOTEBOOK (nb)); + + enable = (enable != FALSE); + + if (enable == nb->priv->tab_scrolling_enabled) + { + return; + } + + nb->priv->tab_scrolling_enabled = enable; +} + +/** + * xed_notebook_get_tab_scrolling_enabled: + * @nb: a #XedNotebook + * + * Whether notebook tab scrolling is enabled + * + * Returns: %TRUE if tab scrolling is enabled + */ +gboolean +xed_notebook_get_tab_scrolling_enabled (XedNotebook *nb) +{ + g_return_val_if_fail (XED_IS_NOTEBOOK (nb), TRUE); + + return nb->priv->tab_scrolling_enabled; +} diff --git a/xed/xed-notebook.h b/xed/xed-notebook.h index f75fb2e..8a8c059 100644 --- a/xed/xed-notebook.h +++ b/xed/xed-notebook.h @@ -2,7 +2,7 @@ * xed-notebook.h * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ /* This file is a modified version of the epiphany file ephy-notebook.h @@ -34,7 +34,7 @@ * Copyright (C) 2003, 2004 Christian Persch * */ - + #ifndef XED_NOTEBOOK_H #define XED_NOTEBOOK_H @@ -62,7 +62,7 @@ typedef struct _XedNotebookPrivate XedNotebookPrivate; * Main object structure */ typedef struct _XedNotebook XedNotebook; - + struct _XedNotebook { GtkNotebook notebook; @@ -113,17 +113,12 @@ void xed_notebook_remove_all_tabs (XedNotebook *nb); void xed_notebook_reorder_tab (XedNotebook *src, XedTab *tab, gint dest_position); - + void xed_notebook_move_tab (XedNotebook *src, XedNotebook *dest, XedTab *tab, gint dest_position); -/* FIXME: do we really need this function ? */ -void xed_notebook_set_always_show_tabs - (XedNotebook *nb, - gboolean show_tabs); - void xed_notebook_set_close_buttons_sensitive (XedNotebook *nb, gboolean sensitive); @@ -138,6 +133,10 @@ void xed_notebook_set_tab_drag_and_drop_enabled gboolean xed_notebook_get_tab_drag_and_drop_enabled (XedNotebook *nb); +void xed_notebook_set_tab_scrolling_enabled (XedNotebook *nb, + gboolean enable); +gboolean xed_notebook_get_tab_scrolling_enabled (XedNotebook *nb); + G_END_DECLS #endif /* XED_NOTEBOOK_H */ diff --git a/xed/xed-object-module.c b/xed/xed-object-module.c deleted file mode 100644 index 236c320..0000000 --- a/xed/xed-object-module.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * xed-object-module.c - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* This is a modified version of ephy-module.c from Epiphany source code. - * Here the original copyright assignment: - * - * Copyright (C) 2003 Marco Pesenti Gritti - * Copyright (C) 2003, 2004 Christian Persch - * - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id: xed-module.c 6314 2008-06-05 12:57:53Z pborelli $ - */ - -#include "config.h" - -#include "xed-object-module.h" -#include "xed-debug.h" - -typedef GType (*XedObjectModuleRegisterFunc) (GTypeModule *); - -enum { - PROP_0, - PROP_MODULE_NAME, - PROP_PATH, - PROP_TYPE_REGISTRATION, - PROP_RESIDENT -}; - -struct _XedObjectModulePrivate -{ - GModule *library; - - GType type; - gchar *path; - gchar *module_name; - gchar *type_registration; - - gboolean resident; -}; - -G_DEFINE_TYPE (XedObjectModule, xed_object_module, G_TYPE_TYPE_MODULE); - -static gboolean -xed_object_module_load (GTypeModule *gmodule) -{ - XedObjectModule *module = XED_OBJECT_MODULE (gmodule); - XedObjectModuleRegisterFunc register_func; - gchar *path; - - xed_debug_message (DEBUG_PLUGINS, "Loading %s module from %s", - module->priv->module_name, module->priv->path); - - path = g_module_build_path (module->priv->path, module->priv->module_name); - g_return_val_if_fail (path != NULL, FALSE); - xed_debug_message (DEBUG_PLUGINS, "Module filename: %s", path); - - module->priv->library = g_module_open (path, - G_MODULE_BIND_LAZY); - g_free (path); - - if (module->priv->library == NULL) - { - g_warning ("%s: %s", module->priv->module_name, g_module_error()); - - return FALSE; - } - - /* extract symbols from the lib */ - if (!g_module_symbol (module->priv->library, module->priv->type_registration, - (void *) ®ister_func)) - { - g_warning ("%s: %s", module->priv->module_name, g_module_error()); - g_module_close (module->priv->library); - - return FALSE; - } - - /* symbol can still be NULL even though g_module_symbol - * returned TRUE */ - if (register_func == NULL) - { - g_warning ("Symbol '%s' should not be NULL", module->priv->type_registration); - g_module_close (module->priv->library); - - return FALSE; - } - - module->priv->type = register_func (gmodule); - - if (module->priv->type == 0) - { - g_warning ("Invalid object contained by module %s", module->priv->module_name); - return FALSE; - } - - if (module->priv->resident) - { - g_module_make_resident (module->priv->library); - } - - return TRUE; -} - -static void -xed_object_module_unload (GTypeModule *gmodule) -{ - XedObjectModule *module = XED_OBJECT_MODULE (gmodule); - - xed_debug_message (DEBUG_PLUGINS, "Unloading %s", module->priv->path); - - g_module_close (module->priv->library); - - module->priv->library = NULL; - module->priv->type = 0; -} - -static void -xed_object_module_init (XedObjectModule *module) -{ - xed_debug_message (DEBUG_PLUGINS, "XedObjectModule %p initialising", module); - - module->priv = G_TYPE_INSTANCE_GET_PRIVATE (module, - XED_TYPE_OBJECT_MODULE, - XedObjectModulePrivate); -} - -static void -xed_object_module_finalize (GObject *object) -{ - XedObjectModule *module = XED_OBJECT_MODULE (object); - - xed_debug_message (DEBUG_PLUGINS, "XedObjectModule %p finalising", module); - - g_free (module->priv->path); - g_free (module->priv->module_name); - g_free (module->priv->type_registration); - - G_OBJECT_CLASS (xed_object_module_parent_class)->finalize (object); -} - -static void -xed_object_module_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - XedObjectModule *module = XED_OBJECT_MODULE (object); - - switch (prop_id) - { - case PROP_MODULE_NAME: - g_value_set_string (value, module->priv->module_name); - break; - case PROP_PATH: - g_value_set_string (value, module->priv->path); - break; - case PROP_TYPE_REGISTRATION: - g_value_set_string (value, module->priv->type_registration); - break; - case PROP_RESIDENT: - g_value_set_boolean (value, module->priv->resident); - break; - default: - g_return_if_reached (); - } -} - -static void -xed_object_module_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedObjectModule *module = XED_OBJECT_MODULE (object); - - switch (prop_id) - { - case PROP_MODULE_NAME: - module->priv->module_name = g_value_dup_string (value); - g_type_module_set_name (G_TYPE_MODULE (object), - module->priv->module_name); - break; - case PROP_PATH: - module->priv->path = g_value_dup_string (value); - break; - case PROP_TYPE_REGISTRATION: - module->priv->type_registration = g_value_dup_string (value); - break; - case PROP_RESIDENT: - module->priv->resident = g_value_get_boolean (value); - break; - default: - g_return_if_reached (); - } -} - -static void -xed_object_module_class_init (XedObjectModuleClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass); - - object_class->set_property = xed_object_module_set_property; - object_class->get_property = xed_object_module_get_property; - object_class->finalize = xed_object_module_finalize; - - module_class->load = xed_object_module_load; - module_class->unload = xed_object_module_unload; - - g_object_class_install_property (object_class, - PROP_MODULE_NAME, - g_param_spec_string ("module-name", - "Module Name", - "The module to load for this object", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_PATH, - g_param_spec_string ("path", - "Path", - "The path to use when loading this module", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_TYPE_REGISTRATION, - g_param_spec_string ("type-registration", - "Type Registration", - "The name of the type registration function", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_RESIDENT, - g_param_spec_boolean ("resident", - "Resident", - "Whether the module is resident", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (klass, sizeof (XedObjectModulePrivate)); -} - -XedObjectModule * -xed_object_module_new (const gchar *module_name, - const gchar *path, - const gchar *type_registration, - gboolean resident) -{ - return (XedObjectModule *)g_object_new (XED_TYPE_OBJECT_MODULE, - "module-name", - module_name, - "path", - path, - "type-registration", - type_registration, - "resident", - resident, - NULL); -} - -GObject * -xed_object_module_new_object (XedObjectModule *module, - const gchar *first_property_name, - ...) -{ - va_list var_args; - GObject *result; - - g_return_val_if_fail (module->priv->type != 0, NULL); - - xed_debug_message (DEBUG_PLUGINS, "Creating object of type %s", - g_type_name (module->priv->type)); - - va_start (var_args, first_property_name); - result = g_object_new_valist (module->priv->type, first_property_name, var_args); - va_end (var_args); - - return result; -} - -const gchar * -xed_object_module_get_path (XedObjectModule *module) -{ - g_return_val_if_fail (XED_IS_OBJECT_MODULE (module), NULL); - - return module->priv->path; -} - -const gchar * -xed_object_module_get_module_name (XedObjectModule *module) -{ - g_return_val_if_fail (XED_IS_OBJECT_MODULE (module), NULL); - - return module->priv->module_name; -} - -const gchar * -xed_object_module_get_type_registration (XedObjectModule *module) -{ - g_return_val_if_fail (XED_IS_OBJECT_MODULE (module), NULL); - - return module->priv->type_registration; -} - -GType -xed_object_module_get_object_type (XedObjectModule *module) -{ - g_return_val_if_fail (XED_IS_OBJECT_MODULE (module), 0); - - return module->priv->type; -} diff --git a/xed/xed-object-module.h b/xed/xed-object-module.h deleted file mode 100644 index 1258deb..0000000 --- a/xed/xed-object-module.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * xed-object-module.h - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* This is a modified version of xed-module.h from Epiphany source code. - * Here the original copyright assignment: - * - * Copyright (C) 2003 Marco Pesenti Gritti - * Copyright (C) 2003, 2004 Christian Persch - * - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id: xed-module.h 6263 2008-05-05 10:52:10Z sfre $ - */ - -#ifndef __XED_OBJECT_MODULE_H__ -#define __XED_OBJECT_MODULE_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define XED_TYPE_OBJECT_MODULE (xed_object_module_get_type ()) -#define XED_OBJECT_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_OBJECT_MODULE, XedObjectModule)) -#define XED_OBJECT_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_OBJECT_MODULE, XedObjectModuleClass)) -#define XED_IS_OBJECT_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_OBJECT_MODULE)) -#define XED_IS_OBJECT_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_OBJECT_MODULE)) -#define XED_OBJECT_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_OBJECT_MODULE, XedObjectModuleClass)) - -typedef struct _XedObjectModule XedObjectModule; -typedef struct _XedObjectModulePrivate XedObjectModulePrivate; - -struct _XedObjectModule -{ - GTypeModule parent; - - XedObjectModulePrivate *priv; -}; - -typedef struct _XedObjectModuleClass XedObjectModuleClass; - -struct _XedObjectModuleClass -{ - GTypeModuleClass parent_class; - - /* Virtual class methods */ - void (* garbage_collect) (); -}; - -GType xed_object_module_get_type (void) G_GNUC_CONST; - -XedObjectModule *xed_object_module_new (const gchar *module_name, - const gchar *path, - const gchar *type_registration, - gboolean resident); - -GObject *xed_object_module_new_object (XedObjectModule *module, - const gchar *first_property_name, - ...); - -GType xed_object_module_get_object_type (XedObjectModule *module); -const gchar *xed_object_module_get_path (XedObjectModule *module); -const gchar *xed_object_module_get_module_name (XedObjectModule *module); -const gchar *xed_object_module_get_type_registration (XedObjectModule *module); - -G_END_DECLS - -#endif diff --git a/xed/xed-panel.c b/xed/xed-panel.c index 7ee88e0..51addb8 100644 --- a/xed/xed-panel.c +++ b/xed/xed-panel.c @@ -2,7 +2,7 @@ * xed-panel.c * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,13 +16,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. * See the ChangeLog files for a list of changes. * * $Id$ @@ -43,530 +43,339 @@ #define XED_PANEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_PANEL, XedPanelPrivate)) -struct _XedPanelPrivate +struct _XedPanelPrivate { - GtkOrientation orientation; - - /* Title bar (vertical panel only) */ - GtkWidget *title_image; - GtkWidget *title_label; + GtkOrientation orientation; - /* Notebook */ - GtkWidget *notebook; + GtkWidget *main_box; + GtkWidget *notebook; }; typedef struct _XedPanelItem XedPanelItem; -struct _XedPanelItem +struct _XedPanelItem { - gchar *name; - GtkWidget *icon; + gchar *name; + GtkWidget *icon; }; /* Properties */ -enum { - PROP_0, - PROP_ORIENTATION +enum +{ + PROP_0, + PROP_ORIENTATION }; /* Signals */ -enum { - ITEM_ADDED, - ITEM_REMOVED, - CLOSE, - FOCUS_DOCUMENT, - LAST_SIGNAL +enum +{ + ITEM_ADDED, + ITEM_REMOVED, + CLOSE, + FOCUS_DOCUMENT, + LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; -static GObject *xed_panel_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties); +static GObject *xed_panel_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties); -G_DEFINE_TYPE(XedPanel, xed_panel, GTK_TYPE_BOX) +G_DEFINE_TYPE (XedPanel, xed_panel, GTK_TYPE_BIN) static void xed_panel_finalize (GObject *obj) { - if (G_OBJECT_CLASS (xed_panel_parent_class)->finalize) - (*G_OBJECT_CLASS (xed_panel_parent_class)->finalize) (obj); + if (G_OBJECT_CLASS (xed_panel_parent_class)->finalize) + { + (*G_OBJECT_CLASS (xed_panel_parent_class)->finalize) (obj); + } } static void xed_panel_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedPanel *panel = XED_PANEL (object); - - switch (prop_id) - { - case PROP_ORIENTATION: - g_value_set_enum(value, panel->priv->orientation); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + XedPanel *panel = XED_PANEL (object); + + switch (prop_id) + { + case PROP_ORIENTATION: + g_value_set_enum(value, panel->priv->orientation); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_panel_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedPanel *panel = XED_PANEL (object); + XedPanel *panel = XED_PANEL (object); - switch (prop_id) - { - case PROP_ORIENTATION: - panel->priv->orientation = g_value_get_enum (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_ORIENTATION: + panel->priv->orientation = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_panel_close (XedPanel *panel) { - gtk_widget_hide (GTK_WIDGET (panel)); + gtk_widget_hide (GTK_WIDGET (panel)); } static void xed_panel_focus_document (XedPanel *panel) { - GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel)); - if (gtk_widget_is_toplevel (toplevel) && XED_IS_WINDOW (toplevel)) - { - XedView *view; + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel)); + if (gtk_widget_is_toplevel (toplevel) && XED_IS_WINDOW (toplevel)) + { + XedView *view; - view = xed_window_get_active_view (XED_WINDOW (toplevel)); - if (view != NULL) - gtk_widget_grab_focus (GTK_WIDGET (view)); - } + view = xed_window_get_active_view (XED_WINDOW (toplevel)); + if (view != NULL) + { + gtk_widget_grab_focus (GTK_WIDGET (view)); + } + } +} + +static void +xed_panel_get_size (GtkWidget *widget, + GtkOrientation orientation, + gint *minimum, + gint *natural) +{ + GtkBin *bin = GTK_BIN (widget); + GtkWidget *child; + + if (minimum) + { + *minimum = 0; + } + + if (natural) + { + *natural = 0; + } + + child = gtk_bin_get_child (bin); + if (child && gtk_widget_get_visible (child)) + { + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + gtk_widget_get_preferred_width (child, minimum, natural); + } + else + { + gtk_widget_get_preferred_height (child, minimum, natural); + } + } +} + +static void +xed_panel_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + xed_panel_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum, natural); +} + +static void +xed_panel_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + xed_panel_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum, natural); +} + +static void +xed_panel_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkBin *bin = GTK_BIN (widget); + GtkWidget *child; + + GTK_WIDGET_CLASS (xed_panel_parent_class)->size_allocate (widget, allocation); + + child = gtk_bin_get_child (bin); + if (child && gtk_widget_get_visible (child)) + { + gtk_widget_size_allocate (child, allocation); + } } static void xed_panel_grab_focus (GtkWidget *w) { - gint n; - GtkWidget *tab; - XedPanel *panel = XED_PANEL (w); + gint n; + GtkWidget *tab; + XedPanel *panel = XED_PANEL (w); - n = gtk_notebook_get_current_page (GTK_NOTEBOOK (panel->priv->notebook)); - if (n == -1) - return; + n = gtk_notebook_get_current_page (GTK_NOTEBOOK (panel->priv->notebook)); + if (n == -1) + { + return; + } - tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->priv->notebook), - n); - g_return_if_fail (tab != NULL); + tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->priv->notebook), n); + g_return_if_fail (tab != NULL); - gtk_widget_grab_focus (tab); + gtk_widget_grab_focus (tab); } static void xed_panel_class_init (XedPanelClass *klass) { - GtkBindingSet *binding_set; - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkBindingSet *binding_set; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - g_type_class_add_private (klass, sizeof (XedPanelPrivate)); + g_type_class_add_private (klass, sizeof (XedPanelPrivate)); - object_class->constructor = xed_panel_constructor; - object_class->finalize = xed_panel_finalize; - object_class->get_property = xed_panel_get_property; - object_class->set_property = xed_panel_set_property; + object_class->constructor = xed_panel_constructor; + object_class->finalize = xed_panel_finalize; + object_class->get_property = xed_panel_get_property; + object_class->set_property = xed_panel_set_property; - g_object_class_install_property (object_class, - PROP_ORIENTATION, - g_param_spec_enum ("panel-orientation", - "Panel Orientation", - "The panel's orientation", - GTK_TYPE_ORIENTATION, - GTK_ORIENTATION_VERTICAL, - G_PARAM_WRITABLE | - G_PARAM_READABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + widget_class->get_preferred_width = xed_panel_get_preferred_width; + widget_class->get_preferred_height = xed_panel_get_preferred_height; + widget_class->size_allocate = xed_panel_size_allocate; + widget_class->grab_focus = xed_panel_grab_focus; - widget_class->grab_focus = xed_panel_grab_focus; + klass->close = xed_panel_close; + klass->focus_document = xed_panel_focus_document; - klass->close = xed_panel_close; - klass->focus_document = xed_panel_focus_document; + g_object_class_install_property (object_class, + PROP_ORIENTATION, + g_param_spec_enum ("orientation", + "Panel Orientation", + "The panel's orientation", + GTK_TYPE_ORIENTATION, + GTK_ORIENTATION_VERTICAL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); - signals[ITEM_ADDED] = - g_signal_new ("item_added", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (XedPanelClass, item_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - GTK_TYPE_WIDGET); - signals[ITEM_REMOVED] = - g_signal_new ("item_removed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (XedPanelClass, item_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - GTK_TYPE_WIDGET); + signals[ITEM_ADDED] = + g_signal_new ("item_added", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (XedPanelClass, item_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GTK_TYPE_WIDGET); + signals[ITEM_REMOVED] = + g_signal_new ("item_removed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (XedPanelClass, item_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GTK_TYPE_WIDGET); - /* Keybinding signals */ - signals[CLOSE] = - g_signal_new ("close", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (XedPanelClass, close), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[FOCUS_DOCUMENT] = - g_signal_new ("focus_document", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (XedPanelClass, focus_document), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - binding_set = gtk_binding_set_by_class (klass); + /* Keybinding signals */ + signals[CLOSE] = + g_signal_new ("close", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (XedPanelClass, close), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals[FOCUS_DOCUMENT] = + g_signal_new ("focus_document", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (XedPanelClass, focus_document), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Escape, - 0, - "close", - 0); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Return, - GDK_CONTROL_MASK, - "focus_document", - 0); -} - -/* This is ugly, since it supports only known - * storage types of GtkImage, otherwise fall back - * to the empty icon. - * See http://bugzilla.gnome.org/show_bug.cgi?id=317520. - */ -static void -set_gtk_image_from_gtk_image (GtkImage *image, - GtkImage *source) -{ - switch (gtk_image_get_storage_type (source)) - { - case GTK_IMAGE_EMPTY: - gtk_image_clear (image); - break; - case GTK_IMAGE_PIXBUF: - { - GdkPixbuf *pb; - - pb = gtk_image_get_pixbuf (source); - gtk_image_set_from_pixbuf (image, pb); - } - break; - case GTK_IMAGE_STOCK: - { - gchar *s_id; - GtkIconSize s; - - gtk_image_get_stock (source, &s_id, &s); - gtk_image_set_from_stock (image, s_id, s); - } - break; - case GTK_IMAGE_ICON_SET: - { - GtkIconSet *is; - GtkIconSize s; - - gtk_image_get_icon_set (source, &is, &s); - gtk_image_set_from_icon_set (image, is, s); - } - break; - case GTK_IMAGE_ANIMATION: - { - GdkPixbufAnimation *a; - - a = gtk_image_get_animation (source); - gtk_image_set_from_animation (image, a); - } - break; - case GTK_IMAGE_ICON_NAME: - { - const gchar *n; - GtkIconSize s; - - gtk_image_get_icon_name (source, &n, &s); - gtk_image_set_from_icon_name (image, n, s); - } - break; - default: - gtk_image_set_from_stock (image, - GTK_STOCK_FILE, - GTK_ICON_SIZE_MENU); - } -} - -static void -sync_title (XedPanel *panel, - XedPanelItem *item) -{ - if (panel->priv->orientation != GTK_ORIENTATION_VERTICAL) - return; - - if (item != NULL) - { - gtk_label_set_text (GTK_LABEL (panel->priv->title_label), - item->name); - - set_gtk_image_from_gtk_image (GTK_IMAGE (panel->priv->title_image), - GTK_IMAGE (item->icon)); - } - else - { - gtk_label_set_text (GTK_LABEL (panel->priv->title_label), - _("Empty")); - - gtk_image_set_from_stock (GTK_IMAGE (panel->priv->title_image), - GTK_STOCK_FILE, - GTK_ICON_SIZE_MENU); - } -} - -static void -notebook_page_changed (GtkNotebook *notebook, - GtkWidget *page, - guint page_num, - XedPanel *panel) -{ - GtkWidget *item; - XedPanelItem *data; - - item = gtk_notebook_get_nth_page (notebook, page_num); - g_return_if_fail (item != NULL); - - data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), - PANEL_ITEM_KEY); - g_return_if_fail (data != NULL); - - sync_title (panel, data); -} - -static void -panel_show (XedPanel *panel, - gpointer user_data) -{ - gint page; - GtkNotebook *nb; - - nb = GTK_NOTEBOOK (panel->priv->notebook); - - page = gtk_notebook_get_current_page (nb); - - if (page != -1) - notebook_page_changed (nb, NULL, page, panel); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_Escape, + 0, + "close", + 0); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_Return, + GDK_CONTROL_MASK, + "focus_document", + 0); } static void xed_panel_init (XedPanel *panel) { - panel->priv = XED_PANEL_GET_PRIVATE (panel); + panel->priv = XED_PANEL_GET_PRIVATE (panel); - gtk_orientable_set_orientation (GTK_ORIENTABLE (panel), - GTK_ORIENTATION_VERTICAL); -} - -static void -close_button_clicked_cb (GtkWidget *widget, - GtkWidget *panel) -{ - gtk_widget_hide (panel); -} - -static GtkWidget * -create_close_button (XedPanel *panel) -{ - GtkWidget *button; - - button = xed_close_button_new (); - - gtk_widget_set_tooltip_text (button, _("Hide panel")); - - g_signal_connect (button, - "clicked", - G_CALLBACK (close_button_clicked_cb), - panel); - - return button; + panel->priv->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_show (panel->priv->main_box); + gtk_container_add (GTK_CONTAINER (panel), panel->priv->main_box); } static void build_notebook_for_panel (XedPanel *panel) { - /* Create the panel notebook */ - panel->priv->notebook = gtk_notebook_new (); + /* Create the panel notebook */ + panel->priv->notebook = gtk_notebook_new (); - gtk_notebook_set_tab_pos (GTK_NOTEBOOK (panel->priv->notebook), - GTK_POS_BOTTOM); - gtk_notebook_set_scrollable (GTK_NOTEBOOK (panel->priv->notebook), - TRUE); - gtk_notebook_popup_enable (GTK_NOTEBOOK (panel->priv->notebook)); + gtk_notebook_set_scrollable (GTK_NOTEBOOK (panel->priv->notebook), TRUE); + gtk_notebook_popup_enable (GTK_NOTEBOOK (panel->priv->notebook)); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (panel->priv->notebook), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (panel->priv->notebook), FALSE); - gtk_widget_show (GTK_WIDGET (panel->priv->notebook)); - - g_signal_connect (panel->priv->notebook, - "switch-page", - G_CALLBACK (notebook_page_changed), - panel); -} - -static void -build_horizontal_panel (XedPanel *panel) -{ - GtkWidget *box; - GtkWidget *sidebar; - GtkWidget *close_button; - - box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - - gtk_box_pack_start (GTK_BOX (box), - panel->priv->notebook, - TRUE, - TRUE, - 0); - - /* Toolbar, close button and first separator */ - sidebar = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_container_set_border_width (GTK_CONTAINER (sidebar), 4); - - gtk_box_pack_start (GTK_BOX (box), - sidebar, - FALSE, - FALSE, - 0); - - close_button = create_close_button (panel); - - gtk_box_pack_start (GTK_BOX (sidebar), - close_button, - FALSE, - FALSE, - 0); - - gtk_widget_show_all (box); - - gtk_box_pack_start (GTK_BOX (panel), - box, - TRUE, - TRUE, - 0); -} - -static void -build_vertical_panel (XedPanel *panel) -{ - GtkWidget *close_button; - GtkWidget *title_hbox; - GtkWidget *icon_name_hbox; - GtkWidget *dummy_label; - - /* Create title hbox */ - title_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_container_set_border_width (GTK_CONTAINER (title_hbox), 5); - - gtk_box_pack_start (GTK_BOX (panel), title_hbox, FALSE, FALSE, 0); - - icon_name_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start (GTK_BOX (title_hbox), - icon_name_hbox, - TRUE, - TRUE, - 0); - - panel->priv->title_image = - gtk_image_new_from_stock (GTK_STOCK_FILE, - GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (icon_name_hbox), - panel->priv->title_image, - FALSE, - TRUE, - 0); - - dummy_label = gtk_label_new (" "); - - gtk_box_pack_start (GTK_BOX (icon_name_hbox), - dummy_label, - FALSE, - FALSE, - 0); - - panel->priv->title_label = gtk_label_new (_("Empty")); - - gtk_misc_set_alignment (GTK_MISC (panel->priv->title_label), 0, 0.5); - gtk_label_set_ellipsize(GTK_LABEL (panel->priv->title_label), PANGO_ELLIPSIZE_END); - - gtk_box_pack_start (GTK_BOX (icon_name_hbox), - panel->priv->title_label, - TRUE, - TRUE, - 0); - - close_button = create_close_button (panel); - - gtk_box_pack_start (GTK_BOX (title_hbox), - close_button, - FALSE, - FALSE, - 0); - - gtk_widget_show_all (title_hbox); - - gtk_box_pack_start (GTK_BOX (panel), - panel->priv->notebook, - TRUE, - TRUE, - 0); + gtk_widget_show (GTK_WIDGET (panel->priv->notebook)); } static GObject * -xed_panel_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) +xed_panel_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) { - - /* Invoke parent constructor. */ - XedPanelClass *klass = XED_PANEL_CLASS (g_type_class_peek (XED_TYPE_PANEL)); - GObjectClass *parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - GObject *obj = parent_class->constructor (type, - n_construct_properties, - construct_properties); - /* Build the panel, now that we know the orientation - (_init has been called previously) */ - XedPanel *panel = XED_PANEL (obj); + /* Invoke parent constructor. */ + XedPanelClass *klass = XED_PANEL_CLASS (g_type_class_peek (XED_TYPE_PANEL)); + GObjectClass *parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); + GObject *obj = parent_class->constructor (type, n_construct_properties, construct_properties); - build_notebook_for_panel (panel); - if (panel->priv->orientation == GTK_ORIENTATION_HORIZONTAL) - build_horizontal_panel (panel); - else - build_vertical_panel (panel); + /* Build the panel, now that we know the orientation (_init has been called previously) */ + XedPanel *panel = XED_PANEL (obj); - g_signal_connect (panel, - "show", - G_CALLBACK (panel_show), - NULL); + build_notebook_for_panel (panel); + gtk_box_pack_start (GTK_BOX (panel->priv->main_box), panel->priv->notebook, TRUE, TRUE, 0); - return obj; + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (panel)), "xed-panel"); + + if (panel->priv->orientation == GTK_ORIENTATION_VERTICAL) + { + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (panel)), "side"); + } + else + { + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (panel)), "bottom"); + } + + return obj; } /** @@ -582,54 +391,67 @@ xed_panel_constructor (GType type, GtkWidget * xed_panel_new (GtkOrientation orientation) { - return GTK_WIDGET (g_object_new (XED_TYPE_PANEL, "orientation", orientation, NULL)); + return GTK_WIDGET (g_object_new (XED_TYPE_PANEL, "orientation", orientation, NULL)); } static GtkWidget * -build_tab_label (XedPanel *panel, - GtkWidget *item, - const gchar *name, - GtkWidget *icon) +build_tab_label (XedPanel *panel, + GtkWidget *item, + const gchar *name, + GtkWidget *icon) { - GtkWidget *hbox, *label_hbox, *label_ebox; - GtkWidget *label; + GtkWidget *hbox; + GtkWidget *label_hbox; + GtkWidget *label_ebox; + GtkWidget *label; - /* set hbox spacing and label padding (see below) so that there's an - * equal amount of space around the label */ - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + /* set hbox spacing and label padding (see below) so that there's an + * equal amount of space around the label */ + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); - label_ebox = gtk_event_box_new (); - gtk_event_box_set_visible_window (GTK_EVENT_BOX (label_ebox), FALSE); - gtk_box_pack_start (GTK_BOX (hbox), label_ebox, TRUE, TRUE, 0); + label_ebox = gtk_event_box_new (); + gtk_event_box_set_visible_window (GTK_EVENT_BOX (label_ebox), FALSE); + gtk_box_pack_start (GTK_BOX (hbox), label_ebox, TRUE, TRUE, 0); - label_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); - gtk_container_add (GTK_CONTAINER (label_ebox), label_hbox); + label_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_container_add (GTK_CONTAINER (label_ebox), label_hbox); - /* setup icon */ - gtk_box_pack_start (GTK_BOX (label_hbox), icon, FALSE, FALSE, 0); + /* setup icon */ + gtk_box_pack_start (GTK_BOX (label_hbox), icon, FALSE, FALSE, 0); - /* setup label */ + /* setup label */ label = gtk_label_new (name); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_set_margin_left (label, 0); - gtk_widget_set_margin_right (label, 0); - gtk_widget_set_margin_top (label, 0); - gtk_widget_set_margin_bottom (label, 0); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_widget_set_margin_start (label, 0); + gtk_widget_set_margin_end (label, 0); + gtk_widget_set_margin_top (label, 0); + gtk_widget_set_margin_bottom (label, 0); - gtk_box_pack_start (GTK_BOX (label_hbox), label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (label_hbox), label, TRUE, TRUE, 0); - gtk_widget_set_tooltip_text (label_ebox, name); + gtk_widget_set_tooltip_text (label_ebox, name); - gtk_widget_show_all (hbox); + gtk_widget_show_all (hbox); - if (panel->priv->orientation == GTK_ORIENTATION_VERTICAL) - gtk_widget_hide(label); + if (panel->priv->orientation == GTK_ORIENTATION_VERTICAL) + { + gtk_widget_hide(label); + } - g_object_set_data (G_OBJECT (item), "label", label); - g_object_set_data (G_OBJECT (item), "hbox", hbox); + g_object_set_data (G_OBJECT (item), "label", label); + g_object_set_data (G_OBJECT (item), "hbox", hbox); - return hbox; + return hbox; +} + +static void +update_tabs_visibility (XedPanel *panel) +{ + gboolean show_tabs; + + show_tabs = (gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook)) > 1); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (panel->priv->notebook), show_tabs); } /** @@ -637,89 +459,54 @@ build_tab_label (XedPanel *panel, * @panel: a #XedPanel * @item: the #GtkWidget to add to the @panel * @name: the name to be shown in the @panel - * @image: the image to be shown in the @panel + * @icon_name: the name of the icon to be shown in the @panel * * Adds a new item to the @panel. */ void -xed_panel_add_item (XedPanel *panel, - GtkWidget *item, - const gchar *name, - GtkWidget *image) +xed_panel_add_item (XedPanel *panel, + GtkWidget *item, + const gchar *name, + const gchar *icon_name) { - XedPanelItem *data; - GtkWidget *tab_label; - GtkWidget *menu_label; - gint w, h; - - g_return_if_fail (XED_IS_PANEL (panel)); - g_return_if_fail (GTK_IS_WIDGET (item)); - g_return_if_fail (name != NULL); - g_return_if_fail (image == NULL || GTK_IS_IMAGE (image)); + XedPanelItem *data; + GtkWidget *tab_label; + GtkWidget *menu_label; - data = g_new (XedPanelItem, 1); + g_return_if_fail (XED_IS_PANEL (panel)); + g_return_if_fail (GTK_IS_WIDGET (item)); + g_return_if_fail (name != NULL); - data->name = g_strdup (name); + data = g_new (XedPanelItem, 1); - if (image == NULL) - { - /* default to empty */ - data->icon = gtk_image_new_from_stock (GTK_STOCK_FILE, - GTK_ICON_SIZE_MENU); - } - else - { - data->icon = image; - } + data->name = g_strdup (name); - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h); - gtk_widget_set_size_request (data->icon, w, h); - - g_object_set_data (G_OBJECT (item), - PANEL_ITEM_KEY, - data); + if (icon_name) + { + data->icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); + } + else + { + data->icon = gtk_image_new_from_icon_name ("text-x-generic", GTK_ICON_SIZE_MENU); + } - tab_label = build_tab_label (panel, item, data->name, data->icon); + g_object_set_data (G_OBJECT (item), PANEL_ITEM_KEY, data); - menu_label = gtk_label_new (name); + tab_label = build_tab_label (panel, item, data->name, data->icon); - gtk_misc_set_alignment (GTK_MISC (menu_label), 0.0, 0.5); + menu_label = gtk_label_new (name); - if (!gtk_widget_get_visible (item)) - gtk_widget_show (item); + gtk_widget_set_halign (menu_label, GTK_ALIGN_START); - gtk_notebook_append_page_menu (GTK_NOTEBOOK (panel->priv->notebook), - item, - tab_label, - menu_label); + if (!gtk_widget_get_visible (item)) + { + gtk_widget_show (item); + } - g_signal_emit (G_OBJECT (panel), signals[ITEM_ADDED], 0, item); -} + gtk_notebook_append_page_menu (GTK_NOTEBOOK (panel->priv->notebook), item, tab_label, menu_label); + update_tabs_visibility (panel); -/** - * xed_panel_add_item_with_stock_icon: - * @panel: a #XedPanel - * @item: the #GtkWidget to add to the @panel - * @name: the name to be shown in the @panel - * @stock_id: a stock id - * - * Same as xed_panel_add_item() but using an image from stock. - */ -void -xed_panel_add_item_with_stock_icon (XedPanel *panel, - GtkWidget *item, - const gchar *name, - const gchar *stock_id) -{ - GtkWidget *icon = NULL; - - if (stock_id != NULL) - { - icon = gtk_image_new_from_stock (stock_id, - GTK_ICON_SIZE_MENU); - } - - xed_panel_add_item (panel, item, name, icon); + g_signal_emit (G_OBJECT (panel), signals[ITEM_ADDED], 0, item); } /** @@ -733,47 +520,41 @@ xed_panel_add_item_with_stock_icon (XedPanel *panel, * Returns: %TRUE if it was well removed. */ gboolean -xed_panel_remove_item (XedPanel *panel, - GtkWidget *item) +xed_panel_remove_item (XedPanel *panel, + GtkWidget *item) { - XedPanelItem *data; - gint page_num; - - g_return_val_if_fail (XED_IS_PANEL (panel), FALSE); - g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE); + XedPanelItem *data; + gint page_num; - page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), - item); - - if (page_num == -1) - return FALSE; - - data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), - PANEL_ITEM_KEY); - g_return_val_if_fail (data != NULL, FALSE); - - g_free (data->name); - g_free (data); + g_return_val_if_fail (XED_IS_PANEL (panel), FALSE); + g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE); - g_object_set_data (G_OBJECT (item), - PANEL_ITEM_KEY, - NULL); + page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), item); - /* ref the item to keep it alive during signal emission */ - g_object_ref (G_OBJECT (item)); + if (page_num == -1) + { + return FALSE; + } - gtk_notebook_remove_page (GTK_NOTEBOOK (panel->priv->notebook), - page_num); + data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), PANEL_ITEM_KEY); + g_return_val_if_fail (data != NULL, FALSE); - /* if we removed all the pages, reset the title */ - if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook)) == 0) - sync_title (panel, NULL); + g_free (data->name); + g_free (data); - g_signal_emit (G_OBJECT (panel), signals[ITEM_REMOVED], 0, item); + g_object_set_data (G_OBJECT (item), PANEL_ITEM_KEY, NULL); - g_object_unref (G_OBJECT (item)); + /* ref the item to keep it alive during signal emission */ + g_object_ref (G_OBJECT (item)); - return TRUE; + gtk_notebook_remove_page (GTK_NOTEBOOK (panel->priv->notebook), page_num); + update_tabs_visibility (panel); + + g_signal_emit (G_OBJECT (panel), signals[ITEM_REMOVED], 0, item); + + g_object_unref (G_OBJECT (item)); + + return TRUE; } /** @@ -786,24 +567,24 @@ xed_panel_remove_item (XedPanel *panel, * Returns: %TRUE if it was activated */ gboolean -xed_panel_activate_item (XedPanel *panel, - GtkWidget *item) +xed_panel_activate_item (XedPanel *panel, + GtkWidget *item) { - gint page_num; + gint page_num; - g_return_val_if_fail (XED_IS_PANEL (panel), FALSE); - g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE); + g_return_val_if_fail (XED_IS_PANEL (panel), FALSE); + g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE); - page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), - item); + page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), item); - if (page_num == -1) - return FALSE; + if (page_num == -1) + { + return FALSE; + } - gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->priv->notebook), - page_num); + gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->priv->notebook), page_num); - return TRUE; + return TRUE; } /** @@ -816,41 +597,41 @@ xed_panel_activate_item (XedPanel *panel, * Returns: %TRUE if @item is the active widget */ gboolean -xed_panel_item_is_active (XedPanel *panel, - GtkWidget *item) +xed_panel_item_is_active (XedPanel *panel, + GtkWidget *item) { - gint cur_page; - gint page_num; + gint cur_page; + gint page_num; - g_return_val_if_fail (XED_IS_PANEL (panel), FALSE); - g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE); + g_return_val_if_fail (XED_IS_PANEL (panel), FALSE); + g_return_val_if_fail (GTK_IS_WIDGET (item), FALSE); - page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), - item); + page_num = gtk_notebook_page_num (GTK_NOTEBOOK (panel->priv->notebook), item); - if (page_num == -1) - return FALSE; + if (page_num == -1) + { + return FALSE; + } - cur_page = gtk_notebook_get_current_page ( - GTK_NOTEBOOK (panel->priv->notebook)); + cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (panel->priv->notebook)); - return (page_num == cur_page); + return (page_num == cur_page); } /** * xed_panel_get_orientation: * @panel: a #XedPanel * - * Gets the orientation of the @panel. + * Gets the orientation of the @panel. * * Returns: the #GtkOrientation of #XedPanel */ GtkOrientation xed_panel_get_orientation (XedPanel *panel) { - g_return_val_if_fail (XED_IS_PANEL (panel), GTK_ORIENTATION_VERTICAL); + g_return_val_if_fail (XED_IS_PANEL (panel), GTK_ORIENTATION_VERTICAL); - return panel->priv->orientation; + return panel->priv->orientation; } /** @@ -858,81 +639,77 @@ xed_panel_get_orientation (XedPanel *panel) * @panel: a #XedPanel * * Gets the number of items in a @panel. - * + * * Returns: the number of items contained in #XedPanel */ gint xed_panel_get_n_items (XedPanel *panel) { - g_return_val_if_fail (XED_IS_PANEL (panel), -1); + g_return_val_if_fail (XED_IS_PANEL (panel), -1); - return gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook)); + return gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook)); } gint _xed_panel_get_active_item_id (XedPanel *panel) { - gint cur_page; - GtkWidget *item; - XedPanelItem *data; + gint cur_page; + GtkWidget *item; + XedPanelItem *data; - g_return_val_if_fail (XED_IS_PANEL (panel), 0); + g_return_val_if_fail (XED_IS_PANEL (panel), 0); - cur_page = gtk_notebook_get_current_page ( - GTK_NOTEBOOK (panel->priv->notebook)); - if (cur_page == -1) - return 0; + cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (panel->priv->notebook)); + if (cur_page == -1) + { + return 0; + } - item = gtk_notebook_get_nth_page ( - GTK_NOTEBOOK (panel->priv->notebook), - cur_page); + item = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->priv->notebook), cur_page); - /* FIXME: for now we use as the hash of the name as id. - * However the name is not guaranteed to be unique and - * it is a translated string, so it's subotimal, but should - * be good enough for now since we don't want to add an - * ad hoc id argument. - */ + /* FIXME: for now we use as the hash of the name as id. + * However the name is not guaranteed to be unique and + * it is a translated string, so it's subotimal, but should + * be good enough for now since we don't want to add an + * ad hoc id argument. + */ - data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), - PANEL_ITEM_KEY); - g_return_val_if_fail (data != NULL, 0); + data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), PANEL_ITEM_KEY); + g_return_val_if_fail (data != NULL, 0); - return g_str_hash (data->name); + return g_str_hash (data->name); } void _xed_panel_set_active_item_by_id (XedPanel *panel, - gint id) + gint id) { - gint n, i; + gint n, i; - g_return_if_fail (XED_IS_PANEL (panel)); + g_return_if_fail (XED_IS_PANEL (panel)); - if (id == 0) - return; + if (id == 0) + { + return; + } - n = gtk_notebook_get_n_pages ( - GTK_NOTEBOOK (panel->priv->notebook)); + n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->priv->notebook)); - for (i = 0; i < n; i++) - { - GtkWidget *item; - XedPanelItem *data; + for (i = 0; i < n; i++) + { + GtkWidget *item; + XedPanelItem *data; - item = gtk_notebook_get_nth_page ( - GTK_NOTEBOOK (panel->priv->notebook), i); + item = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->priv->notebook), i); - data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), - PANEL_ITEM_KEY); - g_return_if_fail (data != NULL); + data = (XedPanelItem *)g_object_get_data (G_OBJECT (item), PANEL_ITEM_KEY); + g_return_if_fail (data != NULL); - if (g_str_hash (data->name) == id) - { - gtk_notebook_set_current_page ( - GTK_NOTEBOOK (panel->priv->notebook), i); + if (g_str_hash (data->name) == id) + { + gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->priv->notebook), i); - return; - } - } + return; + } + } } diff --git a/xed/xed-panel.h b/xed/xed-panel.h index 5cf152f..667b9c4 100644 --- a/xed/xed-panel.h +++ b/xed/xed-panel.h @@ -2,7 +2,7 @@ * xed-panel.h * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -38,12 +38,12 @@ G_BEGIN_DECLS /* * Type checking and casting macros */ -#define XED_TYPE_PANEL (xed_panel_get_type()) -#define XED_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PANEL, XedPanel)) -#define XED_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_PANEL, XedPanelClass)) -#define XED_IS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_PANEL)) -#define XED_IS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PANEL)) -#define XED_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PANEL, XedPanelClass)) +#define XED_TYPE_PANEL (xed_panel_get_type()) +#define XED_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PANEL, XedPanel)) +#define XED_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_PANEL, XedPanelClass)) +#define XED_IS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_PANEL)) +#define XED_IS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PANEL)) +#define XED_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PANEL, XedPanelClass)) /* Private structure type */ typedef struct _XedPanelPrivate XedPanelPrivate; @@ -53,12 +53,12 @@ typedef struct _XedPanelPrivate XedPanelPrivate; */ typedef struct _XedPanel XedPanel; -struct _XedPanel +struct _XedPanel { - GtkBox vbox; + GtkBin parent; - /*< private > */ - XedPanelPrivate *priv; + /*< private > */ + XedPanelPrivate *priv; }; /* @@ -66,64 +66,59 @@ struct _XedPanel */ typedef struct _XedPanelClass XedPanelClass; -struct _XedPanelClass +struct _XedPanelClass { - GtkBoxClass parent_class; + GtkBinClass parent_class; - void (* item_added) (XedPanel *panel, - GtkWidget *item); - void (* item_removed) (XedPanel *panel, - GtkWidget *item); + void (* item_added) (XedPanel *panel, + GtkWidget *item); + void (* item_removed) (XedPanel *panel, + GtkWidget *item); - /* Keybinding signals */ - void (* close) (XedPanel *panel); - void (* focus_document) (XedPanel *panel); + /* Keybinding signals */ + void (* close) (XedPanel *panel); + void (* focus_document) (XedPanel *panel); - /* Padding for future expansion */ - void (*_xed_reserved1) (void); - void (*_xed_reserved2) (void); - void (*_xed_reserved3) (void); - void (*_xed_reserved4) (void); + /* Padding for future expansion */ + void (*_xed_reserved1) (void); + void (*_xed_reserved2) (void); + void (*_xed_reserved3) (void); + void (*_xed_reserved4) (void); }; /* * Public methods */ -GType xed_panel_get_type (void) G_GNUC_CONST; +GType xed_panel_get_type (void) G_GNUC_CONST; -GtkWidget *xed_panel_new (GtkOrientation orientation); +GtkWidget *xed_panel_new (GtkOrientation orientation); -void xed_panel_add_item (XedPanel *panel, - GtkWidget *item, - const gchar *name, - GtkWidget *image); +void xed_panel_add_item (XedPanel *panel, + GtkWidget *item, + const gchar *name, + const gchar *icon_name); -void xed_panel_add_item_with_stock_icon (XedPanel *panel, - GtkWidget *item, - const gchar *name, - const gchar *stock_id); +gboolean xed_panel_remove_item (XedPanel *panel, + GtkWidget *item); -gboolean xed_panel_remove_item (XedPanel *panel, - GtkWidget *item); +gboolean xed_panel_activate_item (XedPanel *panel, + GtkWidget *item); -gboolean xed_panel_activate_item (XedPanel *panel, - GtkWidget *item); +gboolean xed_panel_item_is_active (XedPanel *panel, + GtkWidget *item); -gboolean xed_panel_item_is_active (XedPanel *panel, - GtkWidget *item); +GtkOrientation xed_panel_get_orientation (XedPanel *panel); -GtkOrientation xed_panel_get_orientation (XedPanel *panel); - -gint xed_panel_get_n_items (XedPanel *panel); +gint xed_panel_get_n_items (XedPanel *panel); /* * Non exported functions */ -gint _xed_panel_get_active_item_id (XedPanel *panel); +gint _xed_panel_get_active_item_id (XedPanel *panel); -void _xed_panel_set_active_item_by_id (XedPanel *panel, - gint id); +void _xed_panel_set_active_item_by_id (XedPanel *panel, + gint id); G_END_DECLS diff --git a/xed/xed-plugin-info-priv.h b/xed/xed-plugin-info-priv.h deleted file mode 100644 index 23f799f..0000000 --- a/xed/xed-plugin-info-priv.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * xed-plugin-info-priv.h - * This file is part of xed - * - * Copyright (C) 2002-2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2007. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_PLUGIN_INFO_PRIV_H__ -#define __XED_PLUGIN_INFO_PRIV_H__ - -#include "xed-plugin-info.h" -#include "xed-plugin.h" - -struct _XedPluginInfo -{ - gint refcount; - - XedPlugin *plugin; - gchar *file; - - gchar *module_name; - gchar *loader; - gchar **dependencies; - - gchar *name; - gchar *desc; - gchar *icon_name; - gchar **authors; - gchar *copyright; - gchar *website; - gchar *version; - - /* A plugin is unavailable if it is not possible to activate it - due to an error loading the plugin module (e.g. for Python plugins - when the interpreter has not been correctly initializated) */ - gint available : 1; -}; - -XedPluginInfo *_xed_plugin_info_new (const gchar *file); -void _xed_plugin_info_ref (XedPluginInfo *info); -void _xed_plugin_info_unref (XedPluginInfo *info); - - -#endif /* __XED_PLUGIN_INFO_PRIV_H__ */ diff --git a/xed/xed-plugin-info.c b/xed/xed-plugin-info.c deleted file mode 100644 index aa6f249..0000000 --- a/xed/xed-plugin-info.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * xed-plugin-info.c - * This file is part of xed - * - * Copyright (C) 2002-2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2007. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "xed-plugin-info.h" -#include "xed-plugin-info-priv.h" -#include "xed-debug.h" -#include "xed-plugin.h" - -void -_xed_plugin_info_ref (XedPluginInfo *info) -{ - g_atomic_int_inc (&info->refcount); -} - -static XedPluginInfo * -xed_plugin_info_copy (XedPluginInfo *info) -{ - _xed_plugin_info_ref (info); - return info; -} - -void -_xed_plugin_info_unref (XedPluginInfo *info) -{ - if (!g_atomic_int_dec_and_test (&info->refcount)) - return; - - if (info->plugin != NULL) - { - xed_debug_message (DEBUG_PLUGINS, "Unref plugin %s", info->name); - - g_object_unref (info->plugin); - } - - g_free (info->file); - g_free (info->module_name); - g_strfreev (info->dependencies); - g_free (info->name); - g_free (info->desc); - g_free (info->icon_name); - g_free (info->website); - g_free (info->copyright); - g_free (info->loader); - g_free (info->version); - g_strfreev (info->authors); - - g_free (info); -} - -/** - * xed_plugin_info_get_type: - * - * Retrieves the #GType object which is associated with the #XedPluginInfo - * class. - * - * Return value: the GType associated with #XedPluginInfo. - **/ -GType -xed_plugin_info_get_type (void) -{ - static GType the_type = 0; - - if (G_UNLIKELY (!the_type)) - the_type = g_boxed_type_register_static ( - "XedPluginInfo", - (GBoxedCopyFunc) xed_plugin_info_copy, - (GBoxedFreeFunc) _xed_plugin_info_unref); - - return the_type; -} - -/** - * xed_plugin_info_new: - * @filename: the filename where to read the plugin information - * - * Creates a new #XedPluginInfo from a file on the disk. - * - * Return value: a newly created #XedPluginInfo. - */ -XedPluginInfo * -_xed_plugin_info_new (const gchar *file) -{ - XedPluginInfo *info; - GKeyFile *plugin_file = NULL; - gchar *str; - - g_return_val_if_fail (file != NULL, NULL); - - xed_debug_message (DEBUG_PLUGINS, "Loading plugin: %s", file); - - info = g_new0 (XedPluginInfo, 1); - info->refcount = 1; - info->file = g_strdup (file); - - plugin_file = g_key_file_new (); - if (!g_key_file_load_from_file (plugin_file, file, G_KEY_FILE_NONE, NULL)) - { - g_warning ("Bad plugin file: %s", file); - goto error; - } - - if (!g_key_file_has_key (plugin_file, - "Xed Plugin", - "IAge", - NULL)) - { - xed_debug_message (DEBUG_PLUGINS, - "IAge key does not exist in file: %s", file); - goto error; - } - - /* Check IAge=2 */ - if (g_key_file_get_integer (plugin_file, - "Xed Plugin", - "IAge", - NULL) != 2) - { - xed_debug_message (DEBUG_PLUGINS, - "Wrong IAge in file: %s", file); - goto error; - } - - /* Get module name */ - str = g_key_file_get_string (plugin_file, - "Xed Plugin", - "Module", - NULL); - - if ((str != NULL) && (*str != '\0')) - { - info->module_name = str; - } - else - { - g_warning ("Could not find 'Module' in %s", file); - g_free (str); - goto error; - } - - /* Get the dependency list */ - info->dependencies = g_key_file_get_string_list (plugin_file, - "Xed Plugin", - "Depends", - NULL, - NULL); - if (info->dependencies == NULL) - { - xed_debug_message (DEBUG_PLUGINS, "Could not find 'Depends' in %s", file); - info->dependencies = g_new0 (gchar *, 1); - } - - /* Get the loader for this plugin */ - str = g_key_file_get_string (plugin_file, - "Xed Plugin", - "Loader", - NULL); - - if ((str != NULL) && (*str != '\0')) - { - info->loader = str; - } - else - { - /* default to the C loader */ - info->loader = g_strdup("c"); - g_free (str); - } - - /* Get Name */ - str = g_key_file_get_locale_string (plugin_file, - "Xed Plugin", - "Name", - NULL, NULL); - if (str) - info->name = str; - else - { - g_warning ("Could not find 'Name' in %s", file); - goto error; - } - - /* Get Description */ - str = g_key_file_get_locale_string (plugin_file, - "Xed Plugin", - "Description", - NULL, NULL); - if (str) - info->desc = str; - else - xed_debug_message (DEBUG_PLUGINS, "Could not find 'Description' in %s", file); - - /* Get Icon */ - str = g_key_file_get_locale_string (plugin_file, - "Xed Plugin", - "Icon", - NULL, NULL); - if (str) - info->icon_name = str; - else - xed_debug_message (DEBUG_PLUGINS, "Could not find 'Icon' in %s, using 'xed-plugin'", file); - - - /* Get Authors */ - info->authors = g_key_file_get_string_list (plugin_file, - "Xed Plugin", - "Authors", - NULL, - NULL); - if (info->authors == NULL) - xed_debug_message (DEBUG_PLUGINS, "Could not find 'Authors' in %s", file); - - - /* Get Copyright */ - str = g_key_file_get_string (plugin_file, - "Xed Plugin", - "Copyright", - NULL); - if (str) - info->copyright = str; - else - xed_debug_message (DEBUG_PLUGINS, "Could not find 'Copyright' in %s", file); - - /* Get Website */ - str = g_key_file_get_string (plugin_file, - "Xed Plugin", - "Website", - NULL); - if (str) - info->website = str; - else - xed_debug_message (DEBUG_PLUGINS, "Could not find 'Website' in %s", file); - - /* Get Version */ - str = g_key_file_get_string (plugin_file, - "Xed Plugin", - "Version", - NULL); - if (str) - info->version = str; - else - xed_debug_message (DEBUG_PLUGINS, "Could not find 'Version' in %s", file); - - g_key_file_free (plugin_file); - - /* If we know nothing about the availability of the plugin, - set it as available */ - info->available = TRUE; - - return info; - -error: - g_free (info->file); - g_free (info->module_name); - g_free (info->name); - g_free (info->loader); - g_free (info); - g_key_file_free (plugin_file); - - return NULL; -} - -gboolean -xed_plugin_info_is_active (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, FALSE); - - return info->available && info->plugin != NULL; -} - -gboolean -xed_plugin_info_is_available (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, FALSE); - - return info->available != FALSE; -} - -gboolean -xed_plugin_info_is_configurable (XedPluginInfo *info) -{ - xed_debug_message (DEBUG_PLUGINS, "Is '%s' configurable?", info->name); - - g_return_val_if_fail (info != NULL, FALSE); - - if (info->plugin == NULL || !info->available) - return FALSE; - - return xed_plugin_is_configurable (info->plugin); -} - -const gchar * -xed_plugin_info_get_module_name (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - - return info->module_name; -} - -const gchar * -xed_plugin_info_get_name (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - - return info->name; -} - -const gchar * -xed_plugin_info_get_description (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - - return info->desc; -} - -const gchar * -xed_plugin_info_get_icon_name (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - - /* use the xed-plugin icon as a default if the plugin does not - have its own */ - if (info->icon_name != NULL && - gtk_icon_theme_has_icon (gtk_icon_theme_get_default (), - info->icon_name)) - return info->icon_name; - else - return "xed-plugin"; -} - -const gchar ** -xed_plugin_info_get_authors (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, (const gchar **)NULL); - - return (const gchar **) info->authors; -} - -const gchar * -xed_plugin_info_get_website (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - - return info->website; -} - -const gchar * -xed_plugin_info_get_copyright (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - - return info->copyright; -} - -const gchar * -xed_plugin_info_get_version (XedPluginInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - - return info->version; -} diff --git a/xed/xed-plugin-info.h b/xed/xed-plugin-info.h deleted file mode 100644 index b8e4395..0000000 --- a/xed/xed-plugin-info.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * xed-plugin-info.h - * This file is part of xed - * - * Copyright (C) 2002-2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2007. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_PLUGIN_INFO_H__ -#define __XED_PLUGIN_INFO_H__ - -#include - -G_BEGIN_DECLS - -#define XED_TYPE_PLUGIN_INFO (xed_plugin_info_get_type ()) -#define XED_PLUGIN_INFO(obj) ((XedPluginInfo *) (obj)) - -typedef struct _XedPluginInfo XedPluginInfo; - -GType xed_plugin_info_get_type (void) G_GNUC_CONST; - -gboolean xed_plugin_info_is_active (XedPluginInfo *info); -gboolean xed_plugin_info_is_available (XedPluginInfo *info); -gboolean xed_plugin_info_is_configurable (XedPluginInfo *info); - -const gchar *xed_plugin_info_get_module_name (XedPluginInfo *info); - -const gchar *xed_plugin_info_get_name (XedPluginInfo *info); -const gchar *xed_plugin_info_get_description (XedPluginInfo *info); -const gchar *xed_plugin_info_get_icon_name (XedPluginInfo *info); -const gchar **xed_plugin_info_get_authors (XedPluginInfo *info); -const gchar *xed_plugin_info_get_website (XedPluginInfo *info); -const gchar *xed_plugin_info_get_copyright (XedPluginInfo *info); -const gchar *xed_plugin_info_get_version (XedPluginInfo *info); - -G_END_DECLS - -#endif /* __XED_PLUGIN_INFO_H__ */ - diff --git a/xed/xed-plugin-loader.c b/xed/xed-plugin-loader.c deleted file mode 100644 index 1c7e728..0000000 --- a/xed/xed-plugin-loader.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * xed-plugin-loader.c - * This file is part of xed - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "xed-plugin-loader.h" - -static void -xed_plugin_loader_base_init (gpointer g_class) -{ - static gboolean initialized = FALSE; - - if (G_UNLIKELY (!initialized)) - { - /* create interface signals here. */ - initialized = TRUE; - } -} - -GType -xed_plugin_loader_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GTypeInfo info = - { - sizeof (XedPluginLoaderInterface), - xed_plugin_loader_base_init, /* base_init */ - NULL, /* base_finalize */ - NULL, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL /* instance_init */ - }; - - type = g_type_register_static (G_TYPE_INTERFACE, "XedPluginLoader", &info, 0); - } - - return type; -} - -const gchar * -xed_plugin_loader_type_get_id (GType type) -{ - GTypeClass *klass; - XedPluginLoaderInterface *iface; - - klass = g_type_class_ref (type); - - if (klass == NULL) - { - g_warning ("Could not get class info for plugin loader"); - return NULL; - } - - iface = g_type_interface_peek (klass, XED_TYPE_PLUGIN_LOADER); - - if (iface == NULL) - { - g_warning ("Could not get plugin loader interface"); - g_type_class_unref (klass); - - return NULL; - } - - g_return_val_if_fail (iface->get_id != NULL, NULL); - return iface->get_id (); -} - -XedPlugin * -xed_plugin_loader_load (XedPluginLoader *loader, - XedPluginInfo *info, - const gchar *path) -{ - XedPluginLoaderInterface *iface; - - g_return_val_if_fail (XED_IS_PLUGIN_LOADER (loader), NULL); - - iface = XED_PLUGIN_LOADER_GET_INTERFACE (loader); - g_return_val_if_fail (iface->load != NULL, NULL); - - return iface->load (loader, info, path); -} - -void -xed_plugin_loader_unload (XedPluginLoader *loader, - XedPluginInfo *info) -{ - XedPluginLoaderInterface *iface; - - g_return_if_fail (XED_IS_PLUGIN_LOADER (loader)); - - iface = XED_PLUGIN_LOADER_GET_INTERFACE (loader); - g_return_if_fail (iface->unload != NULL); - - iface->unload (loader, info); -} - -void -xed_plugin_loader_garbage_collect (XedPluginLoader *loader) -{ - XedPluginLoaderInterface *iface; - - g_return_if_fail (XED_IS_PLUGIN_LOADER (loader)); - - iface = XED_PLUGIN_LOADER_GET_INTERFACE (loader); - - if (iface->garbage_collect != NULL) - iface->garbage_collect (loader); -} diff --git a/xed/xed-plugin-loader.h b/xed/xed-plugin-loader.h deleted file mode 100644 index d30fb25..0000000 --- a/xed/xed-plugin-loader.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * xed-plugin-loader.h - * This file is part of xed - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XED_PLUGIN_LOADER_H__ -#define __XED_PLUGIN_LOADER_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define XED_TYPE_PLUGIN_LOADER (xed_plugin_loader_get_type ()) -#define XED_PLUGIN_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_PLUGIN_LOADER, XedPluginLoader)) -#define XED_IS_PLUGIN_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_PLUGIN_LOADER)) -#define XED_PLUGIN_LOADER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), XED_TYPE_PLUGIN_LOADER, XedPluginLoaderInterface)) - -typedef struct _XedPluginLoader XedPluginLoader; /* dummy object */ -typedef struct _XedPluginLoaderInterface XedPluginLoaderInterface; - -struct _XedPluginLoaderInterface { - GTypeInterface parent; - - const gchar *(*get_id) (void); - - XedPlugin *(*load) (XedPluginLoader *loader, - XedPluginInfo *info, - const gchar *path); - - void (*unload) (XedPluginLoader *loader, - XedPluginInfo *info); - - void (*garbage_collect) (XedPluginLoader *loader); -}; - -GType xed_plugin_loader_get_type (void); - -const gchar *xed_plugin_loader_type_get_id (GType type); -XedPlugin *xed_plugin_loader_load (XedPluginLoader *loader, - XedPluginInfo *info, - const gchar *path); -void xed_plugin_loader_unload (XedPluginLoader *loader, - XedPluginInfo *info); -void xed_plugin_loader_garbage_collect (XedPluginLoader *loader); - -/** - * XED_PLUGIN_LOADER_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init): - * - * Utility macro used to register interfaces for gobject types in plugin loaders. - */ -#define XED_PLUGIN_LOADER_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) \ - const GInterfaceInfo g_implement_interface_info = \ - { \ - (GInterfaceInitFunc) iface_init, \ - NULL, \ - NULL \ - }; \ - \ - g_type_module_add_interface (type_module, \ - g_define_type_id, \ - TYPE_IFACE, \ - &g_implement_interface_info); - -/** - * XED_PLUGIN_LOADER_REGISTER_TYPE(PluginLoaderName, plugin_loader_name, PARENT_TYPE, loader_interface_init): - * - * Utility macro used to register plugin loaders. - */ -#define XED_PLUGIN_LOADER_REGISTER_TYPE(PluginLoaderName, plugin_loader_name, PARENT_TYPE, loader_iface_init) \ - G_DEFINE_DYNAMIC_TYPE_EXTENDED (PluginLoaderName, \ - plugin_loader_name, \ - PARENT_TYPE, \ - 0, \ - XED_PLUGIN_LOADER_IMPLEMENT_INTERFACE(XED_TYPE_PLUGIN_LOADER, loader_iface_init)); \ - \ - \ -G_MODULE_EXPORT GType \ -register_xed_plugin_loader (GTypeModule *type_module) \ -{ \ - plugin_loader_name##_register_type (type_module); \ - \ - return plugin_loader_name##_get_type(); \ -} - -G_END_DECLS - -#endif /* __XED_PLUGIN_LOADER_H__ */ diff --git a/xed/xed-plugin-manager.c b/xed/xed-plugin-manager.c deleted file mode 100644 index 7365614..0000000 --- a/xed/xed-plugin-manager.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * xed-plugin-manager.c - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi and James Willcox - * Copyright (C) 2003-2006 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 1998-2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include "xed-plugin-manager.h" -#include "xed-utils.h" -#include "xed-plugins-engine.h" -#include "xed-plugin.h" -#include "xed-debug.h" - -enum -{ - ACTIVE_COLUMN, - AVAILABLE_COLUMN, - INFO_COLUMN, - N_COLUMNS -}; - -#define PLUGIN_MANAGER_NAME_TITLE _("Plugin") -#define PLUGIN_MANAGER_ACTIVE_TITLE _("Enabled") - -#define XED_PLUGIN_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_PLUGIN_MANAGER, XedPluginManagerPrivate)) - -struct _XedPluginManagerPrivate -{ - GtkWidget *tree; - - GtkWidget *about_button; - GtkWidget *configure_button; - - XedPluginsEngine *engine; - - GtkWidget *about; - - GtkWidget *popup_menu; -}; - -G_DEFINE_TYPE(XedPluginManager, xed_plugin_manager, GTK_TYPE_BOX) - -static XedPluginInfo *plugin_manager_get_selected_plugin (XedPluginManager *pm); -static void plugin_manager_toggle_active (XedPluginManager *pm, GtkTreeIter *iter, GtkTreeModel *model); -static void xed_plugin_manager_finalize (GObject *object); - -static void -xed_plugin_manager_class_init (XedPluginManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_plugin_manager_finalize; - - g_type_class_add_private (object_class, sizeof (XedPluginManagerPrivate)); -} - -static void -about_button_cb (GtkWidget *button, - XedPluginManager *pm) -{ - XedPluginInfo *info; - - xed_debug (DEBUG_PLUGINS); - - info = plugin_manager_get_selected_plugin (pm); - - g_return_if_fail (info != NULL); - - /* if there is another about dialog already open destroy it */ - if (pm->priv->about) - gtk_widget_destroy (pm->priv->about); - - pm->priv->about = g_object_new (GTK_TYPE_ABOUT_DIALOG, - "program-name", xed_plugin_info_get_name (info), - "copyright", xed_plugin_info_get_copyright (info), - "authors", xed_plugin_info_get_authors (info), - "comments", xed_plugin_info_get_description (info), - "website", xed_plugin_info_get_website (info), - "logo-icon-name", xed_plugin_info_get_icon_name (info), - "version", xed_plugin_info_get_version (info), - NULL); - - gtk_window_set_destroy_with_parent (GTK_WINDOW (pm->priv->about), - TRUE); - - g_signal_connect (pm->priv->about, - "response", - G_CALLBACK (gtk_widget_destroy), - NULL); - g_signal_connect (pm->priv->about, - "destroy", - G_CALLBACK (gtk_widget_destroyed), - &pm->priv->about); - - gtk_window_set_transient_for (GTK_WINDOW (pm->priv->about), - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(pm)))); - gtk_widget_show (pm->priv->about); -} - -static void -configure_button_cb (GtkWidget *button, - XedPluginManager *pm) -{ - XedPluginInfo *info; - GtkWindow *toplevel; - - xed_debug (DEBUG_PLUGINS); - - info = plugin_manager_get_selected_plugin (pm); - - g_return_if_fail (info != NULL); - - xed_debug_message (DEBUG_PLUGINS, "Configuring: %s\n", - xed_plugin_info_get_name (info)); - - toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(pm))); - - xed_plugins_engine_configure_plugin (pm->priv->engine, - info, toplevel); - - xed_debug_message (DEBUG_PLUGINS, "Done"); -} - -static void -plugin_manager_view_info_cell_cb (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - XedPluginInfo *info; - gchar *text; - - g_return_if_fail (tree_model != NULL); - g_return_if_fail (tree_column != NULL); - - gtk_tree_model_get (tree_model, iter, INFO_COLUMN, &info, -1); - - if (info == NULL) - return; - - text = g_markup_printf_escaped ("%s\n%s", - xed_plugin_info_get_name (info), - xed_plugin_info_get_description (info)); - g_object_set (G_OBJECT (cell), - "markup", text, - "sensitive", xed_plugin_info_is_available (info), - NULL); - - g_free (text); -} - -static void -plugin_manager_view_icon_cell_cb (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - XedPluginInfo *info; - - g_return_if_fail (tree_model != NULL); - g_return_if_fail (tree_column != NULL); - - gtk_tree_model_get (tree_model, iter, INFO_COLUMN, &info, -1); - - if (info == NULL) - return; - - g_object_set (G_OBJECT (cell), - "icon-name", xed_plugin_info_get_icon_name (info), - "sensitive", xed_plugin_info_is_available (info), - NULL); -} - - -static void -active_toggled_cb (GtkCellRendererToggle *cell, - gchar *path_str, - XedPluginManager *pm) -{ - GtkTreeIter iter; - GtkTreePath *path; - GtkTreeModel *model; - - xed_debug (DEBUG_PLUGINS); - - path = gtk_tree_path_new_from_string (path_str); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree)); - g_return_if_fail (model != NULL); - - gtk_tree_model_get_iter (model, &iter, path); - - if (&iter != NULL) - plugin_manager_toggle_active (pm, &iter, model); - - gtk_tree_path_free (path); -} - -static void -cursor_changed_cb (GtkTreeView *view, - gpointer data) -{ - XedPluginManager *pm = data; - XedPluginInfo *info; - - xed_debug (DEBUG_PLUGINS); - - info = plugin_manager_get_selected_plugin (pm); - - gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->about_button), - info != NULL); - gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->configure_button), - (info != NULL) && - xed_plugin_info_is_configurable (info)); -} - -static void -row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - gpointer data) -{ - XedPluginManager *pm = data; - GtkTreeIter iter; - GtkTreeModel *model; - - xed_debug (DEBUG_PLUGINS); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree)); - - g_return_if_fail (model != NULL); - - gtk_tree_model_get_iter (model, &iter, path); - - g_return_if_fail (&iter != NULL); - - plugin_manager_toggle_active (pm, &iter, model); -} - -static void -plugin_manager_populate_lists (XedPluginManager *pm) -{ - const GList *plugins; - GtkListStore *model; - GtkTreeIter iter; - - xed_debug (DEBUG_PLUGINS); - - plugins = xed_plugins_engine_get_plugin_list (pm->priv->engine); - - model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree))); - - while (plugins) - { - XedPluginInfo *info; - info = (XedPluginInfo *)plugins->data; - - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, - ACTIVE_COLUMN, xed_plugin_info_is_active (info), - AVAILABLE_COLUMN, xed_plugin_info_is_available (info), - INFO_COLUMN, info, - -1); - - plugins = plugins->next; - } - - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)) - { - GtkTreeSelection *selection; - XedPluginInfo* info; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree)); - g_return_if_fail (selection != NULL); - - gtk_tree_selection_select_iter (selection, &iter); - - gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, - INFO_COLUMN, &info, -1); - - gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->configure_button), - xed_plugin_info_is_configurable (info)); - } -} - -static gboolean -plugin_manager_set_active (XedPluginManager *pm, - GtkTreeIter *iter, - GtkTreeModel *model, - gboolean active) -{ - XedPluginInfo *info; - gboolean res = TRUE; - - xed_debug (DEBUG_PLUGINS); - - gtk_tree_model_get (model, iter, INFO_COLUMN, &info, -1); - - g_return_val_if_fail (info != NULL, FALSE); - - if (active) - { - /* activate the plugin */ - if (!xed_plugins_engine_activate_plugin (pm->priv->engine, info)) { - xed_debug_message (DEBUG_PLUGINS, "Could not activate %s.\n", - xed_plugin_info_get_name (info)); - - res = FALSE; - } - } - else - { - /* deactivate the plugin */ - if (!xed_plugins_engine_deactivate_plugin (pm->priv->engine, info)) { - xed_debug_message (DEBUG_PLUGINS, "Could not deactivate %s.\n", - xed_plugin_info_get_name (info)); - - res = FALSE; - } - } - - return res; -} - -static void -plugin_manager_toggle_active (XedPluginManager *pm, - GtkTreeIter *iter, - GtkTreeModel *model) -{ - gboolean active; - - xed_debug (DEBUG_PLUGINS); - - gtk_tree_model_get (model, iter, ACTIVE_COLUMN, &active, -1); - - active ^= 1; - - plugin_manager_set_active (pm, iter, model, active); -} - -static XedPluginInfo * -plugin_manager_get_selected_plugin (XedPluginManager *pm) -{ - XedPluginInfo *info = NULL; - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreeSelection *selection; - - xed_debug (DEBUG_PLUGINS); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree)); - g_return_val_if_fail (model != NULL, NULL); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree)); - g_return_val_if_fail (selection != NULL, NULL); - - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - gtk_tree_model_get (model, &iter, INFO_COLUMN, &info, -1); - } - - return info; -} - -static void -plugin_manager_set_active_all (XedPluginManager *pm, - gboolean active) -{ - GtkTreeModel *model; - GtkTreeIter iter; - - xed_debug (DEBUG_PLUGINS); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree)); - - g_return_if_fail (model != NULL); - - gtk_tree_model_get_iter_first (model, &iter); - - do { - plugin_manager_set_active (pm, &iter, model, active); - } - while (gtk_tree_model_iter_next (model, &iter)); -} - -/* Callback used as the interactive search comparison function */ -static gboolean -name_search_cb (GtkTreeModel *model, - gint column, - const gchar *key, - GtkTreeIter *iter, - gpointer data) -{ - XedPluginInfo *info; - gchar *normalized_string; - gchar *normalized_key; - gchar *case_normalized_string; - gchar *case_normalized_key; - gint key_len; - gboolean retval; - - gtk_tree_model_get (model, iter, INFO_COLUMN, &info, -1); - if (!info) - return FALSE; - - normalized_string = g_utf8_normalize (xed_plugin_info_get_name (info), -1, G_NORMALIZE_ALL); - normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL); - case_normalized_string = g_utf8_casefold (normalized_string, -1); - case_normalized_key = g_utf8_casefold (normalized_key, -1); - - key_len = strlen (case_normalized_key); - - /* Oddly enough, this callback must return whether to stop the search - * because we found a match, not whether we actually matched. - */ - retval = (strncmp (case_normalized_key, case_normalized_string, key_len) != 0); - - g_free (normalized_key); - g_free (normalized_string); - g_free (case_normalized_key); - g_free (case_normalized_string); - - return retval; -} - -static void -enable_plugin_menu_cb (GtkMenu *menu, - XedPluginManager *pm) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreeSelection *selection; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree)); - g_return_if_fail (model != NULL); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree)); - g_return_if_fail (selection != NULL); - - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - plugin_manager_toggle_active (pm, &iter, model); -} - -static void -enable_all_menu_cb (GtkMenu *menu, - XedPluginManager *pm) -{ - plugin_manager_set_active_all (pm, TRUE); -} - -static void -disable_all_menu_cb (GtkMenu *menu, - XedPluginManager *pm) -{ - plugin_manager_set_active_all (pm, FALSE); -} - -static GtkWidget * -create_tree_popup_menu (XedPluginManager *pm) -{ - GtkWidget *menu; - GtkWidget *item; - GtkWidget *image; - XedPluginInfo *info; - - info = plugin_manager_get_selected_plugin (pm); - - menu = gtk_menu_new (); - - item = gtk_image_menu_item_new_with_mnemonic (_("_About")); - image = gtk_image_new_from_stock (GTK_STOCK_ABOUT, - GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - g_signal_connect (item, "activate", - G_CALLBACK (about_button_cb), pm); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_image_menu_item_new_with_mnemonic (_("C_onfigure")); - image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, - GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - g_signal_connect (item, "activate", - G_CALLBACK (configure_button_cb), pm); - gtk_widget_set_sensitive (item, xed_plugin_info_is_configurable (info)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_check_menu_item_new_with_mnemonic (_("A_ctivate")); - gtk_widget_set_sensitive (item, xed_plugin_info_is_available (info)); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), - xed_plugin_info_is_active (info)); - g_signal_connect (item, "toggled", - G_CALLBACK (enable_plugin_menu_cb), pm); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_menu_item_new_with_mnemonic (_("Ac_tivate All")); - g_signal_connect (item, "activate", - G_CALLBACK (enable_all_menu_cb), pm); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - item = gtk_menu_item_new_with_mnemonic (_("_Deactivate All")); - g_signal_connect (item, "activate", - G_CALLBACK (disable_all_menu_cb), pm); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - gtk_widget_show_all (menu); - - return menu; -} - -static void -tree_popup_menu_detach (XedPluginManager *pm, - GtkMenu *menu) -{ - pm->priv->popup_menu = NULL; -} - -static void -show_tree_popup_menu (GtkTreeView *tree, - XedPluginManager *pm, - GdkEventButton *event) -{ - if (pm->priv->popup_menu) - gtk_widget_destroy (pm->priv->popup_menu); - - pm->priv->popup_menu = create_tree_popup_menu (pm); - - gtk_menu_attach_to_widget (GTK_MENU (pm->priv->popup_menu), - GTK_WIDGET (pm), - (GtkMenuDetachFunc) tree_popup_menu_detach); - - if (event != NULL) - { - gtk_menu_popup (GTK_MENU (pm->priv->popup_menu), NULL, NULL, - NULL, NULL, - event->button, event->time); - } - else - { - gtk_menu_popup (GTK_MENU (pm->priv->popup_menu), NULL, NULL, - xed_utils_menu_position_under_tree_view, tree, - 0, gtk_get_current_event_time ()); - - gtk_menu_shell_select_first (GTK_MENU_SHELL (pm->priv->popup_menu), - FALSE); - } -} - -static gboolean -button_press_event_cb (GtkWidget *tree, - GdkEventButton *event, - XedPluginManager *pm) -{ - /* We want the treeview selection to be updated before showing the menu. - * This code is evil, thanks to Federico Mena Quintero's black magic. - * See: http://mail.gnome.org/archives/gtk-devel-list/2006-February/msg00168.html - * FIXME: Let's remove it asap. - */ - - static gboolean in_press = FALSE; - gboolean handled; - - if (in_press) - return FALSE; /* we re-entered */ - - if (GDK_BUTTON_PRESS != event->type || 3 != event->button) - return FALSE; /* let the normal handler run */ - - in_press = TRUE; - handled = gtk_widget_event (tree, (GdkEvent *) event); - in_press = FALSE; - - if (!handled) - return FALSE; - - /* The selection is fully updated by now */ - show_tree_popup_menu (GTK_TREE_VIEW (tree), pm, event); - return TRUE; -} - -static gboolean -popup_menu_cb (GtkTreeView *tree, - XedPluginManager *pm) -{ - show_tree_popup_menu (tree, pm, NULL); - return TRUE; -} - -static gint -model_name_sort_func (GtkTreeModel *model, - GtkTreeIter *iter1, - GtkTreeIter *iter2, - gpointer user_data) -{ - XedPluginInfo *info1, *info2; - - gtk_tree_model_get (model, iter1, INFO_COLUMN, &info1, -1); - gtk_tree_model_get (model, iter2, INFO_COLUMN, &info2, -1); - - return g_utf8_collate (xed_plugin_info_get_name (info1), - xed_plugin_info_get_name (info2)); -} - -static void -plugin_manager_construct_tree (XedPluginManager *pm) -{ - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - GtkListStore *model; - - xed_debug (DEBUG_PLUGINS); - - model = gtk_list_store_new (N_COLUMNS, - G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN, - G_TYPE_POINTER); - - gtk_tree_view_set_model (GTK_TREE_VIEW (pm->priv->tree), - GTK_TREE_MODEL (model)); - g_object_unref (model); - - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (pm->priv->tree), TRUE); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (pm->priv->tree), FALSE); - - /* first column */ - cell = gtk_cell_renderer_toggle_new (); - g_object_set (cell, "xpad", 6, NULL); - g_signal_connect (cell, - "toggled", - G_CALLBACK (active_toggled_cb), - pm); - column = gtk_tree_view_column_new_with_attributes (PLUGIN_MANAGER_ACTIVE_TITLE, - cell, - "active", - ACTIVE_COLUMN, - "activatable", - AVAILABLE_COLUMN, - "sensitive", - AVAILABLE_COLUMN, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column); - - /* second column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, PLUGIN_MANAGER_NAME_TITLE); - gtk_tree_view_column_set_resizable (column, TRUE); - - cell = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, cell, FALSE); - g_object_set (cell, "stock-size", GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); - gtk_tree_view_column_set_cell_data_func (column, cell, - plugin_manager_view_icon_cell_cb, - pm, NULL); - - cell = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, cell, TRUE); - g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - gtk_tree_view_column_set_cell_data_func (column, cell, - plugin_manager_view_info_cell_cb, - pm, NULL); - - - gtk_tree_view_column_set_spacing (column, 6); - gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column); - - /* Sort on the plugin names */ - gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model), - model_name_sort_func, - NULL, - NULL); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), - GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, - GTK_SORT_ASCENDING); - - /* Enable search for our non-string column */ - gtk_tree_view_set_search_column (GTK_TREE_VIEW (pm->priv->tree), - INFO_COLUMN); - gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (pm->priv->tree), - name_search_cb, - NULL, - NULL); - - g_signal_connect (pm->priv->tree, - "cursor_changed", - G_CALLBACK (cursor_changed_cb), - pm); - g_signal_connect (pm->priv->tree, - "row_activated", - G_CALLBACK (row_activated_cb), - pm); - - g_signal_connect (pm->priv->tree, - "button-press-event", - G_CALLBACK (button_press_event_cb), - pm); - g_signal_connect (pm->priv->tree, - "popup-menu", - G_CALLBACK (popup_menu_cb), - pm); - gtk_widget_show (pm->priv->tree); -} - -static void -plugin_toggled_cb (XedPluginsEngine *engine, - XedPluginInfo *info, - XedPluginManager *pm) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean info_found = FALSE; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree)); - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - /* There is an item selected: it's probably the one we want! */ - XedPluginInfo *tinfo; - gtk_tree_model_get (model, &iter, INFO_COLUMN, &tinfo, -1); - info_found = info == tinfo; - } - - if (!info_found) - { - gtk_tree_model_get_iter_first (model, &iter); - - do - { - XedPluginInfo *tinfo; - gtk_tree_model_get (model, &iter, INFO_COLUMN, &tinfo, -1); - info_found = info == tinfo; - } - while (!info_found && gtk_tree_model_iter_next (model, &iter)); - } - - if (!info_found) - { - g_warning ("XedPluginManager: plugin '%s' not found in the tree model", - xed_plugin_info_get_name (info)); - return; - } - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, ACTIVE_COLUMN, xed_plugin_info_is_active (info), -1); -} - -static void -xed_plugin_manager_init (XedPluginManager *pm) -{ - GtkWidget *label; - GtkWidget *viewport; - GtkWidget *hbuttonbox; - - xed_debug (DEBUG_PLUGINS); - - pm->priv = XED_PLUGIN_MANAGER_GET_PRIVATE (pm); - - gtk_orientable_set_orientation (GTK_ORIENTABLE (pm), - GTK_ORIENTATION_VERTICAL); - - /* - * Always we create the manager, firstly we rescan the plugins directory - */ - xed_plugins_engine_rescan_plugins (xed_plugins_engine_get_default ()); - - gtk_box_set_spacing (GTK_BOX (pm), 6); - - label = gtk_label_new_with_mnemonic (_("Active _Plugins:")); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - - gtk_box_pack_start (GTK_BOX (pm), label, FALSE, TRUE, 0); - - viewport = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (viewport), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (viewport), - GTK_SHADOW_IN); - - gtk_box_pack_start (GTK_BOX (pm), viewport, TRUE, TRUE, 0); - - pm->priv->tree = gtk_tree_view_new (); - gtk_container_add (GTK_CONTAINER (viewport), pm->priv->tree); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), pm->priv->tree); - - hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); - - gtk_box_pack_start (GTK_BOX (pm), hbuttonbox, FALSE, FALSE, 0); - gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing (GTK_BOX (hbuttonbox), 8); - - pm->priv->about_button = xed_gtk_button_new_with_stock_icon (_("_About Plugin"), - GTK_STOCK_ABOUT); - gtk_container_add (GTK_CONTAINER (hbuttonbox), pm->priv->about_button); - - pm->priv->configure_button = xed_gtk_button_new_with_stock_icon (_("C_onfigure Plugin"), - GTK_STOCK_PREFERENCES); - gtk_container_add (GTK_CONTAINER (hbuttonbox), pm->priv->configure_button); - - /* setup a window of a sane size. */ - gtk_widget_set_size_request (GTK_WIDGET (viewport), 270, 100); - - g_signal_connect (pm->priv->about_button, - "clicked", - G_CALLBACK (about_button_cb), - pm); - g_signal_connect (pm->priv->configure_button, - "clicked", - G_CALLBACK (configure_button_cb), - pm); - - plugin_manager_construct_tree (pm); - - /* get the plugin engine and populate the treeview */ - pm->priv->engine = xed_plugins_engine_get_default (); - - g_signal_connect_after (pm->priv->engine, - "activate-plugin", - G_CALLBACK (plugin_toggled_cb), - pm); - g_signal_connect_after (pm->priv->engine, - "deactivate-plugin", - G_CALLBACK (plugin_toggled_cb), - pm); - - if (xed_plugins_engine_get_plugin_list (pm->priv->engine) != NULL) - { - plugin_manager_populate_lists (pm); - } - else - { - gtk_widget_set_sensitive (pm->priv->about_button, FALSE); - gtk_widget_set_sensitive (pm->priv->configure_button, FALSE); - } -} - -static void -xed_plugin_manager_finalize (GObject *object) -{ - XedPluginManager *pm = XED_PLUGIN_MANAGER (object); - - g_signal_handlers_disconnect_by_func (pm->priv->engine, - plugin_toggled_cb, - pm); - - if (pm->priv->popup_menu) - gtk_widget_destroy (pm->priv->popup_menu); - - G_OBJECT_CLASS (xed_plugin_manager_parent_class)->finalize (object); - -} - -GtkWidget *xed_plugin_manager_new (void) -{ - return g_object_new (XED_TYPE_PLUGIN_MANAGER,0); -} diff --git a/xed/xed-plugin-manager.h b/xed/xed-plugin-manager.h deleted file mode 100644 index be1923f..0000000 --- a/xed/xed-plugin-manager.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * xed-plugin-manager.h - * This file is part of xed - * - * Copyright (C) 2002-2005 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_PLUGIN_MANAGER_H__ -#define __XED_PLUGIN_MANAGER_H__ - -#include - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_PLUGIN_MANAGER (xed_plugin_manager_get_type()) -#define XED_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PLUGIN_MANAGER, XedPluginManager)) -#define XED_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_PLUGIN_MANAGER, XedPluginManagerClass)) -#define XED_IS_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_PLUGIN_MANAGER)) -#define XED_IS_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PLUGIN_MANAGER)) -#define XED_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PLUGIN_MANAGER, XedPluginManagerClass)) - -/* Private structure type */ -typedef struct _XedPluginManagerPrivate XedPluginManagerPrivate; - -/* - * Main object structure - */ -typedef struct _XedPluginManager XedPluginManager; - -struct _XedPluginManager -{ - GtkBox vbox; - - /*< private > */ - XedPluginManagerPrivate *priv; -}; - -/* - * Class definition - */ -typedef struct _XedPluginManagerClass XedPluginManagerClass; - -struct _XedPluginManagerClass -{ - GtkBoxClass parent_class; -}; - -/* - * Public methods - */ -GType xed_plugin_manager_get_type (void) G_GNUC_CONST; - -GtkWidget *xed_plugin_manager_new (void); - -G_END_DECLS - -#endif /* __XED_PLUGIN_MANAGER_H__ */ diff --git a/xed/xed-plugin.c b/xed/xed-plugin.c deleted file mode 100644 index 87c3eb9..0000000 --- a/xed/xed-plugin.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * xed-plugin.h - * This file is part of xed - * - * Copyright (C) 2002-2005 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "xed-plugin.h" -#include "xed-dirs.h" - -/* properties */ -enum { - PROP_0, - PROP_INSTALL_DIR, - PROP_DATA_DIR_NAME, - PROP_DATA_DIR -}; - -typedef struct _XedPluginPrivate XedPluginPrivate; - -struct _XedPluginPrivate -{ - gchar *install_dir; - gchar *data_dir_name; -}; - -#define XED_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_PLUGIN, XedPluginPrivate)) - -G_DEFINE_TYPE(XedPlugin, xed_plugin, G_TYPE_OBJECT) - -static void -dummy (XedPlugin *plugin, XedWindow *window) -{ - /* Empty */ -} - -static GtkWidget * -create_configure_dialog (XedPlugin *plugin) -{ - return NULL; -} - -static gboolean -is_configurable (XedPlugin *plugin) -{ - return (XED_PLUGIN_GET_CLASS (plugin)->create_configure_dialog != - create_configure_dialog); -} - -static void -xed_plugin_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - case PROP_INSTALL_DIR: - g_value_take_string (value, xed_plugin_get_install_dir (XED_PLUGIN (object))); - break; - case PROP_DATA_DIR: - g_value_take_string (value, xed_plugin_get_data_dir (XED_PLUGIN (object))); - break; - default: - g_return_if_reached (); - } -} - -static void -xed_plugin_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedPluginPrivate *priv = XED_PLUGIN_GET_PRIVATE (object); - - switch (prop_id) - { - case PROP_INSTALL_DIR: - priv->install_dir = g_value_dup_string (value); - break; - case PROP_DATA_DIR_NAME: - priv->data_dir_name = g_value_dup_string (value); - break; - default: - g_return_if_reached (); - } -} - -static void -xed_plugin_finalize (GObject *object) -{ - XedPluginPrivate *priv = XED_PLUGIN_GET_PRIVATE (object); - - g_free (priv->install_dir); - g_free (priv->data_dir_name); - - G_OBJECT_CLASS (xed_plugin_parent_class)->finalize (object); -} - -static void -xed_plugin_class_init (XedPluginClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - klass->activate = dummy; - klass->deactivate = dummy; - klass->update_ui = dummy; - - klass->create_configure_dialog = create_configure_dialog; - klass->is_configurable = is_configurable; - - object_class->get_property = xed_plugin_get_property; - object_class->set_property = xed_plugin_set_property; - object_class->finalize = xed_plugin_finalize; - - g_object_class_install_property (object_class, - PROP_INSTALL_DIR, - g_param_spec_string ("install-dir", - "Install Directory", - "The directory where the plugin is installed", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /* the basename of the data dir is set at construction time by the plugin loader - * while the full path is constructed on the fly to take into account relocability - * that's why we have a writeonly prop and a readonly prop */ - g_object_class_install_property (object_class, - PROP_DATA_DIR_NAME, - g_param_spec_string ("data-dir-name", - "Basename of the data directory", - "The basename of the directory where the plugin should look for its data files", - NULL, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_DATA_DIR, - g_param_spec_string ("data-dir", - "Data Directory", - "The full path of the directory where the plugin should look for its data files", - NULL, - G_PARAM_READABLE)); - - g_type_class_add_private (klass, sizeof (XedPluginPrivate)); -} - -static void -xed_plugin_init (XedPlugin *plugin) -{ - /* Empty */ -} - -/** - * xed_plugin_get_install_dir: - * @plugin: a #XedPlugin - * - * Get the path of the directory where the plugin is installed. - * - * Return value: a newly allocated string with the path of the - * directory where the plugin is installed - */ -gchar * -xed_plugin_get_install_dir (XedPlugin *plugin) -{ - g_return_val_if_fail (XED_IS_PLUGIN (plugin), NULL); - - return g_strdup (XED_PLUGIN_GET_PRIVATE (plugin)->install_dir); -} - -/** - * xed_plugin_get_data_dir: - * @plugin: a #XedPlugin - * - * Get the path of the directory where the plugin should look for - * its data files. - * - * Return value: a newly allocated string with the path of the - * directory where the plugin should look for its data files - */ -gchar * -xed_plugin_get_data_dir (XedPlugin *plugin) -{ - XedPluginPrivate *priv; - gchar *xed_lib_dir; - gchar *data_dir; - - g_return_val_if_fail (XED_IS_PLUGIN (plugin), NULL); - - priv = XED_PLUGIN_GET_PRIVATE (plugin); - - /* If it's a "user" plugin the data dir is - * install_dir/data_dir_name if instead it's a - * "system" plugin the data dir is under xed_data_dir, - * so it's under $prefix/share/xed/plugins/data_dir_name - * where data_dir_name usually it's the name of the plugin - */ - xed_lib_dir = xed_dirs_get_xed_lib_dir (); - - /* CHECK: is checking the prefix enough or should we be more - * careful about normalizing paths etc? */ - if (g_str_has_prefix (priv->install_dir, xed_lib_dir)) - { - gchar *xed_data_dir; - - xed_data_dir = xed_dirs_get_xed_data_dir (); - - data_dir = g_build_filename (xed_data_dir, - "plugins", - priv->data_dir_name, - NULL); - - g_free (xed_data_dir); - } - else - { - data_dir = g_build_filename (priv->install_dir, - priv->data_dir_name, - NULL); - } - - g_free (xed_lib_dir); - - return data_dir; -} - -/** - * xed_plugin_activate: - * @plugin: a #XedPlugin - * @window: a #XedWindow - * - * Activates the plugin. - */ -void -xed_plugin_activate (XedPlugin *plugin, - XedWindow *window) -{ - g_return_if_fail (XED_IS_PLUGIN (plugin)); - g_return_if_fail (XED_IS_WINDOW (window)); - - XED_PLUGIN_GET_CLASS (plugin)->activate (plugin, window); -} - -/** - * xed_plugin_deactivate: - * @plugin: a #XedPlugin - * @window: a #XedWindow - * - * Deactivates the plugin. - */ -void -xed_plugin_deactivate (XedPlugin *plugin, - XedWindow *window) -{ - g_return_if_fail (XED_IS_PLUGIN (plugin)); - g_return_if_fail (XED_IS_WINDOW (window)); - - XED_PLUGIN_GET_CLASS (plugin)->deactivate (plugin, window); -} - -/** - * xed_plugin_update_ui: - * @plugin: a #XedPlugin - * @window: a #XedWindow - * - * Triggers an update of the user interface to take into account state changes - * caused by the plugin. - */ -void -xed_plugin_update_ui (XedPlugin *plugin, - XedWindow *window) -{ - g_return_if_fail (XED_IS_PLUGIN (plugin)); - g_return_if_fail (XED_IS_WINDOW (window)); - - XED_PLUGIN_GET_CLASS (plugin)->update_ui (plugin, window); -} - -/** - * xed_plugin_is_configurable: - * @plugin: a #XedPlugin - * - * Whether the plugin is configurable. - * - * Returns: TRUE if the plugin is configurable: - */ -gboolean -xed_plugin_is_configurable (XedPlugin *plugin) -{ - g_return_val_if_fail (XED_IS_PLUGIN (plugin), FALSE); - - return XED_PLUGIN_GET_CLASS (plugin)->is_configurable (plugin); -} - -/** - * xed_plugin_create_configure_dialog: - * @plugin: a #XedPlugin - * - * Creates the configure dialog widget for the plugin. - * - * Returns: the configure dialog widget for the plugin. - */ -GtkWidget * -xed_plugin_create_configure_dialog (XedPlugin *plugin) -{ - g_return_val_if_fail (XED_IS_PLUGIN (plugin), NULL); - - return XED_PLUGIN_GET_CLASS (plugin)->create_configure_dialog (plugin); -} diff --git a/xed/xed-plugin.h b/xed/xed-plugin.h deleted file mode 100644 index 6e68da0..0000000 --- a/xed/xed-plugin.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * xed-plugin.h - * This file is part of xed - * - * Copyright (C) 2002-2005 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_PLUGIN_H__ -#define __XED_PLUGIN_H__ - -#include - -#include -#include - -/* TODO: add a .h file that includes all the .h files normally needed to - * develop a plugin */ - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_PLUGIN (xed_plugin_get_type()) -#define XED_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PLUGIN, XedPlugin)) -#define XED_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_PLUGIN, XedPluginClass)) -#define XED_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_PLUGIN)) -#define XED_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PLUGIN)) -#define XED_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PLUGIN, XedPluginClass)) - -/* - * Main object structure - */ -typedef struct _XedPlugin XedPlugin; - -struct _XedPlugin -{ - GObject parent; -}; - -/* - * Class definition - */ -typedef struct _XedPluginClass XedPluginClass; - -struct _XedPluginClass -{ - GObjectClass parent_class; - - /* Virtual public methods */ - - void (*activate) (XedPlugin *plugin, - XedWindow *window); - void (*deactivate) (XedPlugin *plugin, - XedWindow *window); - - void (*update_ui) (XedPlugin *plugin, - XedWindow *window); - - GtkWidget *(*create_configure_dialog) - (XedPlugin *plugin); - - /* Plugins should not override this, it's handled automatically by - the XedPluginClass */ - gboolean (*is_configurable) - (XedPlugin *plugin); - - /* Padding for future expansion */ - void (*_xed_reserved1) (void); - void (*_xed_reserved2) (void); - void (*_xed_reserved3) (void); - void (*_xed_reserved4) (void); -}; - -/* - * Public methods - */ -GType xed_plugin_get_type (void) G_GNUC_CONST; - -gchar *xed_plugin_get_install_dir (XedPlugin *plugin); -gchar *xed_plugin_get_data_dir (XedPlugin *plugin); - -void xed_plugin_activate (XedPlugin *plugin, - XedWindow *window); -void xed_plugin_deactivate (XedPlugin *plugin, - XedWindow *window); - -void xed_plugin_update_ui (XedPlugin *plugin, - XedWindow *window); - -gboolean xed_plugin_is_configurable (XedPlugin *plugin); -GtkWidget *xed_plugin_create_configure_dialog - (XedPlugin *plugin); - -/** - * XED_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE): - * - * Utility macro used to register plugins with additional code. - */ -#define XED_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE) \ - G_DEFINE_DYNAMIC_TYPE_EXTENDED (PluginName, \ - plugin_name, \ - XED_TYPE_PLUGIN, \ - 0, \ - GTypeModule *module G_GNUC_UNUSED = type_module; /* back compat */ \ - CODE) \ - \ -/* This is not very nice, but G_DEFINE_DYNAMIC wants it and our old macro \ - * did not support it */ \ -static void \ -plugin_name##_class_finalize (PluginName##Class *klass) \ -{ \ -} \ - \ - \ -G_MODULE_EXPORT GType \ -register_xed_plugin (GTypeModule *type_module) \ -{ \ - plugin_name##_register_type (type_module); \ - \ - return plugin_name##_get_type(); \ -} - -/** - * XED_PLUGIN_REGISTER_TYPE(PluginName, plugin_name): - * - * Utility macro used to register plugins. - */ -#define XED_PLUGIN_REGISTER_TYPE(PluginName, plugin_name) \ - XED_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, ;) - -/** - * XED_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE): - * - * Utility macro used to register gobject types in plugins with additional code. - * - * Deprecated: use G_DEFINE_DYNAMIC_TYPE_EXTENDED instead - */ -#define XED_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE) \ - \ -static GType g_define_type_id = 0; \ - \ -GType \ -object_name##_get_type (void) \ -{ \ - return g_define_type_id; \ -} \ - \ -static void object_name##_init (ObjectName *self); \ -static void object_name##_class_init (ObjectName##Class *klass); \ -static gpointer object_name##_parent_class = NULL; \ -static void object_name##_class_intern_init (gpointer klass) \ -{ \ - object_name##_parent_class = g_type_class_peek_parent (klass); \ - object_name##_class_init ((ObjectName##Class *) klass); \ -} \ - \ -GType \ -object_name##_register_type (GTypeModule *type_module) \ -{ \ - GTypeModule *module G_GNUC_UNUSED = type_module; /* back compat */ \ - static const GTypeInfo our_info = \ - { \ - sizeof (ObjectName##Class), \ - NULL, /* base_init */ \ - NULL, /* base_finalize */ \ - (GClassInitFunc) object_name##_class_intern_init, \ - NULL, \ - NULL, /* class_data */ \ - sizeof (ObjectName), \ - 0, /* n_preallocs */ \ - (GInstanceInitFunc) object_name##_init \ - }; \ - \ - g_define_type_id = g_type_module_register_type (type_module, \ - PARENT_TYPE, \ - #ObjectName, \ - &our_info, \ - 0); \ - \ - CODE \ - \ - return g_define_type_id; \ -} - - -/** - * XED_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE): - * - * Utility macro used to register gobject types in plugins. - * - * Deprecated: use G_DEFINE_DYNAMIC instead - */ -#define XED_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE) \ - XED_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, ;) - -/** - * XED_PLUGIN_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init): - * - * Utility macro used to register interfaces for gobject types in plugins. - */ -#define XED_PLUGIN_IMPLEMENT_INTERFACE(object_name, TYPE_IFACE, iface_init) \ - const GInterfaceInfo object_name##_interface_info = \ - { \ - (GInterfaceInitFunc) iface_init, \ - NULL, \ - NULL \ - }; \ - \ - g_type_module_add_interface (type_module, \ - g_define_type_id, \ - TYPE_IFACE, \ - &object_name##_interface_info); - -G_END_DECLS - -#endif /* __XED_PLUGIN_H__ */ diff --git a/xed/xed-plugins-engine.c b/xed/xed-plugins-engine.c index 0fcb992..6b96972 100644 --- a/xed/xed-plugins-engine.c +++ b/xed/xed-plugins-engine.c @@ -35,827 +35,122 @@ #include #include +#include #include "xed-plugins-engine.h" -#include "xed-plugin-info-priv.h" -#include "xed-plugin.h" #include "xed-debug.h" #include "xed-app.h" -#include "xed-prefs-manager.h" -#include "xed-plugin-loader.h" -#include "xed-object-module.h" #include "xed-dirs.h" +#include "xed-settings.h" +#include "xed-utils.h" -#define XED_PLUGINS_ENGINE_BASE_KEY "/apps/xed/plugins" -#define XED_PLUGINS_ENGINE_KEY XED_PLUGINS_ENGINE_BASE_KEY "/active-plugins" - -#define PLUGIN_EXT ".xed-plugin" -#define LOADER_EXT G_MODULE_SUFFIX - -typedef struct -{ - XedPluginLoader *loader; - XedObjectModule *module; -} LoaderInfo; - -/* Signals */ -enum -{ - ACTIVATE_PLUGIN, - DEACTIVATE_PLUGIN, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE(XedPluginsEngine, xed_plugins_engine, G_TYPE_OBJECT) +G_DEFINE_TYPE (XedPluginsEngine, xed_plugins_engine, PEAS_TYPE_ENGINE) struct _XedPluginsEnginePrivate { - GList *plugin_list; - GHashTable *loaders; - - gboolean activate_from_prefs; + GSettings *plugin_settings; }; XedPluginsEngine *default_engine = NULL; -static void xed_plugins_engine_activate_plugin_real (XedPluginsEngine *engine, - XedPluginInfo *info); -static void xed_plugins_engine_deactivate_plugin_real (XedPluginsEngine *engine, - XedPluginInfo *info); - -typedef gboolean (*LoadDirCallback)(XedPluginsEngine *engine, const gchar *filename, gpointer userdata); - -static gboolean -load_dir_real (XedPluginsEngine *engine, - const gchar *dir, - const gchar *suffix, - LoadDirCallback callback, - gpointer userdata) -{ - GError *error = NULL; - GDir *d; - const gchar *dirent; - gboolean ret = TRUE; - - g_return_val_if_fail (dir != NULL, TRUE); - - xed_debug_message (DEBUG_PLUGINS, "DIR: %s", dir); - - d = g_dir_open (dir, 0, &error); - if (!d) - { - g_warning ("%s", error->message); - g_error_free (error); - return TRUE; - } - - while ((dirent = g_dir_read_name (d))) - { - gchar *filename; - - if (!g_str_has_suffix (dirent, suffix)) - continue; - - filename = g_build_filename (dir, dirent, NULL); - - ret = callback (engine, filename, userdata); - - g_free (filename); - - if (!ret) - break; - } - - g_dir_close (d); - return ret; -} - -static gboolean -load_plugin_info (XedPluginsEngine *engine, - const gchar *filename, - gpointer userdata) -{ - XedPluginInfo *info; - - info = _xed_plugin_info_new (filename); - - if (info == NULL) - return TRUE; - - /* If a plugin with this name has already been loaded - * drop this one (user plugins override system plugins) */ - if (xed_plugins_engine_get_plugin_info (engine, xed_plugin_info_get_module_name (info)) != NULL) - { - xed_debug_message (DEBUG_PLUGINS, "Two or more plugins named '%s'. " - "Only the first will be considered.\n", - xed_plugin_info_get_module_name (info)); - - _xed_plugin_info_unref (info); - - return TRUE; - } - - engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info); - - xed_debug_message (DEBUG_PLUGINS, "Plugin %s loaded", info->name); - return TRUE; -} - -static void -load_all_plugins (XedPluginsEngine *engine) -{ - gchar *plugin_dir; - const gchar *pdirs_env = NULL; - - /* load user plugins */ - plugin_dir = xed_dirs_get_user_plugins_dir (); - if (g_file_test (plugin_dir, G_FILE_TEST_IS_DIR)) - { - load_dir_real (engine, - plugin_dir, - PLUGIN_EXT, - load_plugin_info, - NULL); - - } - g_free (plugin_dir); - - /* load system plugins */ - pdirs_env = g_getenv ("XED_PLUGINS_PATH"); - - xed_debug_message (DEBUG_PLUGINS, "XED_PLUGINS_PATH=%s", pdirs_env); - - if (pdirs_env != NULL) - { - gchar **pdirs; - gint i; - - pdirs = g_strsplit (pdirs_env, G_SEARCHPATH_SEPARATOR_S, 0); - - for (i = 0; pdirs[i] != NULL; i++) - { - if (!load_dir_real (engine, - pdirs[i], - PLUGIN_EXT, - load_plugin_info, - NULL)) - { - break; - } - } - - g_strfreev (pdirs); - } - else - { - plugin_dir = xed_dirs_get_xed_plugins_dir (); - - load_dir_real (engine, - plugin_dir, - PLUGIN_EXT, - load_plugin_info, - NULL); - - g_free (plugin_dir); - } -} - -static guint -hash_lowercase (gconstpointer data) -{ - gchar *lowercase; - guint ret; - - lowercase = g_ascii_strdown ((const gchar *)data, -1); - ret = g_str_hash (lowercase); - g_free (lowercase); - - return ret; -} - -static gboolean -equal_lowercase (gconstpointer a, gconstpointer b) -{ - return g_ascii_strcasecmp ((const gchar *)a, (const gchar *)b) == 0; -} - -static void -loader_destroy (LoaderInfo *info) -{ - if (!info) - return; - - if (info->loader) - g_object_unref (info->loader); - - g_free (info); -} - -static void -add_loader (XedPluginsEngine *engine, - const gchar *loader_id, - XedObjectModule *module) -{ - LoaderInfo *info; - - info = g_new (LoaderInfo, 1); - info->loader = NULL; - info->module = module; - - g_hash_table_insert (engine->priv->loaders, g_strdup (loader_id), info); -} - static void xed_plugins_engine_init (XedPluginsEngine *engine) { - xed_debug (DEBUG_PLUGINS); + gchar *typelib_dir; + GError *error = NULL; - if (!g_module_supported ()) - { - g_warning ("xed is not able to initialize the plugins engine."); - return; - } + xed_debug (DEBUG_PLUGINS); - engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, - XED_TYPE_PLUGINS_ENGINE, - XedPluginsEnginePrivate); + engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, XED_TYPE_PLUGINS_ENGINE, XedPluginsEnginePrivate); - load_all_plugins (engine); + engine->priv->plugin_settings = g_settings_new ("org.x.editor.plugins"); - /* make sure that the first reactivation will read active plugins - from the prefs */ - engine->priv->activate_from_prefs = TRUE; + peas_engine_enable_loader (PEAS_ENGINE (engine), "python3"); - /* mapping from loadername -> loader object */ - engine->priv->loaders = g_hash_table_new_full (hash_lowercase, - equal_lowercase, - (GDestroyNotify)g_free, - (GDestroyNotify)loader_destroy); + typelib_dir = g_build_filename (xed_dirs_get_xed_lib_dir (), "girepository-1.0", NULL); + + if (!g_irepository_require_private (g_irepository_get_default (), typelib_dir, "Xed", "1.0", 0, &error)) + { + g_warning ("Could not load Xed repository: %s", error->message); + g_error_free (error); + error = NULL; + } + + g_free (typelib_dir); + + /* This should be moved to libpeas */ + if (!g_irepository_require (g_irepository_get_default (), "Peas", "1.0", 0, &error)) + { + g_warning ("Could not load Peas repository: %s", error->message); + g_error_free (error); + error = NULL; + } + + if (!g_irepository_require (g_irepository_get_default (), "PeasGtk", "1.0", 0, &error)) + { + g_warning ("Could not load PeasGtk repository: %s", error->message); + g_error_free (error); + error = NULL; + } + + // private_path = g_build_filename (LIBDIR, "girepository-1.0", NULL); + + // if (!g_irepository_require_private (g_irepository_get_default (), private_path, "Xed", "1.0", 0, &error)) + // { + // g_warning ("Could not load Xed repository: %s", error->message); + // g_error_free (error); + // error = NULL; + // } + + // g_free (private_path); + + peas_engine_add_search_path (PEAS_ENGINE (engine), + xed_dirs_get_user_plugins_dir (), + xed_dirs_get_user_plugins_dir ()); + + peas_engine_add_search_path (PEAS_ENGINE (engine), + xed_dirs_get_xed_plugins_dir(), + xed_dirs_get_xed_plugins_data_dir()); + + g_settings_bind (engine->priv->plugin_settings, + XED_SETTINGS_ACTIVE_PLUGINS, + engine, + "loaded-plugins", + G_SETTINGS_BIND_DEFAULT); } static void -loader_garbage_collect (const char *id, LoaderInfo *info) +xed_plugins_engine_dispose (GObject *object) { - if (info->loader) - xed_plugin_loader_garbage_collect (info->loader); -} + XedPluginsEngine *engine = XED_PLUGINS_ENGINE (object); -void -xed_plugins_engine_garbage_collect (XedPluginsEngine *engine) -{ - g_hash_table_foreach (engine->priv->loaders, - (GHFunc) loader_garbage_collect, - NULL); -} + if (engine->priv->plugin_settings != NULL) + { + g_object_unref (engine->priv->plugin_settings); + engine->priv->plugin_settings = NULL; + } -static void -xed_plugins_engine_finalize (GObject *object) -{ - XedPluginsEngine *engine = XED_PLUGINS_ENGINE (object); - GList *item; - - xed_debug (DEBUG_PLUGINS); - - /* Firs deactivate all plugins */ - for (item = engine->priv->plugin_list; item; item = item->next) - { - XedPluginInfo *info = XED_PLUGIN_INFO (item->data); - - if (xed_plugin_info_is_active (info)) - xed_plugins_engine_deactivate_plugin_real (engine, info); - } - - /* unref the loaders */ - g_hash_table_destroy (engine->priv->loaders); - - /* and finally free the infos */ - for (item = engine->priv->plugin_list; item; item = item->next) - { - XedPluginInfo *info = XED_PLUGIN_INFO (item->data); - - _xed_plugin_info_unref (info); - } - - g_list_free (engine->priv->plugin_list); - - G_OBJECT_CLASS (xed_plugins_engine_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_plugins_engine_parent_class)->dispose (object); } static void xed_plugins_engine_class_init (XedPluginsEngineClass *klass) { - GType the_type = G_TYPE_FROM_CLASS (klass); - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_plugins_engine_finalize; - klass->activate_plugin = xed_plugins_engine_activate_plugin_real; - klass->deactivate_plugin = xed_plugins_engine_deactivate_plugin_real; + object_class->dispose = xed_plugins_engine_dispose; - signals[ACTIVATE_PLUGIN] = - g_signal_new ("activate-plugin", - the_type, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedPluginsEngineClass, activate_plugin), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, - 1, - XED_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE); - - signals[DEACTIVATE_PLUGIN] = - g_signal_new ("deactivate-plugin", - the_type, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedPluginsEngineClass, deactivate_plugin), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, - 1, - XED_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE); - - g_type_class_add_private (klass, sizeof (XedPluginsEnginePrivate)); -} - -static gboolean -load_loader (XedPluginsEngine *engine, - const gchar *filename, - gpointer data) -{ - XedObjectModule *module; - gchar *base; - gchar *path; - const gchar *id; - GType type; - - /* try to load in the module */ - path = g_path_get_dirname (filename); - base = g_path_get_basename (filename); - - /* for now they are all resident */ - module = xed_object_module_new (base, - path, - "register_xed_plugin_loader", - TRUE); - - g_free (base); - g_free (path); - - /* make sure to load the type definition */ - if (!g_type_module_use (G_TYPE_MODULE (module))) - { - g_object_unref (module); - g_warning ("Plugin loader module `%s' could not be loaded", filename); - - return TRUE; - } - - /* get the exported type and check the name as exported by the - * loader interface */ - type = xed_object_module_get_object_type (module); - id = xed_plugin_loader_type_get_id (type); - - add_loader (engine, id, module); - g_type_module_unuse (G_TYPE_MODULE (module)); - - return TRUE; -} - -static void -ensure_loader (LoaderInfo *info) -{ - if (info->loader == NULL && info->module != NULL) - { - /* create a new loader object */ - XedPluginLoader *loader; - loader = (XedPluginLoader *)xed_object_module_new_object (info->module, NULL); - - if (loader == NULL || !XED_IS_PLUGIN_LOADER (loader)) - { - g_warning ("Loader object is not a valid XedPluginLoader instance"); - - if (loader != NULL && G_IS_OBJECT (loader)) - g_object_unref (loader); - } - else - { - info->loader = loader; - } - } -} - -static XedPluginLoader * -get_plugin_loader (XedPluginsEngine *engine, XedPluginInfo *info) -{ - const gchar *loader_id; - LoaderInfo *loader_info; - - loader_id = info->loader; - - loader_info = (LoaderInfo *)g_hash_table_lookup ( - engine->priv->loaders, - loader_id); - - if (loader_info == NULL) - { - gchar *loader_dir; - - loader_dir = xed_dirs_get_xed_plugin_loaders_dir (); - - /* loader could not be found in the hash, try to find it by - scanning */ - load_dir_real (engine, - loader_dir, - LOADER_EXT, - (LoadDirCallback)load_loader, - NULL); - g_free (loader_dir); - - loader_info = (LoaderInfo *)g_hash_table_lookup ( - engine->priv->loaders, - loader_id); - } - - if (loader_info == NULL) - { - /* cache non-existent so we don't scan again */ - add_loader (engine, loader_id, NULL); - return NULL; - } - - ensure_loader (loader_info); - return loader_info->loader; + g_type_class_add_private (klass, sizeof (XedPluginsEnginePrivate)); } XedPluginsEngine * xed_plugins_engine_get_default (void) { - if (default_engine != NULL) - return default_engine; + if (default_engine == NULL) + { + default_engine = XED_PLUGINS_ENGINE (g_object_new (XED_TYPE_PLUGINS_ENGINE, NULL)); + g_object_add_weak_pointer (G_OBJECT (default_engine), (gpointer) &default_engine); + } - default_engine = XED_PLUGINS_ENGINE (g_object_new (XED_TYPE_PLUGINS_ENGINE, NULL)); - g_object_add_weak_pointer (G_OBJECT (default_engine), - (gpointer) &default_engine); - return default_engine; -} - -const GList * -xed_plugins_engine_get_plugin_list (XedPluginsEngine *engine) -{ - xed_debug (DEBUG_PLUGINS); - - return engine->priv->plugin_list; -} - -static gint -compare_plugin_info_and_name (XedPluginInfo *info, - const gchar *module_name) -{ - return strcmp (xed_plugin_info_get_module_name (info), module_name); -} - -XedPluginInfo * -xed_plugins_engine_get_plugin_info (XedPluginsEngine *engine, - const gchar *name) -{ - GList *l = g_list_find_custom (engine->priv->plugin_list, - name, - (GCompareFunc) compare_plugin_info_and_name); - - return l == NULL ? NULL : (XedPluginInfo *) l->data; -} - -static void -save_active_plugin_list (XedPluginsEngine *engine) -{ - GSList *active_plugins = NULL; - GList *l; - - for (l = engine->priv->plugin_list; l != NULL; l = l->next) - { - XedPluginInfo *info = (XedPluginInfo *) l->data; - - if (xed_plugin_info_is_active (info)) - { - active_plugins = g_slist_prepend (active_plugins, - (gpointer)xed_plugin_info_get_module_name (info)); - } - } - - xed_prefs_manager_set_active_plugins (active_plugins); - - g_slist_free (active_plugins); -} - -static gboolean -load_plugin (XedPluginsEngine *engine, - XedPluginInfo *info) -{ - XedPluginLoader *loader; - gchar *path; - - if (xed_plugin_info_is_active (info)) - return TRUE; - - if (!xed_plugin_info_is_available (info)) - return FALSE; - - loader = get_plugin_loader (engine, info); - - if (loader == NULL) - { - g_warning ("Could not find loader `%s' for plugin `%s'", info->loader, info->name); - info->available = FALSE; - return FALSE; - } - - path = g_path_get_dirname (info->file); - g_return_val_if_fail (path != NULL, FALSE); - - info->plugin = xed_plugin_loader_load (loader, info, path); - - g_free (path); - - if (info->plugin == NULL) - { - g_warning ("Error loading plugin '%s'", info->name); - info->available = FALSE; - return FALSE; - } - - return TRUE; -} - -static void -xed_plugins_engine_activate_plugin_real (XedPluginsEngine *engine, - XedPluginInfo *info) -{ - const GList *wins; - - if (!load_plugin (engine, info)) - return; - - for (wins = xed_app_get_windows (xed_app_get_default ()); - wins != NULL; - wins = wins->next) - { - xed_plugin_activate (info->plugin, XED_WINDOW (wins->data)); - } -} - -gboolean -xed_plugins_engine_activate_plugin (XedPluginsEngine *engine, - XedPluginInfo *info) -{ - xed_debug (DEBUG_PLUGINS); - - g_return_val_if_fail (info != NULL, FALSE); - - if (!xed_plugin_info_is_available (info)) - return FALSE; - - if (xed_plugin_info_is_active (info)) - return TRUE; - - g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info); - - if (xed_plugin_info_is_active (info)) - save_active_plugin_list (engine); - - return xed_plugin_info_is_active (info); -} - -static void -call_plugin_deactivate (XedPlugin *plugin, - XedWindow *window) -{ - xed_plugin_deactivate (plugin, window); - - /* ensure update of ui manager, because we suspect it does something - with expected static strings in the type module (when unloaded the - strings don't exist anymore, and ui manager updates in an idle - func) */ - gtk_ui_manager_ensure_update (xed_window_get_ui_manager (window)); -} - -static void -xed_plugins_engine_deactivate_plugin_real (XedPluginsEngine *engine, - XedPluginInfo *info) -{ - const GList *wins; - XedPluginLoader *loader; - - if (!xed_plugin_info_is_active (info) || - !xed_plugin_info_is_available (info)) - return; - - for (wins = xed_app_get_windows (xed_app_get_default ()); - wins != NULL; - wins = wins->next) - { - call_plugin_deactivate (info->plugin, XED_WINDOW (wins->data)); - } - - /* first unref the plugin (the loader still has one) */ - g_object_unref (info->plugin); - - /* find the loader and tell it to gc and unload the plugin */ - loader = get_plugin_loader (engine, info); - - xed_plugin_loader_garbage_collect (loader); - xed_plugin_loader_unload (loader, info); - - info->plugin = NULL; -} - -gboolean -xed_plugins_engine_deactivate_plugin (XedPluginsEngine *engine, - XedPluginInfo *info) -{ - xed_debug (DEBUG_PLUGINS); - - g_return_val_if_fail (info != NULL, FALSE); - - if (!xed_plugin_info_is_active (info)) - return TRUE; - - g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info); - if (!xed_plugin_info_is_active (info)) - save_active_plugin_list (engine); - - return !xed_plugin_info_is_active (info); -} - -void -xed_plugins_engine_activate_plugins (XedPluginsEngine *engine, - XedWindow *window) -{ - GSList *active_plugins = NULL; - GList *pl; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (XED_IS_PLUGINS_ENGINE (engine)); - g_return_if_fail (XED_IS_WINDOW (window)); - - /* the first time, we get the 'active' plugins from GSettings */ - if (engine->priv->activate_from_prefs) - { - active_plugins = xed_prefs_manager_get_active_plugins (); - } - - for (pl = engine->priv->plugin_list; pl; pl = pl->next) - { - XedPluginInfo *info = (XedPluginInfo*)pl->data; - - if (engine->priv->activate_from_prefs && - g_slist_find_custom (active_plugins, - xed_plugin_info_get_module_name (info), - (GCompareFunc)strcmp) == NULL) - continue; - - /* If plugin is not active, don't try to activate/load it */ - if (!engine->priv->activate_from_prefs && - !xed_plugin_info_is_active (info)) - continue; - - if (load_plugin (engine, info)) - xed_plugin_activate (info->plugin, - window); - } - - if (engine->priv->activate_from_prefs) - { - g_slist_foreach (active_plugins, (GFunc) g_free, NULL); - g_slist_free (active_plugins); - engine->priv->activate_from_prefs = FALSE; - } - - xed_debug_message (DEBUG_PLUGINS, "End"); - - /* also call update_ui after activation */ - xed_plugins_engine_update_plugins_ui (engine, window); -} - -void -xed_plugins_engine_deactivate_plugins (XedPluginsEngine *engine, - XedWindow *window) -{ - GList *pl; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (XED_IS_PLUGINS_ENGINE (engine)); - g_return_if_fail (XED_IS_WINDOW (window)); - - for (pl = engine->priv->plugin_list; pl; pl = pl->next) - { - XedPluginInfo *info = (XedPluginInfo*)pl->data; - - /* check if the plugin is actually active */ - if (!xed_plugin_info_is_active (info)) - continue; - - /* call deactivate for the plugin for this window */ - xed_plugin_deactivate (info->plugin, window); - } - - xed_debug_message (DEBUG_PLUGINS, "End"); -} - -void -xed_plugins_engine_update_plugins_ui (XedPluginsEngine *engine, - XedWindow *window) -{ - GList *pl; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (XED_IS_PLUGINS_ENGINE (engine)); - g_return_if_fail (XED_IS_WINDOW (window)); - - /* call update_ui for all active plugins */ - for (pl = engine->priv->plugin_list; pl; pl = pl->next) - { - XedPluginInfo *info = (XedPluginInfo*)pl->data; - - if (!xed_plugin_info_is_active (info)) - continue; - - xed_debug_message (DEBUG_PLUGINS, "Updating UI of %s", info->name); - xed_plugin_update_ui (info->plugin, window); - } -} - -void -xed_plugins_engine_configure_plugin (XedPluginsEngine *engine, - XedPluginInfo *info, - GtkWindow *parent) -{ - GtkWidget *conf_dlg; - - GtkWindowGroup *wg; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (info != NULL); - - conf_dlg = xed_plugin_create_configure_dialog (info->plugin); - g_return_if_fail (conf_dlg != NULL); - gtk_window_set_transient_for (GTK_WINDOW (conf_dlg), - parent); - - wg = gtk_window_get_group (parent); - if (wg == NULL) - { - wg = gtk_window_group_new (); - gtk_window_group_add_window (wg, parent); - } - - gtk_window_group_add_window (wg, - GTK_WINDOW (conf_dlg)); - - gtk_window_set_modal (GTK_WINDOW (conf_dlg), TRUE); - gtk_widget_show (conf_dlg); -} - -void -xed_plugins_engine_active_plugins_changed (XedPluginsEngine *engine) -{ - gboolean to_activate; - GSList *active_plugins; - GList *pl; - - xed_debug (DEBUG_PLUGINS); - - active_plugins = xed_prefs_manager_get_active_plugins (); - - for (pl = engine->priv->plugin_list; pl; pl = pl->next) - { - XedPluginInfo *info = (XedPluginInfo*)pl->data; - - if (!xed_plugin_info_is_available (info)) - continue; - - to_activate = (g_slist_find_custom (active_plugins, - xed_plugin_info_get_module_name (info), - (GCompareFunc)strcmp) != NULL); - - if (!xed_plugin_info_is_active (info) && to_activate) - g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info); - else if (xed_plugin_info_is_active (info) && !to_activate) - g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info); - } - - g_slist_foreach (active_plugins, (GFunc) g_free, NULL); - g_slist_free (active_plugins); -} - -void -xed_plugins_engine_rescan_plugins (XedPluginsEngine *engine) -{ - xed_debug (DEBUG_PLUGINS); - - load_all_plugins (engine); + return default_engine; } diff --git a/xed/xed-plugins-engine.h b/xed/xed-plugins-engine.h index 1c567d6..f2a0c9a 100644 --- a/xed/xed-plugins-engine.h +++ b/xed/xed-plugins-engine.h @@ -2,7 +2,7 @@ * xed-plugins-engine.h * This file is part of xed * - * Copyright (C) 2002-2005 - Paolo Maggi + * Copyright (C) 2002-2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2002-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -32,9 +32,7 @@ #define __XED_PLUGINS_ENGINE_H__ #include -#include "xed-window.h" -#include "xed-plugin-info.h" -#include "xed-plugin.h" +#include G_BEGIN_DECLS @@ -45,62 +43,25 @@ G_BEGIN_DECLS #define XED_IS_PLUGINS_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PLUGINS_ENGINE)) #define XED_PLUGINS_ENGINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PLUGINS_ENGINE, XedPluginsEngineClass)) -typedef struct _XedPluginsEngine XedPluginsEngine; -typedef struct _XedPluginsEnginePrivate XedPluginsEnginePrivate; +typedef struct _XedPluginsEngine XedPluginsEngine; +typedef struct _XedPluginsEnginePrivate XedPluginsEnginePrivate; struct _XedPluginsEngine { - GObject parent; - XedPluginsEnginePrivate *priv; + PeasEngine parent; + XedPluginsEnginePrivate *priv; }; -typedef struct _XedPluginsEngineClass XedPluginsEngineClass; +typedef struct _XedPluginsEngineClass XedPluginsEngineClass; struct _XedPluginsEngineClass { - GObjectClass parent_class; - - void (* activate_plugin) (XedPluginsEngine *engine, - XedPluginInfo *info); - - void (* deactivate_plugin) (XedPluginsEngine *engine, - XedPluginInfo *info); + PeasEngineClass parent_class; }; -GType xed_plugins_engine_get_type (void) G_GNUC_CONST; +GType xed_plugins_engine_get_type (void) G_GNUC_CONST; -XedPluginsEngine *xed_plugins_engine_get_default (void); - -void xed_plugins_engine_garbage_collect (XedPluginsEngine *engine); - -const GList *xed_plugins_engine_get_plugin_list (XedPluginsEngine *engine); - -XedPluginInfo *xed_plugins_engine_get_plugin_info (XedPluginsEngine *engine, - const gchar *name); - -/* plugin load and unloading (overall, for all windows) */ -gboolean xed_plugins_engine_activate_plugin (XedPluginsEngine *engine, - XedPluginInfo *info); -gboolean xed_plugins_engine_deactivate_plugin (XedPluginsEngine *engine, - XedPluginInfo *info); - -void xed_plugins_engine_configure_plugin (XedPluginsEngine *engine, - XedPluginInfo *info, - GtkWindow *parent); - -/* plugin activation/deactivation per window, private to XedWindow */ -void xed_plugins_engine_activate_plugins (XedPluginsEngine *engine, - XedWindow *window); -void xed_plugins_engine_deactivate_plugins (XedPluginsEngine *engine, - XedWindow *window); -void xed_plugins_engine_update_plugins_ui (XedPluginsEngine *engine, - XedWindow *window); - -/* private for GSettings notification */ -void xed_plugins_engine_active_plugins_changed - (XedPluginsEngine *engine); - -void xed_plugins_engine_rescan_plugins (XedPluginsEngine *engine); +XedPluginsEngine *xed_plugins_engine_get_default (void); G_END_DECLS diff --git a/xed/xed-preferences-dialog.c b/xed/xed-preferences-dialog.c new file mode 100755 index 0000000..7045259 --- /dev/null +++ b/xed/xed-preferences-dialog.c @@ -0,0 +1,1174 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * xed-preferences-dialog.c + * This file is part of xed + * + * Copyright (C) 2001-2005 Paolo Maggi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* + * Modified by the xed Team, 2001-2003. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "xed-preferences-dialog.h" +#include "xed-utils.h" +#include "xed-debug.h" +#include "xed-document.h" +#include "xed-dirs.h" +#include "xed-settings.h" +#include "xed-utils.h" + +/* + * xed-preferences dialog is a singleton since we don't + * want two dialogs showing an inconsistent state of the + * preferences. + * When xed_show_preferences_dialog is called and there + * is already a prefs dialog dialog open, it is reparented + * and shown. + */ + +static GtkWidget *preferences_dialog = NULL; + + +enum +{ + ID_COLUMN = 0, + NAME_COLUMN, + DESC_COLUMN, + NUM_COLUMNS +}; + + +#define XED_PREFERENCES_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ + XED_TYPE_PREFERENCES_DIALOG, \ + XedPreferencesDialogPrivate)) + +struct _XedPreferencesDialogPrivate +{ + GSettings *editor; + GSettings *ui; + + GtkWidget *notebook; + + /* Font */ + GtkWidget *default_font_checkbutton; + GtkWidget *font_button; + GtkWidget *font_hbox; + + /* Style Scheme */ + GtkWidget *prefer_dark_theme_checkbutton; + GtkListStore *schemes_treeview_model; + GtkWidget *schemes_treeview; + GtkWidget *install_scheme_button; + GtkWidget *uninstall_scheme_button; + + GtkWidget *install_scheme_file_schooser; + + /* Tabs */ + GtkWidget *tabs_width_spinbutton; + GtkWidget *insert_spaces_checkbutton; + GtkWidget *tabs_width_hbox; + + /* Auto indentation */ + GtkWidget *auto_indent_checkbutton; + + /* Text Wrapping */ + GtkWidget *wrap_text_checkbutton; + GtkWidget *split_checkbutton; + + /* File Saving */ + GtkWidget *backup_copy_checkbutton; + GtkWidget *auto_save_checkbutton; + GtkWidget *auto_save_spinbutton; + GtkWidget *autosave_hbox; + + /* Line numbers */ + GtkWidget *display_line_numbers_checkbutton; + + /* Highlight current line */ + GtkWidget *highlight_current_line_checkbutton; + + /* Highlight matching bracket */ + GtkWidget *bracket_matching_checkbutton; + + /* Right margin */ + GtkWidget *right_margin_checkbutton; + GtkWidget *right_margin_position_spinbutton; + GtkWidget *right_margin_position_hbox; + + /* Tab scrolling */ + GtkWidget *tab_scrolling_checkbutton; + + /* Plugins manager */ + GtkWidget *plugin_manager_place_holder; + + /* Style Scheme editor dialog */ + GtkWidget *style_scheme_dialog; +}; + + +G_DEFINE_TYPE(XedPreferencesDialog, xed_preferences_dialog, GTK_TYPE_DIALOG) + +static void +xed_preferences_dialog_dispose (GObject *object) +{ + XedPreferencesDialog *dlg = XED_PREFERENCES_DIALOG (object); + + g_clear_object (&dlg->priv->editor); + g_clear_object (&dlg->priv->ui); + + G_OBJECT_CLASS (xed_preferences_dialog_parent_class)->dispose (object); +} + +static void +xed_preferences_dialog_class_init (XedPreferencesDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = xed_preferences_dialog_dispose; + + g_type_class_add_private (object_class, sizeof (XedPreferencesDialogPrivate)); +} + +static void +dialog_response_handler (GtkDialog *dlg, + gint res_id) +{ + xed_debug (DEBUG_PREFS); + + switch (res_id) + { + case GTK_RESPONSE_HELP: + xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-prefs"); + g_signal_stop_emission_by_name (dlg, "response"); + break; + default: + gtk_widget_destroy (GTK_WIDGET (dlg)); + } +} + +static void +on_auto_save_changed (GSettings *settings, + const gchar *key, + XedPreferencesDialog *dlg) +{ + gboolean value; + + xed_debug (DEBUG_PREFS); + + value = g_settings_get_boolean (settings, key); + + gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton, value); +} + +static void +setup_editor_page (XedPreferencesDialog *dlg) +{ + gboolean auto_save; + + xed_debug (DEBUG_PREFS); + + /* Get values */ + auto_save = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_AUTO_SAVE); + + /* Set widget sensitivity */ + gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton, auto_save); + + /* Connect signal */ + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_TABS_SIZE, + dlg->priv->tabs_width_spinbutton, + "value", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_INSERT_SPACES, + dlg->priv->insert_spaces_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_AUTO_INDENT, + dlg->priv->auto_indent_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_CREATE_BACKUP_COPY, + dlg->priv->backup_copy_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_BRACKET_MATCHING, + dlg->priv->bracket_matching_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_AUTO_SAVE_INTERVAL, + dlg->priv->auto_save_spinbutton, + "value", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_signal_connect (dlg->priv->editor, "changed::auto_save", + G_CALLBACK (on_auto_save_changed), dlg); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_AUTO_SAVE, + dlg->priv->auto_save_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->ui, + XED_SETTINGS_ENABLE_TAB_SCROLLING, + dlg->priv->tab_scrolling_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); +} + +static gboolean split_button_state = TRUE; + +static void +wrap_mode_checkbutton_toggled (GtkToggleButton *button, + XedPreferencesDialog *dlg) +{ + GtkWrapMode mode; + + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton))) + { + mode = GTK_WRAP_NONE; + + gtk_widget_set_sensitive (dlg->priv->split_checkbutton, FALSE); + gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE); + } + else + { + gtk_widget_set_sensitive (dlg->priv->split_checkbutton, TRUE); + gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), FALSE); + + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton))) + { + split_button_state = TRUE; + mode = GTK_WRAP_WORD; + } + else + { + split_button_state = FALSE; + mode = GTK_WRAP_CHAR; + } + } + + g_settings_set_enum (dlg->priv->editor, XED_SETTINGS_WRAP_MODE, mode); +} + +static void +right_margin_checkbutton_toggled (GtkToggleButton *button, + XedPreferencesDialog *dlg) +{ + gboolean active; + + g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->right_margin_checkbutton)); + + active = gtk_toggle_button_get_active (button); + + g_settings_set_boolean (dlg->priv->editor, XED_SETTINGS_DISPLAY_RIGHT_MARGIN, active); + + gtk_widget_set_sensitive (dlg->priv->right_margin_position_hbox, active); +} + +static void +setup_view_page (XedPreferencesDialog *dlg) +{ + GtkWrapMode wrap_mode; + gboolean display_right_margin; + + xed_debug (DEBUG_PREFS); + + /* Get values */ + display_right_margin = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_DISPLAY_RIGHT_MARGIN); + + /* Set initial state */ + wrap_mode = g_settings_get_enum (dlg->priv->editor, XED_SETTINGS_WRAP_MODE); + + switch (wrap_mode) + { + case GTK_WRAP_WORD: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE); + break; + case GTK_WRAP_CHAR: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), FALSE); + break; + default: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), FALSE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), split_button_state); + gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE); + + } + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->right_margin_checkbutton), display_right_margin); + + /* Set widgets sensitivity */ + gtk_widget_set_sensitive (dlg->priv->split_checkbutton, (wrap_mode != GTK_WRAP_NONE)); + gtk_widget_set_sensitive (dlg->priv->right_margin_position_hbox, display_right_margin); + + /* Connect signals */ + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_DISPLAY_LINE_NUMBERS, + dlg->priv->display_line_numbers_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_HIGHLIGHT_CURRENT_LINE, + dlg->priv->highlight_current_line_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_RIGHT_MARGIN_POSITION, + dlg->priv->right_margin_position_spinbutton, + "value", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_signal_connect (dlg->priv->wrap_text_checkbutton, "toggled", + G_CALLBACK (wrap_mode_checkbutton_toggled), dlg); + g_signal_connect (dlg->priv->split_checkbutton, "toggled", + G_CALLBACK (wrap_mode_checkbutton_toggled), dlg); + g_signal_connect (dlg->priv->right_margin_checkbutton, "toggled", + G_CALLBACK (right_margin_checkbutton_toggled), dlg); +} + +static void +on_use_default_font_changed (GSettings *settings, + const gchar *key, + XedPreferencesDialog *dlg) +{ + gboolean value; + + xed_debug (DEBUG_PREFS); + + value = g_settings_get_boolean (settings, key); + gtk_widget_set_sensitive (dlg->priv->font_hbox, !value); +} + +static void +setup_font_colors_page_font_section (XedPreferencesDialog *dlg) +{ + GObject *settings; + gboolean use_default_font; + gchar *system_font = NULL; + gchar *label; + + xed_debug (DEBUG_PREFS); + + gtk_widget_set_tooltip_text (dlg->priv->font_button, + _("Click on this button to select the font to be used by the editor")); + + xed_utils_set_atk_relation (dlg->priv->font_button, + dlg->priv->default_font_checkbutton, + ATK_RELATION_CONTROLLED_BY); + xed_utils_set_atk_relation (dlg->priv->default_font_checkbutton, + dlg->priv->font_button, + ATK_RELATION_CONTROLLER_FOR); + + /* Get values */ + settings = _xed_app_get_settings (XED_APP (g_application_get_default ())); + system_font = xed_settings_get_system_font (XED_SETTINGS (settings)); + use_default_font = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_USE_DEFAULT_FONT); + + label = g_strdup_printf(_("_Use the system fixed width font (%s)"), system_font); + gtk_button_set_label (GTK_BUTTON (dlg->priv->default_font_checkbutton), label); + g_free (system_font); + g_free (label); + + /* read current config and setup initial state */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->default_font_checkbutton), use_default_font); + + /* Connect signals */ + g_signal_connect (dlg->priv->editor, "changed::use-default-font", + G_CALLBACK (on_use_default_font_changed), dlg); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_USE_DEFAULT_FONT, + dlg->priv->default_font_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_EDITOR_FONT, + dlg->priv->font_button, + "font-name", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); + + /* Set initial widget sensitivity */ + gtk_widget_set_sensitive (dlg->priv->font_hbox, !use_default_font); +} + +static gboolean +is_xed_user_style_scheme (const gchar *scheme_id) +{ + GtkSourceStyleSchemeManager *manager; + GtkSourceStyleScheme *scheme; + gboolean res = FALSE; + + manager = gtk_source_style_scheme_manager_get_default (); + scheme = gtk_source_style_scheme_manager_get_scheme (manager, scheme_id); + if (scheme != NULL) + { + const gchar *filename; + + filename = gtk_source_style_scheme_get_filename (scheme); + if (filename != NULL) + { + res = g_str_has_prefix (filename, xed_dirs_get_user_styles_dir ()); + } + } + + return res; +} + +static void +set_buttons_sensisitivity_according_to_scheme (XedPreferencesDialog *dlg, + const gchar *scheme_id) +{ + gboolean editable; + + editable = ((scheme_id != NULL) && is_xed_user_style_scheme (scheme_id)); + + gtk_widget_set_sensitive (dlg->priv->uninstall_scheme_button, editable); +} + +static void +style_scheme_changed (GtkWidget *treeview, + XedPreferencesDialog *dlg) +{ + GtkTreePath *path; + GtkTreeIter iter; + gchar *id; + + gtk_tree_view_get_cursor (GTK_TREE_VIEW (dlg->priv->schemes_treeview), &path, NULL); + gtk_tree_model_get_iter (GTK_TREE_MODEL (dlg->priv->schemes_treeview_model), &iter, path); + gtk_tree_path_free (path); + gtk_tree_model_get (GTK_TREE_MODEL (dlg->priv->schemes_treeview_model), &iter, ID_COLUMN, &id, -1); + + g_settings_set_string (dlg->priv->editor, XED_SETTINGS_SCHEME, id); + + set_buttons_sensisitivity_according_to_scheme (dlg, id); + + g_free (id); +} + +static const gchar * +ensure_color_scheme_id (XedPreferencesDialog *dlg, + const gchar *id) +{ + GtkSourceStyleSchemeManager *manager; + GtkSourceStyleScheme *scheme = NULL; + + manager = gtk_source_style_scheme_manager_get_default (); + if (id == NULL) + { + gchar *pref_id; + + pref_id = g_settings_get_string (dlg->priv->editor, XED_SETTINGS_SCHEME); + scheme = gtk_source_style_scheme_manager_get_scheme (manager, pref_id); + g_free (pref_id); + } + else + { + scheme = gtk_source_style_scheme_manager_get_scheme (manager, id); + } + + if (scheme == NULL) + { + /* Fall-back to classic style scheme */ + scheme = gtk_source_style_scheme_manager_get_scheme (manager, "classic"); + } + + if (scheme == NULL) + { + /* Cannot determine default style scheme -> broken GtkSourceView installation */ + return NULL; + } + + return gtk_source_style_scheme_get_id (scheme); +} + +static const gchar * +populate_color_scheme_list (XedPreferencesDialog *dlg, + const gchar *def_id) +{ + GtkSourceStyleSchemeManager *manager; + const gchar * const *ids; + gint i; + + gtk_list_store_clear (dlg->priv->schemes_treeview_model); + + def_id = ensure_color_scheme_id (dlg, def_id); + if (def_id == NULL) + { + g_warning ("Cannot build the list of available color schemes.\n" + "Please check your GtkSourceView installation."); + return NULL; + } + + manager = gtk_source_style_scheme_manager_get_default (); + ids = gtk_source_style_scheme_manager_get_scheme_ids (manager); + for (i = 0; ids[i] != NULL; i++) + { + GtkSourceStyleScheme *scheme; + const gchar *name; + const gchar *description; + GtkTreeIter iter; + + scheme = gtk_source_style_scheme_manager_get_scheme (manager, ids[i]); + name = gtk_source_style_scheme_get_name (scheme); + description = gtk_source_style_scheme_get_description (scheme); + + gtk_list_store_append (dlg->priv->schemes_treeview_model, &iter); + gtk_list_store_set (dlg->priv->schemes_treeview_model, + &iter, + ID_COLUMN, ids[i], + NAME_COLUMN, name, + DESC_COLUMN, description, + -1); + + g_return_val_if_fail (def_id != NULL, NULL); + if (strcmp (ids[i], def_id) == 0) + { + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview)); + gtk_tree_selection_select_iter (selection, &iter); + } + } + + return def_id; +} + +/* + * file_copy: + * @name: a pointer to a %NULL-terminated string, that names + * the file to be copied, in the GLib file name encoding + * @dest_name: a pointer to a %NULL-terminated string, that is the + * name for the destination file, in the GLib file name encoding + * @error: return location for a #GError, or %NULL + * + * Copies file @name to @dest_name. + * + * If the call was successful, it returns %TRUE. If the call was not + * successful, it returns %FALSE and sets @error. The error domain + * is #G_FILE_ERROR. Possible error + * codes are those in the #GFileError enumeration. + * + * Return value: %TRUE on success, %FALSE otherwise. + */ +static gboolean +file_copy (const gchar *name, + const gchar *dest_name, + GError **error) +{ + gchar *contents; + gsize length; + gchar *dest_dir; + + /* FIXME - Paolo (Aug. 13, 2007): + * Since the style scheme files are relatively small, we can implement + * file copy getting all the content of the source file in a buffer and + * then write the content to the destination file. In this way we + * can use the g_file_get_contents and g_file_set_contents and avoid to + * write custom code to copy the file (with sane error management). + * If needed we can improve this code later. */ + + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (dest_name != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* Note: we allow to copy a file to itself since this is not a problem + * in our use case */ + + /* Ensure the destination directory exists */ + dest_dir = g_path_get_dirname (dest_name); + + errno = 0; + if (g_mkdir_with_parents (dest_dir, 0755) != 0) + { + gint save_errno = errno; + gchar *display_filename = g_filename_display_name (dest_dir); + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Directory '%s' could not be created: g_mkdir_with_parents() failed: %s"), + display_filename, + g_strerror (save_errno)); + + g_free (dest_dir); + g_free (display_filename); + + return FALSE; + } + + g_free (dest_dir); + + if (!g_file_get_contents (name, &contents, &length, error)) + { + return FALSE; + } + + if (!g_file_set_contents (dest_name, contents, length, error)) + { + return FALSE; + } + + g_free (contents); + + return TRUE; +} + +/* + * install_style_scheme: + * @manager: a #GtkSourceStyleSchemeManager + * @fname: the file name of the style scheme to be installed + * + * Install a new user scheme. + * This function copies @fname in #XED_STYLES_DIR and ask the style manager to + * recompute the list of available style schemes. It then checks if a style + * scheme with the right file name exists. + * + * If the call was succesful, it returns the id of the installed scheme + * otherwise %NULL. + * + * Return value: the id of the installed scheme, %NULL otherwise. + */ +static const gchar * +install_style_scheme (const gchar *fname) +{ + GtkSourceStyleSchemeManager *manager; + gchar *new_file_name = NULL; + gchar *dirname; + const gchar *styles_dir; + GError *error = NULL; + gboolean copied = FALSE; + const gchar* const *ids; + + g_return_val_if_fail (fname != NULL, NULL); + + manager = gtk_source_style_scheme_manager_get_default (); + + dirname = g_path_get_dirname (fname); + styles_dir = xed_dirs_get_user_styles_dir (); + + if (strcmp (dirname, styles_dir) != 0) + { + gchar *basename; + + basename = g_path_get_basename (fname); + new_file_name = g_build_filename (styles_dir, basename, NULL); + g_free (basename); + + /* Copy the style scheme file into GEDIT_STYLES_DIR */ + if (!file_copy (fname, new_file_name, &error)) + { + g_free (new_file_name); + + g_message ("Cannot install style scheme:\n%s", error->message); + + return NULL; + } + + copied = TRUE; + } + else + { + new_file_name = g_strdup (fname); + } + + g_free (dirname); + + /* Reload the available style schemes */ + gtk_source_style_scheme_manager_force_rescan (manager); + + /* Check the new style scheme has been actually installed */ + ids = gtk_source_style_scheme_manager_get_scheme_ids (manager); + + while (*ids != NULL) + { + GtkSourceStyleScheme *scheme; + const gchar *filename; + + scheme = gtk_source_style_scheme_manager_get_scheme (manager, *ids); + + filename = gtk_source_style_scheme_get_filename (scheme); + + if (filename && (strcmp (filename, new_file_name) == 0)) + { + /* The style scheme has been correctly installed */ + g_free (new_file_name); + + return gtk_source_style_scheme_get_id (scheme); + } + ++ids; + } + + /* The style scheme has not been correctly installed */ + if (copied) + { + g_unlink (new_file_name); + } + + g_free (new_file_name); + + return NULL; +} + +/** + * uninstall_style_scheme: + * @manager: a #GtkSourceStyleSchemeManager + * @id: the id of the style scheme to be uninstalled + * + * Uninstall a user scheme. + * + * If the call was succesful, it returns %TRUE + * otherwise %FALSE. + * + * Return value: %TRUE on success, %FALSE otherwise. + */ +static gboolean +uninstall_style_scheme (const gchar *id) +{ + GtkSourceStyleSchemeManager *manager; + GtkSourceStyleScheme *scheme; + const gchar *filename; + + g_return_val_if_fail (id != NULL, FALSE); + + manager = gtk_source_style_scheme_manager_get_default (); + + scheme = gtk_source_style_scheme_manager_get_scheme (manager, id); + if (scheme == NULL) + { + return FALSE; + } + + filename = gtk_source_style_scheme_get_filename (scheme); + if (filename == NULL) + { + return FALSE; + } + + if (g_unlink (filename) == -1) + { + return FALSE; + } + + /* Reload the available style schemes */ + gtk_source_style_scheme_manager_force_rescan (manager); + + return TRUE; +} + +static void +add_scheme_chooser_response_cb (GtkDialog *chooser, + gint res_id, + XedPreferencesDialog *dlg) +{ + gchar* filename; + const gchar *scheme_id; + + if (res_id != GTK_RESPONSE_ACCEPT) + { + gtk_widget_hide (GTK_WIDGET (chooser)); + return; + } + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); + if (filename == NULL) + { + return; + } + + gtk_widget_hide (GTK_WIDGET (chooser)); + + scheme_id = install_style_scheme (filename); + g_free (filename); + + if (scheme_id == NULL) + { + xed_warning (GTK_WINDOW (dlg), _("The selected color scheme cannot be installed.")); + return; + } + + g_settings_set_string (dlg->priv->editor, XED_SETTINGS_SCHEME, scheme_id); + + scheme_id = populate_color_scheme_list (dlg, scheme_id); + + set_buttons_sensisitivity_according_to_scheme (dlg, scheme_id); +} + +static void +install_scheme_clicked (GtkButton *button, + XedPreferencesDialog *dlg) +{ + GtkWidget *chooser; + GtkFileFilter *filter; + + if (dlg->priv->install_scheme_file_schooser != NULL) + { + gtk_window_present (GTK_WINDOW (dlg->priv->install_scheme_file_schooser)); + gtk_widget_grab_focus (dlg->priv->install_scheme_file_schooser); + return; + } + + chooser = gtk_file_chooser_dialog_new (_("Add Scheme"), + GTK_WINDOW (dlg), + GTK_FILE_CHOOSER_ACTION_OPEN, + _("Cancel"), GTK_RESPONSE_CANCEL, + NULL); + + gtk_dialog_add_button (GTK_DIALOG (chooser), _("Add Scheme"), GTK_RESPONSE_ACCEPT); + + gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE); + + /* Filters */ + filter = gtk_file_filter_new (); + gtk_file_filter_set_name (filter, _("Color Scheme Files")); + gtk_file_filter_add_pattern (filter, "*.xml"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter); + + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter); + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name (filter, _("All Files")); + gtk_file_filter_add_pattern (filter, "*"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter); + + gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT); + + g_signal_connect (chooser, "response", + G_CALLBACK (add_scheme_chooser_response_cb), dlg); + + dlg->priv->install_scheme_file_schooser = chooser; + + g_object_add_weak_pointer (G_OBJECT (chooser), (gpointer) &dlg->priv->install_scheme_file_schooser); + + gtk_widget_show (chooser); +} + +static void +uninstall_scheme_clicked (GtkButton *button, + XedPreferencesDialog *dlg) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview)); + model = GTK_TREE_MODEL (dlg->priv->schemes_treeview_model); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + gchar *id; + gchar *name; + + gtk_tree_model_get (model, &iter, ID_COLUMN, &id, NAME_COLUMN, &name, -1); + + if (!uninstall_style_scheme (id)) + { + xed_warning (GTK_WINDOW (dlg), _("Could not remove color scheme \"%s\"."), name); + } + else + { + const gchar *real_new_id; + gchar *new_id = NULL; + GtkTreePath *path; + GtkTreeIter new_iter; + gboolean new_iter_set = FALSE; + + /* If the removed style scheme is the last of the list, + * set as new default style scheme the previous one, + * otherwise set the next one. + * To make this possible, we need to get the id of the + * new default style scheme before re-populating the list. + * Fall back to "classic" if it is not possible to get + * the id + */ + path = gtk_tree_model_get_path (model, &iter); + + /* Try to move to the next path */ + gtk_tree_path_next (path); + if (!gtk_tree_model_get_iter (model, &new_iter, path)) + { + /* It seems the removed style scheme was the + * last of the list. Try to move to the + * previous one */ + gtk_tree_path_free (path); + + path = gtk_tree_model_get_path (model, &iter); + + gtk_tree_path_prev (path); + if (gtk_tree_model_get_iter (model, &new_iter, path)) + { + new_iter_set = TRUE; + } + } + else + { + new_iter_set = TRUE; + } + + gtk_tree_path_free (path); + + if (new_iter_set) + { + gtk_tree_model_get (model, &new_iter, ID_COLUMN, &new_id, -1); + } + + real_new_id = populate_color_scheme_list (dlg, new_id); + g_free (new_id); + + set_buttons_sensisitivity_according_to_scheme (dlg, real_new_id); + + if (real_new_id != NULL) + { + g_settings_set_string (dlg->priv->editor, XED_SETTINGS_SCHEME, real_new_id); + } + } + + g_free (id); + g_free (name); + } +} + +static void +scheme_description_cell_data_func (GtkTreeViewColumn *column, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + gchar *name; + gchar *desc; + gchar *text; + + gtk_tree_model_get (model, iter, NAME_COLUMN, &name, DESC_COLUMN, &desc, -1); + + if (desc != NULL) + { + text = g_markup_printf_escaped ("%s - %s", name, desc); + } + else + { + text = g_markup_printf_escaped ("%s", name); + } + + g_free (name); + g_free (desc); + + g_object_set (G_OBJECT (renderer), "markup", text, NULL); + + g_free (text); +} + +static void +setup_font_colors_page_style_scheme_section (XedPreferencesDialog *dlg) +{ + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *selection; + const gchar *def_id; + + xed_debug (DEBUG_PREFS); + + /* Create GtkListStore for styles & setup treeview. */ + dlg->priv->schemes_treeview_model = gtk_list_store_new (NUM_COLUMNS, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (dlg->priv->schemes_treeview_model), + 0, GTK_SORT_ASCENDING); + gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->schemes_treeview), + GTK_TREE_MODEL (dlg->priv->schemes_treeview_model)); + + column = gtk_tree_view_column_new (); + + renderer = gtk_cell_renderer_text_new (); + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_cell_data_func (column, + renderer, + scheme_description_cell_data_func, + dlg, + NULL); + + gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->schemes_treeview), column); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + + def_id = populate_color_scheme_list (dlg, NULL); + + /* Connect signals */ + g_signal_connect (dlg->priv->schemes_treeview, "cursor-changed", + G_CALLBACK (style_scheme_changed), dlg); + g_signal_connect (dlg->priv->install_scheme_button, "clicked", + G_CALLBACK (install_scheme_clicked), dlg); + g_signal_connect (dlg->priv->uninstall_scheme_button, "clicked", + G_CALLBACK (uninstall_scheme_clicked), dlg); + + /* Set initial widget sensitivity */ + set_buttons_sensisitivity_according_to_scheme (dlg, def_id); +} + +static void +setup_font_colors_page (XedPreferencesDialog *dlg) +{ + setup_font_colors_page_font_section (dlg); + setup_font_colors_page_style_scheme_section (dlg); + + g_settings_bind (dlg->priv->editor, + XED_SETTINGS_PREFER_DARK_THEME, + dlg->priv->prefer_dark_theme_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); +} + +static void +setup_plugins_page (XedPreferencesDialog *dlg) +{ + GtkWidget *page_content; + + xed_debug (DEBUG_PREFS); + + page_content = peas_gtk_plugin_manager_new (NULL); + g_return_if_fail (page_content != NULL); + + gtk_box_pack_start (GTK_BOX (dlg->priv->plugin_manager_place_holder), page_content, TRUE, TRUE, 0); + + gtk_widget_show_all (page_content); +} + +static void +xed_preferences_dialog_init (XedPreferencesDialog *dlg) +{ + GtkBuilder *builder; + gchar *root_objects[] = { + "notebook", + "adjustment1", + "adjustment2", + "adjustment3", + NULL + }; + + xed_debug (DEBUG_PREFS); + + dlg->priv = XED_PREFERENCES_DIALOG_GET_PRIVATE (dlg); + dlg->priv->editor = g_settings_new ("org.x.editor.preferences.editor"); + dlg->priv->ui = g_settings_new ("org.x.editor.preferences.ui"); + + gtk_dialog_add_buttons (GTK_DIALOG (dlg), + _("Close"), GTK_RESPONSE_CLOSE, + _("Help"), GTK_RESPONSE_HELP, + NULL); + + gtk_window_set_title (GTK_WINDOW (dlg), _("Xed Preferences")); + gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE); + gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE); + + /* HIG defaults */ + gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), 2); /* 2 * 5 + 2 = 12 */ + gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 5); + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 6); + + g_signal_connect (dlg, "response", + G_CALLBACK (dialog_response_handler), NULL); + + builder = gtk_builder_new (); + gtk_builder_add_objects_from_resource (builder, "/org/x/editor/ui/xed-preferences-dialog.ui", root_objects, NULL); + dlg->priv->notebook = GTK_WIDGET (gtk_builder_get_object (builder, "notebook")); + g_object_ref (dlg->priv->notebook); + dlg->priv->display_line_numbers_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "display_line_numbers_checkbutton")); + dlg->priv->highlight_current_line_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "highlight_current_line_checkbutton")); + dlg->priv->bracket_matching_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "bracket_matching_checkbutton")); + dlg->priv->wrap_text_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "wrap_text_checkbutton")); + dlg->priv->split_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "split_checkbutton")); + dlg->priv->right_margin_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "right_margin_checkbutton")); + dlg->priv->right_margin_position_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "right_margin_position_spinbutton")); + dlg->priv->right_margin_position_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "right_margin_position_hbox")); + dlg->priv->tabs_width_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "tabs_width_spinbutton")); + dlg->priv->tabs_width_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "tabs_width_hbox")); + dlg->priv->insert_spaces_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "insert_spaces_checkbutton")); + dlg->priv->auto_indent_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "auto_indent_checkbutton")); + dlg->priv->autosave_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "autosave_hbox")); + dlg->priv->backup_copy_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "backup_copy_checkbutton")); + dlg->priv->auto_save_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "auto_save_checkbutton")); + dlg->priv->auto_save_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "auto_save_spinbutton")); + dlg->priv->tab_scrolling_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "tab_scrolling_checkbutton")); + dlg->priv->default_font_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "default_font_checkbutton")); + dlg->priv->font_button = GTK_WIDGET (gtk_builder_get_object (builder, "font_button")); + dlg->priv->font_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "font_hbox")); + dlg->priv->prefer_dark_theme_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "prefer_dark_theme_checkbutton")); + dlg->priv->schemes_treeview = GTK_WIDGET (gtk_builder_get_object (builder, "schemes_treeview")); + dlg->priv->install_scheme_button = GTK_WIDGET (gtk_builder_get_object (builder, "install_scheme_button")); + dlg->priv->uninstall_scheme_button = GTK_WIDGET (gtk_builder_get_object (builder, "uninstall_scheme_button")); + dlg->priv->plugin_manager_place_holder = GTK_WIDGET (gtk_builder_get_object (builder, "plugin_manager_place_holder")); + g_object_unref (builder); + + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), dlg->priv->notebook, FALSE, FALSE, 0); + g_object_unref (dlg->priv->notebook); + gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->notebook), 5); + + setup_editor_page (dlg); + setup_view_page (dlg); + setup_font_colors_page (dlg); + setup_plugins_page (dlg); +} + +void +xed_show_preferences_dialog (XedWindow *parent) +{ + xed_debug (DEBUG_PREFS); + + g_return_if_fail (XED_IS_WINDOW (parent)); + + if (preferences_dialog == NULL) + { + preferences_dialog = GTK_WIDGET (g_object_new (XED_TYPE_PREFERENCES_DIALOG, NULL)); + g_signal_connect (preferences_dialog, "destroy", + G_CALLBACK (gtk_widget_destroyed), &preferences_dialog); + } + + if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (preferences_dialog))) + { + gtk_window_set_transient_for (GTK_WINDOW (preferences_dialog), GTK_WINDOW (parent)); + } + + gtk_window_present (GTK_WINDOW (preferences_dialog)); +} diff --git a/xed/dialogs/xed-preferences-dialog.h b/xed/xed-preferences-dialog.h similarity index 100% rename from xed/dialogs/xed-preferences-dialog.h rename to xed/xed-preferences-dialog.h diff --git a/xed/xed-prefs-manager-app.c b/xed/xed-prefs-manager-app.c deleted file mode 100644 index bdeddb6..0000000 --- a/xed/xed-prefs-manager-app.c +++ /dev/null @@ -1,1414 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-prefs-manager.c - * This file is part of xed - * - * Copyright (C) 2002-2005 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2003. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include -#include "xed-prefs-manager.h" -#include "xed-prefs-manager-private.h" -#include "xed-prefs-manager-app.h" -#include "xed-app.h" -#include "xed-debug.h" -#include "xed-view.h" -#include "xed-window.h" -#include "xed-window-private.h" -#include "xed-plugins-engine.h" -#include "xed-style-scheme-manager.h" -#include "xed-dirs.h" - -static void xed_prefs_manager_editor_font_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_system_font_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_tabs_size_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_wrap_mode_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_line_numbers_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_auto_indent_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_undo_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_right_margin_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_smart_home_end_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_hl_current_line_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_bracket_matching_changed(GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_syntax_hl_enable_changed(GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_search_hl_enable_changed(GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_source_style_scheme_changed(GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_max_recents_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_auto_save_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -static void xed_prefs_manager_active_plugins_changed (GSettings *settings, - gchar *key, - gpointer user_data); - -/* GUI state is serialized to a .desktop file, not in GSettings */ - -#define XED_STATE_DEFAULT_WINDOW_STATE 0 -#define XED_STATE_DEFAULT_WINDOW_WIDTH 650 -#define XED_STATE_DEFAULT_WINDOW_HEIGHT 500 -#define XED_STATE_DEFAULT_SIDE_PANEL_SIZE 200 -#define XED_STATE_DEFAULT_BOTTOM_PANEL_SIZE 140 - -#define XED_STATE_FILE_LOCATION "xed.ini" - -#define XED_STATE_WINDOW_GROUP "window" -#define XED_STATE_WINDOW_STATE "state" -#define XED_STATE_WINDOW_HEIGHT "height" -#define XED_STATE_WINDOW_WIDTH "width" -#define XED_STATE_SIDE_PANEL_SIZE "side_panel_size" -#define XED_STATE_BOTTOM_PANEL_SIZE "bottom_panel_size" -#define XED_STATE_SIDE_PANEL_ACTIVE_PAGE "side_panel_active_page" -#define XED_STATE_BOTTOM_PANEL_ACTIVE_PAGE "bottom_panel_active_page" - -#define XED_STATE_FILEFILTER_GROUP "filefilter" -#define XED_STATE_FILEFILTER_ID "id" - -static gint window_state = -1; -static gint window_height = -1; -static gint window_width = -1; -static gint side_panel_size = -1; -static gint bottom_panel_size = -1; -static gint side_panel_active_page = -1; -static gint bottom_panel_active_page = -1; -static gint active_file_filter = -1; - - -static gchar * -get_state_filename (void) -{ - gchar *config_dir; - gchar *filename = NULL; - - config_dir = xed_dirs_get_user_config_dir (); - - if (config_dir != NULL) - { - filename = g_build_filename (config_dir, - XED_STATE_FILE_LOCATION, - NULL); - g_free (config_dir); - } - - return filename; -} - -static GKeyFile * -get_xed_state_file (void) -{ - static GKeyFile *state_file = NULL; - - if (state_file == NULL) - { - gchar *filename; - GError *err = NULL; - - state_file = g_key_file_new (); - - filename = get_state_filename (); - - if (!g_key_file_load_from_file (state_file, - filename, - G_KEY_FILE_NONE, - &err)) - { - if (err->domain != G_FILE_ERROR || - err->code != G_FILE_ERROR_NOENT) - { - g_warning ("Could not load xed state file: %s\n", - err->message); - } - - g_error_free (err); - } - - g_free (filename); - } - - return state_file; -} - -static void -xed_state_get_int (const gchar *group, - const gchar *key, - gint defval, - gint *result) -{ - GKeyFile *state_file; - gint res; - GError *err = NULL; - - state_file = get_xed_state_file (); - res = g_key_file_get_integer (state_file, - group, - key, - &err); - - if (err != NULL) - { - if ((err->domain != G_KEY_FILE_ERROR) || - ((err->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND && - err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND))) - { - g_warning ("Could not get state value %s::%s : %s\n", - group, - key, - err->message); - } - - *result = defval; - g_error_free (err); - } - else - { - *result = res; - } -} - -static void -xed_state_set_int (const gchar *group, - const gchar *key, - gint value) -{ - GKeyFile *state_file; - - state_file = get_xed_state_file (); - g_key_file_set_integer (state_file, - group, - key, - value); -} - -static gboolean -xed_state_file_sync (void) -{ - GKeyFile *state_file; - gchar *config_dir; - gchar *filename = NULL; - gchar *content = NULL; - gsize length; - gint res; - GError *err = NULL; - gboolean ret = FALSE; - - state_file = get_xed_state_file (); - g_return_val_if_fail (state_file != NULL, FALSE); - - config_dir = xed_dirs_get_user_config_dir (); - if (config_dir == NULL) - { - g_warning ("Could not get config directory\n"); - return ret; - } - - res = g_mkdir_with_parents (config_dir, 0755); - if (res < 0) - { - g_warning ("Could not create config directory\n"); - goto out; - } - - content = g_key_file_to_data (state_file, - &length, - &err); - - if (err != NULL) - { - g_warning ("Could not get data from state file: %s\n", - err->message); - goto out; - } - - if (content != NULL) - { - filename = get_state_filename (); - if (!g_file_set_contents (filename, - content, - length, - &err)) - { - g_warning ("Could not write xed state file: %s\n", - err->message); - goto out; - } - } - - ret = TRUE; - - out: - if (err != NULL) - g_error_free (err); - - g_free (config_dir); - g_free (filename); - g_free (content); - - return ret; -} - -/* Window state */ -gint -xed_prefs_manager_get_window_state (void) -{ - if (window_state == -1) - { - xed_state_get_int (XED_STATE_WINDOW_GROUP, - XED_STATE_WINDOW_STATE, - XED_STATE_DEFAULT_WINDOW_STATE, - &window_state); - } - - return window_state; -} - -void -xed_prefs_manager_set_window_state (gint ws) -{ - g_return_if_fail (ws > -1); - - window_state = ws; - - xed_state_set_int (XED_STATE_WINDOW_GROUP, - XED_STATE_WINDOW_STATE, - ws); -} - -gboolean -xed_prefs_manager_window_state_can_set (void) -{ - return TRUE; -} - -/* Window size */ -void -xed_prefs_manager_get_window_size (gint *width, gint *height) -{ - g_return_if_fail (width != NULL && height != NULL); - - if (window_width == -1) - { - xed_state_get_int (XED_STATE_WINDOW_GROUP, - XED_STATE_WINDOW_WIDTH, - XED_STATE_DEFAULT_WINDOW_WIDTH, - &window_width); - } - - if (window_height == -1) - { - xed_state_get_int (XED_STATE_WINDOW_GROUP, - XED_STATE_WINDOW_HEIGHT, - XED_STATE_DEFAULT_WINDOW_HEIGHT, - &window_height); - } - - *width = window_width; - *height = window_height; -} - -void -xed_prefs_manager_get_default_window_size (gint *width, gint *height) -{ - g_return_if_fail (width != NULL && height != NULL); - - *width = XED_STATE_DEFAULT_WINDOW_WIDTH; - *height = XED_STATE_DEFAULT_WINDOW_HEIGHT; -} - -void -xed_prefs_manager_set_window_size (gint width, gint height) -{ - g_return_if_fail (width > -1 && height > -1); - - window_width = width; - window_height = height; - - xed_state_set_int (XED_STATE_WINDOW_GROUP, - XED_STATE_WINDOW_WIDTH, - width); - xed_state_set_int (XED_STATE_WINDOW_GROUP, - XED_STATE_WINDOW_HEIGHT, - height); -} - -gboolean -xed_prefs_manager_window_size_can_set (void) -{ - return TRUE; -} - -/* Side panel */ -gint -xed_prefs_manager_get_side_panel_size (void) -{ - if (side_panel_size == -1) - { - xed_state_get_int (XED_STATE_WINDOW_GROUP, - XED_STATE_SIDE_PANEL_SIZE, - XED_STATE_DEFAULT_SIDE_PANEL_SIZE, - &side_panel_size); - } - - return side_panel_size; -} - -gint -xed_prefs_manager_get_default_side_panel_size (void) -{ - return XED_STATE_DEFAULT_SIDE_PANEL_SIZE; -} - -void -xed_prefs_manager_set_side_panel_size (gint ps) -{ - g_return_if_fail (ps > -1); - - if (side_panel_size == ps) - return; - - side_panel_size = ps; - xed_state_set_int (XED_STATE_WINDOW_GROUP, - XED_STATE_SIDE_PANEL_SIZE, - ps); -} - -gboolean -xed_prefs_manager_side_panel_size_can_set (void) -{ - return TRUE; -} - -gint -xed_prefs_manager_get_side_panel_active_page (void) -{ - if (side_panel_active_page == -1) - { - xed_state_get_int (XED_STATE_WINDOW_GROUP, - XED_STATE_SIDE_PANEL_ACTIVE_PAGE, - 0, - &side_panel_active_page); - } - - return side_panel_active_page; -} - -void -xed_prefs_manager_set_side_panel_active_page (gint id) -{ - if (side_panel_active_page == id) - return; - - side_panel_active_page = id; - xed_state_set_int (XED_STATE_WINDOW_GROUP, - XED_STATE_SIDE_PANEL_ACTIVE_PAGE, - id); -} - -gboolean -xed_prefs_manager_side_panel_active_page_can_set (void) -{ - return TRUE; -} - -/* Bottom panel */ -gint -xed_prefs_manager_get_bottom_panel_size (void) -{ - if (bottom_panel_size == -1) - { - xed_state_get_int (XED_STATE_WINDOW_GROUP, - XED_STATE_BOTTOM_PANEL_SIZE, - XED_STATE_DEFAULT_BOTTOM_PANEL_SIZE, - &bottom_panel_size); - } - - return bottom_panel_size; -} - -gint -xed_prefs_manager_get_default_bottom_panel_size (void) -{ - return XED_STATE_DEFAULT_BOTTOM_PANEL_SIZE; -} - -void -xed_prefs_manager_set_bottom_panel_size (gint ps) -{ - g_return_if_fail (ps > -1); - - if (bottom_panel_size == ps) - return; - - bottom_panel_size = ps; - xed_state_set_int (XED_STATE_WINDOW_GROUP, - XED_STATE_BOTTOM_PANEL_SIZE, - ps); -} - -gboolean -xed_prefs_manager_bottom_panel_size_can_set (void) -{ - return TRUE; -} - -gint -xed_prefs_manager_get_bottom_panel_active_page (void) -{ - if (bottom_panel_active_page == -1) - { - xed_state_get_int (XED_STATE_WINDOW_GROUP, - XED_STATE_BOTTOM_PANEL_ACTIVE_PAGE, - 0, - &bottom_panel_active_page); - } - - return bottom_panel_active_page; -} - -void -xed_prefs_manager_set_bottom_panel_active_page (gint id) -{ - if (bottom_panel_active_page == id) - return; - - bottom_panel_active_page = id; - xed_state_set_int (XED_STATE_WINDOW_GROUP, - XED_STATE_BOTTOM_PANEL_ACTIVE_PAGE, - id); -} - -gboolean -xed_prefs_manager_bottom_panel_active_page_can_set (void) -{ - return TRUE; -} - -/* File filter */ -gint -xed_prefs_manager_get_active_file_filter (void) -{ - if (active_file_filter == -1) - { - xed_state_get_int (XED_STATE_FILEFILTER_GROUP, - XED_STATE_FILEFILTER_ID, - 0, - &active_file_filter); - } - - return active_file_filter; -} - -void -xed_prefs_manager_set_active_file_filter (gint id) -{ - g_return_if_fail (id >= 0); - - if (active_file_filter == id) - return; - - active_file_filter = id; - xed_state_set_int (XED_STATE_FILEFILTER_GROUP, - XED_STATE_FILEFILTER_ID, - id); -} - -gboolean -xed_prefs_manager_active_file_filter_can_set (void) -{ - return TRUE; -} - -/* Normal prefs are stored in GSettings */ - -gboolean -xed_prefs_manager_app_init (void) -{ - xed_debug (DEBUG_PREFS); - - g_return_val_if_fail (xed_prefs_manager == NULL, FALSE); - - xed_prefs_manager_init (); - - if (xed_prefs_manager != NULL) - { - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_USE_DEFAULT_FONT, - G_CALLBACK (xed_prefs_manager_editor_font_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_EDITOR_FONT, - G_CALLBACK (xed_prefs_manager_editor_font_changed), - NULL); - - g_signal_connect (xed_prefs_manager->interface_settings, - "changed::" GPM_SYSTEM_FONT, - G_CALLBACK (xed_prefs_manager_system_font_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_TABS_SIZE, - G_CALLBACK (xed_prefs_manager_tabs_size_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_INSERT_SPACES, - G_CALLBACK (xed_prefs_manager_tabs_size_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_WRAP_MODE, - G_CALLBACK (xed_prefs_manager_wrap_mode_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_DISPLAY_LINE_NUMBERS, - G_CALLBACK (xed_prefs_manager_line_numbers_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_AUTO_INDENT, - G_CALLBACK (xed_prefs_manager_auto_indent_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_UNDO_ACTIONS_LIMIT, - G_CALLBACK (xed_prefs_manager_undo_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_DISPLAY_RIGHT_MARGIN, - G_CALLBACK (xed_prefs_manager_right_margin_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_RIGHT_MARGIN_POSITION, - G_CALLBACK (xed_prefs_manager_right_margin_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_SMART_HOME_END, - G_CALLBACK (xed_prefs_manager_smart_home_end_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_HIGHLIGHT_CURRENT_LINE, - G_CALLBACK (xed_prefs_manager_hl_current_line_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_BRACKET_MATCHING, - G_CALLBACK (xed_prefs_manager_bracket_matching_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_SYNTAX_HL_ENABLE, - G_CALLBACK (xed_prefs_manager_syntax_hl_enable_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_SEARCH_HIGHLIGHTING_ENABLE, - G_CALLBACK (xed_prefs_manager_search_hl_enable_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_SOURCE_STYLE_SCHEME, - G_CALLBACK (xed_prefs_manager_source_style_scheme_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_MAX_RECENTS, - G_CALLBACK (xed_prefs_manager_max_recents_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_CREATE_BACKUP_COPY, - G_CALLBACK (xed_prefs_manager_auto_save_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_AUTO_SAVE_INTERVAL, - G_CALLBACK (xed_prefs_manager_auto_save_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_WRITABLE_VFS_SCHEMES, - G_CALLBACK (xed_prefs_manager_auto_save_changed), - NULL); - - g_signal_connect (xed_prefs_manager->settings, - "changed::" GPM_ACTIVE_PLUGINS, - G_CALLBACK (xed_prefs_manager_active_plugins_changed), - NULL); - } - - return xed_prefs_manager != NULL; -} - -/* This function must be called before exiting xed */ -void -xed_prefs_manager_app_shutdown (void) -{ - xed_debug (DEBUG_PREFS); - - xed_prefs_manager_shutdown (); - - xed_state_file_sync (); -} - - -static void -xed_prefs_manager_editor_font_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - GList *views; - GList *l; - gchar *font = NULL; - gboolean def = TRUE; - gint ts; - - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_USE_DEFAULT_FONT) == 0) - { - def = g_settings_get_boolean (settings, key); - - if (def) - font = xed_prefs_manager_get_system_font (); - else - font = xed_prefs_manager_get_editor_font (); - } - else if (strcmp (key, GPM_EDITOR_FONT) == 0) - { - font = g_settings_get_string (settings, key); - - def = xed_prefs_manager_get_use_default_font (); - } - else - return; - - g_return_if_fail (font != NULL); - - ts = xed_prefs_manager_get_tabs_size (); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - /* Note: we use def=FALSE to avoid XedView to query GSettings */ - xed_view_set_font (XED_VIEW (l->data), FALSE, font); - gtk_source_view_set_tab_width (GTK_SOURCE_VIEW (l->data), ts); - - l = l->next; - } - - g_list_free (views); - g_free (font); -} - -static void -xed_prefs_manager_system_font_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - GList *views; - GList *l; - gchar *font; - gint ts; - - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_SYSTEM_FONT) != 0) - return; - - if (!xed_prefs_manager_get_use_default_font ()) - return; - - font = g_settings_get_string (settings, key); - - ts = xed_prefs_manager_get_tabs_size (); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - /* Note: we use def=FALSE to avoid XedView to query GSettings */ - xed_view_set_font (XED_VIEW (l->data), FALSE, font); - - gtk_source_view_set_tab_width (GTK_SOURCE_VIEW (l->data), ts); - l = l->next; - } - - g_list_free (views); - g_free (font); -} - -static void -xed_prefs_manager_tabs_size_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_TABS_SIZE) == 0) - { - gint tab_width; - GList *views; - GList *l; - - tab_width = g_settings_get_int (settings, key); - - tab_width = CLAMP (tab_width, 1, 24); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_source_view_set_tab_width (GTK_SOURCE_VIEW (l->data), - tab_width); - - l = l->next; - } - - g_list_free (views); - } - else if (strcmp (key, GPM_INSERT_SPACES) == 0) - { - gboolean enable; - GList *views; - GList *l; - - enable = g_settings_get_boolean (settings, key); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_source_view_set_insert_spaces_instead_of_tabs ( - GTK_SOURCE_VIEW (l->data), - enable); - - l = l->next; - } - - g_list_free (views); - } -} - -static GtkWrapMode -get_wrap_mode_from_string (const gchar* str) -{ - GtkWrapMode res; - - g_return_val_if_fail (str != NULL, GTK_WRAP_WORD); - - if (strcmp (str, "GTK_WRAP_NONE") == 0) - res = GTK_WRAP_NONE; - else - { - if (strcmp (str, "GTK_WRAP_CHAR") == 0) - res = GTK_WRAP_CHAR; - else - res = GTK_WRAP_WORD; - } - - return res; -} - -static void -xed_prefs_manager_wrap_mode_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_WRAP_MODE) == 0) - { - GtkWrapMode wrap_mode; - GList *views; - GList *l; - - wrap_mode = get_wrap_mode_from_string (g_settings_get_string(settings, key)); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (l->data), - wrap_mode); - - l = l->next; - } - - g_list_free (views); - } -} - -static void -xed_prefs_manager_line_numbers_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_DISPLAY_LINE_NUMBERS) == 0) - { - gboolean dln; - GList *views; - GList *l; - - dln = g_settings_get_boolean (settings, key); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_source_view_set_show_line_numbers (GTK_SOURCE_VIEW (l->data), - dln); - - l = l->next; - } - - g_list_free (views); - } -} - -static void -xed_prefs_manager_hl_current_line_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_HIGHLIGHT_CURRENT_LINE) == 0) - { - gboolean hl; - GList *views; - GList *l; - - hl = g_settings_get_boolean (settings, key); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW (l->data), - hl); - - l = l->next; - } - - g_list_free (views); - } -} - -static void -xed_prefs_manager_bracket_matching_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_BRACKET_MATCHING) == 0) - { - gboolean enable; - GList *docs; - GList *l; - - enable = g_settings_get_boolean (settings, key); - - docs = xed_app_get_documents (xed_app_get_default ()); - l = docs; - - while (l != NULL) - { - gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (l->data), - enable); - - l = l->next; - } - - g_list_free (docs); - } -} - -static void -xed_prefs_manager_auto_indent_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_AUTO_INDENT) == 0) - { - gboolean enable; - GList *views; - GList *l; - - enable = g_settings_get_boolean (settings, key); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_source_view_set_auto_indent (GTK_SOURCE_VIEW (l->data), - enable); - - l = l->next; - } - - g_list_free (views); - } -} - -static void -xed_prefs_manager_undo_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_UNDO_ACTIONS_LIMIT) == 0) - { - gint ul; - GList *docs; - GList *l; - - ul = g_settings_get_int (settings, key); - - ul = CLAMP (ul, -1, 250); - - docs = xed_app_get_documents (xed_app_get_default ()); - l = docs; - - while (l != NULL) - { - gtk_source_buffer_set_max_undo_levels (GTK_SOURCE_BUFFER (l->data), - ul); - - l = l->next; - } - - g_list_free (docs); - } -} - -static void -xed_prefs_manager_right_margin_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_RIGHT_MARGIN_POSITION) == 0) - { - gint pos; - GList *views; - GList *l; - - pos = g_settings_get_int (settings, key); - - pos = CLAMP (pos, 1, 160); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_source_view_set_right_margin_position (GTK_SOURCE_VIEW (l->data), - pos); - - l = l->next; - } - - g_list_free (views); - } - else if (strcmp (key, GPM_DISPLAY_RIGHT_MARGIN) == 0) - { - gboolean display; - GList *views; - GList *l; - - display = g_settings_get_boolean (settings, key); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_source_view_set_show_right_margin (GTK_SOURCE_VIEW (l->data), - display); - - l = l->next; - } - - g_list_free (views); - } -} - -static GtkSourceSmartHomeEndType -get_smart_home_end_from_string (const gchar *str) -{ - GtkSourceSmartHomeEndType res; - - g_return_val_if_fail (str != NULL, GTK_SOURCE_SMART_HOME_END_AFTER); - - if (strcmp (str, "DISABLED") == 0) - res = GTK_SOURCE_SMART_HOME_END_DISABLED; - else if (strcmp (str, "BEFORE") == 0) - res = GTK_SOURCE_SMART_HOME_END_BEFORE; - else if (strcmp (str, "ALWAYS") == 0) - res = GTK_SOURCE_SMART_HOME_END_ALWAYS; - else - res = GTK_SOURCE_SMART_HOME_END_AFTER; - - return res; -} - -static void -xed_prefs_manager_smart_home_end_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_SMART_HOME_END) == 0) - { - GtkSourceSmartHomeEndType smart_he; - GList *views; - GList *l; - - smart_he = get_smart_home_end_from_string (g_settings_get_string (settings, key)); - - views = xed_app_get_views (xed_app_get_default ()); - l = views; - - while (l != NULL) - { - gtk_source_view_set_smart_home_end (GTK_SOURCE_VIEW (l->data), - smart_he); - - l = l->next; - } - - g_list_free (views); - } -} - -static void -xed_prefs_manager_syntax_hl_enable_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_SYNTAX_HL_ENABLE) == 0) - { - gboolean enable; - GList *docs; - GList *l; - const GList *windows; - - enable = g_settings_get_boolean (settings, key); - - docs = xed_app_get_documents (xed_app_get_default ()); - l = docs; - - while (l != NULL) - { - g_return_if_fail (GTK_SOURCE_IS_BUFFER (l->data)); - - gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (l->data), - enable); - - l = l->next; - } - - g_list_free (docs); - - /* update the sensitivity of the Higlight Mode menu item */ - windows = xed_app_get_windows (xed_app_get_default ()); - while (windows != NULL) - { - GtkUIManager *ui; - GtkAction *a; - - ui = xed_window_get_ui_manager (XED_WINDOW (windows->data)); - - a = gtk_ui_manager_get_action (ui, - "/MenuBar/ViewMenu/ViewHighlightModeMenu"); - - gtk_action_set_sensitive (a, enable); - - windows = g_list_next (windows); - } - } -} - -static void -xed_prefs_manager_search_hl_enable_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_SEARCH_HIGHLIGHTING_ENABLE) == 0) - { - gboolean enable; - GList *docs; - GList *l; - - enable = g_settings_get_boolean (settings, key); - - docs = xed_app_get_documents (xed_app_get_default ()); - l = docs; - - while (l != NULL) - { - g_return_if_fail (XED_IS_DOCUMENT (l->data)); - - xed_document_set_enable_search_highlighting (XED_DOCUMENT (l->data), - enable); - - l = l->next; - } - - g_list_free (docs); - } -} - -static void -xed_prefs_manager_source_style_scheme_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_SOURCE_STYLE_SCHEME) == 0) - { - static gchar *old_scheme = NULL; - gchar *scheme; - GtkSourceStyleScheme *style; - GList *docs; - GList *l; - - scheme = g_settings_get_string (settings, key); - - if (old_scheme != NULL && (strcmp (scheme, old_scheme) == 0)) - return; - - g_free (old_scheme); - old_scheme = scheme; - - style = gtk_source_style_scheme_manager_get_scheme ( - xed_get_style_scheme_manager (), - scheme); - - if (style == NULL) - { - g_warning ("Default style scheme '%s' not found, falling back to 'classic'", scheme); - - style = gtk_source_style_scheme_manager_get_scheme ( - xed_get_style_scheme_manager (), - "classic"); - - if (style == NULL) - { - g_warning ("Style scheme 'classic' cannot be found, check your GtkSourceView installation."); - return; - } - } - - docs = xed_app_get_documents (xed_app_get_default ()); - for (l = docs; l != NULL; l = l->next) - { - g_return_if_fail (GTK_SOURCE_IS_BUFFER (l->data)); - - gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (l->data), - style); - } - - g_list_free (docs); - } -} - -static void -xed_prefs_manager_max_recents_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_MAX_RECENTS) == 0) - { - const GList *windows; - gint max; - - max = g_settings_get_int (settings, key); - - if (max < 0) - { - max = GPM_DEFAULT_MAX_RECENTS; - } - - /* FIXME: we have no way at the moment to trigger the - * update of the inline recents in the File menu */ - } -} - -static void -xed_prefs_manager_auto_save_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - GList *docs; - GList *l; - - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_AUTO_SAVE) == 0) - { - gboolean auto_save; - - auto_save = g_settings_get_boolean (settings, key); - - docs = xed_app_get_documents (xed_app_get_default ()); - l = docs; - - while (l != NULL) - { - XedDocument *doc = XED_DOCUMENT (l->data); - XedTab *tab = xed_tab_get_from_document (doc); - - xed_tab_set_auto_save_enabled (tab, auto_save); - - l = l->next; - } - - g_list_free (docs); - } - else if (strcmp (key, GPM_AUTO_SAVE_INTERVAL) == 0) - { - gint auto_save_interval; - - auto_save_interval = g_settings_get_int (settings, key); - - if (auto_save_interval <= 0) - auto_save_interval = GPM_DEFAULT_AUTO_SAVE_INTERVAL; - - docs = xed_app_get_documents (xed_app_get_default ()); - l = docs; - - while (l != NULL) - { - XedDocument *doc = XED_DOCUMENT (l->data); - XedTab *tab = xed_tab_get_from_document (doc); - - xed_tab_set_auto_save_interval (tab, auto_save_interval); - - l = l->next; - } - - g_list_free (docs); - } -} - -static void -xed_prefs_manager_active_plugins_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - xed_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_ACTIVE_PLUGINS) == 0) - { - XedPluginsEngine *engine; - - engine = xed_plugins_engine_get_default (); - - xed_plugins_engine_active_plugins_changed (engine); - } -} - diff --git a/xed/xed-prefs-manager-app.h b/xed/xed-prefs-manager-app.h deleted file mode 100644 index 817dc51..0000000 --- a/xed/xed-prefs-manager-app.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * xed-prefs-manager-app.h - * This file is part of xed - * - * Copyright (C) 2002-2005 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - * - */ - -#ifndef __XED_PREFS_MANAGER_APP_H__ -#define __XED_PREFS_MANAGER_APP_H__ - -#include -#include - -/** LIFE CYCLE MANAGEMENT FUNCTIONS **/ - -gboolean xed_prefs_manager_app_init (void); - -/* This function must be called before exiting xed */ -void xed_prefs_manager_app_shutdown (void); - - -/* Window state */ -gint xed_prefs_manager_get_window_state (void); -void xed_prefs_manager_set_window_state (gint ws); -gboolean xed_prefs_manager_window_state_can_set (void); - -/* Window size */ -void xed_prefs_manager_get_window_size (gint *width, - gint *height); -void xed_prefs_manager_get_default_window_size (gint *width, - gint *height); -void xed_prefs_manager_set_window_size (gint width, - gint height); -gboolean xed_prefs_manager_window_size_can_set (void); - -/* Side panel */ -gint xed_prefs_manager_get_side_panel_size (void); -gint xed_prefs_manager_get_default_side_panel_size(void); -void xed_prefs_manager_set_side_panel_size (gint ps); -gboolean xed_prefs_manager_side_panel_size_can_set (void); -gint xed_prefs_manager_get_side_panel_active_page (void); -void xed_prefs_manager_set_side_panel_active_page (gint id); -gboolean xed_prefs_manager_side_panel_active_page_can_set (void); - -/* Bottom panel */ -gint xed_prefs_manager_get_bottom_panel_size (void); -gint xed_prefs_manager_get_default_bottom_panel_size(void); -void xed_prefs_manager_set_bottom_panel_size (gint ps); -gboolean xed_prefs_manager_bottom_panel_size_can_set (void); -gint xed_prefs_manager_get_bottom_panel_active_page (void); -void xed_prefs_manager_set_bottom_panel_active_page (gint id); -gboolean xed_prefs_manager_bottom_panel_active_page_can_set (void); - -/* File filter */ -gint xed_prefs_manager_get_active_file_filter (void); -void xed_prefs_manager_set_active_file_filter (gint id); -gboolean xed_prefs_manager_active_file_filter_can_set (void); - - -#endif /* __XED_PREFS_MANAGER_APP_H__ */ diff --git a/xed/xed-prefs-manager.c b/xed/xed-prefs-manager.c deleted file mode 100644 index 55fc695..0000000 --- a/xed/xed-prefs-manager.c +++ /dev/null @@ -1,846 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-prefs-manager.c - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include -#include - -#include "xed-prefs-manager.h" -#include "xed-prefs-manager-private.h" -#include "xed-debug.h" -#include "xed-encodings.h" -#include "xed-utils.h" - -#define DEFINE_BOOL_PREF(name, key) gboolean \ -xed_prefs_manager_get_ ## name (void) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - return xed_prefs_manager_get_bool (key); \ -} \ - \ -void \ -xed_prefs_manager_set_ ## name (gboolean v) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - xed_prefs_manager_set_bool (key, \ - v); \ -} \ - \ -gboolean \ -xed_prefs_manager_ ## name ## _can_set (void) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - return xed_prefs_manager_key_is_writable (key); \ -} - - - -#define DEFINE_INT_PREF(name, key) gint \ -xed_prefs_manager_get_ ## name (void) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - return xed_prefs_manager_get_int (key); \ -} \ - \ -void \ -xed_prefs_manager_set_ ## name (gint v) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - xed_prefs_manager_set_int (key, \ - v); \ -} \ - \ -gboolean \ -xed_prefs_manager_ ## name ## _can_set (void) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - return xed_prefs_manager_key_is_writable (key); \ -} - - - -#define DEFINE_STRING_PREF(name, key) gchar* \ -xed_prefs_manager_get_ ## name (void) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - return xed_prefs_manager_get_string (key); \ -} \ - \ -void \ -xed_prefs_manager_set_ ## name (const gchar* v) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - xed_prefs_manager_set_string (key, \ - v); \ -} \ - \ -gboolean \ -xed_prefs_manager_ ## name ## _can_set (void) \ -{ \ - xed_debug (DEBUG_PREFS); \ - \ - return xed_prefs_manager_key_is_writable (key); \ -} - - -XedPrefsManager *xed_prefs_manager = NULL; - - -static GtkWrapMode get_wrap_mode_from_string (const gchar* str); - -static gboolean xed_prefs_manager_get_bool (const gchar* key); - -static gint xed_prefs_manager_get_int (const gchar* key); - -static gchar *xed_prefs_manager_get_string (const gchar* key); - - -gboolean -xed_prefs_manager_init (void) -{ - xed_debug (DEBUG_PREFS); - - if (xed_prefs_manager == NULL) - { - xed_prefs_manager = g_new0 (XedPrefsManager, 1); - xed_prefs_manager->settings = g_settings_new (XED_SCHEMA); - xed_prefs_manager->interface_settings = g_settings_new (GPM_INTERFACE_SCHEMA); - } - - return xed_prefs_manager != NULL; -} - -void -xed_prefs_manager_shutdown (void) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (xed_prefs_manager != NULL); - - g_object_unref (xed_prefs_manager->settings); - xed_prefs_manager->settings = NULL; - g_object_unref (xed_prefs_manager->interface_settings); - xed_prefs_manager->interface_settings = NULL; -} - -static gboolean -xed_prefs_manager_get_bool (const gchar* key) -{ - xed_debug (DEBUG_PREFS); - - return g_settings_get_boolean (xed_prefs_manager->settings, key); -} - -static gint -xed_prefs_manager_get_int (const gchar* key) -{ - xed_debug (DEBUG_PREFS); - - return g_settings_get_int (xed_prefs_manager->settings, key); -} - -static gchar * -xed_prefs_manager_get_string (const gchar* key) -{ - xed_debug (DEBUG_PREFS); - - return g_settings_get_string (xed_prefs_manager->settings, key); -} - -static void -xed_prefs_manager_set_bool (const gchar* key, gboolean value) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (g_settings_is_writable ( - xed_prefs_manager->settings, key)); - - g_settings_set_boolean (xed_prefs_manager->settings, key, value); -} - -static void -xed_prefs_manager_set_int (const gchar* key, gint value) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (g_settings_is_writable ( - xed_prefs_manager->settings, key)); - - g_settings_set_int (xed_prefs_manager->settings, key, value); -} - -static void -xed_prefs_manager_set_string (const gchar* key, const gchar* value) -{ - xed_debug (DEBUG_PREFS); - - g_return_if_fail (value != NULL); - - g_return_if_fail (g_settings_is_writable ( - xed_prefs_manager->settings, key)); - - g_settings_set_string (xed_prefs_manager->settings, key, value); -} - -static gboolean -xed_prefs_manager_key_is_writable (const gchar* key) -{ - xed_debug (DEBUG_PREFS); - - g_return_val_if_fail (xed_prefs_manager != NULL, FALSE); - g_return_val_if_fail (xed_prefs_manager->settings != NULL, FALSE); - - return g_settings_is_writable (xed_prefs_manager->settings, key); -} - -/* Use default font */ -DEFINE_BOOL_PREF (use_default_font, - GPM_USE_DEFAULT_FONT) - -/* Editor font */ -DEFINE_STRING_PREF (editor_font, - GPM_EDITOR_FONT) - -/* System font */ -gchar * -xed_prefs_manager_get_system_font (void) -{ - xed_debug (DEBUG_PREFS); - - return g_settings_get_string (xed_prefs_manager->interface_settings, - GPM_SYSTEM_FONT); -} - -/* Create backup copy */ -DEFINE_BOOL_PREF (create_backup_copy, - GPM_CREATE_BACKUP_COPY) - -/* Auto save */ -DEFINE_BOOL_PREF (auto_save, - GPM_AUTO_SAVE) - -/* Auto save interval */ -DEFINE_INT_PREF (auto_save_interval, - GPM_AUTO_SAVE_INTERVAL) - - -/* Undo actions limit: if < 1 then no limits */ -DEFINE_INT_PREF (undo_actions_limit, - GPM_UNDO_ACTIONS_LIMIT) - -static GtkWrapMode -get_wrap_mode_from_string (const gchar* str) -{ - GtkWrapMode res; - - g_return_val_if_fail (str != NULL, GTK_WRAP_WORD); - - if (strcmp (str, "GTK_WRAP_NONE") == 0) - res = GTK_WRAP_NONE; - else - { - if (strcmp (str, "GTK_WRAP_CHAR") == 0) - res = GTK_WRAP_CHAR; - else - res = GTK_WRAP_WORD; - } - - return res; -} - -/* Wrap mode */ -GtkWrapMode -xed_prefs_manager_get_wrap_mode (void) -{ - gchar *str; - GtkWrapMode res; - - xed_debug (DEBUG_PREFS); - - str = xed_prefs_manager_get_string (GPM_WRAP_MODE); - - res = get_wrap_mode_from_string (str); - - g_free (str); - - return res; -} - -void -xed_prefs_manager_set_wrap_mode (GtkWrapMode wp) -{ - const gchar * str; - - xed_debug (DEBUG_PREFS); - - switch (wp) - { - case GTK_WRAP_NONE: - str = "GTK_WRAP_NONE"; - break; - - case GTK_WRAP_CHAR: - str = "GTK_WRAP_CHAR"; - break; - - default: /* GTK_WRAP_WORD */ - str = "GTK_WRAP_WORD"; - } - - xed_prefs_manager_set_string (GPM_WRAP_MODE, - str); -} - -gboolean -xed_prefs_manager_wrap_mode_can_set (void) -{ - xed_debug (DEBUG_PREFS); - - return xed_prefs_manager_key_is_writable (GPM_WRAP_MODE); -} - - -/* Tabs size */ -DEFINE_INT_PREF (tabs_size, - GPM_TABS_SIZE) - -/* Insert spaces */ -DEFINE_BOOL_PREF (insert_spaces, - GPM_INSERT_SPACES) - -/* Auto indent */ -DEFINE_BOOL_PREF (auto_indent, - GPM_AUTO_INDENT) - -/* Display line numbers */ -DEFINE_BOOL_PREF (display_line_numbers, - GPM_DISPLAY_LINE_NUMBERS) - -/* Toolbar visibility */ -DEFINE_BOOL_PREF (toolbar_visible, - GPM_TOOLBAR_VISIBLE) - -/* Statusbar visiblity */ -DEFINE_BOOL_PREF (statusbar_visible, - GPM_STATUSBAR_VISIBLE) - -/* Side Pane visiblity */ -DEFINE_BOOL_PREF (side_pane_visible, - GPM_SIDE_PANE_VISIBLE) - -/* Bottom Panel visiblity */ -DEFINE_BOOL_PREF (bottom_panel_visible, - GPM_BOTTOM_PANEL_VISIBLE) - -/* Print syntax highlighting */ -DEFINE_BOOL_PREF (print_syntax_hl, - GPM_PRINT_SYNTAX) - -/* Print header */ -DEFINE_BOOL_PREF (print_header, - GPM_PRINT_HEADER) - - -/* Print Wrap mode */ -GtkWrapMode -xed_prefs_manager_get_print_wrap_mode (void) -{ - gchar *str; - GtkWrapMode res; - - xed_debug (DEBUG_PREFS); - - str = xed_prefs_manager_get_string (GPM_PRINT_WRAP_MODE); - - if (strcmp (str, "GTK_WRAP_NONE") == 0) - res = GTK_WRAP_NONE; - else - { - if (strcmp (str, "GTK_WRAP_WORD") == 0) - res = GTK_WRAP_WORD; - else - res = GTK_WRAP_CHAR; - } - - g_free (str); - - return res; -} - -void -xed_prefs_manager_set_print_wrap_mode (GtkWrapMode pwp) -{ - const gchar *str; - - xed_debug (DEBUG_PREFS); - - switch (pwp) - { - case GTK_WRAP_NONE: - str = "GTK_WRAP_NONE"; - break; - - case GTK_WRAP_WORD: - str = "GTK_WRAP_WORD"; - break; - - default: /* GTK_WRAP_CHAR */ - str = "GTK_WRAP_CHAR"; - } - - xed_prefs_manager_set_string (GPM_PRINT_WRAP_MODE, str); -} - -gboolean -xed_prefs_manager_print_wrap_mode_can_set (void) -{ - xed_debug (DEBUG_PREFS); - - return xed_prefs_manager_key_is_writable (GPM_PRINT_WRAP_MODE); -} - -/* Print line numbers */ -DEFINE_INT_PREF (print_line_numbers, - GPM_PRINT_LINE_NUMBERS) - -/* Printing fonts */ -DEFINE_STRING_PREF (print_font_body, - GPM_PRINT_FONT_BODY) - -static gchar * -xed_prefs_manager_get_default_string_value (const gchar *key) -{ - gchar *font = NULL; - g_settings_delay (xed_prefs_manager->settings); - g_settings_reset (xed_prefs_manager->settings, key); - font = g_settings_get_string (xed_prefs_manager->settings, key); - g_settings_revert (xed_prefs_manager->settings); - return font; -} - -gchar * -xed_prefs_manager_get_default_print_font_body (void) -{ - return xed_prefs_manager_get_default_string_value (GPM_PRINT_FONT_BODY); -} - -DEFINE_STRING_PREF (print_font_header, - GPM_PRINT_FONT_HEADER) - -gchar * -xed_prefs_manager_get_default_print_font_header (void) -{ - return xed_prefs_manager_get_default_string_value (GPM_PRINT_FONT_HEADER); -} - -DEFINE_STRING_PREF (print_font_numbers, - GPM_PRINT_FONT_NUMBERS) - -gchar * -xed_prefs_manager_get_default_print_font_numbers (void) -{ - return xed_prefs_manager_get_default_string_value (GPM_PRINT_FONT_NUMBERS); -} - -/* Max number of files in "Recent Files" menu. - * This is configurable only using gsettings, dconf or dconf-editor - */ -gint -xed_prefs_manager_get_max_recents (void) -{ - xed_debug (DEBUG_PREFS); - - return xed_prefs_manager_get_int (GPM_MAX_RECENTS); - -} - -/* GSettings/GSList utility functions from mate-panel */ - -GSList* -xed_prefs_manager_get_gslist (GSettings *settings, const gchar *key) -{ - gchar **array; - GSList *list = NULL; - gint i; - array = g_settings_get_strv (settings, key); - if (array != NULL) { - for (i = 0; array[i]; i++) { - list = g_slist_append (list, g_strdup (array[i])); - } - } - g_strfreev (array); - return list; -} - -void -xed_prefs_manager_set_gslist (GSettings *settings, const gchar *key, GSList *list) -{ - GArray *array; - GSList *l; - array = g_array_new (TRUE, TRUE, sizeof (gchar *)); - for (l = list; l; l = l->next) { - array = g_array_append_val (array, l->data); - } - g_settings_set_strv (settings, key, (const gchar **) array->data); - g_array_free (array, TRUE); -} - - -/* Encodings */ - -static gboolean -data_exists (GSList *list, - const gpointer data) -{ - while (list != NULL) - { - if (list->data == data) - return TRUE; - - list = g_slist_next (list); - } - - return FALSE; -} - -GSList * -xed_prefs_manager_get_auto_detected_encodings (void) -{ - GSList *strings; - GSList *res = NULL; - - xed_debug (DEBUG_PREFS); - - g_return_val_if_fail (xed_prefs_manager != NULL, NULL); - g_return_val_if_fail (xed_prefs_manager->settings != NULL, NULL); - - strings = xed_prefs_manager_get_gslist (xed_prefs_manager->settings, GPM_AUTO_DETECTED_ENCODINGS); - - if (strings != NULL) - { - GSList *tmp; - const XedEncoding *enc; - - tmp = strings; - - while (tmp) - { - const char *charset = tmp->data; - - if (strcmp (charset, "CURRENT") == 0) - g_get_charset (&charset); - - g_return_val_if_fail (charset != NULL, NULL); - enc = xed_encoding_get_from_charset (charset); - - if (enc != NULL) - { - if (!data_exists (res, (gpointer)enc)) - res = g_slist_prepend (res, (gpointer)enc); - - } - - tmp = g_slist_next (tmp); - } - - g_slist_foreach (strings, (GFunc) g_free, NULL); - g_slist_free (strings); - - res = g_slist_reverse (res); - } - - xed_debug_message (DEBUG_PREFS, "Done"); - - return res; -} - -GSList * -xed_prefs_manager_get_shown_in_menu_encodings (void) -{ - GSList *strings; - GSList *res = NULL; - - xed_debug (DEBUG_PREFS); - - g_return_val_if_fail (xed_prefs_manager != NULL, NULL); - g_return_val_if_fail (xed_prefs_manager->settings != NULL, NULL); - - strings = xed_prefs_manager_get_gslist (xed_prefs_manager->settings, GPM_SHOWN_IN_MENU_ENCODINGS); - - if (strings != NULL) - { - GSList *tmp; - const XedEncoding *enc; - - tmp = strings; - - while (tmp) - { - const char *charset = tmp->data; - - if (strcmp (charset, "CURRENT") == 0) - g_get_charset (&charset); - - g_return_val_if_fail (charset != NULL, NULL); - enc = xed_encoding_get_from_charset (charset); - - if (enc != NULL) - { - if (!data_exists (res, (gpointer)enc)) - res = g_slist_prepend (res, (gpointer)enc); - } - - tmp = g_slist_next (tmp); - } - - g_slist_foreach (strings, (GFunc) g_free, NULL); - g_slist_free (strings); - - res = g_slist_reverse (res); - } - - return res; -} - -void -xed_prefs_manager_set_shown_in_menu_encodings (const GSList *encs) -{ - GSList *list = NULL; - - g_return_if_fail (xed_prefs_manager != NULL); - g_return_if_fail (xed_prefs_manager->settings != NULL); - g_return_if_fail (xed_prefs_manager_shown_in_menu_encodings_can_set ()); - - while (encs != NULL) - { - const XedEncoding *enc; - const gchar *charset; - - enc = (const XedEncoding *)encs->data; - - charset = xed_encoding_get_charset (enc); - g_return_if_fail (charset != NULL); - - list = g_slist_prepend (list, (gpointer)charset); - - encs = g_slist_next (encs); - } - - list = g_slist_reverse (list); - - xed_prefs_manager_set_gslist (xed_prefs_manager->settings, GPM_SHOWN_IN_MENU_ENCODINGS, list); - - g_slist_free (list); -} - -gboolean -xed_prefs_manager_shown_in_menu_encodings_can_set (void) -{ - xed_debug (DEBUG_PREFS); - - return xed_prefs_manager_key_is_writable (GPM_SHOWN_IN_MENU_ENCODINGS); - -} - -/* Highlight current line */ -DEFINE_BOOL_PREF (highlight_current_line, - GPM_HIGHLIGHT_CURRENT_LINE) - -/* Highlight matching bracket */ -DEFINE_BOOL_PREF (bracket_matching, - GPM_BRACKET_MATCHING) - -/* Display Right Margin */ -DEFINE_BOOL_PREF (display_right_margin, - GPM_DISPLAY_RIGHT_MARGIN) - -/* Right Margin Position */ -DEFINE_INT_PREF (right_margin_position, - GPM_RIGHT_MARGIN_POSITION) - -static GtkSourceSmartHomeEndType -get_smart_home_end_from_string (const gchar *str) -{ - GtkSourceSmartHomeEndType res; - - g_return_val_if_fail (str != NULL, GTK_SOURCE_SMART_HOME_END_AFTER); - - if (strcmp (str, "DISABLED") == 0) - res = GTK_SOURCE_SMART_HOME_END_DISABLED; - else if (strcmp (str, "BEFORE") == 0) - res = GTK_SOURCE_SMART_HOME_END_BEFORE; - else if (strcmp (str, "ALWAYS") == 0) - res = GTK_SOURCE_SMART_HOME_END_ALWAYS; - else - res = GTK_SOURCE_SMART_HOME_END_AFTER; - - return res; -} - -GtkSourceSmartHomeEndType -xed_prefs_manager_get_smart_home_end (void) -{ - gchar *str; - GtkSourceSmartHomeEndType res; - - xed_debug (DEBUG_PREFS); - - str = xed_prefs_manager_get_string (GPM_SMART_HOME_END); - - res = get_smart_home_end_from_string (str); - - g_free (str); - - return res; -} - -void -xed_prefs_manager_set_smart_home_end (GtkSourceSmartHomeEndType smart_he) -{ - const gchar *str; - - xed_debug (DEBUG_PREFS); - - switch (smart_he) - { - case GTK_SOURCE_SMART_HOME_END_DISABLED: - str = "DISABLED"; - break; - - case GTK_SOURCE_SMART_HOME_END_BEFORE: - str = "BEFORE"; - break; - - case GTK_SOURCE_SMART_HOME_END_ALWAYS: - str = "ALWAYS"; - break; - - default: /* GTK_SOURCE_SMART_HOME_END_AFTER */ - str = "AFTER"; - } - - xed_prefs_manager_set_string (GPM_WRAP_MODE, str); -} - -gboolean -xed_prefs_manager_smart_home_end_can_set (void) -{ - xed_debug (DEBUG_PREFS); - - return xed_prefs_manager_key_is_writable (GPM_SMART_HOME_END); -} - -/* Enable syntax highlighting */ -DEFINE_BOOL_PREF (enable_syntax_highlighting, - GPM_SYNTAX_HL_ENABLE) - -/* Enable search highlighting */ -DEFINE_BOOL_PREF (enable_search_highlighting, - GPM_SEARCH_HIGHLIGHTING_ENABLE) - -/* Source style scheme */ -DEFINE_STRING_PREF (source_style_scheme, - GPM_SOURCE_STYLE_SCHEME) - -GSList * -xed_prefs_manager_get_writable_vfs_schemes (void) -{ - GSList *strings; - - xed_debug (DEBUG_PREFS); - - g_return_val_if_fail (xed_prefs_manager != NULL, NULL); - g_return_val_if_fail (xed_prefs_manager->settings != NULL, NULL); - - strings = xed_prefs_manager_get_gslist (xed_prefs_manager->settings, GPM_WRITABLE_VFS_SCHEMES); - - /* The 'file' scheme is writable by default. */ - strings = g_slist_prepend (strings, g_strdup ("file")); - - xed_debug_message (DEBUG_PREFS, "Done"); - - return strings; -} - -gboolean -xed_prefs_manager_get_restore_cursor_position (void) -{ - xed_debug (DEBUG_PREFS); - - return xed_prefs_manager_get_bool (GPM_RESTORE_CURSOR_POSITION); -} - -/* Plugins: we just store/return a list of strings, all the magic has to - * happen in the plugin engine */ - -GSList * -xed_prefs_manager_get_active_plugins (void) -{ - GSList *plugins; - - xed_debug (DEBUG_PREFS); - - g_return_val_if_fail (xed_prefs_manager != NULL, NULL); - g_return_val_if_fail (xed_prefs_manager->settings != NULL, NULL); - - plugins = xed_prefs_manager_get_gslist (xed_prefs_manager->settings, GPM_ACTIVE_PLUGINS); - - return plugins; -} - -void -xed_prefs_manager_set_active_plugins (const GSList *plugins) -{ - g_return_if_fail (xed_prefs_manager != NULL); - g_return_if_fail (xed_prefs_manager->settings != NULL); - g_return_if_fail (xed_prefs_manager_active_plugins_can_set ()); - - xed_prefs_manager_set_gslist (xed_prefs_manager->settings, GPM_ACTIVE_PLUGINS, (GSList *) plugins); -} - -gboolean -xed_prefs_manager_active_plugins_can_set (void) -{ - xed_debug (DEBUG_PREFS); - - return xed_prefs_manager_key_is_writable (GPM_ACTIVE_PLUGINS); -} diff --git a/xed/xed-prefs-manager.h b/xed/xed-prefs-manager.h deleted file mode 100644 index 41e45e9..0000000 --- a/xed/xed-prefs-manager.h +++ /dev/null @@ -1,313 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-prefs-manager.h - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifndef __XED_PREFS_MANAGER_H__ -#define __XED_PREFS_MANAGER_H__ - -#include -#include -#include -#include "xed-app.h" - -#define XED_SCHEMA "org.x.editor" - -/* Editor */ -#define GPM_USE_DEFAULT_FONT "use-default-font" -#define GPM_EDITOR_FONT "editor-font" - -#define GPM_CREATE_BACKUP_COPY "create-backup-copy" - -#define GPM_AUTO_SAVE "auto-save" -#define GPM_AUTO_SAVE_INTERVAL "auto-save-interval" - -#define GPM_UNDO_ACTIONS_LIMIT "max-undo-actions" - -#define GPM_WRAP_MODE "wrap-mode" - -#define GPM_TABS_SIZE "tabs-size" -#define GPM_INSERT_SPACES "insert-spaces" - -#define GPM_AUTO_INDENT "auto-indent" - -#define GPM_DISPLAY_LINE_NUMBERS "display-line-numbers" - -#define GPM_HIGHLIGHT_CURRENT_LINE "highlight-current-line" - -#define GPM_BRACKET_MATCHING "bracket-matching" - -#define GPM_DISPLAY_RIGHT_MARGIN "display-right-margin" -#define GPM_RIGHT_MARGIN_POSITION "right-margin-position" - -#define GPM_SMART_HOME_END "smart-home-end" - -#define GPM_RESTORE_CURSOR_POSITION "restore-cursor-position" - -#define GPM_SEARCH_HIGHLIGHTING_ENABLE "enable-search-highlighting" - -#define GPM_SOURCE_STYLE_SCHEME "color-scheme" - -/* UI */ -#define GPM_TOOLBAR_VISIBLE "toolbar-visible" - -#define GPM_STATUSBAR_VISIBLE "statusbar-visible" - -#define GPM_SIDE_PANE_VISIBLE "side-pane-visible" - -#define GPM_BOTTOM_PANEL_VISIBLE "bottom-panel-visible" - -#define GPM_MAX_RECENTS "max-recents" - -/* Print */ -#define GPM_PRINT_SYNTAX "print-syntax-highlighting" -#define GPM_PRINT_HEADER "print-header" -#define GPM_PRINT_WRAP_MODE "print-wrap-mode" -#define GPM_PRINT_LINE_NUMBERS "print-line-numbers" - -#define GPM_PRINT_FONT_BODY "print-font-body-pango" -#define GPM_PRINT_FONT_HEADER "print-font-header-pango" -#define GPM_PRINT_FONT_NUMBERS "print-font-numbers-pango" - -/* Encodings */ -#define GPM_AUTO_DETECTED_ENCODINGS "auto-detected-encodings" -#define GPM_SHOWN_IN_MENU_ENCODINGS "shown-in-menu-encodings" - -/* Syntax highlighting */ -#define GPM_SYNTAX_HL_ENABLE "enable-syntax-highlighting" - -/* White list of writable mate-vfs methods */ -#define GPM_WRITABLE_VFS_SCHEMES "writable-vfs-schemes" - -/* Plugins */ -#define GPM_ACTIVE_PLUGINS "active-plugins" - -/* Global Interface keys */ -#define GPM_INTERFACE_SCHEMA "org.gnome.desktop.interface" -#define GPM_SYSTEM_FONT "monospace-font-name" - -/* Fallback default values. Keep in sync with org.x.editor.gschema.xml */ -#define GPM_DEFAULT_AUTO_SAVE_INTERVAL 10 /* minutes */ -#define GPM_DEFAULT_MAX_RECENTS 5 - -/** LIFE CYCLE MANAGEMENT FUNCTIONS **/ - -gboolean xed_prefs_manager_init (void); - -/* This function must be called before exiting xed */ -void xed_prefs_manager_shutdown (void); - - -/** PREFS MANAGEMENT FUNCTIONS **/ - -/* Use default font */ -gboolean xed_prefs_manager_get_use_default_font (void); -void xed_prefs_manager_set_use_default_font (gboolean udf); -gboolean xed_prefs_manager_use_default_font_can_set (void); - -/* Editor font */ -gchar *xed_prefs_manager_get_editor_font (void); -void xed_prefs_manager_set_editor_font (const gchar *font); -gboolean xed_prefs_manager_editor_font_can_set (void); - -/* System font */ -gchar *xed_prefs_manager_get_system_font (void); - -/* Create backup copy */ -gboolean xed_prefs_manager_get_create_backup_copy (void); -void xed_prefs_manager_set_create_backup_copy (gboolean cbc); -gboolean xed_prefs_manager_create_backup_copy_can_set (void); - -/* Auto save */ -gboolean xed_prefs_manager_get_auto_save (void); -void xed_prefs_manager_set_auto_save (gboolean as); -gboolean xed_prefs_manager_auto_save_can_set (void); - -/* Auto save interval */ -gint xed_prefs_manager_get_auto_save_interval (void); -void xed_prefs_manager_set_auto_save_interval (gint asi); -gboolean xed_prefs_manager_auto_save_interval_can_set (void); - -/* Undo actions limit: if < 1 then no limits */ -gint xed_prefs_manager_get_undo_actions_limit (void); -void xed_prefs_manager_set_undo_actions_limit (gint ual); -gboolean xed_prefs_manager_undo_actions_limit_can_set (void); - -/* Wrap mode */ -GtkWrapMode xed_prefs_manager_get_wrap_mode (void); -void xed_prefs_manager_set_wrap_mode (GtkWrapMode wp); -gboolean xed_prefs_manager_wrap_mode_can_set (void); - -/* Tabs size */ -gint xed_prefs_manager_get_tabs_size (void); -void xed_prefs_manager_set_tabs_size (gint ts); -gboolean xed_prefs_manager_tabs_size_can_set (void); - -/* Insert spaces */ -gboolean xed_prefs_manager_get_insert_spaces (void); -void xed_prefs_manager_set_insert_spaces (gboolean ai); -gboolean xed_prefs_manager_insert_spaces_can_set (void); - -/* Auto indent */ -gboolean xed_prefs_manager_get_auto_indent (void); -void xed_prefs_manager_set_auto_indent (gboolean ai); -gboolean xed_prefs_manager_auto_indent_can_set (void); - -/* Display line numbers */ -gboolean xed_prefs_manager_get_display_line_numbers (void); -void xed_prefs_manager_set_display_line_numbers (gboolean dln); -gboolean xed_prefs_manager_display_line_numbers_can_set (void); - -/* Toolbar visible */ -gboolean xed_prefs_manager_get_toolbar_visible (void); -void xed_prefs_manager_set_toolbar_visible (gboolean tv); -gboolean xed_prefs_manager_toolbar_visible_can_set (void); - -/* Statusbar visible */ -gboolean xed_prefs_manager_get_statusbar_visible (void); -void xed_prefs_manager_set_statusbar_visible (gboolean sv); -gboolean xed_prefs_manager_statusbar_visible_can_set (void); - -/* Side pane visible */ -gboolean xed_prefs_manager_get_side_pane_visible (void); -void xed_prefs_manager_set_side_pane_visible (gboolean tv); -gboolean xed_prefs_manager_side_pane_visible_can_set (void); - -/* Bottom panel visible */ -gboolean xed_prefs_manager_get_bottom_panel_visible (void); -void xed_prefs_manager_set_bottom_panel_visible (gboolean tv); -gboolean xed_prefs_manager_bottom_panel_visible_can_set(void); -/* Print syntax highlighting */ -gboolean xed_prefs_manager_get_print_syntax_hl (void); -void xed_prefs_manager_set_print_syntax_hl (gboolean ps); -gboolean xed_prefs_manager_print_syntax_hl_can_set (void); - -/* Print header */ -gboolean xed_prefs_manager_get_print_header (void); -void xed_prefs_manager_set_print_header (gboolean ph); -gboolean xed_prefs_manager_print_header_can_set (void); - -/* Wrap mode while printing */ -GtkWrapMode xed_prefs_manager_get_print_wrap_mode (void); -void xed_prefs_manager_set_print_wrap_mode (GtkWrapMode pwm); -gboolean xed_prefs_manager_print_wrap_mode_can_set (void); - -/* Print line numbers */ -gint xed_prefs_manager_get_print_line_numbers (void); -void xed_prefs_manager_set_print_line_numbers (gint pln); -gboolean xed_prefs_manager_print_line_numbers_can_set (void); - -/* Font used to print the body of documents */ -gchar *xed_prefs_manager_get_print_font_body (void); -void xed_prefs_manager_set_print_font_body (const gchar *font); -gboolean xed_prefs_manager_print_font_body_can_set (void); -gchar *xed_prefs_manager_get_default_print_font_body (void); - -/* Font used to print headers */ -gchar *xed_prefs_manager_get_print_font_header (void); -void xed_prefs_manager_set_print_font_header (const gchar *font); -gboolean xed_prefs_manager_print_font_header_can_set (void); -gchar *xed_prefs_manager_get_default_print_font_header (void); - -/* Font used to print line numbers */ -gchar *xed_prefs_manager_get_print_font_numbers (void); -void xed_prefs_manager_set_print_font_numbers (const gchar *font); -gboolean xed_prefs_manager_print_font_numbers_can_set (void); -gchar *xed_prefs_manager_get_default_print_font_numbers (void); - -/* Max number of files in "Recent Files" menu. - * This is configurable only using gsettings, dconf or dconf-editor - */ -gint xed_prefs_manager_get_max_recents (void); - -/* Encodings */ -GSList *xed_prefs_manager_get_auto_detected_encodings (void); - -GSList *xed_prefs_manager_get_shown_in_menu_encodings (void); -void xed_prefs_manager_set_shown_in_menu_encodings (const GSList *encs); -gboolean xed_prefs_manager_shown_in_menu_encodings_can_set (void); - -/* Highlight current line */ -gboolean xed_prefs_manager_get_highlight_current_line (void); -void xed_prefs_manager_set_highlight_current_line (gboolean hl); -gboolean xed_prefs_manager_highlight_current_line_can_set (void); - -/* Highlight matching bracket */ -gboolean xed_prefs_manager_get_bracket_matching (void); -void xed_prefs_manager_set_bracket_matching (gboolean bm); -gboolean xed_prefs_manager_bracket_matching_can_set (void); - -/* Display right margin */ -gboolean xed_prefs_manager_get_display_right_margin (void); -void xed_prefs_manager_set_display_right_margin (gboolean drm); -gboolean xed_prefs_manager_display_right_margin_can_set (void); - -/* Right margin position */ -gint xed_prefs_manager_get_right_margin_position (void); -void xed_prefs_manager_set_right_margin_position (gint rmp); -gboolean xed_prefs_manager_right_margin_position_can_set (void); - -/* Smart home end */ -GtkSourceSmartHomeEndType - xed_prefs_manager_get_smart_home_end (void); -void xed_prefs_manager_set_smart_home_end (GtkSourceSmartHomeEndType smart_he); -gboolean xed_prefs_manager_smart_home_end_can_set (void); - -/* Enable syntax highlighting */ -gboolean xed_prefs_manager_get_enable_syntax_highlighting (void); -void xed_prefs_manager_set_enable_syntax_highlighting (gboolean esh); -gboolean xed_prefs_manager_enable_syntax_highlighting_can_set (void); - -/* Writable VFS schemes */ -GSList *xed_prefs_manager_get_writable_vfs_schemes (void); - -/* Restore cursor position */ -gboolean xed_prefs_manager_get_restore_cursor_position (void); - -/* Enable search highlighting */ -gboolean xed_prefs_manager_get_enable_search_highlighting (void); -void xed_prefs_manager_set_enable_search_highlighting (gboolean esh); -gboolean xed_prefs_manager_enable_search_highlighting_can_set (void); - -/* Style scheme */ -gchar *xed_prefs_manager_get_source_style_scheme (void); -void xed_prefs_manager_set_source_style_scheme (const gchar *scheme); -gboolean xed_prefs_manager_source_style_scheme_can_set(void); - -/* Plugins */ -GSList *xed_prefs_manager_get_active_plugins (void); -void xed_prefs_manager_set_active_plugins (const GSList *plugins); -gboolean xed_prefs_manager_active_plugins_can_set (void); - -/* GSettings utilities */ -GSList* xed_prefs_manager_get_gslist (GSettings *settings, const gchar *key); -void xed_prefs_manager_set_gslist (GSettings *settings, const gchar *key, GSList *list); - - -#endif /* __XED_PREFS_MANAGER_H__ */ - - diff --git a/xed/xed-print-job.c b/xed/xed-print-job.c index 9be4b00..e76d0d8 100644 --- a/xed/xed-print-job.c +++ b/xed/xed-print-job.c @@ -3,7 +3,7 @@ * This file is part of xed * * Copyright (C) 2000-2001 Chema Celorio, Paolo Maggi - * Copyright (C) 2002-2008 Paolo Maggi + * Copyright (C) 2002-2008 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,14 +17,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 1998-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 1998-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id: xed-print.c 6022 2007-12-09 14:38:57Z pborelli $ */ @@ -38,68 +38,70 @@ #include "xed-print-job.h" #include "xed-debug.h" -#include "xed-prefs-manager.h" #include "xed-print-preview.h" #include "xed-marshal.h" #include "xed-utils.h" #include "xed-dirs.h" +#include "xed-settings.h" #define XED_PRINT_JOB_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_PRINT_JOB, \ - XedPrintJobPrivate)) + XED_TYPE_PRINT_JOB, \ + XedPrintJobPrivate)) struct _XedPrintJobPrivate { - XedView *view; - XedDocument *doc; + GSettings *print_settings; - GtkPrintOperation *operation; - GtkSourcePrintCompositor *compositor; + XedView *view; + XedDocument *doc; - GtkPrintSettings *settings; + GtkPrintOperation *operation; + GtkSourcePrintCompositor *compositor; - GtkWidget *preview; + GtkPrintSettings *settings; - XedPrintJobStatus status; - - gchar *status_string; + GtkWidget *preview; - gdouble progress; + XedPrintJobStatus status; - gboolean is_preview; + gchar *status_string; - /* widgets part of the custom print preferences widget. - * These pointers are valid just when the dialog is displayed */ - GtkWidget *syntax_checkbutton; - GtkWidget *page_header_checkbutton; - GtkWidget *line_numbers_checkbutton; - GtkWidget *line_numbers_hbox; - GtkWidget *line_numbers_spinbutton; - GtkWidget *text_wrapping_checkbutton; - GtkWidget *do_not_split_checkbutton; - GtkWidget *fonts_table; - GtkWidget *body_font_label; - GtkWidget *headers_font_label; - GtkWidget *numbers_font_label; - GtkWidget *body_fontbutton; - GtkWidget *headers_fontbutton; - GtkWidget *numbers_fontbutton; - GtkWidget *restore_button; + gdouble progress; + + gboolean is_preview; + + /* widgets part of the custom print preferences widget. + * These pointers are valid just when the dialog is displayed */ + GtkWidget *syntax_checkbutton; + GtkWidget *page_header_checkbutton; + GtkWidget *line_numbers_checkbutton; + GtkWidget *line_numbers_hbox; + GtkWidget *line_numbers_spinbutton; + GtkWidget *text_wrapping_checkbutton; + GtkWidget *do_not_split_checkbutton; + GtkWidget *fonts_table; + GtkWidget *body_font_label; + GtkWidget *headers_font_label; + GtkWidget *numbers_font_label; + GtkWidget *body_fontbutton; + GtkWidget *headers_fontbutton; + GtkWidget *numbers_fontbutton; + GtkWidget *restore_button; }; enum { - PROP_0, - PROP_VIEW + PROP_0, + PROP_VIEW }; -enum +enum { - PRINTING, - SHOW_PREVIEW, - DONE, - LAST_SIGNAL + PRINTING, + SHOW_PREVIEW, + DONE, + LAST_SIGNAL }; static guint print_job_signals[LAST_SIGNAL] = { 0 }; @@ -107,763 +109,689 @@ static guint print_job_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (XedPrintJob, xed_print_job, G_TYPE_OBJECT) static void -set_view (XedPrintJob *job, XedView *view) +set_view (XedPrintJob *job, + XedView *view) { - job->priv->view = view; - job->priv->doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + job->priv->view = view; + job->priv->doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); } -static void +static void xed_print_job_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedPrintJob *job = XED_PRINT_JOB (object); + XedPrintJob *job = XED_PRINT_JOB (object); - switch (prop_id) - { - case PROP_VIEW: - g_value_set_object (value, job->priv->view); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_VIEW: + g_value_set_object (value, job->priv->view); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } -static void +static void xed_print_job_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedPrintJob *job = XED_PRINT_JOB (object); + XedPrintJob *job = XED_PRINT_JOB (object); - switch (prop_id) - { - case PROP_VIEW: - set_view (job, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_VIEW: + set_view (job, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_print_job_finalize (GObject *object) { - XedPrintJob *job = XED_PRINT_JOB (object); + XedPrintJob *job = XED_PRINT_JOB (object); - g_free (job->priv->status_string); - - if (job->priv->compositor != NULL) - g_object_unref (job->priv->compositor); + g_free (job->priv->status_string); - if (job->priv->operation != NULL) - g_object_unref (job->priv->operation); + if (job->priv->compositor != NULL) + { + g_object_unref (job->priv->compositor); + } - G_OBJECT_CLASS (xed_print_job_parent_class)->finalize (object); + if (job->priv->operation != NULL) + { + g_object_unref (job->priv->operation); + } + + G_OBJECT_CLASS (xed_print_job_parent_class)->finalize (object); } -static void +static void +xed_print_job_dispose (GObject *object) +{ + XedPrintJob *job = XED_PRINT_JOB (object); + + g_clear_object (&job->priv->print_settings); + + G_OBJECT_CLASS (xed_print_job_parent_class)->dispose (object); +} + +static void xed_print_job_class_init (XedPrintJobClass *klass) { - GObjectClass *object_class; + GObjectClass *object_class; - object_class = G_OBJECT_CLASS (klass); + object_class = G_OBJECT_CLASS (klass); - object_class->get_property = xed_print_job_get_property; - object_class->set_property = xed_print_job_set_property; - object_class->finalize = xed_print_job_finalize; + object_class->get_property = xed_print_job_get_property; + object_class->set_property = xed_print_job_set_property; + object_class->finalize = xed_print_job_finalize; + object_class->dispose = xed_print_job_dispose; - g_object_class_install_property (object_class, - PROP_VIEW, - g_param_spec_object ("view", - "Xed View", - "Xed View to print", - XED_TYPE_VIEW, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_VIEW, + g_param_spec_object ("view", + "Xed View", + "Xed View to print", + XED_TYPE_VIEW, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY)); - print_job_signals[PRINTING] = - g_signal_new ("printing", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedPrintJobClass, printing), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, - 1, - G_TYPE_UINT); + print_job_signals[PRINTING] = + g_signal_new ("printing", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedPrintJobClass, printing), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, + 1, + G_TYPE_UINT); - print_job_signals[SHOW_PREVIEW] = - g_signal_new ("show-preview", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedPrintJobClass, show_preview), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - GTK_TYPE_WIDGET); + print_job_signals[SHOW_PREVIEW] = + g_signal_new ("show-preview", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedPrintJobClass, show_preview), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GTK_TYPE_WIDGET); - print_job_signals[DONE] = - g_signal_new ("done", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedPrintJobClass, done), - NULL, NULL, - xed_marshal_VOID__UINT_POINTER, - G_TYPE_NONE, - 2, - G_TYPE_UINT, - G_TYPE_POINTER); - - g_type_class_add_private (object_class, sizeof (XedPrintJobPrivate)); + print_job_signals[DONE] = + g_signal_new ("done", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedPrintJobClass, done), + NULL, NULL, + xed_marshal_VOID__UINT_POINTER, + G_TYPE_NONE, + 2, + G_TYPE_UINT, + G_TYPE_POINTER); + + g_type_class_add_private (object_class, sizeof (XedPrintJobPrivate)); } static void line_numbers_checkbutton_toggled (GtkToggleButton *button, - XedPrintJob *job) + XedPrintJob *job) { - if (gtk_toggle_button_get_active (button)) - { - gtk_widget_set_sensitive (job->priv->line_numbers_hbox, - xed_prefs_manager_print_line_numbers_can_set ()); - } - else - { - gtk_widget_set_sensitive (job->priv->line_numbers_hbox, FALSE); - } + gtk_widget_set_sensitive (job->priv->line_numbers_hbox, gtk_toggle_button_get_active (button)); } static void wrap_mode_checkbutton_toggled (GtkToggleButton *button, - XedPrintJob *job) + XedPrintJob *job) { - if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton))) - { - gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, - FALSE); - gtk_toggle_button_set_inconsistent ( - GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), - TRUE); - } - else - { - gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, - TRUE); - gtk_toggle_button_set_inconsistent ( - GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), - FALSE); - } + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton))) + { + gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, FALSE); + gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), TRUE); + } + else + { + gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, TRUE); + gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), FALSE); + } } static void -restore_button_clicked (GtkButton *button, - XedPrintJob *job) +restore_button_clicked (GtkButton *button, + XedPrintJob *job) { - if (xed_prefs_manager_print_font_body_can_set ()) - { - gchar *font; + gchar *body; + gchar *header; + gchar *numbers; - font = xed_prefs_manager_get_default_print_font_body (); + body = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_BODY_PANGO); + header = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_HEADER_PANGO); + numbers = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO); - gtk_font_button_set_font_name ( - GTK_FONT_BUTTON (job->priv->body_fontbutton), - font); + gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->body_fontbutton), body); + gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->headers_fontbutton), header); + gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->numbers_fontbutton), numbers); - g_free (font); - } - - if (xed_prefs_manager_print_font_header_can_set ()) - { - gchar *font; - - font = xed_prefs_manager_get_default_print_font_header (); - - gtk_font_button_set_font_name ( - GTK_FONT_BUTTON (job->priv->headers_fontbutton), - font); - - g_free (font); - } - - if (xed_prefs_manager_print_font_numbers_can_set ()) - { - gchar *font; - - font = xed_prefs_manager_get_default_print_font_numbers (); - - gtk_font_button_set_font_name ( - GTK_FONT_BUTTON (job->priv->numbers_fontbutton), - font); - - g_free (font); - } + g_free (body); + g_free (header); + g_free (numbers); } static GObject * -create_custom_widget_cb (GtkPrintOperation *operation, - XedPrintJob *job) +create_custom_widget_cb (GtkPrintOperation *operation, + XedPrintJob *job) { - gboolean ret; - GtkWidget *widget; - GtkWidget *error_widget; - gchar *font; - gint line_numbers; - gboolean can_set; - GtkWrapMode wrap_mode; - gchar *file; - gchar *root_objects[] = { - "adjustment1", - "contents", - NULL - }; + GtkBuilder *builder; + GtkWidget *contents; + guint line_numbers; + GtkWrapMode wrap_mode; + gboolean syntax_hl; + gboolean print_header; + gchar *font_body, *font_header, *font_numbers; + gchar *root_objects[] = { + "adjustment1", + "contents", + NULL + }; - file = xed_dirs_get_ui_file ("xed-print-preferences.ui"); - ret = xed_utils_get_ui_objects (file, - root_objects, - &error_widget, - "contents", &widget, - "syntax_checkbutton", &job->priv->syntax_checkbutton, - "line_numbers_checkbutton", &job->priv->line_numbers_checkbutton, - "line_numbers_hbox", &job->priv->line_numbers_hbox, - "line_numbers_spinbutton", &job->priv->line_numbers_spinbutton, - "page_header_checkbutton", &job->priv->page_header_checkbutton, - "text_wrapping_checkbutton", &job->priv->text_wrapping_checkbutton, - "do_not_split_checkbutton", &job->priv->do_not_split_checkbutton, - "fonts_table", &job->priv->fonts_table, - "body_font_label", &job->priv->body_font_label, - "body_fontbutton", &job->priv->body_fontbutton, - "headers_font_label", &job->priv->headers_font_label, - "headers_fontbutton", &job->priv->headers_fontbutton, - "numbers_font_label", &job->priv->numbers_font_label, - "numbers_fontbutton", &job->priv->numbers_fontbutton, - "restore_button", &job->priv->restore_button, - NULL); - g_free (file); + builder = gtk_builder_new (); + gtk_builder_add_objects_from_resource (builder, "/org/x/editor/ui/xed-print-preferences.ui", root_objects, NULL); + contents = GTK_WIDGET (gtk_builder_get_object (builder, "contents")); + g_object_ref (contents); + job->priv->syntax_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "syntax_checkbutton")); + job->priv->line_numbers_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "line_numbers_checkbutton")); + job->priv->line_numbers_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "line_numbers_hbox")); + job->priv->line_numbers_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "line_numbers_spinbutton")); + job->priv->page_header_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "page_header_checkbutton")); + job->priv->text_wrapping_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "text_wrapping_checkbutton")); + job->priv->do_not_split_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "do_not_split_checkbutton")); + job->priv->fonts_table = GTK_WIDGET (gtk_builder_get_object (builder, "fonts_table")); + job->priv->body_font_label = GTK_WIDGET (gtk_builder_get_object (builder, "body_font_label")); + job->priv->body_fontbutton = GTK_WIDGET (gtk_builder_get_object (builder, "body_fontbutton")); + job->priv->headers_font_label = GTK_WIDGET (gtk_builder_get_object (builder, "headers_font_label")); + job->priv->headers_fontbutton = GTK_WIDGET (gtk_builder_get_object (builder, "headers_fontbutton")); + job->priv->numbers_font_label = GTK_WIDGET (gtk_builder_get_object (builder, "numbers_font_label")); + job->priv->numbers_fontbutton = GTK_WIDGET (gtk_builder_get_object (builder, "numbers_fontbutton")); + job->priv->restore_button = GTK_WIDGET (gtk_builder_get_object (builder, "restore_button")); + g_object_unref (builder); - if (!ret) - { - return G_OBJECT (error_widget); - } + /* Get all settings values */ + syntax_hl = g_settings_get_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING); + print_header = g_settings_get_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_HEADER); + line_numbers = g_settings_get_uint (job->priv->print_settings, XED_SETTINGS_PRINT_LINE_NUMBERS); + font_body = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_BODY_PANGO); + font_header = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_HEADER_PANGO); + font_numbers = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO); - /* Print syntax */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->syntax_checkbutton), - xed_prefs_manager_get_print_syntax_hl ()); - gtk_widget_set_sensitive (job->priv->syntax_checkbutton, - xed_prefs_manager_print_syntax_hl_can_set ()); + /* Print syntax */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->syntax_checkbutton), syntax_hl); - /* Print page headers */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->page_header_checkbutton), - xed_prefs_manager_get_print_header ()); - gtk_widget_set_sensitive (job->priv->page_header_checkbutton, - xed_prefs_manager_print_header_can_set ()); + /* Print page headers */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->page_header_checkbutton), print_header); - /* Line numbers */ - line_numbers = xed_prefs_manager_get_print_line_numbers (); - can_set = xed_prefs_manager_print_line_numbers_can_set (); + /* Line numbers */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->line_numbers_checkbutton), line_numbers > 0); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->line_numbers_checkbutton), - line_numbers > 0); - gtk_widget_set_sensitive (job->priv->line_numbers_checkbutton, can_set); + if (line_numbers > 0) + { + gtk_spin_button_set_value (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton), (guint) line_numbers); + gtk_widget_set_sensitive (job->priv->line_numbers_hbox, TRUE); + } + else + { + gtk_spin_button_set_value (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton), 1); + gtk_widget_set_sensitive (job->priv->line_numbers_hbox, FALSE); + } - if (line_numbers > 0) - { - gtk_spin_button_set_value (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton), - (guint) line_numbers); - gtk_widget_set_sensitive (job->priv->line_numbers_hbox, can_set); - } - else - { - gtk_spin_button_set_value (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton), - 1); - gtk_widget_set_sensitive (job->priv->line_numbers_hbox, FALSE); - } + /* Text wrapping */ + wrap_mode = g_settings_get_enum (job->priv->print_settings, XED_SETTINGS_PRINT_WRAP_MODE); - /* Text wrapping */ - wrap_mode = xed_prefs_manager_get_print_wrap_mode (); + switch (wrap_mode) + { + case GTK_WRAP_WORD: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), TRUE); + break; + case GTK_WRAP_CHAR: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), FALSE); + break; + default: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), FALSE); + gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), TRUE); + } - switch (wrap_mode) - { - case GTK_WRAP_WORD: - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), TRUE); - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), TRUE); - break; - case GTK_WRAP_CHAR: - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), TRUE); - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), FALSE); - break; - default: - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), FALSE); - gtk_toggle_button_set_inconsistent ( - GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), TRUE); - } + gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, wrap_mode != GTK_WRAP_NONE); - can_set = xed_prefs_manager_print_wrap_mode_can_set (); + /* Set initial values */ + gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->body_fontbutton), font_body); + g_free (font_body); - gtk_widget_set_sensitive (job->priv->text_wrapping_checkbutton, can_set); - gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, - can_set && (wrap_mode != GTK_WRAP_NONE)); + gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->headers_fontbutton), font_header); + g_free (font_header); - /* Set initial values */ - font = xed_prefs_manager_get_print_font_body (); - gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->body_fontbutton), - font); - g_free (font); + gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->numbers_fontbutton), font_numbers); + g_free (font_numbers); - font = xed_prefs_manager_get_print_font_header (); - gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->headers_fontbutton), - font); - g_free (font); + g_signal_connect (job->priv->line_numbers_checkbutton, "toggled", + G_CALLBACK (line_numbers_checkbutton_toggled), job); + g_signal_connect (job->priv->text_wrapping_checkbutton, "toggled", + G_CALLBACK (wrap_mode_checkbutton_toggled), job); + g_signal_connect (job->priv->do_not_split_checkbutton, "toggled", + G_CALLBACK (wrap_mode_checkbutton_toggled), job); + g_signal_connect (job->priv->restore_button, "clicked", + G_CALLBACK (restore_button_clicked), job); - font = xed_prefs_manager_get_print_font_numbers (); - gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->numbers_fontbutton), - font); - g_free (font); - - can_set = xed_prefs_manager_print_font_body_can_set (); - gtk_widget_set_sensitive (job->priv->body_fontbutton, can_set); - gtk_widget_set_sensitive (job->priv->body_font_label, can_set); - - can_set = xed_prefs_manager_print_font_header_can_set (); - gtk_widget_set_sensitive (job->priv->headers_fontbutton, can_set); - gtk_widget_set_sensitive (job->priv->headers_font_label, can_set); - - can_set = xed_prefs_manager_print_font_numbers_can_set (); - gtk_widget_set_sensitive (job->priv->numbers_fontbutton, can_set); - gtk_widget_set_sensitive (job->priv->numbers_font_label, can_set); - - g_signal_connect (job->priv->line_numbers_checkbutton, - "toggled", - G_CALLBACK (line_numbers_checkbutton_toggled), - job); - g_signal_connect (job->priv->text_wrapping_checkbutton, - "toggled", - G_CALLBACK (wrap_mode_checkbutton_toggled), - job); - g_signal_connect (job->priv->do_not_split_checkbutton, - "toggled", - G_CALLBACK (wrap_mode_checkbutton_toggled), - job); - g_signal_connect (job->priv->restore_button, - "clicked", - G_CALLBACK (restore_button_clicked), - job); - - return G_OBJECT (widget); + return G_OBJECT (contents); } static void custom_widget_apply_cb (GtkPrintOperation *operation, - GtkWidget *widget, - XedPrintJob *job) + GtkWidget *widget, + XedPrintJob *job) { - xed_prefs_manager_set_print_syntax_hl (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->syntax_checkbutton))); + gboolean syntax, page_header; + const gchar *body, *header, *numbers; + GtkWrapMode wrap_mode; - xed_prefs_manager_set_print_header (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->page_header_checkbutton))); + syntax = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->syntax_checkbutton)); + page_header = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->page_header_checkbutton)); + body = gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->body_fontbutton)); + header = gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->headers_fontbutton)); + numbers = gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->numbers_fontbutton)); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->line_numbers_checkbutton))) - { - xed_prefs_manager_set_print_line_numbers ( - MAX (1, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton)))); - } - else - { - xed_prefs_manager_set_print_line_numbers (0); - } + g_settings_set_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING, syntax); + g_settings_set_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_HEADER, page_header); + g_settings_set_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_BODY_PANGO, body); + g_settings_set_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_HEADER_PANGO, header); + g_settings_set_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO, numbers); - if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton))) - { - xed_prefs_manager_set_print_wrap_mode (GTK_WRAP_NONE); - } - else - { - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton))) - { - xed_prefs_manager_set_print_wrap_mode (GTK_WRAP_WORD); - } - else - { - xed_prefs_manager_set_print_wrap_mode (GTK_WRAP_CHAR); - } - } + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->line_numbers_checkbutton))) + { + g_settings_set_uint (job->priv->print_settings, XED_SETTINGS_PRINT_LINE_NUMBERS, + MAX (1, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton)))); + } + else + { + g_settings_set_uint (job->priv->print_settings, XED_SETTINGS_PRINT_LINE_NUMBERS, 0); + } - xed_prefs_manager_set_print_font_body (gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->body_fontbutton))); - xed_prefs_manager_set_print_font_header (gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->headers_fontbutton))); - xed_prefs_manager_set_print_font_numbers (gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->numbers_fontbutton))); + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton))) + { + wrap_mode = GTK_WRAP_NONE; + } + else + { + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton))) + { + wrap_mode = GTK_WRAP_WORD; + } + else + { + wrap_mode = GTK_WRAP_CHAR; + } + } + + g_settings_set_enum (job->priv->print_settings, XED_SETTINGS_PRINT_WRAP_MODE, wrap_mode); } static void create_compositor (XedPrintJob *job) { - gchar *print_font_body; - gchar *print_font_header; - gchar *print_font_numbers; - - /* Create and initialize print compositor */ - print_font_body = xed_prefs_manager_get_print_font_body (); - print_font_header = xed_prefs_manager_get_print_font_header (); - print_font_numbers = xed_prefs_manager_get_print_font_numbers (); - - job->priv->compositor = GTK_SOURCE_PRINT_COMPOSITOR ( - g_object_new (GTK_SOURCE_TYPE_PRINT_COMPOSITOR, - "buffer", GTK_SOURCE_BUFFER (job->priv->doc), - "tab-width", gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (job->priv->view)), - "highlight-syntax", gtk_source_buffer_get_highlight_syntax (GTK_SOURCE_BUFFER (job->priv->doc)) && - xed_prefs_manager_get_print_syntax_hl (), - "wrap-mode", xed_prefs_manager_get_print_wrap_mode (), - "print-line-numbers", xed_prefs_manager_get_print_line_numbers (), - "print-header", xed_prefs_manager_get_print_header (), - "print-footer", FALSE, - "body-font-name", print_font_body, - "line-numbers-font-name", print_font_numbers, - "header-font-name", print_font_header, - NULL)); + gchar *print_font_body; + gchar *print_font_header; + gchar *print_font_numbers; + gboolean syntax_hl; + GtkWrapMode wrap_mode; + guint print_line_numbers; + gboolean print_header; - g_free (print_font_body); - g_free (print_font_header); - g_free (print_font_numbers); - - if (xed_prefs_manager_get_print_header ()) - { - gchar *doc_name; - gchar *name_to_display; - gchar *left; + /* Create and initialize print compositor */ + print_font_body = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_BODY_PANGO); + print_font_header = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_HEADER_PANGO); + print_font_numbers = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO); + syntax_hl = g_settings_get_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING); + print_line_numbers = g_settings_get_uint (job->priv->print_settings, XED_SETTINGS_PRINT_LINE_NUMBERS); + print_header = g_settings_get_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_HEADER); + wrap_mode = g_settings_get_enum (job->priv->print_settings, XED_SETTINGS_PRINT_WRAP_MODE); - doc_name = xed_document_get_uri_for_display (job->priv->doc); - name_to_display = xed_utils_str_middle_truncate (doc_name, 60); + job->priv->compositor = GTK_SOURCE_PRINT_COMPOSITOR ( + g_object_new (GTK_SOURCE_TYPE_PRINT_COMPOSITOR, + "buffer", GTK_SOURCE_BUFFER (job->priv->doc), + "tab-width", gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (job->priv->view)), + "highlight-syntax", gtk_source_buffer_get_highlight_syntax (GTK_SOURCE_BUFFER (job->priv->doc)) && + syntax_hl, + "wrap-mode", wrap_mode, + "print-line-numbers", print_line_numbers, + "print-header", print_header, + "print-footer", FALSE, + "body-font-name", print_font_body, + "line-numbers-font-name", print_font_numbers, + "header-font-name", print_font_header, + NULL)); - left = g_strdup_printf (_("File: %s"), name_to_display); + g_free (print_font_body); + g_free (print_font_header); + g_free (print_font_numbers); - /* Translators: %N is the current page number, %Q is the total - * number of pages (ex. Page 2 of 10) - */ - gtk_source_print_compositor_set_header_format (job->priv->compositor, - TRUE, - left, - NULL, - _("Page %N of %Q")); + if (print_header) + { + gchar *doc_name; + gchar *name_to_display; + gchar *left; - g_free (doc_name); - g_free (name_to_display); - g_free (left); - } + doc_name = xed_document_get_uri_for_display (job->priv->doc); + name_to_display = xed_utils_str_middle_truncate (doc_name, 60); + + left = g_strdup_printf (_("File: %s"), name_to_display); + + /* Translators: %N is the current page number, %Q is the total + * number of pages (ex. Page 2 of 10) + */ + gtk_source_print_compositor_set_header_format (job->priv->compositor, + TRUE, + left, + NULL, + _("Page %N of %Q")); + + g_free (doc_name); + g_free (name_to_display); + g_free (left); + } } static void -begin_print_cb (GtkPrintOperation *operation, - GtkPrintContext *context, - XedPrintJob *job) +begin_print_cb (GtkPrintOperation *operation, + GtkPrintContext *context, + XedPrintJob *job) { - create_compositor (job); + create_compositor (job); - job->priv->status = XED_PRINT_JOB_STATUS_PAGINATING; + job->priv->status = XED_PRINT_JOB_STATUS_PAGINATING; - job->priv->progress = 0.0; - - g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status); + job->priv->progress = 0.0; + + g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status); } static void preview_ready (GtkPrintOperationPreview *gtk_preview, - GtkPrintContext *context, - XedPrintJob *job) + GtkPrintContext *context, + XedPrintJob *job) { - job->priv->is_preview = TRUE; + job->priv->is_preview = TRUE; - g_signal_emit (job, print_job_signals[SHOW_PREVIEW], 0, job->priv->preview); + g_signal_emit (job, print_job_signals[SHOW_PREVIEW], 0, job->priv->preview); } static void preview_destroyed (GtkWidget *preview, - GtkPrintOperationPreview *gtk_preview) + GtkPrintOperationPreview *gtk_preview) { - gtk_print_operation_preview_end_preview (gtk_preview); -} - -static gboolean -preview_cb (GtkPrintOperation *op, - GtkPrintOperationPreview *gtk_preview, - GtkPrintContext *context, - GtkWindow *parent, - XedPrintJob *job) -{ - job->priv->preview = xed_print_preview_new (op, gtk_preview, context); - - g_signal_connect_after (gtk_preview, - "ready", - G_CALLBACK (preview_ready), - job); - - /* FIXME: should this go in the preview widget itself? */ - g_signal_connect (job->priv->preview, - "destroy", - G_CALLBACK (preview_destroyed), - gtk_preview); - - return TRUE; + gtk_print_operation_preview_end_preview (gtk_preview); } static gboolean -paginate_cb (GtkPrintOperation *operation, - GtkPrintContext *context, - XedPrintJob *job) +preview_cb (GtkPrintOperation *op, + GtkPrintOperationPreview *gtk_preview, + GtkPrintContext *context, + GtkWindow *parent, + XedPrintJob *job) { - gboolean res; - - job->priv->status = XED_PRINT_JOB_STATUS_PAGINATING; - - res = gtk_source_print_compositor_paginate (job->priv->compositor, context); - - if (res) - { - gint n_pages; + job->priv->preview = xed_print_preview_new (op, gtk_preview, context); - n_pages = gtk_source_print_compositor_get_n_pages (job->priv->compositor); - gtk_print_operation_set_n_pages (job->priv->operation, n_pages); - } + g_signal_connect_after (gtk_preview, "ready", + G_CALLBACK (preview_ready), job); - job->priv->progress = gtk_source_print_compositor_get_pagination_progress (job->priv->compositor); + /* FIXME: should this go in the preview widget itself? */ + g_signal_connect (job->priv->preview, "destroy", + G_CALLBACK (preview_destroyed), gtk_preview); - /* When previewing, the progress is just for pagination, when printing - * it's split between pagination and rendering */ - if (!job->priv->is_preview) - job->priv->progress /= 2.0; + return TRUE; +} - g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status); +static gboolean +paginate_cb (GtkPrintOperation *operation, + GtkPrintContext *context, + XedPrintJob *job) +{ + gboolean res; - return res; + job->priv->status = XED_PRINT_JOB_STATUS_PAGINATING; + + res = gtk_source_print_compositor_paginate (job->priv->compositor, context); + + if (res) + { + gint n_pages; + + n_pages = gtk_source_print_compositor_get_n_pages (job->priv->compositor); + gtk_print_operation_set_n_pages (job->priv->operation, n_pages); + } + + job->priv->progress = gtk_source_print_compositor_get_pagination_progress (job->priv->compositor); + + /* When previewing, the progress is just for pagination, when printing + * it's split between pagination and rendering */ + if (!job->priv->is_preview) + { + job->priv->progress /= 2.0; + } + + g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status); + + return res; } static void draw_page_cb (GtkPrintOperation *operation, - GtkPrintContext *context, - gint page_nr, - XedPrintJob *job) + GtkPrintContext *context, + gint page_nr, + XedPrintJob *job) { - gint n_pages; + gint n_pages; - /* In preview, pages are drawn on the fly, so rendering is - * not part of the progress */ - if (!job->priv->is_preview) - { - g_free (job->priv->status_string); - - n_pages = gtk_source_print_compositor_get_n_pages (job->priv->compositor); - - job->priv->status = XED_PRINT_JOB_STATUS_DRAWING; - - job->priv->status_string = g_strdup_printf ("Rendering page %d of %d...", - page_nr + 1, - n_pages); - - job->priv->progress = page_nr / (2.0 * n_pages) + 0.5; + /* In preview, pages are drawn on the fly, so rendering is + * not part of the progress */ + if (!job->priv->is_preview) + { + g_free (job->priv->status_string); - g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status); - } + n_pages = gtk_source_print_compositor_get_n_pages (job->priv->compositor); - gtk_source_print_compositor_draw_page (job->priv->compositor, context, page_nr); + job->priv->status = XED_PRINT_JOB_STATUS_DRAWING; + + job->priv->status_string = g_strdup_printf ("Rendering page %d of %d...", page_nr + 1, n_pages); + + job->priv->progress = page_nr / (2.0 * n_pages) + 0.5; + + g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status); + } + + gtk_source_print_compositor_draw_page (job->priv->compositor, context, page_nr); } static void -end_print_cb (GtkPrintOperation *operation, - GtkPrintContext *context, - XedPrintJob *job) +end_print_cb (GtkPrintOperation *operation, + GtkPrintContext *context, + XedPrintJob *job) { - g_object_unref (job->priv->compositor); - job->priv->compositor = NULL; + g_object_unref (job->priv->compositor); + job->priv->compositor = NULL; } static void done_cb (GtkPrintOperation *operation, - GtkPrintOperationResult result, - XedPrintJob *job) + GtkPrintOperationResult result, + XedPrintJob *job) { - GError *error = NULL; - XedPrintJobResult print_result; + GError *error = NULL; + XedPrintJobResult print_result; - switch (result) - { - case GTK_PRINT_OPERATION_RESULT_CANCEL: - print_result = XED_PRINT_JOB_RESULT_CANCEL; - break; + switch (result) + { + case GTK_PRINT_OPERATION_RESULT_CANCEL: + print_result = XED_PRINT_JOB_RESULT_CANCEL; + break; - case GTK_PRINT_OPERATION_RESULT_APPLY: - print_result = XED_PRINT_JOB_RESULT_OK; - break; + case GTK_PRINT_OPERATION_RESULT_APPLY: + print_result = XED_PRINT_JOB_RESULT_OK; + break; - case GTK_PRINT_OPERATION_RESULT_ERROR: - print_result = XED_PRINT_JOB_RESULT_ERROR; - gtk_print_operation_get_error (operation, &error); - break; + case GTK_PRINT_OPERATION_RESULT_ERROR: + print_result = XED_PRINT_JOB_RESULT_ERROR; + gtk_print_operation_get_error (operation, &error); + break; - default: - g_return_if_reached (); - } - - /* Avoid job is destroyed in the handler of the "done" message */ - g_object_ref (job); - - g_signal_emit (job, print_job_signals[DONE], 0, print_result, error); - - g_object_unref (operation); - job->priv->operation = NULL; - - g_object_unref (job); + default: + g_return_if_reached (); + } + + /* Avoid job is destroyed in the handler of the "done" message */ + g_object_ref (job); + + g_signal_emit (job, print_job_signals[DONE], 0, print_result, error); + + g_object_unref (operation); + job->priv->operation = NULL; + + g_object_unref (job); } /* Note that xed_print_job_print can can only be called once on a given XedPrintJob */ -GtkPrintOperationResult -xed_print_job_print (XedPrintJob *job, - GtkPrintOperationAction action, - GtkPageSetup *page_setup, - GtkPrintSettings *settings, - GtkWindow *parent, - GError **error) +GtkPrintOperationResult +xed_print_job_print (XedPrintJob *job, + GtkPrintOperationAction action, + GtkPageSetup *page_setup, + GtkPrintSettings *settings, + GtkWindow *parent, + GError **error) { - XedPrintJobPrivate *priv; - gchar *job_name; + XedPrintJobPrivate *priv; + gchar *job_name; - g_return_val_if_fail (job->priv->compositor == NULL, GTK_PRINT_OPERATION_RESULT_ERROR); + g_return_val_if_fail (job->priv->compositor == NULL, GTK_PRINT_OPERATION_RESULT_ERROR); - priv = job->priv; + priv = job->priv; - /* Check if we are previewing */ - priv->is_preview = (action == GTK_PRINT_OPERATION_ACTION_PREVIEW); + /* Check if we are previewing */ + priv->is_preview = (action == GTK_PRINT_OPERATION_ACTION_PREVIEW); - /* Create print operation */ - job->priv->operation = gtk_print_operation_new (); + /* Create print operation */ + job->priv->operation = gtk_print_operation_new (); - if (settings) - gtk_print_operation_set_print_settings (priv->operation, - settings); + if (settings) + { + gtk_print_operation_set_print_settings (priv->operation, settings); + } - if (page_setup != NULL) - gtk_print_operation_set_default_page_setup (priv->operation, - page_setup); + if (page_setup != NULL) + { + gtk_print_operation_set_default_page_setup (priv->operation, page_setup); + } - job_name = xed_document_get_short_name_for_display (priv->doc); - gtk_print_operation_set_job_name (priv->operation, job_name); - g_free (job_name); + job_name = xed_document_get_short_name_for_display (priv->doc); + gtk_print_operation_set_job_name (priv->operation, job_name); + g_free (job_name); - gtk_print_operation_set_embed_page_setup (priv->operation, TRUE); + gtk_print_operation_set_embed_page_setup (priv->operation, TRUE); - gtk_print_operation_set_custom_tab_label (priv->operation, - _("Text Editor")); + gtk_print_operation_set_custom_tab_label (priv->operation, _("Text Editor")); - gtk_print_operation_set_allow_async (priv->operation, TRUE); + gtk_print_operation_set_allow_async (priv->operation, TRUE); - g_signal_connect (priv->operation, - "create-custom-widget", - G_CALLBACK (create_custom_widget_cb), - job); - g_signal_connect (priv->operation, - "custom-widget-apply", - G_CALLBACK (custom_widget_apply_cb), - job); - g_signal_connect (priv->operation, - "begin-print", - G_CALLBACK (begin_print_cb), - job); - g_signal_connect (priv->operation, - "preview", - G_CALLBACK (preview_cb), - job); - g_signal_connect (priv->operation, - "paginate", - G_CALLBACK (paginate_cb), - job); - g_signal_connect (priv->operation, - "draw-page", - G_CALLBACK (draw_page_cb), - job); - g_signal_connect (priv->operation, - "end-print", - G_CALLBACK (end_print_cb), - job); - g_signal_connect (priv->operation, - "done", - G_CALLBACK (done_cb), - job); + g_signal_connect (priv->operation, "create-custom-widget", + G_CALLBACK (create_custom_widget_cb), job); + g_signal_connect (priv->operation, "custom-widget-apply", + G_CALLBACK (custom_widget_apply_cb), job); + g_signal_connect (priv->operation, "begin-print", + G_CALLBACK (begin_print_cb), job); + g_signal_connect (priv->operation, "preview", + G_CALLBACK (preview_cb), job); + g_signal_connect (priv->operation, "paginate", + G_CALLBACK (paginate_cb), job); + g_signal_connect (priv->operation, "draw-page", + G_CALLBACK (draw_page_cb), job); + g_signal_connect (priv->operation, "end-print", + G_CALLBACK (end_print_cb), job); + g_signal_connect (priv->operation, "done", + G_CALLBACK (done_cb), job); - return gtk_print_operation_run (priv->operation, - action, - parent, - error); + return gtk_print_operation_run (priv->operation, action, parent, error); } static void xed_print_job_init (XedPrintJob *job) { - job->priv = XED_PRINT_JOB_GET_PRIVATE (job); - - job->priv->status = XED_PRINT_JOB_STATUS_INIT; - - job->priv->status_string = g_strdup (_("Preparing...")); + job->priv = XED_PRINT_JOB_GET_PRIVATE (job); + + job->priv->print_settings = g_settings_new ("org.x.editor.preferences.print"); + + job->priv->status = XED_PRINT_JOB_STATUS_INIT; + + job->priv->status_string = g_strdup (_("Preparing...")); } XedPrintJob * xed_print_job_new (XedView *view) { - XedPrintJob *job; - - g_return_val_if_fail (XED_IS_VIEW (view), NULL); - - job = XED_PRINT_JOB (g_object_new (XED_TYPE_PRINT_JOB, - "view", view, - NULL)); + XedPrintJob *job; - return job; + g_return_val_if_fail (XED_IS_VIEW (view), NULL); + + job = XED_PRINT_JOB (g_object_new (XED_TYPE_PRINT_JOB, "view", view, NULL)); + + return job; } void xed_print_job_cancel (XedPrintJob *job) { - g_return_if_fail (XED_IS_PRINT_JOB (job)); + g_return_if_fail (XED_IS_PRINT_JOB (job)); - gtk_print_operation_cancel (job->priv->operation); + gtk_print_operation_cancel (job->priv->operation); } const gchar * xed_print_job_get_status_string (XedPrintJob *job) { - g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL); - g_return_val_if_fail (job->priv->status_string != NULL, NULL); - - return job->priv->status_string; + g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL); + g_return_val_if_fail (job->priv->status_string != NULL, NULL); + + return job->priv->status_string; } gdouble xed_print_job_get_progress (XedPrintJob *job) { - g_return_val_if_fail (XED_IS_PRINT_JOB (job), 0.0); + g_return_val_if_fail (XED_IS_PRINT_JOB (job), 0.0); - return job->priv->progress; + return job->priv->progress; } GtkPrintSettings * xed_print_job_get_print_settings (XedPrintJob *job) { - g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL); + g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL); - return gtk_print_operation_get_print_settings (job->priv->operation); + return gtk_print_operation_get_print_settings (job->priv->operation); } GtkPageSetup * xed_print_job_get_page_setup (XedPrintJob *job) { - g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL); + g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL); - return gtk_print_operation_get_default_page_setup (job->priv->operation); + return gtk_print_operation_get_default_page_setup (job->priv->operation); } diff --git a/xed/xed-print-preview.c b/xed/xed-print-preview.c index ec2271e..54164d4 100644 --- a/xed/xed-print-preview.c +++ b/xed/xed-print-preview.c @@ -44,140 +44,138 @@ struct _XedPrintPreviewPrivate { - GtkPrintOperation *operation; - GtkPrintContext *context; - GtkPrintOperationPreview *gtk_preview; + GtkPrintOperation *operation; + GtkPrintContext *context; + GtkPrintOperationPreview *gtk_preview; - GtkWidget *layout; - GtkWidget *scrolled_window; + GtkWidget *layout; + GtkWidget *scrolled_window; - GtkToolItem *next; - GtkToolItem *prev; - GtkWidget *page_entry; - GtkWidget *last; - GtkToolItem *multi; - GtkToolItem *zoom_one; - GtkToolItem *zoom_fit; - GtkToolItem *zoom_in; - GtkToolItem *zoom_out; + GtkWidget *next; + GtkWidget *prev; + GtkWidget *page_entry; + GtkWidget *last; + GtkWidget *multi; + GtkWidget *zoom_one; + GtkWidget *zoom_fit; + GtkWidget *zoom_in; + GtkWidget *zoom_out; - /* real size of the page in inches */ - double paper_w; - double paper_h; - double dpi; + /* real size of the page in inches */ + double paper_w; + double paper_h; + double dpi; - double scale; + double scale; - /* size of the tile of a page (including padding - * and drop shadow) in pixels */ - gint tile_w; - gint tile_h; + /* size of the tile of a page (including padding + * and drop shadow) in pixels */ + gint tile_w; + gint tile_h; - GtkPageOrientation orientation; + GtkPageOrientation orientation; - /* multipage support */ - gint rows; - gint cols; + /* multipage support */ + gint rows; + gint cols; - guint n_pages; - guint cur_page; + guint n_pages; + guint cur_page; }; G_DEFINE_TYPE (XedPrintPreview, xed_print_preview, GTK_TYPE_BOX) -static void +static void xed_print_preview_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - //XedPrintPreview *preview = XED_PRINT_PREVIEW (object); - - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + //XedPrintPreview *preview = XED_PRINT_PREVIEW (object); + + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } -static void +static void xed_print_preview_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - //XedPrintPreview *preview = XED_PRINT_PREVIEW (object); - - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + //XedPrintPreview *preview = XED_PRINT_PREVIEW (object); + + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_print_preview_finalize (GObject *object) { - //XedPrintPreview *preview = XED_PRINT_PREVIEW (object); + //XedPrintPreview *preview = XED_PRINT_PREVIEW (object); - G_OBJECT_CLASS (xed_print_preview_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_print_preview_parent_class)->finalize (object); } static void xed_print_preview_grab_focus (GtkWidget *widget) { - XedPrintPreview *preview; + XedPrintPreview *preview; - preview = XED_PRINT_PREVIEW (widget); + preview = XED_PRINT_PREVIEW (widget); - gtk_widget_grab_focus (GTK_WIDGET (preview->priv->layout)); + gtk_widget_grab_focus (GTK_WIDGET (preview->priv->layout)); } -static void +static void xed_print_preview_class_init (XedPrintPreviewClass *klass) { - GObjectClass *object_class; - GtkWidgetClass *widget_class; + GObjectClass *object_class; + GtkWidgetClass *widget_class; - object_class = G_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); + object_class = G_OBJECT_CLASS (klass); + widget_class = GTK_WIDGET_CLASS (klass); - object_class->get_property = xed_print_preview_get_property; - object_class->set_property = xed_print_preview_set_property; - object_class->finalize = xed_print_preview_finalize; + object_class->get_property = xed_print_preview_get_property; + object_class->set_property = xed_print_preview_set_property; + object_class->finalize = xed_print_preview_finalize; - widget_class->grab_focus = xed_print_preview_grab_focus; + widget_class->grab_focus = xed_print_preview_grab_focus; - g_type_class_add_private (object_class, sizeof(XedPrintPreviewPrivate)); + g_type_class_add_private (object_class, sizeof(XedPrintPreviewPrivate)); } static void update_layout_size (XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; + XedPrintPreviewPrivate *priv; - priv = preview->priv; + priv = preview->priv; - /* force size of the drawing area to make the scrolled window work */ - gtk_layout_set_size (GTK_LAYOUT (priv->layout), - priv->tile_w * priv->cols, - priv->tile_h * priv->rows); + /* force size of the drawing area to make the scrolled window work */ + gtk_layout_set_size (GTK_LAYOUT (priv->layout), priv->tile_w * priv->cols, priv->tile_h * priv->rows); - gtk_widget_queue_draw (preview->priv->layout); + gtk_widget_queue_draw (preview->priv->layout); } static void set_rows_and_cols (XedPrintPreview *preview, - gint rows, - gint cols) + gint rows, + gint cols) { - /* TODO: set the zoom appropriately */ + /* TODO: set the zoom appropriately */ - preview->priv->rows = rows; - preview->priv->cols = cols; - update_layout_size (preview); + preview->priv->rows = rows; + preview->priv->cols = cols; + update_layout_size (preview); } /* get the paper size in points: these must be used only @@ -186,17 +184,17 @@ set_rows_and_cols (XedPrintPreview *preview, static double get_paper_width (XedPrintPreview *preview) { - return preview->priv->paper_w * preview->priv->dpi; + return preview->priv->paper_w * preview->priv->dpi; } static double get_paper_height (XedPrintPreview *preview) { - return preview->priv->paper_h * preview->priv->dpi; + return preview->priv->paper_h * preview->priv->dpi; } #define PAGE_PAD 12 -#define PAGE_SHADOW_OFFSET 5 +#define PAGE_SHADOW_OFFSET 5 /* The tile size is the size of the area where a page * will be drawn including the padding and idependent @@ -206,25 +204,25 @@ get_paper_height (XedPrintPreview *preview) static void update_tile_size (XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; - gint w, h; + XedPrintPreviewPrivate *priv; + gint w, h; - priv = preview->priv; + priv = preview->priv; - w = 2 * PAGE_PAD + floor (priv->scale * get_paper_width (preview) + 0.5); - h = 2 * PAGE_PAD + floor (priv->scale * get_paper_height (preview) + 0.5); + w = 2 * PAGE_PAD + floor (priv->scale * get_paper_width (preview) + 0.5); + h = 2 * PAGE_PAD + floor (priv->scale * get_paper_height (preview) + 0.5); - if ((priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) || - (priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)) - { - priv->tile_w = h; - priv->tile_h = w; - } - else - { - priv->tile_w = w; - priv->tile_h = h; - } + if ((priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) || + (priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)) + { + priv->tile_w = h; + priv->tile_h = w; + } + else + { + priv->tile_w = w; + priv->tile_h = h; + } } /* Zoom should always be set with one of these two function @@ -232,67 +230,63 @@ update_tile_size (XedPrintPreview *preview) static void set_zoom_factor (XedPrintPreview *preview, - double zoom) + double zoom) { - XedPrintPreviewPrivate *priv; + XedPrintPreviewPrivate *priv; - priv = preview->priv; + priv = preview->priv; - priv->scale = zoom; + priv->scale = zoom; - update_tile_size (preview); - update_layout_size (preview); + update_tile_size (preview); + update_layout_size (preview); } static void set_zoom_fit_to_size (XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; - double width, height; - double p_width, p_height; - double zoomx, zoomy; + XedPrintPreviewPrivate *priv; + double width, height; + double p_width, p_height; + double zoomx, zoomy; - priv = preview->priv; + priv = preview->priv; - g_object_get (gtk_layout_get_hadjustment (GTK_LAYOUT (priv->layout)), - "page-size", &width, - NULL); - g_object_get (gtk_layout_get_vadjustment (GTK_LAYOUT (priv->layout)), - "page-size", &height, - NULL); + g_object_get (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (priv->layout)), "page-size", &width, NULL); + g_object_get (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->layout)), "page-size", &height, NULL); - width /= priv->cols; - height /= priv->rows; + width /= priv->cols; + height /= priv->rows; - if ((priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) || - (priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)) - { - p_width = get_paper_height (preview); - p_height = get_paper_width (preview); - } - else - { - p_width = get_paper_width (preview); - p_height = get_paper_height (preview); - } + if ((priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) || + (priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)) + { + p_width = get_paper_height (preview); + p_height = get_paper_width (preview); + } + else + { + p_width = get_paper_width (preview); + p_height = get_paper_height (preview); + } - zoomx = MAX (1, width - 2 * PAGE_PAD) / p_width; - zoomy = MAX (1, height - 2 * PAGE_PAD) / p_height; + zoomx = MAX (1, width - 2 * PAGE_PAD) / p_width; + zoomy = MAX (1, height - 2 * PAGE_PAD) / p_height; - if (zoomx <= zoomy) - { - priv->tile_w = width; - priv->tile_h = floor (0.5 + width * (p_height / p_width)); - priv->scale = zoomx; - } - else - { - priv->tile_w = floor (0.5 + height * (p_width / p_height)); - priv->tile_h = height; - priv->scale = zoomy; - } + if (zoomx <= zoomy) + { + priv->tile_w = width; + priv->tile_h = floor (0.5 + width * (p_height / p_width)); + priv->scale = zoomx; + } + else + { + priv->tile_w = floor (0.5 + height * (p_width / p_height)); + priv->tile_h = height; + priv->scale = zoomy; + } - update_layout_size (preview); + update_layout_size (preview); } #define ZOOM_IN_FACTOR (1.2) @@ -301,746 +295,738 @@ set_zoom_fit_to_size (XedPrintPreview *preview) static void zoom_in (XedPrintPreview *preview) { - set_zoom_factor (preview, - preview->priv->scale * ZOOM_IN_FACTOR); + set_zoom_factor (preview, preview->priv->scale * ZOOM_IN_FACTOR); } static void zoom_out (XedPrintPreview *preview) { - set_zoom_factor (preview, - preview->priv->scale * ZOOM_OUT_FACTOR); + set_zoom_factor (preview, preview->priv->scale * ZOOM_OUT_FACTOR); } static void -goto_page (XedPrintPreview *preview, gint page) +goto_page (XedPrintPreview *preview, + gint page) { - gchar c[32]; + gchar c[32]; - g_snprintf (c, 32, "%d", page + 1); - gtk_entry_set_text (GTK_ENTRY (preview->priv->page_entry), c); + g_snprintf (c, 32, "%d", page + 1); + gtk_entry_set_text (GTK_ENTRY (preview->priv->page_entry), c); - gtk_widget_set_sensitive (GTK_WIDGET (preview->priv->prev), - (page > 0) && (preview->priv->n_pages > 1)); - gtk_widget_set_sensitive (GTK_WIDGET (preview->priv->next), - (page != (preview->priv->n_pages - 1)) && - (preview->priv->n_pages > 1)); + gtk_widget_set_sensitive (GTK_WIDGET (preview->priv->prev), (page > 0) && (preview->priv->n_pages > 1)); + gtk_widget_set_sensitive (GTK_WIDGET (preview->priv->next), + (page != (preview->priv->n_pages - 1)) && + (preview->priv->n_pages > 1)); - if (page != preview->priv->cur_page) - { - preview->priv->cur_page = page; - if (preview->priv->n_pages > 0) - gtk_widget_queue_draw (preview->priv->layout); - } + if (page != preview->priv->cur_page) + { + preview->priv->cur_page = page; + if (preview->priv->n_pages > 0) + { + gtk_widget_queue_draw (preview->priv->layout); + } + } } static void -prev_button_clicked (GtkWidget *button, - XedPrintPreview *preview) +prev_button_clicked (GtkWidget *button, + XedPrintPreview *preview) { - GdkEvent *event; - gint page; + GdkEvent *event; + gint page; - event = gtk_get_current_event (); + event = gtk_get_current_event (); - if (event->button.state & GDK_SHIFT_MASK) - page = 0; - else - page = preview->priv->cur_page - preview->priv->rows * preview->priv->cols; + if (event->button.state & GDK_SHIFT_MASK) + { + page = 0; + } + else + { + page = preview->priv->cur_page - preview->priv->rows * preview->priv->cols; + } - goto_page (preview, MAX (page, 0)); + goto_page (preview, MAX (page, 0)); - gdk_event_free (event); + gdk_event_free (event); } static void -next_button_clicked (GtkWidget *button, - XedPrintPreview *preview) +next_button_clicked (GtkWidget *button, + XedPrintPreview *preview) { - GdkEvent *event; - gint page; + GdkEvent *event; + gint page; - event = gtk_get_current_event (); + event = gtk_get_current_event (); - if (event->button.state & GDK_SHIFT_MASK) - page = preview->priv->n_pages - 1; - else - page = preview->priv->cur_page + preview->priv->rows * preview->priv->cols; + if (event->button.state & GDK_SHIFT_MASK) + { + page = preview->priv->n_pages - 1; + } + else + { + page = preview->priv->cur_page + preview->priv->rows * preview->priv->cols; + } - goto_page (preview, MIN (page, preview->priv->n_pages - 1)); + goto_page (preview, MIN (page, preview->priv->n_pages - 1)); - gdk_event_free (event); + gdk_event_free (event); } static void -page_entry_activated (GtkEntry *entry, - XedPrintPreview *preview) +page_entry_activated (GtkEntry *entry, + XedPrintPreview *preview) { - const gchar *text; - gint page; + const gchar *text; + gint page; - text = gtk_entry_get_text (entry); + text = gtk_entry_get_text (entry); - page = CLAMP (atoi (text), 1, preview->priv->n_pages) - 1; - goto_page (preview, page); + page = CLAMP (atoi (text), 1, preview->priv->n_pages) - 1; + goto_page (preview, page); - gtk_widget_grab_focus (GTK_WIDGET (preview->priv->layout)); + gtk_widget_grab_focus (GTK_WIDGET (preview->priv->layout)); } static void page_entry_insert_text (GtkEditable *editable, - const gchar *text, - gint length, - gint *position) + const gchar *text, + gint length, + gint *position) { - gunichar c; - const gchar *p; - const gchar *end; + gunichar c; + const gchar *p; + const gchar *end; - p = text; - end = text + length; + p = text; + end = text + length; - while (p != end) - { - const gchar *next; - next = g_utf8_next_char (p); + while (p != end) + { + const gchar *next; + next = g_utf8_next_char (p); - c = g_utf8_get_char (p); + c = g_utf8_get_char (p); - if (!g_unichar_isdigit (c)) - { - g_signal_stop_emission_by_name (editable, "insert-text"); - break; - } + if (!g_unichar_isdigit (c)) + { + g_signal_stop_emission_by_name (editable, "insert-text"); + break; + } - p = next; - } + p = next; + } } -static gboolean -page_entry_focus_out (GtkWidget *widget, - GdkEventFocus *event, - XedPrintPreview *preview) +static gboolean +page_entry_focus_out (GtkWidget *widget, + GdkEventFocus *event, + XedPrintPreview *preview) { - const gchar *text; - gint page; + const gchar *text; + gint page; - text = gtk_entry_get_text (GTK_ENTRY (widget)); - page = atoi (text) - 1; + text = gtk_entry_get_text (GTK_ENTRY (widget)); + page = atoi (text) - 1; - /* Reset the page number only if really needed */ - if (page != preview->priv->cur_page) - { - gchar *str; + /* Reset the page number only if really needed */ + if (page != preview->priv->cur_page) + { + gchar *str; - str = g_strdup_printf ("%d", preview->priv->cur_page + 1); - gtk_entry_set_text (GTK_ENTRY (widget), str); - g_free (str); - } + str = g_strdup_printf ("%d", preview->priv->cur_page + 1); + gtk_entry_set_text (GTK_ENTRY (widget), str); + g_free (str); + } - return FALSE; + return FALSE; } static void -on_1x1_clicked (GtkMenuItem *i, XedPrintPreview *preview) +on_1x1_clicked (GtkMenuItem *i, + XedPrintPreview *preview) { - set_rows_and_cols (preview, 1, 1); + set_rows_and_cols (preview, 1, 1); } static void -on_1x2_clicked (GtkMenuItem *i, XedPrintPreview *preview) +on_1x2_clicked (GtkMenuItem *i, + XedPrintPreview *preview) { - set_rows_and_cols (preview, 1, 2); + set_rows_and_cols (preview, 1, 2); } static void -on_2x1_clicked (GtkMenuItem *i, XedPrintPreview *preview) +on_2x1_clicked (GtkMenuItem *i, + XedPrintPreview *preview) { - set_rows_and_cols (preview, 2, 1); + set_rows_and_cols (preview, 2, 1); } static void -on_2x2_clicked (GtkMenuItem *i, XedPrintPreview *preview) +on_2x2_clicked (GtkMenuItem *i, + XedPrintPreview *preview) { - set_rows_and_cols (preview, 2, 2); + set_rows_and_cols (preview, 2, 2); } static void -multi_button_clicked (GtkWidget *button, - XedPrintPreview *preview) +multi_button_clicked (GtkWidget *button, + XedPrintPreview *preview) { - GtkWidget *m, *i; + GtkWidget *m, *i; - m = gtk_menu_new (); - gtk_widget_show (m); - g_signal_connect (m, - "selection_done", - G_CALLBACK (gtk_widget_destroy), - m); + m = gtk_menu_new (); + gtk_widget_show (m); + g_signal_connect (m, "selection_done", + G_CALLBACK (gtk_widget_destroy), m); - i = gtk_menu_item_new_with_label ("1x1"); - gtk_widget_show (i); - gtk_menu_attach (GTK_MENU (m), i, 0, 1, 0, 1); - g_signal_connect (i, "activate", G_CALLBACK (on_1x1_clicked), preview); + i = gtk_menu_item_new_with_label ("1x1"); + gtk_widget_show (i); + gtk_menu_attach (GTK_MENU (m), i, 0, 1, 0, 1); + g_signal_connect (i, "activate", G_CALLBACK (on_1x1_clicked), preview); - i = gtk_menu_item_new_with_label ("2x1"); - gtk_widget_show (i); - gtk_menu_attach (GTK_MENU (m), i, 0, 1, 1, 2); - g_signal_connect (i, "activate", G_CALLBACK (on_2x1_clicked), preview); + i = gtk_menu_item_new_with_label ("2x1"); + gtk_widget_show (i); + gtk_menu_attach (GTK_MENU (m), i, 0, 1, 1, 2); + g_signal_connect (i, "activate", G_CALLBACK (on_2x1_clicked), preview); - i = gtk_menu_item_new_with_label ("1x2"); - gtk_widget_show (i); - gtk_menu_attach (GTK_MENU (m), i, 1, 2, 0, 1); - g_signal_connect (i, "activate", G_CALLBACK (on_1x2_clicked), preview); + i = gtk_menu_item_new_with_label ("1x2"); + gtk_widget_show (i); + gtk_menu_attach (GTK_MENU (m), i, 1, 2, 0, 1); + g_signal_connect (i, "activate", G_CALLBACK (on_1x2_clicked), preview); - i = gtk_menu_item_new_with_label ("2x2"); - gtk_widget_show (i); - gtk_menu_attach (GTK_MENU (m), i, 1, 2, 1, 2); - g_signal_connect (i, "activate", G_CALLBACK (on_2x2_clicked), preview); + i = gtk_menu_item_new_with_label ("2x2"); + gtk_widget_show (i); + gtk_menu_attach (GTK_MENU (m), i, 1, 2, 1, 2); + g_signal_connect (i, "activate", G_CALLBACK (on_2x2_clicked), preview); - gtk_menu_popup (GTK_MENU (m), - NULL, NULL, NULL, preview, 0, - GDK_CURRENT_TIME); + gtk_menu_popup (GTK_MENU (m), NULL, NULL, NULL, preview, 0, GDK_CURRENT_TIME); } static void -zoom_one_button_clicked (GtkWidget *button, - XedPrintPreview *preview) +zoom_one_button_clicked (GtkWidget *button, + XedPrintPreview *preview) { - set_zoom_factor (preview, 1); + set_zoom_factor (preview, 1); } static void -zoom_fit_button_clicked (GtkWidget *button, - XedPrintPreview *preview) +zoom_fit_button_clicked (GtkWidget *button, + XedPrintPreview *preview) { - set_zoom_fit_to_size (preview); + set_zoom_fit_to_size (preview); } static void -zoom_in_button_clicked (GtkWidget *button, - XedPrintPreview *preview) +zoom_in_button_clicked (GtkWidget *button, + XedPrintPreview *preview) { - zoom_in (preview); + zoom_in (preview); } static void -zoom_out_button_clicked (GtkWidget *button, - XedPrintPreview *preview) +zoom_out_button_clicked (GtkWidget *button, + XedPrintPreview *preview) { - zoom_out (preview); + zoom_out (preview); } static void -close_button_clicked (GtkWidget *button, - XedPrintPreview *preview) +close_button_clicked (GtkWidget *button, + XedPrintPreview *preview) { - gtk_widget_destroy (GTK_WIDGET (preview)); + gtk_widget_destroy (GTK_WIDGET (preview)); } static void create_bar (XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; - GtkWidget *toolbar; - GtkToolItem *i; - AtkObject *atko; - GtkWidget *status; + XedPrintPreviewPrivate *priv; + GtkWidget *toolbar; + GtkToolItem *i; + AtkObject *atko; + GtkWidget *status; + GtkWidget *box; + GtkWidget *close_button; - priv = preview->priv; + priv = preview->priv; - toolbar = gtk_toolbar_new (); - gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), - GTK_TOOLBAR_BOTH_HORIZ); - gtk_widget_show (toolbar); - gtk_box_pack_start (GTK_BOX (preview), - toolbar, - FALSE, FALSE, 0); + toolbar = gtk_toolbar_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (toolbar), "inline-toolbar"); + gtk_widget_show (toolbar); + gtk_box_pack_start (GTK_BOX (preview), toolbar, FALSE, FALSE, 0); - priv->prev = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK); - gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->prev), - "P_revious Page"); - gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->prev), TRUE); - gtk_tool_item_set_tooltip_text (priv->prev, _("Show the previous page")); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->prev, -1); - g_signal_connect (priv->prev, - "clicked", - G_CALLBACK (prev_button_clicked), - preview); - gtk_widget_show (GTK_WIDGET (priv->prev)); + i = gtk_tool_item_new (); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); - priv->next = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD); - gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->next), - "_Next Page"); - gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->next), TRUE); - gtk_tool_item_set_tooltip_text (priv->next, _("Show the next page")); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->next, -1); - g_signal_connect (priv->next, - "clicked", - G_CALLBACK (next_button_clicked), - preview); - gtk_widget_show (GTK_WIDGET (priv->next)); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_style_context_add_class (gtk_widget_get_style_context (box), "linked"); + gtk_container_add (GTK_CONTAINER (i), box); - i = gtk_separator_tool_item_new (); - gtk_widget_show (GTK_WIDGET (i)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + priv->prev = gtk_button_new_from_icon_name ("go-previous-symbolic", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (box), priv->prev, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (priv->prev, _("Show the previous page")); + g_signal_connect (priv->prev, "clicked", + G_CALLBACK (prev_button_clicked), preview); - status = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); - priv->page_entry = gtk_entry_new (); - gtk_entry_set_width_chars (GTK_ENTRY (priv->page_entry), 3); - gtk_entry_set_max_length (GTK_ENTRY (priv->page_entry), 6); - gtk_widget_set_tooltip_text (priv->page_entry, _("Current page (Alt+P)")); + priv->next = gtk_button_new_from_icon_name ("go-next-symbolic", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (box), priv->next, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (priv->next, _("Show the next page")); + g_signal_connect (priv->next, "clicked", + G_CALLBACK (next_button_clicked), preview); - g_signal_connect (priv->page_entry, - "activate", - G_CALLBACK (page_entry_activated), - preview); - g_signal_connect (priv->page_entry, - "insert-text", - G_CALLBACK (page_entry_insert_text), - NULL); - g_signal_connect (priv->page_entry, - "focus-out-event", - G_CALLBACK (page_entry_focus_out), - preview); + gtk_widget_show_all (GTK_WIDGET (i)); - gtk_box_pack_start (GTK_BOX (status), - priv->page_entry, - FALSE, FALSE, 0); - /* gtk_label_set_mnemonic_widget ((GtkLabel *) l, mp->priv->page_entry); */ + i = gtk_separator_tool_item_new (); + gtk_widget_show (GTK_WIDGET (i)); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); - /* We are displaying 'XXX of XXX'. */ - gtk_box_pack_start (GTK_BOX (status), - /* Translators: the "of" from "1 of 19" in print preview. */ - gtk_label_new (_("of")), - FALSE, FALSE, 0); + status = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + priv->page_entry = gtk_entry_new (); + gtk_entry_set_width_chars (GTK_ENTRY (priv->page_entry), 3); + gtk_entry_set_max_length (GTK_ENTRY (priv->page_entry), 6); + gtk_widget_set_tooltip_text (priv->page_entry, _("Current page (Alt+P)")); - priv->last = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (status), - priv->last, - FALSE, FALSE, 0); - atko = gtk_widget_get_accessible (priv->last); - atk_object_set_name (atko, _("Page total")); - atk_object_set_description (atko, _("The total number of pages in the document")); + g_signal_connect (priv->page_entry, "activate", + G_CALLBACK (page_entry_activated), preview); + g_signal_connect (priv->page_entry, "insert-text", + G_CALLBACK (page_entry_insert_text), NULL); + g_signal_connect (priv->page_entry, "focus-out-event", + G_CALLBACK (page_entry_focus_out), preview); - gtk_widget_show_all (status); + gtk_box_pack_start (GTK_BOX (status), priv->page_entry, FALSE, FALSE, 0); + /* gtk_label_set_mnemonic_widget ((GtkLabel *) l, mp->priv->page_entry); */ - i = gtk_tool_item_new (); - gtk_container_add (GTK_CONTAINER (i), status); - gtk_widget_show (GTK_WIDGET (i)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + /* We are displaying 'XXX of XXX'. */ + /* Translators: the "of" from "1 of 19" in print preview. */ + gtk_box_pack_start (GTK_BOX (status), gtk_label_new (_("of")), FALSE, FALSE, 0); - i = gtk_separator_tool_item_new (); - gtk_widget_show (GTK_WIDGET (i)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); - - priv->multi = gtk_tool_button_new_from_stock (GTK_STOCK_DND_MULTIPLE); - gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->multi), - "_Show Multiple Pages"); - gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->multi), TRUE); - gtk_tool_item_set_tooltip_text (priv->multi, _("Show multiple pages")); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->multi, -1); - g_signal_connect (priv->multi, - "clicked", - G_CALLBACK (multi_button_clicked), - preview); - gtk_widget_show (GTK_WIDGET (priv->multi)); + priv->last = gtk_label_new (""); + gtk_box_pack_start (GTK_BOX (status), priv->last, FALSE, FALSE, 0); + atko = gtk_widget_get_accessible (priv->last); + atk_object_set_name (atko, _("Page total")); + atk_object_set_description (atko, _("The total number of pages in the document")); - i = gtk_separator_tool_item_new (); - gtk_widget_show (GTK_WIDGET (i)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + gtk_widget_show_all (status); - priv->zoom_one = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_100); - gtk_tool_item_set_tooltip_text (priv->zoom_one, _("Zoom 1:1")); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_one, -1); - g_signal_connect (priv->zoom_one, - "clicked", - G_CALLBACK (zoom_one_button_clicked), - preview); - gtk_widget_show (GTK_WIDGET (priv->zoom_one)); + i = gtk_tool_item_new (); + gtk_container_add (GTK_CONTAINER (i), status); + gtk_widget_show (GTK_WIDGET (i)); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); - priv->zoom_fit = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_FIT); - gtk_tool_item_set_tooltip_text (priv->zoom_fit, _("Zoom to fit the whole page")); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_fit, -1); - g_signal_connect (priv->zoom_fit, - "clicked", - G_CALLBACK (zoom_fit_button_clicked), - preview); - gtk_widget_show (GTK_WIDGET (priv->zoom_fit)); + i = gtk_separator_tool_item_new (); + gtk_widget_show (GTK_WIDGET (i)); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); - priv->zoom_in = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_IN); - gtk_tool_item_set_tooltip_text (priv->zoom_in, _("Zoom the page in")); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_in, -1); - g_signal_connect (priv->zoom_in, - "clicked", - G_CALLBACK (zoom_in_button_clicked), - preview); - gtk_widget_show (GTK_WIDGET (priv->zoom_in)); + i = gtk_tool_item_new (); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_container_add (GTK_CONTAINER (i), box); - priv->zoom_out = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_OUT); - gtk_tool_item_set_tooltip_text (priv->zoom_out, _("Zoom the page out")); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_out, -1); - g_signal_connect (priv->zoom_out, - "clicked", - G_CALLBACK (zoom_out_button_clicked), - preview); - gtk_widget_show (GTK_WIDGET (priv->zoom_out)); + priv->multi = gtk_button_new_from_icon_name ("view-grid-symbolic", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (box), priv->multi, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (priv->multi, _("Show multiple pages")); + g_signal_connect (priv->multi, "clicked", + G_CALLBACK (multi_button_clicked), preview); - i = gtk_separator_tool_item_new (); - gtk_widget_show (GTK_WIDGET (i)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + gtk_widget_show_all (GTK_WIDGET (i)); - i = gtk_tool_button_new (NULL, _("_Close Preview")); - gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (i), TRUE); - gtk_tool_item_set_is_important (i, TRUE); - gtk_tool_item_set_tooltip_text (i, _("Close print preview")); - g_signal_connect (i, "clicked", - G_CALLBACK (close_button_clicked), preview); - gtk_widget_show (GTK_WIDGET (i)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + i = gtk_separator_tool_item_new (); + gtk_widget_show (GTK_WIDGET (i)); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + + i = gtk_tool_item_new (); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_style_context_add_class (gtk_widget_get_style_context (box), "linked"); + gtk_container_add (GTK_CONTAINER (i), box); + + priv->zoom_one = gtk_button_new_from_icon_name ("zoom-original-symbolic", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (box), priv->zoom_one, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (priv->zoom_one, _("Zoom 1:1")); + g_signal_connect (priv->zoom_one, "clicked", + G_CALLBACK (zoom_one_button_clicked), preview); + + priv->zoom_fit = gtk_button_new_from_icon_name ("zoom-fit-best-symbolic", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (box), priv->zoom_fit, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (priv->zoom_fit, _("Zoom to fit the whole page")); + g_signal_connect (priv->zoom_fit, "clicked", + G_CALLBACK (zoom_fit_button_clicked), preview); + + priv->zoom_in = gtk_button_new_from_icon_name ("zoom-in-symbolic", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (box), priv->zoom_in, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (priv->zoom_in, _("Zoom the page in")); + g_signal_connect (priv->zoom_in, "clicked", + G_CALLBACK (zoom_in_button_clicked), preview); + + priv->zoom_out = gtk_button_new_from_icon_name ("zoom-out-symbolic", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (box), priv->zoom_out, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (priv->zoom_out, _("Zoom the page out")); + g_signal_connect (priv->zoom_out, "clicked", + G_CALLBACK (zoom_out_button_clicked), preview); + + gtk_widget_show_all (GTK_WIDGET (i)); + + i = gtk_separator_tool_item_new (); + gtk_widget_show (GTK_WIDGET (i)); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + + i = gtk_tool_item_new (); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_container_add (GTK_CONTAINER (i), box); + + close_button = gtk_button_new_with_mnemonic (_("_Close preview")); + gtk_box_pack_start (GTK_BOX (box), close_button, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (close_button, _("Close print preview")); + g_signal_connect (close_button, "clicked", + G_CALLBACK (close_button_clicked), preview); + + gtk_widget_show_all (GTK_WIDGET (i)); } static gint get_first_page_displayed (XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; + XedPrintPreviewPrivate *priv; - priv = preview->priv; + priv = preview->priv; - return priv->cur_page - priv->cur_page % (priv->cols * priv->rows); + return priv->cur_page - priv->cur_page % (priv->cols * priv->rows); } /* returns the page number (starting from 0) or -1 if no page */ static gint get_page_at_coords (XedPrintPreview *preview, - gint x, - gint y) + gint x, + gint y) { - XedPrintPreviewPrivate *priv; - GtkAdjustment *hadj, *vadj; - gint r, c, pg; + XedPrintPreviewPrivate *priv; + GtkAdjustment *hadj, *vadj; + gint r, c, pg; - priv = preview->priv; + priv = preview->priv; - if (priv->tile_h <= 0 || priv->tile_h <= 0) - return -1; + if (priv->tile_h <= 0 || priv->tile_h <= 0) + { + return -1; + } - hadj = gtk_layout_get_hadjustment (GTK_LAYOUT (priv->layout)); - vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (priv->layout)); + hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (priv->layout)); + vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->layout)); - x += gtk_adjustment_get_value (hadj); - y += gtk_adjustment_get_value (vadj); + x += gtk_adjustment_get_value (hadj); + y += gtk_adjustment_get_value (vadj); - r = 1 + y / (priv->tile_h); - c = 1 + x / (priv->tile_w); + r = 1 + y / (priv->tile_h); + c = 1 + x / (priv->tile_w); - if (c > priv->cols) - return -1; + if (c > priv->cols) + { + return -1; + } - pg = get_first_page_displayed (preview) - 1; - pg += (r - 1) * priv->cols + c; + pg = get_first_page_displayed (preview) - 1; + pg += (r - 1) * priv->cols + c; - if (pg >= priv->n_pages) - return -1; + if (pg >= priv->n_pages) + { + return -1; + } - /* FIXME: we could try to be picky and check - * if we actually are inside the page */ - return pg; + /* FIXME: we could try to be picky and check + * if we actually are inside the page */ + return pg; } static gboolean -preview_layout_query_tooltip (GtkWidget *widget, - gint x, - gint y, - gboolean keyboard_tip, - GtkTooltip *tooltip, - XedPrintPreview *preview) +preview_layout_query_tooltip (GtkWidget *widget, + gint x, + gint y, + gboolean keyboard_tip, + GtkTooltip *tooltip, + XedPrintPreview *preview) { - gint pg; - gchar *tip; + gint pg; + gchar *tip; - pg = get_page_at_coords (preview, x, y); - if (pg < 0) - return FALSE; + pg = get_page_at_coords (preview, x, y); + if (pg < 0) + { + return FALSE; + } - tip = g_strdup_printf (_("Page %d of %d"), pg + 1, preview->priv->n_pages); - gtk_tooltip_set_text (tooltip, tip); - g_free (tip); + tip = g_strdup_printf (_("Page %d of %d"), pg + 1, preview->priv->n_pages); + gtk_tooltip_set_text (tooltip, tip); + g_free (tip); - return TRUE; + return TRUE; } static gint -preview_layout_key_press (GtkWidget *widget, - GdkEventKey *event, - XedPrintPreview *preview) +preview_layout_key_press (GtkWidget *widget, + GdkEventKey *event, + XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; - GtkAdjustment *hadj, *vadj; - double x, y; - guint h, w; - double hlower, hupper, vlower, vupper; - double hpage, vpage; - double hstep, vstep; - gboolean domove = FALSE; - gboolean ret = TRUE; + XedPrintPreviewPrivate *priv; + GtkAdjustment *hadj, *vadj; + double x, y; + guint h, w; + double hlower, hupper, vlower, vupper; + double hpage, vpage; + double hstep, vstep; + gboolean domove = FALSE; + gboolean ret = TRUE; - priv = preview->priv; + priv = preview->priv; - hadj = gtk_layout_get_hadjustment (GTK_LAYOUT (priv->layout)); - vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (priv->layout)); + hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (priv->layout)); + vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->layout)); - x = gtk_adjustment_get_value (hadj); - y = gtk_adjustment_get_value (vadj); + x = gtk_adjustment_get_value (hadj); + y = gtk_adjustment_get_value (vadj); - g_object_get (hadj, - "lower", &hlower, - "upper", &hupper, - "page-size", &hpage, - NULL); - g_object_get (vadj, - "lower", &vlower, - "upper", &vupper, - "page-size", &vpage, - NULL); + g_object_get (hadj, + "lower", &hlower, + "upper", &hupper, + "page-size", &hpage, + NULL); + g_object_get (vadj, + "lower", &vlower, + "upper", &vupper, + "page-size", &vpage, + NULL); - gtk_layout_get_size (GTK_LAYOUT (priv->layout), &w, &h); + gtk_layout_get_size (GTK_LAYOUT (priv->layout), &w, &h); - hstep = 10; - vstep = 10; + hstep = 10; + vstep = 10; - switch (event->keyval) { - case '1': - set_zoom_fit_to_size (preview); - break; - case '+': - case '=': - case GDK_KEY_KP_Add: - zoom_in (preview); - break; - case '-': - case '_': - case GDK_KEY_KP_Subtract: - zoom_out (preview); - break; - case GDK_KEY_KP_Right: - case GDK_KEY_Right: - if (event->state & GDK_SHIFT_MASK) - x = hupper - hpage; - else - x = MIN (hupper - hpage, x + hstep); - domove = TRUE; - break; - case GDK_KEY_KP_Left: - case GDK_KEY_Left: - if (event->state & GDK_SHIFT_MASK) - x = hlower; - else - x = MAX (hlower, x - hstep); - domove = TRUE; - break; - case GDK_KEY_KP_Up: - case GDK_KEY_Up: - if (event->state & GDK_SHIFT_MASK) - goto page_up; - y = MAX (vlower, y - vstep); - domove = TRUE; - break; - case GDK_KEY_KP_Down: - case GDK_KEY_Down: - if (event->state & GDK_SHIFT_MASK) - goto page_down; - y = MIN (vupper - vpage, y + vstep); - domove = TRUE; - break; - case GDK_KEY_KP_Page_Up: - case GDK_KEY_Page_Up: - case GDK_KEY_Delete: - case GDK_KEY_KP_Delete: - case GDK_KEY_BackSpace: - page_up: - if (y <= vlower) - { - if (preview->priv->cur_page > 0) - { - goto_page (preview, preview->priv->cur_page - 1); - y = (vupper - vpage); - } - } - else - { - y = vlower; - } - domove = TRUE; - break; - case GDK_KEY_KP_Page_Down: - case GDK_KEY_Page_Down: - case ' ': - page_down: - if (y >= (vupper - vpage)) - { - if (preview->priv->cur_page < preview->priv->n_pages - 1) - { - goto_page (preview, preview->priv->cur_page + 1); - y = vlower; - } - } - else - { - y = (vupper - vpage); - } - domove = TRUE; - break; - case GDK_KEY_KP_Home: - case GDK_KEY_Home: - goto_page (preview, 0); - y = 0; - domove = TRUE; - break; - case GDK_KEY_KP_End: - case GDK_KEY_End: - goto_page (preview, preview->priv->n_pages - 1); - y = 0; - domove = TRUE; - break; - case GDK_KEY_Escape: - gtk_widget_destroy (GTK_WIDGET (preview)); - break; - case 'c': - if (event->state & GDK_MOD1_MASK) - { - gtk_widget_destroy (GTK_WIDGET (preview)); - } - break; - case 'p': - if (event->state & GDK_MOD1_MASK) - { - gtk_widget_grab_focus (preview->priv->page_entry); - } - break; - default: - /* by default do not stop the default handler */ - ret = FALSE; - } + switch (event->keyval) + { + case '1': + set_zoom_fit_to_size (preview); + break; + case '+': + case '=': + case GDK_KEY_KP_Add: + zoom_in (preview); + break; + case '-': + case '_': + case GDK_KEY_KP_Subtract: + zoom_out (preview); + break; + case GDK_KEY_KP_Right: + case GDK_KEY_Right: + if (event->state & GDK_SHIFT_MASK) + x = hupper - hpage; + else + x = MIN (hupper - hpage, x + hstep); + domove = TRUE; + break; + case GDK_KEY_KP_Left: + case GDK_KEY_Left: + if (event->state & GDK_SHIFT_MASK) + x = hlower; + else + x = MAX (hlower, x - hstep); + domove = TRUE; + break; + case GDK_KEY_KP_Up: + case GDK_KEY_Up: + if (event->state & GDK_SHIFT_MASK) + goto page_up; + y = MAX (vlower, y - vstep); + domove = TRUE; + break; + case GDK_KEY_KP_Down: + case GDK_KEY_Down: + if (event->state & GDK_SHIFT_MASK) + goto page_down; + y = MIN (vupper - vpage, y + vstep); + domove = TRUE; + break; + case GDK_KEY_KP_Page_Up: + case GDK_KEY_Page_Up: + case GDK_KEY_Delete: + case GDK_KEY_KP_Delete: + case GDK_KEY_BackSpace: + page_up: + if (y <= vlower) + { + if (preview->priv->cur_page > 0) + { + goto_page (preview, preview->priv->cur_page - 1); + y = (vupper - vpage); + } + } + else + { + y = vlower; + } + domove = TRUE; + break; + case GDK_KEY_KP_Page_Down: + case GDK_KEY_Page_Down: + case ' ': + page_down: + if (y >= (vupper - vpage)) + { + if (preview->priv->cur_page < preview->priv->n_pages - 1) + { + goto_page (preview, preview->priv->cur_page + 1); + y = vlower; + } + } + else + { + y = (vupper - vpage); + } + domove = TRUE; + break; + case GDK_KEY_KP_Home: + case GDK_KEY_Home: + goto_page (preview, 0); + y = 0; + domove = TRUE; + break; + case GDK_KEY_KP_End: + case GDK_KEY_End: + goto_page (preview, preview->priv->n_pages - 1); + y = 0; + domove = TRUE; + break; + case GDK_KEY_Escape: + gtk_widget_destroy (GTK_WIDGET (preview)); + break; + case 'c': + if (event->state & GDK_MOD1_MASK) + { + gtk_widget_destroy (GTK_WIDGET (preview)); + } + break; + case 'p': + if (event->state & GDK_MOD1_MASK) + { + gtk_widget_grab_focus (preview->priv->page_entry); + } + break; + default: + /* by default do not stop the default handler */ + ret = FALSE; + } - if (domove) - { - gtk_adjustment_set_value (hadj, x); - gtk_adjustment_set_value (vadj, y); + if (domove) + { + gtk_adjustment_set_value (hadj, x); + gtk_adjustment_set_value (vadj, y); - gtk_adjustment_value_changed (hadj); - gtk_adjustment_value_changed (vadj); - } + gtk_adjustment_value_changed (hadj); + gtk_adjustment_value_changed (vadj); + } - return ret; + return ret; } static void create_preview_layout (XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; - AtkObject *atko; + XedPrintPreviewPrivate *priv; + AtkObject *atko; - priv = preview->priv; + priv = preview->priv; - priv->layout = gtk_layout_new (NULL, NULL); -// gtk_widget_set_double_buffered (priv->layout, FALSE); + priv->layout = gtk_layout_new (NULL, NULL); +// gtk_widget_set_double_buffered (priv->layout, FALSE); - atko = gtk_widget_get_accessible (GTK_WIDGET (priv->layout)); - atk_object_set_name (atko, _("Page Preview")); - atk_object_set_description (atko, _("The preview of a page in the document to be printed")); + atko = gtk_widget_get_accessible (GTK_WIDGET (priv->layout)); + atk_object_set_name (atko, _("Page Preview")); + atk_object_set_description (atko, _("The preview of a page in the document to be printed")); - gtk_widget_add_events (priv->layout, - GDK_POINTER_MOTION_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_KEY_PRESS_MASK); + gtk_widget_add_events (priv->layout, + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_KEY_PRESS_MASK); - gtk_widget_set_can_focus (priv->layout, TRUE); + gtk_widget_set_can_focus (priv->layout, TRUE); - g_signal_connect (priv->layout, - "key-press-event", - G_CALLBACK (preview_layout_key_press), - preview); + g_signal_connect (priv->layout, "key-press-event", + G_CALLBACK (preview_layout_key_press), preview); - g_object_set (priv->layout, "has-tooltip", TRUE, NULL); - g_signal_connect (priv->layout, - "query-tooltip", - G_CALLBACK (preview_layout_query_tooltip), - preview); + g_object_set (priv->layout, "has-tooltip", TRUE, NULL); + g_signal_connect (priv->layout, "query-tooltip", + G_CALLBACK (preview_layout_query_tooltip), preview); - priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); + priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (priv->scrolled_window), priv->layout); - gtk_box_pack_end (GTK_BOX (preview), - priv->scrolled_window, - TRUE, TRUE, 0); + gtk_container_add (GTK_CONTAINER (priv->scrolled_window), priv->layout); + gtk_box_pack_end (GTK_BOX (preview), priv->scrolled_window, TRUE, TRUE, 0); - gtk_widget_show_all (GTK_WIDGET (priv->scrolled_window)); - gtk_widget_grab_focus (GTK_WIDGET (priv->layout)); + gtk_widget_show_all (GTK_WIDGET (priv->scrolled_window)); + gtk_widget_grab_focus (GTK_WIDGET (priv->layout)); } static void xed_print_preview_init (XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; - - priv = G_TYPE_INSTANCE_GET_PRIVATE (preview, - XED_TYPE_PRINT_PREVIEW, - XedPrintPreviewPrivate); + XedPrintPreviewPrivate *priv; - preview->priv = priv; + priv = G_TYPE_INSTANCE_GET_PRIVATE (preview, XED_TYPE_PRINT_PREVIEW, XedPrintPreviewPrivate); - priv->operation = NULL; - priv->context = NULL; - priv->gtk_preview = NULL; + preview->priv = priv; - gtk_orientable_set_orientation (GTK_ORIENTABLE (preview), - GTK_ORIENTATION_VERTICAL); + priv->operation = NULL; + priv->context = NULL; + priv->gtk_preview = NULL; - create_bar (preview); - create_preview_layout (preview); + gtk_orientable_set_orientation (GTK_ORIENTABLE (preview), GTK_ORIENTATION_VERTICAL); - // FIXME - priv->cur_page = 0; - priv->paper_w = 0; - priv->paper_h = 0; - priv->dpi = PRINTER_DPI; - priv->scale = 1.0; - priv->rows = 1; - priv->cols = 1; + create_bar (preview); + create_preview_layout (preview); + + // FIXME + priv->cur_page = 0; + priv->paper_w = 0; + priv->paper_h = 0; + priv->dpi = PRINTER_DPI; + priv->scale = 1.0; + priv->rows = 1; + priv->cols = 1; } static void -draw_page_content (cairo_t *cr, - gint page_number, - XedPrintPreview *preview) +draw_page_content (cairo_t *cr, + gint page_number, + XedPrintPreview *preview) { - /* scale to the desired size */ - cairo_scale (cr, preview->priv->scale, preview->priv->scale); + /* scale to the desired size */ + cairo_scale (cr, preview->priv->scale, preview->priv->scale); - /* rotate acording to page orientation if needed */ - if ((preview->priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) || - (preview->priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)) - { - cairo_matrix_t matrix; + /* rotate acording to page orientation if needed */ + if ((preview->priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) || + (preview->priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)) + { + cairo_matrix_t matrix; - cairo_matrix_init (&matrix, - 0, -1, - 1, 0, - 0, get_paper_width (preview)); - cairo_transform (cr, &matrix); - } + cairo_matrix_init (&matrix, + 0, -1, + 1, 0, + 0, get_paper_width (preview)); + cairo_transform (cr, &matrix); + } - gtk_print_context_set_cairo_context (preview->priv->context, - cr, - preview->priv->dpi, - preview->priv->dpi); + gtk_print_context_set_cairo_context (preview->priv->context, + cr, + preview->priv->dpi, + preview->priv->dpi); - gtk_print_operation_preview_render_page (preview->priv->gtk_preview, - page_number); + gtk_print_operation_preview_render_page (preview->priv->gtk_preview, page_number); } /* For the frame, we scale and rotate manually, since @@ -1048,202 +1034,195 @@ draw_page_content (cairo_t *cr, * the drop shadow should be on the bottom right no matter * the orientation */ static void -draw_page_frame (cairo_t *cr, - XedPrintPreview *preview) +draw_page_frame (cairo_t *cr, + XedPrintPreview *preview) { - double w, h; + double w, h; - w = get_paper_width (preview); - h = get_paper_height (preview); + w = get_paper_width (preview); + h = get_paper_height (preview); - if ((preview->priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) || - (preview->priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)) - { - double tmp; + if ((preview->priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) || + (preview->priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)) + { + double tmp; - tmp = w; - w = h; - h = tmp; - } + tmp = w; + w = h; + h = tmp; + } - w *= preview->priv->scale; - h *= preview->priv->scale; + w *= preview->priv->scale; + h *= preview->priv->scale; - /* drop shadow */ - cairo_set_source_rgb (cr, 0, 0, 0); - cairo_rectangle (cr, - PAGE_SHADOW_OFFSET, PAGE_SHADOW_OFFSET, - w, h); - cairo_fill (cr); + /* drop shadow */ + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_rectangle (cr, PAGE_SHADOW_OFFSET, PAGE_SHADOW_OFFSET, w, h); + cairo_fill (cr); - /* page frame */ - cairo_set_source_rgb (cr, 1, 1, 1); - cairo_rectangle (cr, - 0, 0, - w, h); - cairo_fill_preserve (cr); - cairo_set_source_rgb (cr, 0, 0, 0); - cairo_set_line_width (cr, 1); - cairo_stroke (cr); + /* page frame */ + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_rectangle (cr, 0, 0, w, h); + cairo_fill_preserve (cr); + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_line_width (cr, 1); + cairo_stroke (cr); } static void -draw_page (cairo_t *cr, - double x, - double y, - gint page_number, - XedPrintPreview *preview) +draw_page (cairo_t *cr, + double x, + double y, + gint page_number, + XedPrintPreview *preview) { - cairo_save (cr); + cairo_save (cr); - /* move to the page top left corner */ - cairo_translate (cr, x + PAGE_PAD, y + PAGE_PAD); + /* move to the page top left corner */ + cairo_translate (cr, x + PAGE_PAD, y + PAGE_PAD); - draw_page_frame (cr, preview); - draw_page_content (cr, page_number, preview); + draw_page_frame (cr, preview); + draw_page_content (cr, page_number, preview); - cairo_restore (cr); + cairo_restore (cr); } static gboolean -preview_draw (GtkWidget *widget, - cairo_t *cr, - XedPrintPreview *preview) +preview_draw (GtkWidget *widget, + cairo_t *cr, + XedPrintPreview *preview) { - XedPrintPreviewPrivate *priv; - GdkWindow *bin_window; - gint pg; - gint i, j; + XedPrintPreviewPrivate *priv; + GdkWindow *bin_window; + gint pg; + gint i, j; - priv = preview->priv; + priv = preview->priv; - bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (priv->layout)); + bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (priv->layout)); - if (!gtk_cairo_should_draw_window (cr, bin_window)) - return TRUE; + if (!gtk_cairo_should_draw_window (cr, bin_window)) + { + return TRUE; + } - cairo_save (cr); + cairo_save (cr); - gtk_cairo_transform_to_window (cr, widget, bin_window); + gtk_cairo_transform_to_window (cr, widget, bin_window); - /* get the first page to display */ - pg = get_first_page_displayed (preview); + /* get the first page to display */ + pg = get_first_page_displayed (preview); - for (i = 0; i < priv->cols; ++i) - { - for (j = 0; j < priv->rows; ++j) - { - if (!gtk_print_operation_preview_is_selected (priv->gtk_preview, - pg)) - { - continue; - } + for (i = 0; i < priv->cols; ++i) + { + for (j = 0; j < priv->rows; ++j) + { + if (!gtk_print_operation_preview_is_selected (priv->gtk_preview, pg)) + { + continue; + } - if (pg == priv->n_pages) - break; + if (pg == priv->n_pages) + { + break; + } - draw_page (cr, - j * priv->tile_w, - i * priv->tile_h, - pg, - preview); + draw_page (cr, j * priv->tile_w, i * priv->tile_h, pg, preview); - ++pg; - } - } + ++pg; + } + } - cairo_restore (cr); + cairo_restore (cr); - return TRUE; + return TRUE; } static double get_screen_dpi (XedPrintPreview *preview) { - GdkScreen *screen; - double dpi; + GdkScreen *screen; + double dpi; - screen = gtk_widget_get_screen (GTK_WIDGET (preview)); + screen = gtk_widget_get_screen (GTK_WIDGET (preview)); - dpi = gdk_screen_get_resolution (screen); - if (dpi < 30. || 600. < dpi) - { - g_warning ("Invalid the x-resolution for the screen, assuming 96dpi"); - dpi = 96.; - } + dpi = gdk_screen_get_resolution (screen); + if (dpi < 30. || 600. < dpi) + { + g_warning ("Invalid the x-resolution for the screen, assuming 96dpi"); + dpi = 96.; + } - return dpi; + return dpi; } static void set_n_pages (XedPrintPreview *preview, - gint n_pages) + gint n_pages) { - gchar *str; + gchar *str; - preview->priv->n_pages = n_pages; + preview->priv->n_pages = n_pages; - // FIXME: count the visible pages + // FIXME: count the visible pages - str = g_strdup_printf ("%d", n_pages); - gtk_label_set_markup (GTK_LABEL (preview->priv->last), str); - g_free (str); + str = g_strdup_printf ("%d", n_pages); + gtk_label_set_markup (GTK_LABEL (preview->priv->last), str); + g_free (str); } static void preview_ready (GtkPrintOperationPreview *gtk_preview, - GtkPrintContext *context, - XedPrintPreview *preview) + GtkPrintContext *context, + XedPrintPreview *preview) { - gint n_pages; + gint n_pages; - g_object_get (preview->priv->operation, "n-pages", &n_pages, NULL); - set_n_pages (preview, n_pages); - goto_page (preview, 0); + g_object_get (preview->priv->operation, "n-pages", &n_pages, NULL); + set_n_pages (preview, n_pages); + goto_page (preview, 0); - /* figure out the dpi */ - preview->priv->dpi = get_screen_dpi (preview); + /* figure out the dpi */ + preview->priv->dpi = get_screen_dpi (preview); - set_zoom_factor (preview, 1.0); + set_zoom_factor (preview, 1.0); - /* let the default gtklayout handler clear the background */ - g_signal_connect_after (preview->priv->layout, - "draw", - G_CALLBACK (preview_draw), - preview); + /* let the default gtklayout handler clear the background */ + g_signal_connect_after (preview->priv->layout, "draw", + G_CALLBACK (preview_draw), preview); - gtk_widget_queue_draw (preview->priv->layout); + gtk_widget_queue_draw (preview->priv->layout); } static void update_paper_size (XedPrintPreview *preview, - GtkPageSetup *page_setup) + GtkPageSetup *page_setup) { - GtkPaperSize *paper_size; + GtkPaperSize *paper_size; - paper_size = gtk_page_setup_get_paper_size (page_setup); + paper_size = gtk_page_setup_get_paper_size (page_setup); - preview->priv->paper_w = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH); - preview->priv->paper_h = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH); + preview->priv->paper_w = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH); + preview->priv->paper_h = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH); - preview->priv->orientation = gtk_page_setup_get_orientation (page_setup); + preview->priv->orientation = gtk_page_setup_get_orientation (page_setup); } static void -preview_got_page_size (GtkPrintOperationPreview *gtk_preview, - GtkPrintContext *context, - GtkPageSetup *page_setup, - XedPrintPreview *preview) +preview_got_page_size (GtkPrintOperationPreview *gtk_preview, + GtkPrintContext *context, + GtkPageSetup *page_setup, + XedPrintPreview *preview) { - update_paper_size (preview, page_setup); + update_paper_size (preview, page_setup); } /* HACK: we need a dummy surface to paginate... can we use something simpler? */ static cairo_status_t dummy_write_func (G_GNUC_UNUSED gpointer closure, - G_GNUC_UNUSED const guchar *data, - G_GNUC_UNUSED guint length) + G_GNUC_UNUSED const guchar *data, + G_GNUC_UNUSED guint length) { return CAIRO_STATUS_SUCCESS; } @@ -1252,8 +1231,8 @@ dummy_write_func (G_GNUC_UNUSED gpointer closure, static cairo_surface_t * create_preview_surface_platform (GtkPaperSize *paper_size, - double *dpi_x, - double *dpi_y) + double *dpi_x, + double *dpi_y) { double width, height; cairo_surface_t *sf; @@ -1263,15 +1242,14 @@ create_preview_surface_platform (GtkPaperSize *paper_size, *dpi_x = *dpi_y = PRINTER_DPI; - sf = cairo_pdf_surface_create_for_stream (dummy_write_func, NULL, - width, height); + sf = cairo_pdf_surface_create_for_stream (dummy_write_func, NULL, width, height); return sf; } static cairo_surface_t * create_preview_surface (XedPrintPreview *preview, - double *dpi_x, - double *dpi_y) + double *dpi_x, + double *dpi_y) { GtkPageSetup *page_setup; GtkPaperSize *paper_size; @@ -1285,45 +1263,45 @@ create_preview_surface (XedPrintPreview *preview, GtkWidget * xed_print_preview_new (GtkPrintOperation *op, - GtkPrintOperationPreview *gtk_preview, - GtkPrintContext *context) + GtkPrintOperationPreview *gtk_preview, + GtkPrintContext *context) { - XedPrintPreview *preview; - GtkPageSetup *page_setup; - cairo_surface_t *surface; - cairo_t *cr; - double dpi_x, dpi_y; + XedPrintPreview *preview; + GtkPageSetup *page_setup; + cairo_surface_t *surface; + cairo_t *cr; + double dpi_x, dpi_y; - g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL); - g_return_val_if_fail (GTK_IS_PRINT_OPERATION_PREVIEW (gtk_preview), NULL); + g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL); + g_return_val_if_fail (GTK_IS_PRINT_OPERATION_PREVIEW (gtk_preview), NULL); - preview = g_object_new (XED_TYPE_PRINT_PREVIEW, NULL); + preview = g_object_new (XED_TYPE_PRINT_PREVIEW, NULL); - preview->priv->operation = g_object_ref (op); - preview->priv->gtk_preview = g_object_ref (gtk_preview); - preview->priv->context = g_object_ref (context); + preview->priv->operation = g_object_ref (op); + preview->priv->gtk_preview = g_object_ref (gtk_preview); + preview->priv->context = g_object_ref (context); - /* FIXME: is this legal?? */ - gtk_print_operation_set_unit (op, GTK_UNIT_POINTS); + /* FIXME: is this legal?? */ + gtk_print_operation_set_unit (op, GTK_UNIT_POINTS); - g_signal_connect (gtk_preview, "ready", - G_CALLBACK (preview_ready), preview); - g_signal_connect (gtk_preview, "got-page-size", - G_CALLBACK (preview_got_page_size), preview); + g_signal_connect (gtk_preview, "ready", + G_CALLBACK (preview_ready), preview); + g_signal_connect (gtk_preview, "got-page-size", + G_CALLBACK (preview_got_page_size), preview); - page_setup = gtk_print_context_get_page_setup (preview->priv->context); - update_paper_size (preview, page_setup); + page_setup = gtk_print_context_get_page_setup (preview->priv->context); + update_paper_size (preview, page_setup); - /* FIXME: we need a cr to paginate... but we can't get the drawing - * area surface because it's not there yet... for now I create - * a dummy pdf surface */ + /* FIXME: we need a cr to paginate... but we can't get the drawing + * area surface because it's not there yet... for now I create + * a dummy pdf surface */ - surface = create_preview_surface (preview, &dpi_x, &dpi_y); - cr = cairo_create (surface); - gtk_print_context_set_cairo_context (context, cr, dpi_x, dpi_y); - cairo_destroy (cr); - cairo_surface_destroy (surface); + surface = create_preview_surface (preview, &dpi_x, &dpi_y); + cr = cairo_create (surface); + gtk_print_context_set_cairo_context (context, cr, dpi_x, dpi_y); + cairo_destroy (cr); + cairo_surface_destroy (surface); - return GTK_WIDGET (preview); + return GTK_WIDGET (preview); } diff --git a/xed/xed-progress-info-bar.c b/xed/xed-progress-info-bar.c new file mode 100644 index 0000000..837be74 --- /dev/null +++ b/xed/xed-progress-info-bar.c @@ -0,0 +1,233 @@ +/* + * xed-progress-message-area.c + * This file is part of xed + * + * Copyright (C) 2005 - Paolo Maggi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. + * + * $Id$ + */ + + /* TODO: add properties */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "xed-progress-info-bar.h" + +enum +{ + PROP_0, + PROP_HAS_CANCEL_BUTTON +}; + + +#define XED_PROGRESS_INFO_BAR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_PROGRESS_INFO_BAR, XedProgressInfoBarPrivate)) + +struct _XedProgressInfoBarPrivate +{ + GtkWidget *image; + GtkWidget *label; + GtkWidget *progress; +}; + +G_DEFINE_TYPE(XedProgressInfoBar, xed_progress_info_bar, GTK_TYPE_INFO_BAR) + +static void +xed_progress_info_bar_set_has_cancel_button (XedProgressInfoBar *bar, + gboolean has_button) +{ + if (has_button) + { + gtk_info_bar_add_button (GTK_INFO_BAR (bar), _("Cancel"), GTK_RESPONSE_CANCEL); + } + + g_object_notify (G_OBJECT (bar), "has-cancel-button"); +} + +static void +xed_progress_info_bar_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XedProgressInfoBar *bar; + + bar = XED_PROGRESS_INFO_BAR (object); + + switch (prop_id) + { + case PROP_HAS_CANCEL_BUTTON: + xed_progress_info_bar_set_has_cancel_button (bar, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_progress_info_bar_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_progress_info_bar_class_init (XedProgressInfoBarClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = xed_progress_info_bar_set_property; + gobject_class->get_property = xed_progress_info_bar_get_property; + + g_object_class_install_property (gobject_class, + PROP_HAS_CANCEL_BUTTON, + g_param_spec_boolean ("has-cancel-button", + "Has Cancel Button", + "If the message area has a cancel button", + TRUE, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private (gobject_class, sizeof (XedProgressInfoBarPrivate)); +} + +static void +xed_progress_info_bar_init (XedProgressInfoBar *bar) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *content; + + bar->priv = XED_PROGRESS_INFO_BAR_GET_PRIVATE (bar); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_widget_show (vbox); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_widget_show (hbox); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0); + + bar->priv->image = gtk_image_new_from_icon_name ("image-missing", GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_widget_show (bar->priv->image); + gtk_widget_set_halign (bar->priv->image, GTK_ALIGN_CENTER); + gtk_widget_set_valign (bar->priv->image, GTK_ALIGN_CENTER); + gtk_box_pack_start (GTK_BOX (hbox), bar->priv->image, FALSE, FALSE, 4); + + bar->priv->label = gtk_label_new (""); + gtk_widget_show (bar->priv->label); + gtk_box_pack_start (GTK_BOX (hbox), bar->priv->label, FALSE, TRUE, 0); + gtk_label_set_use_markup (GTK_LABEL (bar->priv->label), TRUE); + gtk_widget_set_halign (bar->priv->label, GTK_ALIGN_START); + gtk_label_set_ellipsize (GTK_LABEL (bar->priv->label), PANGO_ELLIPSIZE_END); + + bar->priv->progress = gtk_progress_bar_new (); + gtk_widget_set_hexpand (bar->priv->progress, TRUE); + gtk_widget_show (bar->priv->progress); + gtk_box_pack_start (GTK_BOX (vbox), bar->priv->progress, FALSE, TRUE, 0); + gtk_widget_set_size_request (bar->priv->progress, -1, 15); + + content = gtk_info_bar_get_content_area (GTK_INFO_BAR (bar)); + gtk_container_add (GTK_CONTAINER (content), vbox); +} + +GtkWidget * +xed_progress_info_bar_new (const gchar *icon_name, + const gchar *markup, + gboolean has_cancel) +{ + XedProgressInfoBar *bar; + + g_return_val_if_fail (icon_name != NULL, NULL); + g_return_val_if_fail (markup != NULL, NULL); + + bar = XED_PROGRESS_INFO_BAR (g_object_new (XED_TYPE_PROGRESS_INFO_BAR, + "has-cancel-button", has_cancel, + NULL)); + + xed_progress_info_bar_set_image (bar, icon_name); + xed_progress_info_bar_set_markup (bar, markup); + + return GTK_WIDGET (bar); +} + +void +xed_progress_info_bar_set_image (XedProgressInfoBar *bar, + const gchar *icon_name) +{ + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (bar)); + g_return_if_fail (icon_name != NULL); + + gtk_image_set_from_icon_name (GTK_IMAGE (bar->priv->image), icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR); +} + +void +xed_progress_info_bar_set_markup (XedProgressInfoBar *bar, + const gchar *markup) +{ + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (bar)); + g_return_if_fail (markup != NULL); + + gtk_label_set_markup (GTK_LABEL (bar->priv->label), markup); +} + +void +xed_progress_info_bar_set_text (XedProgressInfoBar *bar, + const gchar *text) +{ + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (bar)); + g_return_if_fail (text != NULL); + + gtk_label_set_text (GTK_LABEL (bar->priv->label), text); +} + +void +xed_progress_info_bar_set_fraction (XedProgressInfoBar *bar, + gdouble fraction) +{ + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (bar)); + + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar->priv->progress), fraction); +} + +void +xed_progress_info_bar_pulse (XedProgressInfoBar *bar) +{ + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (bar)); + + gtk_progress_bar_pulse (GTK_PROGRESS_BAR (bar->priv->progress)); +} diff --git a/xed/xed-progress-info-bar.h b/xed/xed-progress-info-bar.h new file mode 100644 index 0000000..0c0da77 --- /dev/null +++ b/xed/xed-progress-info-bar.h @@ -0,0 +1,85 @@ +/* + * xed-progress-info-bar.h + * This file is part of xed + * + * Copyright (C) 2005 - Paolo Maggi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. + * + * $Id$ + */ + +#ifndef __XED_PROGRESS_INFO_BAR_H__ +#define __XED_PROGRESS_INFO_BAR_H__ + +#include + +G_BEGIN_DECLS + +#define XED_TYPE_PROGRESS_INFO_BAR (xed_progress_info_bar_get_type()) +#define XED_PROGRESS_INFO_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PROGRESS_INFO_BAR, XedProgressInfoBar)) +#define XED_PROGRESS_INFO_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_PROGRESS_INFO_BAR, XedProgressInfoBarClass)) +#define XED_IS_PROGRESS_INFO_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_PROGRESS_INFO_BAR)) +#define XED_IS_PROGRESS_INFO_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PROGRESS_INFO_BAR)) +#define XED_PROGRESS_INFO_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PROGRESS_INFO_BAR, XedProgressInfoBarClass)) + +typedef struct _XedProgressInfoBar XedProgressInfoBar; +typedef struct _XedProgressInfoBarClass XedProgressInfoBarClass; +typedef struct _XedProgressInfoBarPrivate XedProgressInfoBarPrivate; + +struct _XedProgressInfoBar +{ + GtkInfoBar parent; + + /*< private > */ + XedProgressInfoBarPrivate *priv; +}; + +struct _XedProgressInfoBarClass +{ + GtkInfoBarClass parent_class; +}; + +GType xed_progress_info_bar_get_type (void) G_GNUC_CONST; + +GtkWidget *xed_progress_info_bar_new (const gchar *icon_name, + const gchar *markup, + gboolean has_cancel); + +void xed_progress_info_bar_set_image (XedProgressInfoBar *area, + const gchar *icon_name); + +void xed_progress_info_bar_set_markup (XedProgressInfoBar *area, + const gchar *markup); + +void xed_progress_info_bar_set_text (XedProgressInfoBar *area, + const gchar *text); + +void xed_progress_info_bar_set_fraction (XedProgressInfoBar *area, + gdouble fraction); + +void xed_progress_info_bar_pulse (XedProgressInfoBar *area); + + +G_END_DECLS + +#endif /* __XED_PROGRESS_INFO_BAR_H__ */ diff --git a/xed/xed-progress-message-area.c b/xed/xed-progress-message-area.c deleted file mode 100644 index 87696fb..0000000 --- a/xed/xed-progress-message-area.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * xed-progress-message-area.c - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - - /* TODO: add properties */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "xed-progress-message-area.h" - -enum { - PROP_0, - PROP_HAS_CANCEL_BUTTON -}; - - -#define XED_PROGRESS_MESSAGE_AREA_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_PROGRESS_MESSAGE_AREA, XedProgressMessageAreaPrivate)) - -struct _XedProgressMessageAreaPrivate -{ - GtkWidget *image; - GtkWidget *label; - GtkWidget *progress; -}; - -G_DEFINE_TYPE(XedProgressMessageArea, xed_progress_message_area, GTK_TYPE_INFO_BAR) - -static void -xed_progress_message_area_set_has_cancel_button (XedProgressMessageArea *area, - gboolean has_button) -{ - if (has_button) - gtk_info_bar_add_button (GTK_INFO_BAR (area), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL); - - g_object_notify (G_OBJECT (area), "has-cancel-button"); -} - -static void -xed_progress_message_area_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedProgressMessageArea *area; - - area = XED_PROGRESS_MESSAGE_AREA (object); - - switch (prop_id) - { - case PROP_HAS_CANCEL_BUTTON: - xed_progress_message_area_set_has_cancel_button (area, - g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_progress_message_area_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_progress_message_area_class_init (XedProgressMessageAreaClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = xed_progress_message_area_set_property; - gobject_class->get_property = xed_progress_message_area_get_property; - - g_object_class_install_property (gobject_class, - PROP_HAS_CANCEL_BUTTON, - g_param_spec_boolean ("has-cancel-button", - "Has Cancel Button", - "If the message area has a cancel button", - TRUE, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_type_class_add_private (gobject_class, sizeof(XedProgressMessageAreaPrivate)); -} - -static void -xed_progress_message_area_init (XedProgressMessageArea *area) -{ - GtkWidget *vbox; - GtkWidget *hbox; - - area->priv = XED_PROGRESS_MESSAGE_AREA_GET_PRIVATE (area); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_widget_show (vbox); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - area->priv->image = gtk_image_new_from_icon_name (GTK_STOCK_MISSING_IMAGE, - GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_widget_show (area->priv->image); - gtk_widget_set_halign (area->priv->image, GTK_ALIGN_CENTER); - gtk_widget_set_valign (area->priv->image, GTK_ALIGN_CENTER); - gtk_box_pack_start (GTK_BOX (hbox), area->priv->image, FALSE, FALSE, 4); - - area->priv->label = gtk_label_new (""); - gtk_widget_show (area->priv->label); - gtk_box_pack_start (GTK_BOX (hbox), area->priv->label, TRUE, TRUE, 0); - gtk_label_set_use_markup (GTK_LABEL (area->priv->label), TRUE); - gtk_misc_set_alignment (GTK_MISC (area->priv->label), 0.0, 0.5); - gtk_label_set_ellipsize (GTK_LABEL (area->priv->label), - PANGO_ELLIPSIZE_END); - - area->priv->progress = gtk_progress_bar_new (); - gtk_widget_show (area->priv->progress); - gtk_box_pack_start (GTK_BOX (vbox), area->priv->progress, TRUE, FALSE, 0); - gtk_widget_set_size_request (area->priv->progress, -1, 15); - - GtkWidget *content; - - content = gtk_info_bar_get_content_area (GTK_INFO_BAR (area)); - gtk_container_add (GTK_CONTAINER (content), vbox); -} - -GtkWidget * -xed_progress_message_area_new (const gchar *stock_id, - const gchar *markup, - gboolean has_cancel) -{ - XedProgressMessageArea *area; - - g_return_val_if_fail (stock_id != NULL, NULL); - g_return_val_if_fail (markup != NULL, NULL); - - area = XED_PROGRESS_MESSAGE_AREA (g_object_new (XED_TYPE_PROGRESS_MESSAGE_AREA, - "has-cancel-button", has_cancel, - NULL)); - - xed_progress_message_area_set_stock_image (area, - stock_id); - - xed_progress_message_area_set_markup (area, - markup); - - return GTK_WIDGET (area); -} - -void -xed_progress_message_area_set_stock_image (XedProgressMessageArea *area, - const gchar *stock_id) -{ - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (area)); - g_return_if_fail (stock_id != NULL); - - gtk_image_set_from_stock (GTK_IMAGE (area->priv->image), - stock_id, - GTK_ICON_SIZE_SMALL_TOOLBAR); -} - -void -xed_progress_message_area_set_markup (XedProgressMessageArea *area, - const gchar *markup) -{ - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (area)); - g_return_if_fail (markup != NULL); - - gtk_label_set_markup (GTK_LABEL (area->priv->label), - markup); -} - -void -xed_progress_message_area_set_text (XedProgressMessageArea *area, - const gchar *text) -{ - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (area)); - g_return_if_fail (text != NULL); - - gtk_label_set_text (GTK_LABEL (area->priv->label), - text); -} - -void -xed_progress_message_area_set_fraction (XedProgressMessageArea *area, - gdouble fraction) -{ - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (area)); - - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (area->priv->progress), - fraction); -} - -void -xed_progress_message_area_pulse (XedProgressMessageArea *area) -{ - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (area)); - - gtk_progress_bar_pulse (GTK_PROGRESS_BAR (area->priv->progress)); -} diff --git a/xed/xed-progress-message-area.h b/xed/xed-progress-message-area.h deleted file mode 100644 index 4b830db..0000000 --- a/xed/xed-progress-message-area.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * xed-progress-message-area.h - * This file is part of xed - * - * Copyright (C) 2005 - Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifndef __XED_PROGRESS_MESSAGE_AREA_H__ -#define __XED_PROGRESS_MESSAGE_AREA_H__ - -#include - -G_BEGIN_DECLS - -/* - * Type checking and casting macros - */ -#define XED_TYPE_PROGRESS_MESSAGE_AREA (xed_progress_message_area_get_type()) -#define XED_PROGRESS_MESSAGE_AREA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PROGRESS_MESSAGE_AREA, XedProgressMessageArea)) -#define XED_PROGRESS_MESSAGE_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_PROGRESS_MESSAGE_AREA, XedProgressMessageAreaClass)) -#define XED_IS_PROGRESS_MESSAGE_AREA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_PROGRESS_MESSAGE_AREA)) -#define XED_IS_PROGRESS_MESSAGE_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PROGRESS_MESSAGE_AREA)) -#define XED_PROGRESS_MESSAGE_AREA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PROGRESS_MESSAGE_AREA, XedProgressMessageAreaClass)) - -/* Private structure type */ -typedef struct _XedProgressMessageAreaPrivate XedProgressMessageAreaPrivate; - -/* - * Main object structure - */ -typedef struct _XedProgressMessageArea XedProgressMessageArea; - -struct _XedProgressMessageArea -{ - GtkInfoBar parent; - - /*< private > */ - XedProgressMessageAreaPrivate *priv; -}; - -/* - * Class definition - */ -typedef struct _XedProgressMessageAreaClass XedProgressMessageAreaClass; - -struct _XedProgressMessageAreaClass -{ - GtkInfoBarClass parent_class; -}; - -/* - * Public methods - */ -GType xed_progress_message_area_get_type (void) G_GNUC_CONST; - -GtkWidget *xed_progress_message_area_new (const gchar *stock_id, - const gchar *markup, - gboolean has_cancel); - -void xed_progress_message_area_set_stock_image (XedProgressMessageArea *area, - const gchar *stock_id); - -void xed_progress_message_area_set_markup (XedProgressMessageArea *area, - const gchar *markup); - -void xed_progress_message_area_set_text (XedProgressMessageArea *area, - const gchar *text); - -void xed_progress_message_area_set_fraction (XedProgressMessageArea *area, - gdouble fraction); - -void xed_progress_message_area_pulse (XedProgressMessageArea *area); - - -G_END_DECLS - -#endif /* __XED_PROGRESS_MESSAGE_AREA_H__ */ diff --git a/xed/xed-searchbar.c b/xed/xed-searchbar.c index 996b9a7..94b33c2 100755 --- a/xed/xed-searchbar.c +++ b/xed/xed-searchbar.c @@ -18,15 +18,16 @@ #define XED_SEARCHBAR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_SEARCHBAR, XedSearchbarPrivate)) -/* Signals */ enum { - SHOW_REPLACE, LAST_SIGNAL + SHOW_REPLACE, + LAST_SIGNAL }; struct _XedSearchbarPrivate { gboolean show_replace; + GtkWidget *revealer; GtkWidget *grid; GtkWidget *search_label; @@ -35,6 +36,7 @@ struct _XedSearchbarPrivate GtkWidget *replace_label; GtkWidget *replace_entry; GtkWidget *replace_text_entry; + GtkWidget *regex_checkbutton; GtkWidget *match_case_checkbutton; GtkWidget *entire_word_checkbutton; GtkWidget *wrap_around_checkbutton; @@ -43,17 +45,39 @@ struct _XedSearchbarPrivate GtkWidget *replace_button; GtkWidget *replace_all_button; GtkWidget *close_button; + + GtkSourceSearchSettings *search_settings; + XedSearchMode search_mode; + + guint update_occurrence_count_id; }; G_DEFINE_TYPE(XedSearchbar, xed_searchbar, GTK_TYPE_BOX) +static void +xed_searchbar_dispose (GObject *object) +{ + XedSearchbar *searchbar = XED_SEARCHBAR (object); + + if (searchbar->priv->update_occurrence_count_id != 0) + { + g_source_remove (searchbar->priv->update_occurrence_count_id); + searchbar->priv->update_occurrence_count_id = 0; + } + + g_clear_object (&searchbar->priv->search_settings); + + G_OBJECT_CLASS (xed_searchbar_parent_class)->dispose (object); +} + static void xed_searchbar_class_init (XedSearchbarClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS(klass); - GtkBindingSet *binding_set; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = xed_searchbar_dispose; + g_type_class_add_private (object_class, sizeof(XedSearchbarPrivate)); - binding_set = gtk_binding_set_by_class (klass); } #define XED_SEARCHBAR_KEY "xed-searchbar-key" @@ -62,178 +86,333 @@ xed_searchbar_class_init (XedSearchbarClass *klass) /* Use occurrences only for Replace All */ static void text_found (XedWindow *window, - gint occurrences) + gint occurrences) { if (occurrences > 1) { - xed_statusbar_flash_message (XED_STATUSBAR(window->priv->statusbar), window->priv->generic_message_cid, - ngettext ("Found and replaced %d occurrence", "Found and replaced %d occurrences", occurrences), - occurrences); + xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), + window->priv->generic_message_cid, + ngettext ("Found and replaced %d occurrence", "Found and replaced %d occurrences", + occurrences), + occurrences); } else { if (occurrences == 1) { - xed_statusbar_flash_message (XED_STATUSBAR(window->priv->statusbar), window->priv->generic_message_cid, + xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), + window->priv->generic_message_cid, _("Found and replaced one occurrence")); } else { - xed_statusbar_flash_message (XED_STATUSBAR(window->priv->statusbar), window->priv->generic_message_cid, + xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar), + window->priv->generic_message_cid, " "); } } } static void -text_not_found (XedWindow *window, - const gchar *text) +text_not_found (XedSearchbar *searchbar) { - gchar *searched; + const gchar *search_text; + gchar *truncated_text; - searched = xed_utils_str_end_truncate (text, MAX_MSG_LENGTH); - xed_statusbar_flash_message (XED_STATUSBAR(window->priv->statusbar), window->priv->generic_message_cid, - _("\"%s\" not found"), searched); - g_free (searched); + search_text = xed_searchbar_get_search_text (searchbar); + truncated_text = xed_utils_str_end_truncate (search_text, MAX_MSG_LENGTH); + + xed_statusbar_flash_message (XED_STATUSBAR (searchbar->window->priv->statusbar), + searchbar->window->priv->generic_message_cid, + _("\"%s\" not found"), truncated_text); + + g_free (truncated_text); } static gboolean -run_search (XedView *view, - gboolean wrap_around, - gboolean search_backwards, - gboolean jump_to_next_result) +forward_search_finished (GtkSourceSearchContext *search_context, + GAsyncResult *result, + XedView *view) { - XedDocument *doc; - GtkTextIter start_iter; - GtkTextIter end_iter; + gboolean found; + GtkSourceBuffer *buffer; GtkTextIter match_start; GtkTextIter match_end; - gboolean found = FALSE; - doc = XED_DOCUMENT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER(doc), &start_iter, &end_iter); - - if (!search_backwards) - { - if (jump_to_next_result) { - found = xed_document_search_forward (doc, &end_iter, NULL, &match_start, &match_end); - } - else { - found = xed_document_search_forward (doc, &start_iter, NULL, &match_start, &match_end); - } - } - else - { - found = xed_document_search_backward (doc, NULL, &start_iter, &match_start, &match_end); - } - - if (!found && wrap_around) - { - if (!search_backwards) - { - /* FIXME: set the end_inter */ - found = xed_document_search_forward (doc, NULL, NULL, &match_start, &match_end); - } - else - { - /* FIXME: set the start_inter */ - found = xed_document_search_backward (doc, NULL, NULL, &match_start, &match_end); - } - } + found = gtk_source_search_context_forward_finish (search_context, result, &match_start, &match_end, NULL); + buffer = gtk_source_search_context_get_buffer (search_context); if (found) { - gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER(doc), &match_start); - gtk_text_buffer_move_mark_by_name (GTK_TEXT_BUFFER(doc), "selection_bound", &match_end); + gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &match_start, &match_end); xed_view_scroll_to_cursor (view); } else { - gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER(doc), &start_iter); + GtkTextIter end_selection; + + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (buffer), NULL, &end_selection); + gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &end_selection, &end_selection); } return found; } static void -do_find (XedSearchbar *searchbar, - gboolean search_backwards, - gboolean jump_to_next_result) +run_forward_search (XedWindow *window, + gboolean jump_to_next_result) { - XedView *active_view; - XedDocument *doc; - gchar *search_text; - const gchar *entry_text; - gboolean match_case; - gboolean entire_word; - gboolean wrap_around; - guint flags = 0; - guint old_flags = 0; - gboolean found; + XedView *view; + GtkTextBuffer *buffer; + GtkTextIter start_at; + GtkTextIter end_at; + GtkSourceSearchContext *search_context; - /* TODO: make the searchbar insensitive when all the tabs are closed - * and assert here that the view is not NULL */ - active_view = xed_window_get_active_view (searchbar->window); - if (active_view == NULL) + view = xed_window_get_active_view (window); + + if (view == NULL) { return; } - doc = XED_DOCUMENT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view))); + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); + search_context = xed_document_get_search_context (XED_DOCUMENT (buffer)); - match_case = xed_searchbar_get_match_case (searchbar); - entire_word = xed_searchbar_get_entire_word (searchbar); - wrap_around = xed_searchbar_get_wrap_around (searchbar); - entry_text = xed_searchbar_get_search_text (searchbar); - - XED_SEARCH_SET_CASE_SENSITIVE(flags, match_case); - XED_SEARCH_SET_ENTIRE_WORD(flags, entire_word); - - search_text = xed_document_get_search_text (doc, &old_flags); - - if ((search_text == NULL) || (strcmp (search_text, entry_text) != 0) || (flags != old_flags)) + if (search_context == NULL) { - xed_document_set_search_text (doc, entry_text, flags); + return; } - g_free (search_text); + gtk_text_buffer_get_selection_bounds (buffer, &start_at, &end_at); - found = run_search (active_view, wrap_around, search_backwards, jump_to_next_result); - - if (found) + if (jump_to_next_result) { - text_found (searchbar->window, 0); + gtk_source_search_context_forward_async (search_context, + &end_at, + NULL, + (GAsyncReadyCallback)forward_search_finished, + view); } else { - text_not_found (searchbar->window, entry_text); + gtk_source_search_context_forward_async (search_context, + &start_at, + NULL, + (GAsyncReadyCallback)forward_search_finished, + view); + } +} + +static gboolean +backward_search_finished (GtkSourceSearchContext *search_context, + GAsyncResult *result, + XedView *view) +{ + gboolean found; + GtkTextIter match_start; + GtkTextIter match_end; + GtkSourceBuffer *buffer; + + found = gtk_source_search_context_backward_finish (search_context, result, &match_start, &match_end, NULL); + buffer = gtk_source_search_context_get_buffer (search_context); + + if (found) + { + gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &match_start, &match_end); + xed_view_scroll_to_cursor (view); + } + else + { + GtkTextIter start_selection; + + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (buffer), &start_selection, NULL); + gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &start_selection, &start_selection); + } + + return found; +} + +static void +run_backward_search (XedWindow *window) +{ + XedView *view; + GtkTextBuffer *buffer; + GtkTextIter start_at; + GtkSourceSearchContext *search_context; + + view = xed_window_get_active_view (window); + + if (view == NULL) + { + return; + } + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); + search_context = xed_document_get_search_context (XED_DOCUMENT (buffer)); + + if (search_context == NULL) + { + return; + } + + gtk_text_buffer_get_selection_bounds (buffer, &start_at, NULL); + gtk_source_search_context_backward_async (search_context, + &start_at, + NULL, + (GAsyncReadyCallback)backward_search_finished, + view); +} + +static void +update_occurrence_count (XedSearchbar *searchbar) +{ + XedDocument *doc; + GtkSourceSearchContext *search_context; + GtkTextIter match_start; + GtkTextIter match_end; + gint count; + gint pos; + + if (searchbar->priv->search_mode == XED_SEARCH_MODE_REPLACE) + { + return; + } + + searchbar->priv->update_occurrence_count_id = 0; + doc = xed_window_get_active_document (searchbar->window); + search_context = xed_document_get_search_context (doc); + + if (search_context == NULL) + { + return; + } + + count = gtk_source_search_context_get_occurrences_count (search_context); + + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), &match_start, &match_end); + pos = gtk_source_search_context_get_occurrence_position (search_context, &match_start, &match_end); + + if (count == -1 || pos == -1) + { + /* Wait for the buffer to be fully scanned */ + return; + } + + if (count == 0) + { + xed_statusbar_flash_message (XED_STATUSBAR (searchbar->window->priv->statusbar), + searchbar->window->priv->generic_message_cid, + _("No matches found")); + return; + } + + if (pos == 0) + { + xed_statusbar_flash_message (XED_STATUSBAR (searchbar->window->priv->statusbar), + searchbar->window->priv->generic_message_cid, + ngettext ("%d match", "%d matches", count), count); + return; + } + + xed_statusbar_flash_message (XED_STATUSBAR (searchbar->window->priv->statusbar), + searchbar->window->priv->generic_message_cid, + ngettext ("%d of %d match", "%d of %d matches", + pos), + pos, count); +} + +static gboolean +update_occurrence_count_id_cb (XedSearchbar *searchbar) +{ + searchbar->priv->update_occurrence_count_id = 0; + update_occurrence_count (searchbar); + + return G_SOURCE_REMOVE; +} + +static void +install_occurrence_count_idle (XedSearchbar *searchbar) +{ + if (searchbar->priv->update_occurrence_count_id == 0) + { + searchbar->priv->update_occurrence_count_id = g_idle_add ((GSourceFunc)update_occurrence_count_id_cb, searchbar); + } +} + +static void +mark_set_cb (GtkTextBuffer *buffer, + GtkTextIter *location, + GtkTextMark *mark, + XedSearchbar *searchbar) +{ + GtkTextMark *insert; + GtkTextMark *selection_bound; + + insert = gtk_text_buffer_get_insert (buffer); + selection_bound = gtk_text_buffer_get_selection_bound (buffer); + + if (mark == insert || mark == selection_bound) + { + install_occurrence_count_idle (searchbar); + } +} + +static void +do_find (XedSearchbar *searchbar, + gboolean search_backwards, + gboolean jump_to_next_result) +{ + XedDocument *doc; + GtkSourceSearchContext *search_context; + GtkSourceSearchSettings *search_settings; + + search_settings = xed_searchbar_get_search_settings (searchbar); + doc = xed_window_get_active_document (searchbar->window); + search_context = xed_document_get_search_context (doc); + searchbar->priv->search_mode = XED_SEARCH_MODE_SEARCH; + + if (search_context == NULL || search_settings != gtk_source_search_context_get_settings (search_context)) + { + search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (doc), search_settings); + + xed_document_set_search_context (doc, search_context); + + g_signal_connect (GTK_TEXT_BUFFER (doc), "mark-set", + G_CALLBACK (mark_set_cb), searchbar); + + g_signal_connect_swapped (search_context, "notify::occurrences-count", + G_CALLBACK (install_occurrence_count_idle), searchbar); + + g_object_unref (search_context); + } + + if (search_backwards) + { + run_backward_search (searchbar->window); + } + else + { + run_forward_search (searchbar->window, jump_to_next_result); } } void xed_searchbar_find_again (XedSearchbar *searchbar, - gboolean backward) + gboolean backward) { - XedView *active_view; - gboolean wrap_around = TRUE; - gpointer data; - - active_view = xed_window_get_active_view (searchbar->window); - g_return_if_fail(active_view != NULL); - - data = g_object_get_data (G_OBJECT(searchbar->window), XED_SEARCHBAR_KEY); - - if (data != NULL) + if (backward) { - wrap_around = xed_searchbar_get_wrap_around (XED_SEARCHBAR(data)); + do_find (searchbar, TRUE, TRUE); + } + else + { + do_find (searchbar, FALSE, TRUE); } - - run_search (active_view, wrap_around, backward, TRUE); } static void search_buttons_set_sensitive (XedSearchbar *searchbar, - gboolean sensitive) + gboolean sensitive) { gtk_widget_set_sensitive (searchbar->priv->find_button, sensitive); gtk_widget_set_sensitive (searchbar->priv->find_prev_button, sensitive); @@ -243,14 +422,14 @@ search_buttons_set_sensitive (XedSearchbar *searchbar, /* FIXME: move in xed-document.c and share it with xed-view */ static gboolean -get_selected_text (GtkTextBuffer *doc, - gchar **selected_text, - gint *len) +get_selected_text (GtkTextBuffer *doc, + gchar **selected_text, + gint *len) { GtkTextIter start, end; - g_return_val_if_fail(selected_text != NULL, FALSE); - g_return_val_if_fail(*selected_text == NULL, FALSE); + g_return_val_if_fail (selected_text != NULL, FALSE); + g_return_val_if_fail (*selected_text == NULL, FALSE); if (!gtk_text_buffer_get_selection_bounds (doc, &start, &end)) { @@ -271,69 +450,45 @@ get_selected_text (GtkTextBuffer *doc, return TRUE; } -static void -replace_selected_text (GtkTextBuffer *buffer, - const gchar *replace) -{ - g_return_if_fail(gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL)); - g_return_if_fail(replace != NULL); - - gtk_text_buffer_begin_user_action (buffer); - gtk_text_buffer_delete_selection (buffer, FALSE, TRUE); - gtk_text_buffer_insert_at_cursor (buffer, replace, strlen (replace)); - gtk_text_buffer_end_user_action (buffer); -} - static void do_replace (XedSearchbar *searchbar) { XedDocument *doc; - const gchar *search_entry_text; + GtkSourceSearchContext *search_context; const gchar *replace_entry_text; - gchar *unescaped_search_text; gchar *unescaped_replace_text; - gchar *selected_text = NULL; - gboolean match_case; + GtkTextIter start; + GtkTextIter end; doc = xed_window_get_active_document (searchbar->window); + if (doc == NULL) { return; } - search_entry_text = xed_searchbar_get_search_text (searchbar); - g_return_if_fail((search_entry_text) != NULL); - g_return_if_fail((*search_entry_text) != '\0'); + search_context = xed_document_get_search_context (doc); - /* replace text may be "", we just delete */ - replace_entry_text = xed_searchbar_get_replace_text (searchbar); - g_return_if_fail((replace_entry_text) != NULL); - - unescaped_search_text = xed_utils_unescape_search_text (search_entry_text); - - get_selected_text (GTK_TEXT_BUFFER(doc), &selected_text, NULL); - - match_case = xed_searchbar_get_match_case (searchbar); - - if ((selected_text == NULL) - || (match_case && (strcmp (selected_text, unescaped_search_text) != 0)) - || (!match_case && !g_utf8_caselessnmatch (selected_text, - unescaped_search_text, - strlen (selected_text), - strlen (unescaped_search_text)) != 0)) + if (search_context == NULL) { - do_find (searchbar, FALSE, TRUE ); - g_free (unescaped_search_text); - g_free (selected_text); - return; } - unescaped_replace_text = xed_utils_unescape_search_text (replace_entry_text); - replace_selected_text (GTK_TEXT_BUFFER(doc), unescaped_replace_text); + /* replace text may be "", we just delete */ + replace_entry_text = xed_searchbar_get_replace_text (searchbar); + g_return_if_fail ((replace_entry_text) != NULL); + + unescaped_replace_text = gtk_source_utils_unescape_search_text (replace_entry_text); + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), &start, &end); + searchbar->priv->search_mode = XED_SEARCH_MODE_REPLACE; + + gtk_source_search_context_replace (search_context, + &start, + &end, + unescaped_replace_text, + -1, + NULL); - g_free (unescaped_search_text); - g_free (selected_text); g_free (unescaped_replace_text); do_find (searchbar, FALSE, TRUE); @@ -342,38 +497,35 @@ do_replace (XedSearchbar *searchbar) static void do_replace_all (XedSearchbar *searchbar) { - XedView *active_view; XedDocument *doc; - const gchar *search_entry_text; + GtkSourceSearchContext *search_context; const gchar *replace_entry_text; - gboolean match_case; - gboolean entire_word; - guint flags = 0; + gchar *unescaped_replace_text; gint count; - active_view = xed_window_get_active_view (searchbar->window); - if (active_view == NULL) + doc = xed_window_get_active_document (searchbar->window); + + if (doc == NULL) { return; } - doc = XED_DOCUMENT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view))); + search_context = xed_document_get_search_context (doc); - search_entry_text = xed_searchbar_get_search_text (searchbar); - g_return_if_fail((search_entry_text) != NULL); - g_return_if_fail((*search_entry_text) != '\0'); + if (search_context == NULL) + { + return; + } /* replace text may be "", we just delete all occurrences */ replace_entry_text = xed_searchbar_get_replace_text (searchbar); - g_return_if_fail((replace_entry_text) != NULL); + g_return_if_fail ((replace_entry_text) != NULL); - match_case = xed_searchbar_get_match_case (searchbar); - entire_word = xed_searchbar_get_entire_word (searchbar); + unescaped_replace_text = gtk_source_utils_unescape_search_text (replace_entry_text); + count = gtk_source_search_context_replace_all (search_context, unescaped_replace_text, -1, NULL); + searchbar->priv->search_mode = XED_SEARCH_MODE_REPLACE; - XED_SEARCH_SET_CASE_SENSITIVE(flags, match_case); - XED_SEARCH_SET_ENTIRE_WORD(flags, entire_word); - - count = xed_document_replace_all (doc, search_entry_text, replace_entry_text, flags); + g_free (unescaped_replace_text); if (count > 0) { @@ -381,49 +533,11 @@ do_replace_all (XedSearchbar *searchbar) } else { - text_not_found (searchbar->window, search_entry_text); + text_not_found (searchbar); } } -static void -insert_text_handler (GtkEditable *editable, - const gchar *text, - gint length, - gint *position, - gpointer data) -{ - static gboolean insert_text = FALSE; - gchar *escaped_text; - gint new_len; - - /* To avoid recursive behavior */ - if (insert_text) - { - return; - } - - escaped_text = xed_utils_escape_search_text (text); - - new_len = strlen (escaped_text); - - if (new_len == length) - { - g_free (escaped_text); - return; - } - - insert_text = TRUE; - - g_signal_stop_emission_by_name (editable, "insert_text"); - - gtk_editable_insert_text (editable, escaped_text, new_len, position); - - insert_text = FALSE; - - g_free (escaped_text); -} - static void search_text_entry_changed (GtkEditable *editable, XedSearchbar *searchbar) @@ -436,26 +550,38 @@ search_text_entry_changed (GtkEditable *editable, if (*search_string != '\0') { search_buttons_set_sensitive (searchbar, TRUE); - do_find (searchbar, FALSE, FALSE); } else { search_buttons_set_sensitive (searchbar, FALSE); - do_find (searchbar, FALSE, FALSE); } + + if (gtk_source_search_settings_get_regex_enabled (searchbar->priv->search_settings)) + { + gtk_source_search_settings_set_search_text (searchbar->priv->search_settings, search_string); + } + else + { + gchar *unescaped_search_string; + + unescaped_search_string = gtk_source_utils_unescape_search_text (search_string); + gtk_source_search_settings_set_search_text (searchbar->priv->search_settings, unescaped_search_string); + + g_free (unescaped_search_string); + } + + do_find (searchbar, FALSE, FALSE); } static void remember_search_entry (XedSearchbar *searchbar) { const gchar *str; + str = gtk_entry_get_text (GTK_ENTRY(searchbar->priv->search_text_entry)); if (*str != '\0') { - gchar *text; - text = xed_utils_unescape_search_text (str); - xed_history_entry_prepend_text (XED_HISTORY_ENTRY(searchbar->priv->search_entry), text); - g_free (text); + xed_history_entry_prepend_text (XED_HISTORY_ENTRY (searchbar->priv->search_entry), str); } } @@ -463,18 +589,16 @@ static void remember_replace_entry (XedSearchbar *searchbar) { const gchar *str; + str = gtk_entry_get_text (GTK_ENTRY(searchbar->priv->replace_text_entry)); if (*str != '\0') { - gchar *text; - text = xed_utils_unescape_search_text (str); - xed_history_entry_prepend_text (XED_HISTORY_ENTRY(searchbar->priv->replace_entry), text); - g_free (text); + xed_history_entry_prepend_text (XED_HISTORY_ENTRY(searchbar->priv->replace_entry), str); } } static void -find_button_clicked_callback (GtkWidget *button, +find_button_clicked_callback (GtkWidget *button, XedSearchbar *searchbar) { remember_search_entry (searchbar); @@ -482,15 +606,15 @@ find_button_clicked_callback (GtkWidget *button, } static void -toggle_button_clicked_callback (GtkWidget *button, - XedSearchbar *searchbar) +toggle_button_clicked_callback (GtkWidget *button, + XedSearchbar *searchbar) { remember_search_entry (searchbar); do_find (searchbar, FALSE, FALSE); } static void -find_prev_button_clicked_callback (GtkWidget *button, +find_prev_button_clicked_callback (GtkWidget *button, XedSearchbar *searchbar) { remember_search_entry (searchbar); @@ -498,7 +622,7 @@ find_prev_button_clicked_callback (GtkWidget *button, } static void -replace_button_clicked_callback (GtkWidget *button, +replace_button_clicked_callback (GtkWidget *button, XedSearchbar *searchbar) { remember_search_entry (searchbar); @@ -507,7 +631,7 @@ replace_button_clicked_callback (GtkWidget *button, } static void -replace_all_button_clicked_callback (GtkWidget *button, +replace_all_button_clicked_callback (GtkWidget *button, XedSearchbar *searchbar) { remember_search_entry (searchbar); @@ -516,7 +640,7 @@ replace_all_button_clicked_callback (GtkWidget *button, } static void -on_search_text_entry_activated (GtkEntry *widget, +on_search_text_entry_activated (GtkEntry *widget, XedSearchbar *searchbar) { remember_search_entry (searchbar); @@ -524,7 +648,7 @@ on_search_text_entry_activated (GtkEntry *widget, } static void -close_button_clicked_callback (GtkWidget *button, +close_button_clicked_callback (GtkWidget *button, XedSearchbar *searchbar) { xed_searchbar_hide (searchbar); @@ -535,39 +659,37 @@ xed_searchbar_init (XedSearchbar *searchbar) { GtkWidget *content; GtkSizeGroup *size_group; - GtkWidget *error_widget; GtkStyleContext *context; GtkCssProvider *provider; - gchar *file; + GtkBuilder *builder; gchar *root_objects[] = { "searchbar_content", NULL }; const gchar *data = ".button {padding: 0;}"; searchbar->priv = XED_SEARCHBAR_GET_PRIVATE (searchbar); - file = xed_dirs_get_ui_file ("xed-searchbar.ui"); - xed_utils_get_ui_objects (file, - root_objects, - &error_widget, - "searchbar_content", &content, - "revealer", &searchbar->priv->revealer, - "grid", &searchbar->priv->grid, - "search_label", &searchbar->priv->search_label, - "replace_with_label", &searchbar->priv->replace_label, - "match_case_checkbutton", &searchbar->priv->match_case_checkbutton, - "entire_word_checkbutton", &searchbar->priv->entire_word_checkbutton, - "wrap_around_checkbutton", &searchbar->priv->wrap_around_checkbutton, - "find_button", &searchbar->priv->find_button, - "find_prev_button", &searchbar->priv->find_prev_button, - "replace_button", &searchbar->priv->replace_button, - "replace_all_button", &searchbar->priv->replace_all_button, - "close_button", &searchbar->priv->close_button, - NULL); - g_free (file); + builder = gtk_builder_new (); + gtk_builder_add_objects_from_resource (builder, "/org/x/editor/ui/xed-searchbar.ui", root_objects, NULL); + content = GTK_WIDGET (gtk_builder_get_object (builder, "searchbar_content")); + g_object_ref (content); + searchbar->priv->revealer = GTK_WIDGET (gtk_builder_get_object (builder, "revealer")); + searchbar->priv->grid = GTK_WIDGET (gtk_builder_get_object (builder, "grid")); + searchbar->priv->search_label = GTK_WIDGET (gtk_builder_get_object (builder, "search_label")); + searchbar->priv->replace_label = GTK_WIDGET (gtk_builder_get_object (builder, "replace_with_label")); + searchbar->priv->regex_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "regex_checkbutton")); + searchbar->priv->match_case_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "match_case_checkbutton")); + searchbar->priv->entire_word_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "entire_word_checkbutton")); + searchbar->priv->wrap_around_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "wrap_around_checkbutton")); + searchbar->priv->find_button = GTK_WIDGET (gtk_builder_get_object (builder, "find_button")); + searchbar->priv->find_prev_button = GTK_WIDGET (gtk_builder_get_object (builder, "find_prev_button")); + searchbar->priv->replace_button = GTK_WIDGET (gtk_builder_get_object (builder, "replace_button")); + searchbar->priv->replace_all_button = GTK_WIDGET (gtk_builder_get_object (builder, "replace_all_button")); + searchbar->priv->close_button = GTK_WIDGET (gtk_builder_get_object (builder, "close_button")); + g_object_unref (builder); - searchbar->priv->search_entry = xed_history_entry_new ("history-search-for", TRUE); + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (searchbar)), "xed-searchbar"); + + searchbar->priv->search_entry = xed_history_entry_new ("history-search-for", FALSE); gtk_widget_set_hexpand (searchbar->priv->search_entry, TRUE); - xed_history_entry_set_escape_func (XED_HISTORY_ENTRY (searchbar->priv->search_entry), - (XedHistoryEntryEscapeFunc) xed_utils_escape_search_text); searchbar->priv->search_text_entry = xed_history_entry_get_entry (XED_HISTORY_ENTRY (searchbar->priv->search_entry)); gtk_entry_set_activates_default (GTK_ENTRY (searchbar->priv->search_text_entry), TRUE); @@ -575,9 +697,7 @@ xed_searchbar_init (XedSearchbar *searchbar) gtk_widget_show (searchbar->priv->search_entry); gtk_grid_attach (GTK_GRID (searchbar->priv->grid), searchbar->priv->search_entry, 2, 0, 1, 1); - searchbar->priv->replace_entry = xed_history_entry_new ("history-replace-with", TRUE); - xed_history_entry_set_escape_func (XED_HISTORY_ENTRY(searchbar->priv->replace_entry), - (XedHistoryEntryEscapeFunc) xed_utils_escape_search_text); + searchbar->priv->replace_entry = xed_history_entry_new ("history-replace-with", FALSE); searchbar->priv->replace_text_entry = xed_history_entry_get_entry ( XED_HISTORY_ENTRY (searchbar->priv->replace_entry)); @@ -610,12 +730,6 @@ xed_searchbar_init (XedSearchbar *searchbar) g_object_unref (content); - g_signal_connect (searchbar->priv->search_text_entry, "insert_text", - G_CALLBACK (insert_text_handler), NULL); - - g_signal_connect (searchbar->priv->replace_text_entry, "insert_text", - G_CALLBACK (insert_text_handler), NULL); - g_signal_connect (searchbar->priv->search_text_entry, "changed", G_CALLBACK (search_text_entry_changed), searchbar); @@ -643,63 +757,81 @@ xed_searchbar_init (XedSearchbar *searchbar) g_signal_connect (searchbar->priv->match_case_checkbutton, "clicked", G_CALLBACK (toggle_button_clicked_callback), searchbar); + + searchbar->priv->search_settings = gtk_source_search_settings_new (); + + g_object_bind_property (searchbar->priv->regex_checkbutton, "active", + searchbar->priv->search_settings, "regex-enabled", + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + + g_object_bind_property (searchbar->priv->match_case_checkbutton, "active", + searchbar->priv->search_settings, "case-sensitive", + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + + g_object_bind_property (searchbar->priv->entire_word_checkbutton, "active", + searchbar->priv->search_settings, "at-word-boundaries", + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + + g_object_bind_property (searchbar->priv->wrap_around_checkbutton, "active", + searchbar->priv->search_settings, "wrap-around", + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); } GtkWidget * -xed_searchbar_new (GtkWindow *parent, - gboolean show_replace) +xed_searchbar_new (GtkWindow *parent) { XedSearchbar *searchbar; + searchbar = g_object_new (XED_TYPE_SEARCHBAR, NULL); - searchbar->window = parent; - return GTK_WIDGET(searchbar); + searchbar->window = XED_WINDOW (parent); + + return GTK_WIDGET (searchbar); } void -xed_searchbar_show (XedSearchbar *searchbar, - gboolean show_replace) +xed_searchbar_show (XedSearchbar *searchbar, + XedSearchMode search_mode) { XedDocument *doc; gboolean selection_exists; gchar *find_text = NULL; - const gchar *search_text = NULL; - gint sel_len; + gint sel_len = 0; doc = xed_window_get_active_document (searchbar->window); - g_return_if_fail(doc != NULL); + g_return_if_fail (doc != NULL); - selection_exists = get_selected_text (GTK_TEXT_BUFFER(doc), &find_text, &sel_len); + selection_exists = get_selected_text (GTK_TEXT_BUFFER (doc), &find_text, &sel_len); if (selection_exists && find_text != NULL && sel_len < 80) { - /* - * Special case: if the currently selected text - * is the same as the unescaped search text, use the - * same old search text. (Without this, if you e.g. - * search for '\n' and then open the search searchbar again, - * you'll get an unprintable single-character literal '\n' in the "search for" box). - */ - search_text = xed_searchbar_get_search_text (XED_SEARCHBAR(searchbar)); - if (!(search_text != NULL && !strcmp (xed_utils_unescape_search_text (search_text), find_text))) + gchar *escaped_find_text; + + if (gtk_source_search_settings_get_regex_enabled (searchbar->priv->search_settings)) { - /* General case */ - xed_searchbar_set_search_text (XED_SEARCHBAR(searchbar), find_text); + escaped_find_text = g_regex_escape_string (find_text, -1); } - g_free (find_text); + else + { + escaped_find_text = gtk_source_utils_escape_search_text (find_text); + } + + xed_searchbar_set_search_text (XED_SEARCHBAR (searchbar), escaped_find_text); + + g_free (escaped_find_text); } - else - { - g_free (find_text); - } - gtk_revealer_set_transition_type (GTK_REVEALER(searchbar->priv->revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP); - gtk_revealer_set_reveal_child (GTK_REVEALER(searchbar->priv->revealer), TRUE); - if (show_replace) + + g_free (find_text); + + gtk_revealer_set_transition_type (GTK_REVEALER (searchbar->priv->revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP); + gtk_revealer_set_reveal_child (GTK_REVEALER (searchbar->priv->revealer), TRUE); + + if (search_mode == XED_SEARCH_MODE_REPLACE) { gtk_widget_show (searchbar->priv->replace_label); gtk_widget_show (searchbar->priv->replace_entry); gtk_widget_show (searchbar->priv->replace_all_button); gtk_widget_show (searchbar->priv->replace_button); - gtk_grid_set_row_spacing (GTK_GRID(searchbar->priv->grid), 10); + gtk_grid_set_row_spacing (GTK_GRID (searchbar->priv->grid), 10); } else { @@ -707,7 +839,7 @@ xed_searchbar_show (XedSearchbar *searchbar, gtk_widget_hide (searchbar->priv->replace_entry); gtk_widget_hide (searchbar->priv->replace_all_button); gtk_widget_hide (searchbar->priv->replace_button); - gtk_grid_set_row_spacing (GTK_GRID(searchbar->priv->grid), 0); + gtk_grid_set_row_spacing (GTK_GRID (searchbar->priv->grid), 0); } gtk_widget_show (searchbar->priv->find_button); @@ -717,98 +849,52 @@ xed_searchbar_show (XedSearchbar *searchbar, void xed_searchbar_hide (XedSearchbar *searchbar) { - gtk_revealer_set_transition_type (GTK_REVEALER(searchbar->priv->revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN); - gtk_revealer_set_reveal_child (GTK_REVEALER(searchbar->priv->revealer), FALSE); + XedView *active_view; + + gtk_revealer_set_transition_type (GTK_REVEALER (searchbar->priv->revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN); + gtk_revealer_set_reveal_child (GTK_REVEALER (searchbar->priv->revealer), FALSE); // focus document - XedView *active_view = xed_window_get_active_view (searchbar->window); + active_view = xed_window_get_active_view (searchbar->window); + if (active_view != NULL) { - gtk_widget_grab_focus (GTK_WIDGET(active_view)); + gtk_widget_grab_focus (GTK_WIDGET (active_view)); } // remove highlighting _xed_cmd_search_clear_highlight (searchbar->window); } -void -xed_searchbar_set_search_text (XedSearchbar *searchbar, - const gchar *text) -{ - g_return_if_fail(XED_IS_SEARCHBAR (searchbar)); - g_return_if_fail(text != NULL); - gtk_entry_set_text (GTK_ENTRY(searchbar->priv->search_text_entry), text); - search_buttons_set_sensitive (searchbar, (text != '\0')); -} - -/* - * The text must be unescaped before searching. - */ -const gchar * -xed_searchbar_get_search_text (XedSearchbar *searchbar) -{ - g_return_val_if_fail(XED_IS_SEARCHBAR (searchbar), NULL); - return gtk_entry_get_text (GTK_ENTRY(searchbar->priv->search_text_entry)); -} - -void -xed_searchbar_set_replace_text (XedSearchbar *searchbar, - const gchar *text) -{ - g_return_if_fail(XED_IS_SEARCHBAR (searchbar)); - g_return_if_fail(text != NULL); - - gtk_entry_set_text (GTK_ENTRY(searchbar->priv->replace_text_entry), text); -} - const gchar * xed_searchbar_get_replace_text (XedSearchbar *searchbar) { - g_return_val_if_fail(XED_IS_SEARCHBAR (searchbar), NULL); - return gtk_entry_get_text (GTK_ENTRY(searchbar->priv->replace_text_entry)); + g_return_val_if_fail (XED_IS_SEARCHBAR (searchbar), NULL); + + return gtk_entry_get_text (GTK_ENTRY (searchbar->priv->replace_text_entry)); +} + +GtkSourceSearchSettings * +xed_searchbar_get_search_settings (XedSearchbar *searchbar) +{ + g_return_val_if_fail (XED_IS_SEARCHBAR (searchbar), NULL); + + return searchbar->priv->search_settings; +} + +const gchar * +xed_searchbar_get_search_text (XedSearchbar *searchbar) +{ + g_return_val_if_fail (XED_IS_SEARCHBAR (searchbar), NULL); + + return gtk_entry_get_text (GTK_ENTRY (searchbar->priv->search_text_entry)); } void -xed_searchbar_set_match_case (XedSearchbar *searchbar, - gboolean match_case) +xed_searchbar_set_search_text (XedSearchbar *searchbar, + const gchar *search_text) { - g_return_if_fail(XED_IS_SEARCHBAR (searchbar)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(searchbar->priv->match_case_checkbutton), match_case); -} + g_return_if_fail (XED_IS_SEARCHBAR (searchbar)); -gboolean -xed_searchbar_get_match_case (XedSearchbar *searchbar) -{ - g_return_val_if_fail(XED_IS_SEARCHBAR (searchbar), FALSE); - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(searchbar->priv->match_case_checkbutton)); -} - -void -xed_searchbar_set_entire_word (XedSearchbar *searchbar, - gboolean entire_word) -{ - g_return_if_fail(XED_IS_SEARCHBAR (searchbar)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(searchbar->priv->entire_word_checkbutton), entire_word); -} - -gboolean -xed_searchbar_get_entire_word (XedSearchbar *searchbar) -{ - g_return_val_if_fail(XED_IS_SEARCHBAR (searchbar), FALSE); - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(searchbar->priv->entire_word_checkbutton)); -} - -void -xed_searchbar_set_wrap_around (XedSearchbar *searchbar, - gboolean wrap_around) -{ - g_return_if_fail(XED_IS_SEARCHBAR (searchbar)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(searchbar->priv->wrap_around_checkbutton), wrap_around); -} - -gboolean -xed_searchbar_get_wrap_around (XedSearchbar *searchbar) -{ - g_return_val_if_fail(XED_IS_SEARCHBAR (searchbar), FALSE); - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(searchbar->priv->wrap_around_checkbutton)); + gtk_entry_set_text (GTK_ENTRY (searchbar->priv->search_text_entry), search_text); } diff --git a/xed/xed-searchbar.h b/xed/xed-searchbar.h index d3b1af5..fd0e755 100755 --- a/xed/xed-searchbar.h +++ b/xed/xed-searchbar.h @@ -3,13 +3,11 @@ #define __XED_SEARCHBAR_H__ #include +#include #include "xed-window.h" G_BEGIN_DECLS -/* - * Type checking and casting macros - */ #define XED_TYPE_SEARCHBAR (xed_searchbar_get_type()) #define XED_SEARCHBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_SEARCHBAR, XedSearchbar)) #define XED_SEARCHBAR_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_SEARCHBAR, XedSearchbar const)) @@ -18,13 +16,9 @@ G_BEGIN_DECLS #define XED_IS_SEARCHBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_SEARCHBAR)) #define XED_SEARCHBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_SEARCHBAR, XedSearchbarClass)) -/* Private structure type */ +typedef struct _XedSearchbar XedSearchbar; typedef struct _XedSearchbarPrivate XedSearchbarPrivate; - -/* - * Main object structure - */ -typedef struct _XedSearchbar XedSearchbar; +typedef struct _XedSearchbarClass XedSearchbarClass; struct _XedSearchbar { @@ -35,11 +29,6 @@ struct _XedSearchbar XedSearchbarPrivate *priv; }; -/* - * Class definition - */ -typedef struct _XedSearchbarClass XedSearchbarClass; - struct _XedSearchbarClass { GtkBoxClass parent_class; @@ -48,41 +37,29 @@ struct _XedSearchbarClass gboolean (* show_replace) (XedSearchbar *dlg); }; -enum +typedef enum { - XED_SEARCHBAR_FIND_RESPONSE = 100, - XED_SEARCHBAR_REPLACE_RESPONSE, - XED_SEARCHBAR_REPLACE_ALL_RESPONSE -}; + XED_SEARCH_MODE_SEARCH, + XED_SEARCH_MODE_REPLACE +} XedSearchMode; -/* - * Public methods - */ GType xed_searchbar_get_type (void) G_GNUC_CONST; -GtkWidget *xed_searchbar_new (GtkWindow *parent, gboolean show_replace); +GtkWidget *xed_searchbar_new (GtkWindow *parent); void xed_searchbar_hide (XedSearchbar *searchbar); -void xed_searchbar_show (XedSearchbar *searchbar, gboolean show_replace); -void xed_searchbar_find_again (XedSearchbar *searchbar, gboolean backward); +void xed_searchbar_show (XedSearchbar *searchbar, XedSearchMode search_mode); +void xed_searchbar_find_again (XedSearchbar *searchbar, gboolean backward); -void xed_searchbar_set_search_text (XedSearchbar *searchbar, const gchar *text); -const gchar *xed_searchbar_get_search_text (XedSearchbar *searchbar); - -void xed_searchbar_set_replace_text (XedSearchbar *searchbar, const gchar *text); const gchar *xed_searchbar_get_replace_text (XedSearchbar *searchbar); +const gchar *xed_searchbar_get_search_text (XedSearchbar *searchbar); -void xed_searchbar_set_match_case (XedSearchbar *searchbar, gboolean match_case); -gboolean xed_searchbar_get_match_case (XedSearchbar *searchbar); - -void xed_searchbar_set_entire_word (XedSearchbar *searchbar, gboolean entire_word); -gboolean xed_searchbar_get_entire_word (XedSearchbar *searchbar); - -void xed_searchbar_set_backwards (XedSearchbar *searchbar, gboolean backwards); gboolean xed_searchbar_get_backwards (XedSearchbar *searchbar); -void xed_searchbar_set_wrap_around (XedSearchbar *searchbar, gboolean wrap_around); -gboolean xed_searchbar_get_wrap_around (XedSearchbar *searchbar); +GtkSourceSearchSettings *xed_searchbar_get_search_settings (XedSearchbar *searchbar); + +void xed_searchbar_set_search_text (XedSearchbar *searchbar, + const gchar *search_text); void xed_searchbar_set_parse_escapes (XedSearchbar *searchbar, gboolean parse_escapes); gboolean xed_searchbar_get_parse_escapes (XedSearchbar *searchbar); diff --git a/xed/xed-session.c b/xed/xed-session.c deleted file mode 100644 index a61ebe7..0000000 --- a/xed/xed-session.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * xed-session.c - Basic session management for xed - * This file is part of xed - * - * Copyright (C) 2002 Ximian, Inc. - * Copyright (C) 2005 - Paolo Maggi - * - * Author: Federico Mena-Quintero - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include -#include - -#include "xed-session.h" - -#include "xed-debug.h" -#include "xed-plugins-engine.h" -#include "xed-prefs-manager-app.h" -#include "xed-metadata-manager.h" -#include "xed-window.h" -#include "xed-app.h" -#include "xed-commands.h" -#include "dialogs/xed-close-confirmation-dialog.h" -#include "smclient/eggsmclient.h" - -/* The master client we use for SM */ -static EggSMClient *master_client = NULL; - -/* global var used during quit_requested */ -static GSList *window_dirty_list; - -static void ask_next_confirmation (void); - -#define XED_SESSION_LIST_OF_DOCS_TO_SAVE "xed-session-list-of-docs-to-save-key" - -static void -save_window_session (GKeyFile *state_file, - const gchar *group_name, - XedWindow *window) -{ - const gchar *role; - int width, height; - XedPanel *panel; - GList *docs, *l; - GPtrArray *doc_array; - XedDocument *active_document; - gchar *uri; - - xed_debug (DEBUG_SESSION); - - role = gtk_window_get_role (GTK_WINDOW (window)); - g_key_file_set_string (state_file, group_name, "role", role); - gtk_window_get_size (GTK_WINDOW (window), &width, &height); - g_key_file_set_integer (state_file, group_name, "width", width); - g_key_file_set_integer (state_file, group_name, "height", height); - - panel = xed_window_get_side_panel (window); - g_key_file_set_boolean (state_file, group_name, "side-panel-visible", - gtk_widget_get_visible (GTK_WIDGET (panel))); - - panel = xed_window_get_bottom_panel (window); - g_key_file_set_boolean (state_file, group_name, "bottom-panel-visible", - gtk_widget_get_visible (GTK_WIDGET (panel))); - - active_document = xed_window_get_active_document (window); - if (active_document) - { - uri = xed_document_get_uri (active_document); - g_key_file_set_string (state_file, group_name, - "active-document", uri); - } - - docs = xed_window_get_documents (window); - - doc_array = g_ptr_array_new (); - for (l = docs; l != NULL; l = g_list_next (l)) - { - uri = xed_document_get_uri (XED_DOCUMENT (l->data)); - - if (uri != NULL) - g_ptr_array_add (doc_array, uri); - - } - g_list_free (docs); - - if (doc_array->len) - { - guint i; - - g_key_file_set_string_list (state_file, group_name, - "documents", - (const char **)doc_array->pdata, - doc_array->len); - for (i = 0; i < doc_array->len; i++) - g_free (doc_array->pdata[i]); - } - g_ptr_array_free (doc_array, TRUE); -} - -static void -client_save_state_cb (EggSMClient *client, - GKeyFile *state_file, - gpointer user_data) -{ - const GList *windows; - gchar *group_name; - int n; - - windows = xed_app_get_windows (xed_app_get_default ()); - n = 1; - - while (windows != NULL) - { - group_name = g_strdup_printf ("xed window %d", n); - save_window_session (state_file, - group_name, - XED_WINDOW (windows->data)); - g_free (group_name); - - windows = g_list_next (windows); - n++; - } -} - -static void -window_handled (XedWindow *window) -{ - window_dirty_list = g_slist_remove (window_dirty_list, window); - - /* whee... we made it! */ - if (window_dirty_list == NULL) - egg_sm_client_will_quit (master_client, TRUE); - else - ask_next_confirmation (); -} - -static void -window_state_change (XedWindow *window, - GParamSpec *pspec, - gpointer data) -{ - XedWindowState state; - GList *unsaved_docs; - GList *docs_to_save; - GList *l; - gboolean done = TRUE; - - state = xed_window_get_state (window); - - /* we are still saving */ - if (state & XED_WINDOW_STATE_SAVING) - return; - - unsaved_docs = xed_window_get_unsaved_documents (window); - - docs_to_save = g_object_get_data (G_OBJECT (window), - XED_SESSION_LIST_OF_DOCS_TO_SAVE); - - - for (l = docs_to_save; l != NULL; l = l->next) - { - if (g_list_find (unsaved_docs, l->data)) - { - done = FALSE; - break; - } - } - - if (done) - { - g_signal_handlers_disconnect_by_func (window, window_state_change, data); - g_list_free (docs_to_save); - g_object_set_data (G_OBJECT (window), - XED_SESSION_LIST_OF_DOCS_TO_SAVE, - NULL); - - window_handled (window); - } - - g_list_free (unsaved_docs); -} - -static void -close_confirmation_dialog_response_handler (XedCloseConfirmationDialog *dlg, - gint response_id, - XedWindow *window) -{ - GList *selected_documents; - GSList *l; - - xed_debug (DEBUG_COMMANDS); - - switch (response_id) - { - case GTK_RESPONSE_YES: - /* save selected docs */ - - g_signal_connect (window, - "notify::state", - G_CALLBACK (window_state_change), - NULL); - - selected_documents = xed_close_confirmation_dialog_get_selected_documents (dlg); - - g_return_if_fail (g_object_get_data (G_OBJECT (window), - XED_SESSION_LIST_OF_DOCS_TO_SAVE) == NULL); - - g_object_set_data (G_OBJECT (window), - XED_SESSION_LIST_OF_DOCS_TO_SAVE, - selected_documents); - - _xed_cmd_file_save_documents_list (window, selected_documents); - - /* FIXME: also need to lock the window to prevent further changes... */ - - break; - - case GTK_RESPONSE_NO: - /* dont save */ - window_handled (window); - break; - - default: - /* disconnect window_state_changed where needed */ - for (l = window_dirty_list; l != NULL; l = l->next) - g_signal_handlers_disconnect_by_func (window, - window_state_change, NULL); - g_slist_free (window_dirty_list); - window_dirty_list = NULL; - - /* cancel shutdown */ - egg_sm_client_will_quit (master_client, FALSE); - - break; - } - - gtk_widget_destroy (GTK_WIDGET (dlg)); -} - -static void -show_confirmation_dialog (XedWindow *window) -{ - GList *unsaved_docs; - GtkWidget *dlg; - - xed_debug (DEBUG_SESSION); - - unsaved_docs = xed_window_get_unsaved_documents (window); - - g_return_if_fail (unsaved_docs != NULL); - - if (unsaved_docs->next == NULL) - { - /* There is only one unsaved document */ - XedTab *tab; - XedDocument *doc; - - doc = XED_DOCUMENT (unsaved_docs->data); - - tab = xed_tab_get_from_document (doc); - g_return_if_fail (tab != NULL); - - xed_window_set_active_tab (window, tab); - - dlg = xed_close_confirmation_dialog_new_single ( - GTK_WINDOW (window), - doc, - TRUE); - } - else - { - dlg = xed_close_confirmation_dialog_new (GTK_WINDOW (window), - unsaved_docs, - TRUE); - } - - g_list_free (unsaved_docs); - - g_signal_connect (dlg, - "response", - G_CALLBACK (close_confirmation_dialog_response_handler), - window); - - gtk_widget_show (dlg); -} - -static void -ask_next_confirmation (void) -{ - g_return_if_fail (window_dirty_list != NULL); - - /* pop up the confirmation dialog for the first window - * in the dirty list. The next confirmation is asked once - * this one has been handled. - */ - show_confirmation_dialog (XED_WINDOW (window_dirty_list->data)); -} - -/* quit_requested handler for the master client */ -static void -client_quit_requested_cb (EggSMClient *client, gpointer data) -{ - XedApp *app; - const GList *l; - - xed_debug (DEBUG_SESSION); - - app = xed_app_get_default (); - - if (window_dirty_list != NULL) - { - g_critical ("global variable window_dirty_list not NULL"); - window_dirty_list = NULL; - } - - for (l = xed_app_get_windows (app); l != NULL; l = l->next) - { - if (xed_window_get_unsaved_documents (XED_WINDOW (l->data)) != NULL) - { - window_dirty_list = g_slist_prepend (window_dirty_list, l->data); - } - } - - /* no modified docs */ - if (window_dirty_list == NULL) - { - egg_sm_client_will_quit (client, TRUE); - - return; - } - - ask_next_confirmation (); - - xed_debug_message (DEBUG_SESSION, "END"); -} - -/* quit handler for the master client */ -static void -client_quit_cb (EggSMClient *client, gpointer data) -{ -#if 0 - xed_debug (DEBUG_SESSION); - - if (!client->save_yourself_emitted) - xed_file_close_all (); - - xed_debug_message (DEBUG_FILE, "All files closed."); - - matecomponent_mdi_destroy (MATECOMPONENT_MDI (xed_mdi)); - - xed_debug_message (DEBUG_FILE, "Unref xed_mdi."); - - g_object_unref (G_OBJECT (xed_mdi)); - - xed_debug_message (DEBUG_FILE, "Unref xed_mdi: DONE"); - - xed_debug_message (DEBUG_FILE, "Unref xed_app_server."); - - matecomponent_object_unref (xed_app_server); - - xed_debug_message (DEBUG_FILE, "Unref xed_app_server: DONE"); -#endif - - gtk_main_quit (); -} - -/** - * xed_session_init: - * - * Initializes session management support. This function should be called near - * the beginning of the program. - **/ -void -xed_session_init (void) -{ - xed_debug (DEBUG_SESSION); - - if (master_client) - return; - - master_client = egg_sm_client_get (); - g_signal_connect (master_client, - "save_state", - G_CALLBACK (client_save_state_cb), - NULL); - g_signal_connect (master_client, - "quit_requested", - G_CALLBACK (client_quit_requested_cb), - NULL); - g_signal_connect (master_client, - "quit", - G_CALLBACK (client_quit_cb), - NULL); -} - -/** - * xed_session_is_restored: - * - * Returns whether this xed is running from a restarted session. - * - * Return value: TRUE if the session manager restarted us, FALSE otherwise. - * This should be used to determine whether to pay attention to command line - * arguments in case the session was not restored. - **/ -gboolean -xed_session_is_restored (void) -{ - gboolean restored; - - xed_debug (DEBUG_SESSION); - - if (!master_client) - return FALSE; - - restored = egg_sm_client_is_resumed (master_client); - - xed_debug_message (DEBUG_SESSION, restored ? "RESTORED" : "NOT RESTORED"); - - return restored; -} - -static void -parse_window (GKeyFile *state_file, const char *group_name) -{ - XedWindow *window; - gchar *role, *active_document, **documents; - int width, height; - gboolean visible; - XedPanel *panel; - GError *error = NULL; - - role = g_key_file_get_string (state_file, group_name, "role", NULL); - - xed_debug_message (DEBUG_SESSION, "Window role: %s", role); - - window = _xed_app_restore_window (xed_app_get_default (), (gchar *) role); - g_free (role); - - if (window == NULL) - { - g_warning ("Couldn't restore window"); - return; - } - - width = g_key_file_get_integer (state_file, group_name, - "width", &error); - if (error) - { - g_clear_error (&error); - width = -1; - } - height = g_key_file_get_integer (state_file, group_name, - "height", &error); - if (error) - { - g_clear_error (&error); - height = -1; - } - gtk_window_set_default_size (GTK_WINDOW (window), width, height); - - - visible = g_key_file_get_boolean (state_file, group_name, - "side-panel-visible", &error); - if (error) - { - g_clear_error (&error); - visible = FALSE; - } - - panel = xed_window_get_side_panel (window); - - if (visible) - { - xed_debug_message (DEBUG_SESSION, "Side panel visible"); - gtk_widget_show (GTK_WIDGET (panel)); - } - else - { - xed_debug_message (DEBUG_SESSION, "Side panel _NOT_ visible"); - gtk_widget_hide (GTK_WIDGET (panel)); - } - - visible = g_key_file_get_boolean (state_file, group_name, - "bottom-panel-visible", &error); - if (error) - { - g_clear_error (&error); - visible = FALSE; - } - - panel = xed_window_get_bottom_panel (window); - if (visible) - { - xed_debug_message (DEBUG_SESSION, "Bottom panel visible"); - gtk_widget_show (GTK_WIDGET (panel)); - } - else - { - xed_debug_message (DEBUG_SESSION, "Bottom panel _NOT_ visible"); - gtk_widget_hide (GTK_WIDGET (panel)); - } - - active_document = g_key_file_get_string (state_file, group_name, - "active-document", NULL); - documents = g_key_file_get_string_list (state_file, group_name, - "documents", NULL, NULL); - if (documents) - { - int i; - gboolean jump_to = FALSE; - - for (i = 0; documents[i]; i++) - { - if (active_document != NULL) - jump_to = strcmp (active_document, - documents[i]) == 0; - - xed_debug_message (DEBUG_SESSION, - "URI: %s (%s)", - documents[i], - jump_to ? "active" : "not active"); - xed_window_create_tab_from_uri (window, - documents[i], - NULL, - 0, - FALSE, - jump_to); - } - g_strfreev (documents); - } - - g_free (active_document); - - gtk_widget_show (GTK_WIDGET (window)); -} - -/** - * xed_session_load: - * - * Loads the session by fetching the necessary information from the session - * manager and opening files. - * - * Return value: TRUE if the session was loaded successfully, FALSE otherwise. - **/ -gboolean -xed_session_load (void) -{ - GKeyFile *state_file; - gchar **groups; - int i; - - xed_debug (DEBUG_SESSION); - - state_file = egg_sm_client_get_state_file (master_client); - if (state_file == NULL) - return FALSE; - - groups = g_key_file_get_groups (state_file, NULL); - - for (i = 0; groups[i] != NULL; i++) - { - if (g_str_has_prefix (groups[i], "xed window ")) - parse_window (state_file, groups[i]); - } - - g_strfreev (groups); - g_key_file_free (state_file); - - return TRUE; -} diff --git a/xed/xed-session.h b/xed/xed-session.h deleted file mode 100644 index e8f5822..0000000 --- a/xed/xed-session.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * xed-session.h - Basic session management for xed - * This file is part of xed - * - * Copyright (C) 2002 Ximian, Inc. - * Copyright (C) 2005 - Paolo Maggi - * - * Author: Federico Mena-Quintero - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id - */ - -#ifndef __XED_SESSION_H__ -#define __XED_SESSION_H__ - -#include - -G_BEGIN_DECLS - -void xed_session_init (void); -gboolean xed_session_is_restored (void); -gboolean xed_session_load (void); - -G_END_DECLS - -#endif /* __XED_SESSION_H__ */ diff --git a/xed/xed-settings.c b/xed/xed-settings.c new file mode 100644 index 0000000..3a1d02d --- /dev/null +++ b/xed/xed-settings.c @@ -0,0 +1,491 @@ +/* + * xed-settings.c + * This file is part of xed + * + * Copyright (C) 2002-2005 - Paolo Maggi + * 2009 - Ignacio Casal Quinteiro + * + * xed is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xed; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +#include + +#include "xed-settings.h" +#include "xed-app.h" +#include "xed-debug.h" +#include "xed-view.h" +#include "xed-window.h" +#include "xed-notebook.h" +#include "xed-plugins-engine.h" +#include "xed-dirs.h" +#include "xed-utils.h" +#include "xed-window-private.h" + +#define XED_SETTINGS_SYSTEM_FONT "monospace-font-name" + +#define XED_SETTINGS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_SETTINGS, XedSettingsPrivate)) + +struct _XedSettingsPrivate +{ + GSettings *interface; + GSettings *editor; + GSettings *ui; + + gchar *old_scheme; +}; + +G_DEFINE_TYPE (XedSettings, xed_settings, G_TYPE_OBJECT) + +static void +xed_settings_finalize (GObject *object) +{ + XedSettings *xs = XED_SETTINGS (object); + + g_free (xs->priv->old_scheme); + + G_OBJECT_CLASS (xed_settings_parent_class)->finalize (object); +} + +static void +xed_settings_dispose (GObject *object) +{ + XedSettings *xs = XED_SETTINGS (object); + + if (xs->priv->interface != NULL) + { + g_object_unref (xs->priv->interface); + xs->priv->interface = NULL; + } + + if (xs->priv->editor != NULL) + { + g_object_unref (xs->priv->editor); + xs->priv->editor = NULL; + } + + if (xs->priv->ui != NULL) + { + g_object_unref (xs->priv->ui); + xs->priv->ui = NULL; + } + + G_OBJECT_CLASS (xed_settings_parent_class)->dispose (object); +} + +static void +set_font (XedSettings *xs, + const gchar *font) +{ + GList *views, *l; + guint ts; + + ts = g_settings_get_uint (xs->priv->editor, XED_SETTINGS_TABS_SIZE); + + views = xed_app_get_views (XED_APP (g_application_get_default ())); + + for (l = views; l != NULL; l = g_list_next (l)) + { + /* Note: we use def=FALSE to avoid XedView to query dconf */ + xed_view_set_font (XED_VIEW (l->data), FALSE, font); + + gtk_source_view_set_tab_width (GTK_SOURCE_VIEW (l->data), ts); + } + + g_list_free (views); +} + +static void +on_system_font_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + + gboolean use_default_font; + gchar *font; + + use_default_font = g_settings_get_boolean (xs->priv->editor, XED_SETTINGS_USE_DEFAULT_FONT); + if (!use_default_font) + { + return; + } + + font = g_settings_get_string (settings, key); + + set_font (xs, font); + + g_free (font); +} + +static void +on_use_default_font_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + gboolean def; + gchar *font; + + def = g_settings_get_boolean (settings, key); + + if (def) + { + font = g_settings_get_string (xs->priv->interface, XED_SETTINGS_SYSTEM_FONT); + } + else + { + font = g_settings_get_string (xs->priv->editor, XED_SETTINGS_EDITOR_FONT); + } + + set_font (xs, font); + + g_free (font); +} + +static void +on_editor_font_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + gboolean use_default_font; + gchar *font; + + use_default_font = g_settings_get_boolean (xs->priv->editor, XED_SETTINGS_USE_DEFAULT_FONT); + if (use_default_font) + { + return; + } + + font = g_settings_get_string (settings, key); + + set_font (xs, font); + + g_free (font); +} + +static void +on_prefer_dark_theme_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + GtkSettings *gtk_settings; + gboolean prefer_dark_theme; + + prefer_dark_theme = g_settings_get_boolean (xs->priv->editor, XED_SETTINGS_PREFER_DARK_THEME); + gtk_settings = gtk_settings_get_default (); + + g_object_set (G_OBJECT (gtk_settings), "gtk-application-prefer-dark-theme", prefer_dark_theme, NULL); +} + +static void +on_scheme_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + GtkSourceStyleSchemeManager *manager; + GtkSourceStyleScheme *style; + gchar *scheme; + GList *docs; + GList *l; + + scheme = g_settings_get_string (settings, key); + + if (xs->priv->old_scheme != NULL && (strcmp (scheme, xs->priv->old_scheme) == 0)) + { + return; + } + + g_free (xs->priv->old_scheme); + xs->priv->old_scheme = scheme; + + manager = gtk_source_style_scheme_manager_get_default (); + style = gtk_source_style_scheme_manager_get_scheme (manager, scheme); + + if (style == NULL) + { + g_warning ("Default style scheme '%s' not found, falling back to 'classic'", scheme); + + style = gtk_source_style_scheme_manager_get_scheme (manager, "classic"); + + if (style == NULL) + { + g_warning ("Style scheme 'classic' cannot be found, check your GtkSourceView installation."); + return; + } + } + + docs = xed_app_get_documents (XED_APP (g_application_get_default ())); + for (l = docs; l != NULL; l = g_list_next (l)) + { + g_return_if_fail (GTK_SOURCE_IS_BUFFER (l->data)); + + gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (l->data), style); + } + + g_list_free (docs); +} + +static void +on_auto_save_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + GList *docs, *l; + gboolean auto_save; + + auto_save = g_settings_get_boolean (settings, key); + + docs = xed_app_get_documents (XED_APP (g_application_get_default ())); + + for (l = docs; l != NULL; l = g_list_next (l)) + { + XedTab *tab = xed_tab_get_from_document (XED_DOCUMENT (l->data)); + + xed_tab_set_auto_save_enabled (tab, auto_save); + } + + g_list_free (docs); +} + +static void +on_auto_save_interval_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + GList *docs, *l; + gint auto_save_interval; + + g_settings_get (settings, key, "u", &auto_save_interval); + + docs = xed_app_get_documents (XED_APP (g_application_get_default ())); + + for (l = docs; l != NULL; l = g_list_next (l)) + { + XedTab *tab = xed_tab_get_from_document (XED_DOCUMENT (l->data)); + + xed_tab_set_auto_save_interval (tab, auto_save_interval); + } + + g_list_free (docs); +} + +static void +on_wrap_mode_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + GtkWrapMode wrap_mode; + GList *views, *l; + + wrap_mode = g_settings_get_enum (settings, key); + + views = xed_app_get_views (XED_APP (g_application_get_default ())); + + for (l = views; l != NULL; l = g_list_next (l)) + { + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (l->data), wrap_mode); + } + + g_list_free (views); +} + +static void +on_syntax_highlighting_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + GList *docs, *windows, *l; + gboolean enable; + + enable = g_settings_get_boolean (settings, key); + + docs = xed_app_get_documents (XED_APP (g_application_get_default ())); + + for (l = docs; l != NULL; l = g_list_next (l)) + { + gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (l->data), enable); + } + + g_list_free (docs); + + /* update the sensitivity of the Higlight Mode menu item */ + windows = xed_app_get_main_windows (XED_APP (g_application_get_default ())); + for (l = windows; l != NULL; l = g_list_next (l)) + { + GtkUIManager *ui; + GtkAction *a; + + ui = xed_window_get_ui_manager (XED_WINDOW (l->data)); + + a = gtk_ui_manager_get_action (ui, "/MenuBar/ViewMenu/ViewHighlightModeMenu"); + + gtk_action_set_sensitive (a, enable); + } + + g_list_free (windows); +} + +static void +on_enable_tab_scrolling_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + const GList *windows; + gboolean enable; + + enable = g_settings_get_boolean (settings, key); + + windows = xed_app_get_main_windows (XED_APP (g_application_get_default ())); + while (windows != NULL) + { + XedNotebook *notebook; + + notebook = XED_NOTEBOOK (_xed_window_get_notebook (windows->data)); + xed_notebook_set_tab_scrolling_enabled (notebook, enable); + + windows = g_list_next (windows); + } +} + +static void +on_max_recents_changed (GSettings *settings, + const gchar *key, + XedSettings *xs) +{ + /* FIXME: we have no way at the moment to trigger the + * update of the inline recents in the File menu */ +} + +static void +xed_settings_init (XedSettings *xs) +{ + xs->priv = XED_SETTINGS_GET_PRIVATE (xs); + + xs->priv->old_scheme = NULL; + xs->priv->editor = g_settings_new ("org.x.editor.preferences.editor"); + xs->priv->ui = g_settings_new ("org.x.editor.preferences.ui"); + + /* Load settings */ + xs->priv->interface = g_settings_new ("org.gnome.desktop.interface"); + + g_signal_connect (xs->priv->interface, "changed::monospace-font-name", + G_CALLBACK (on_system_font_changed), xs); + + /* editor changes */ + g_signal_connect (xs->priv->editor, "changed::use-default-font", + G_CALLBACK (on_use_default_font_changed), xs); + g_signal_connect (xs->priv->editor, "changed::editor-font", + G_CALLBACK (on_editor_font_changed), xs); + g_signal_connect (xs->priv->editor, "changed::prefer-dark-theme", + G_CALLBACK (on_prefer_dark_theme_changed), xs); + g_signal_connect (xs->priv->editor, "changed::scheme", + G_CALLBACK (on_scheme_changed), xs); + g_signal_connect (xs->priv->editor, "changed::auto-save", + G_CALLBACK (on_auto_save_changed), xs); + g_signal_connect (xs->priv->editor, "changed::auto-save-interval", + G_CALLBACK (on_auto_save_interval_changed), xs); + g_signal_connect (xs->priv->editor, "changed::syntax-highlighting", + G_CALLBACK (on_syntax_highlighting_changed), xs); + g_signal_connect (xs->priv->ui, "changed::enable-tab-scrolling", + G_CALLBACK (on_enable_tab_scrolling_changed), xs); + + /* ui changes */ + g_signal_connect (xs->priv->ui, "changed::max-recents", + G_CALLBACK (on_max_recents_changed), xs); +} + +static void +xed_settings_class_init (XedSettingsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = xed_settings_finalize; + object_class->dispose = xed_settings_dispose; + + g_type_class_add_private (object_class, sizeof (XedSettingsPrivate)); +} + +GObject * +xed_settings_new () +{ + return g_object_new (XED_TYPE_SETTINGS, NULL); +} + +gchar * +xed_settings_get_system_font (XedSettings *xs) +{ + gchar *system_font; + + g_return_val_if_fail (XED_IS_SETTINGS (xs), NULL); + + system_font = g_settings_get_string (xs->priv->interface, "monospace-font-name"); + + return system_font; +} + +GSList * +xed_settings_get_list (GSettings *settings, + const gchar *key) +{ + GSList *list = NULL; + gchar **values; + gsize i; + + g_return_val_if_fail (G_IS_SETTINGS (settings), NULL); + g_return_val_if_fail (key != NULL, NULL); + + values = g_settings_get_strv (settings, key); + i = 0; + + while (values[i] != NULL) + { + list = g_slist_prepend (list, values[i]); + i++; + } + + g_free (values); + + return g_slist_reverse (list); +} + +void +xed_settings_set_list (GSettings *settings, + const gchar *key, + const GSList *list) +{ + gchar **values = NULL; + const GSList *l; + + g_return_if_fail (G_IS_SETTINGS (settings)); + g_return_if_fail (key != NULL); + + if (list != NULL) + { + gint i, len; + + len = g_slist_length ((GSList *)list); + values = g_new (gchar *, len + 1); + + for (l = list, i = 0; l != NULL; l = g_slist_next (l), i++) + { + values[i] = l->data; + } + values [i] = NULL; + } + + g_settings_set_strv (settings, key, (const gchar * const *)values); + g_free (values); +} diff --git a/xed/xed-settings.h b/xed/xed-settings.h new file mode 100644 index 0000000..f65c01f --- /dev/null +++ b/xed/xed-settings.h @@ -0,0 +1,125 @@ +/* + * xed-settings.h + * This file is part of xed + * + * Copyright (C) 2009 - Ignacio Casal Quinteiro + * 2002 - Paolo Maggi + * + * xed is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xed; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + + +#ifndef __XED_SETTINGS_H__ +#define __XED_SETTINGS_H__ + +#include +#include +#include "xed-app.h" + +G_BEGIN_DECLS + +#define XED_TYPE_SETTINGS (xed_settings_get_type ()) +#define XED_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_SETTINGS, XedSettings)) +#define XED_SETTINGS_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_SETTINGS, XedSettings const)) +#define XED_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_SETTINGS, XedSettingsClass)) +#define XED_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_SETTINGS)) +#define XED_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_SETTINGS)) +#define XED_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_SETTINGS, XedSettingsClass)) + +typedef struct _XedSettings XedSettings; +typedef struct _XedSettingsClass XedSettingsClass; +typedef struct _XedSettingsPrivate XedSettingsPrivate; + +struct _XedSettings +{ + GObject parent; + + XedSettingsPrivate *priv; +}; + +struct _XedSettingsClass +{ + GObjectClass parent_class; +}; + +GType xed_settings_get_type (void) G_GNUC_CONST; + +GObject *xed_settings_new (void); + +gchar *xed_settings_get_system_font (XedSettings *xs); + +/* Utility functions */ +GSList *xed_settings_get_list (GSettings *settings, + const gchar *key); + +void xed_settings_set_list (GSettings *settings, + const gchar *key, + const GSList *list); + +/* key constants */ +#define XED_SETTINGS_USE_DEFAULT_FONT "use-default-font" +#define XED_SETTINGS_EDITOR_FONT "editor-font" +#define XED_SETTINGS_PREFER_DARK_THEME "prefer-dark-theme" +#define XED_SETTINGS_SCHEME "scheme" +#define XED_SETTINGS_CREATE_BACKUP_COPY "create-backup-copy" +#define XED_SETTINGS_AUTO_SAVE "auto-save" +#define XED_SETTINGS_AUTO_SAVE_INTERVAL "auto-save-interval" +#define XED_SETTINGS_UNDO_ACTIONS_LIMIT "undo-actions-limit" +#define XED_SETTINGS_MAX_UNDO_ACTIONS "max-undo-actions" +#define XED_SETTINGS_WRAP_MODE "wrap-mode" +#define XED_SETTINGS_TABS_SIZE "tabs-size" +#define XED_SETTINGS_INSERT_SPACES "insert-spaces" +#define XED_SETTINGS_AUTO_INDENT "auto-indent" +#define XED_SETTINGS_DISPLAY_LINE_NUMBERS "display-line-numbers" +#define XED_SETTINGS_HIGHLIGHT_CURRENT_LINE "highlight-current-line" +#define XED_SETTINGS_BRACKET_MATCHING "bracket-matching" +#define XED_SETTINGS_DISPLAY_RIGHT_MARGIN "display-right-margin" +#define XED_SETTINGS_RIGHT_MARGIN_POSITION "right-margin-position" +#define XED_SETTINGS_SMART_HOME_END "smart-home-end" +#define XED_SETTINGS_WRITABLE_VFS_SCHEMES "writable-vfs-schemes" +#define XED_SETTINGS_RESTORE_CURSOR_POSITION "restore-cursor-position" +#define XED_SETTINGS_SYNTAX_HIGHLIGHTING "syntax-highlighting" +#define XED_SETTINGS_SEARCH_HIGHLIGHTING "search-highlighting" +#define XED_SETTINGS_ENABLE_TAB_SCROLLING "enable-tab-scrolling" +#define XED_SETTINGS_TOOLBAR_VISIBLE "toolbar-visible" +#define XED_SETTINGS_STATUSBAR_VISIBLE "statusbar-visible" +#define XED_SETTINGS_SIDE_PANEL_VISIBLE "side-panel-visible" +#define XED_SETTINGS_BOTTOM_PANEL_VISIBLE "bottom-panel-visible" +#define XED_SETTINGS_MAX_RECENTS "max-recents" +#define XED_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING "print-syntax-highlighting" +#define XED_SETTINGS_PRINT_HEADER "print-header" +#define XED_SETTINGS_PRINT_WRAP_MODE "print-wrap-mode" +#define XED_SETTINGS_PRINT_LINE_NUMBERS "print-line-numbers" +#define XED_SETTINGS_PRINT_FONT_BODY_PANGO "print-font-body-pango" +#define XED_SETTINGS_PRINT_FONT_HEADER_PANGO "print-font-header-pango" +#define XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO "print-font-numbers-pango" +#define XED_SETTINGS_ENCODING_AUTO_DETECTED "auto-detected" +#define XED_SETTINGS_ENCODING_SHOWN_IN_MENU "shown-in-menu" +#define XED_SETTINGS_ACTIVE_PLUGINS "active-plugins" +#define XED_SETTINGS_ENSURE_TRAILING_NEWLINE "ensure-trailing-newline" + +/* window state keys */ +#define XED_SETTINGS_WINDOW_STATE "state" +#define XED_SETTINGS_WINDOW_SIZE "size" +#define XED_SETTINGS_SIDE_PANEL_SIZE "side-panel-size" +#define XED_SETTINGS_SIDE_PANEL_ACTIVE_PAGE "side-panel-active-page" +#define XED_SETTINGS_BOTTOM_PANEL_SIZE "bottom-panel-size" +#define XED_SETTINGS_BOTTOM_PANEL_ACTIVE_PAGE "bottom-panel-active-page" +#define XED_SETTINGS_ACTIVE_FILE_FILTER "filter-id" + +G_END_DECLS + +#endif /* __XED_SETTINGS_H__ */ diff --git a/xed/xed-smart-charset-converter.c b/xed/xed-smart-charset-converter.c deleted file mode 100644 index 33b02f1..0000000 --- a/xed/xed-smart-charset-converter.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * xed-smart-charset-converter.c - * This file is part of xed - * - * Copyright (C) 2009 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#include "xed-smart-charset-converter.h" -#include "xed-debug.h" -#include "xed-document.h" - -#include -#include - -#define XED_SMART_CHARSET_CONVERTER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_SMART_CHARSET_CONVERTER, XedSmartCharsetConverterPrivate)) - -struct _XedSmartCharsetConverterPrivate -{ - GCharsetConverter *charset_conv; - - GSList *encodings; - GSList *current_encoding; - - guint is_utf8 : 1; - guint use_first : 1; -}; - -static void xed_smart_charset_converter_iface_init (GConverterIface *iface); - -G_DEFINE_TYPE_WITH_CODE (XedSmartCharsetConverter, xed_smart_charset_converter, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, - xed_smart_charset_converter_iface_init)) - -static void -xed_smart_charset_converter_finalize (GObject *object) -{ - XedSmartCharsetConverter *smart = XED_SMART_CHARSET_CONVERTER (object); - - g_slist_free (smart->priv->encodings); - - xed_debug_message (DEBUG_UTILS, "finalizing smart charset converter"); - - G_OBJECT_CLASS (xed_smart_charset_converter_parent_class)->finalize (object); -} - -static void -xed_smart_charset_converter_dispose (GObject *object) -{ - XedSmartCharsetConverter *smart = XED_SMART_CHARSET_CONVERTER (object); - - if (smart->priv->charset_conv != NULL) - { - g_object_unref (smart->priv->charset_conv); - smart->priv->charset_conv = NULL; - } - - xed_debug_message (DEBUG_UTILS, "disposing smart charset converter"); - - G_OBJECT_CLASS (xed_smart_charset_converter_parent_class)->dispose (object); -} - -static void -xed_smart_charset_converter_class_init (XedSmartCharsetConverterClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_smart_charset_converter_finalize; - object_class->dispose = xed_smart_charset_converter_dispose; - - g_type_class_add_private (object_class, sizeof (XedSmartCharsetConverterPrivate)); -} - -static void -xed_smart_charset_converter_init (XedSmartCharsetConverter *smart) -{ - smart->priv = XED_SMART_CHARSET_CONVERTER_GET_PRIVATE (smart); - - smart->priv->charset_conv = NULL; - smart->priv->encodings = NULL; - smart->priv->current_encoding = NULL; - smart->priv->is_utf8 = FALSE; - smart->priv->use_first = FALSE; - - xed_debug_message (DEBUG_UTILS, "initializing smart charset converter"); -} - -static const XedEncoding * -get_encoding (XedSmartCharsetConverter *smart) -{ - if (smart->priv->current_encoding == NULL) - { - smart->priv->current_encoding = smart->priv->encodings; - } - else - { - smart->priv->current_encoding = g_slist_next (smart->priv->current_encoding); - } - - if (smart->priv->current_encoding != NULL) - return (const XedEncoding *)smart->priv->current_encoding->data; - -#if 0 - FIXME: uncomment this when using fallback - /* If we tried all encodings, we return the first encoding */ - smart->priv->use_first = TRUE; - smart->priv->current_encoding = smart->priv->encodings; - - return (const XedEncoding *)smart->priv->current_encoding->data; -#endif - return NULL; -} - -static gboolean -try_convert (GCharsetConverter *converter, - const void *inbuf, - gsize inbuf_size) -{ - GError *err; - gsize bytes_read, nread; - gsize bytes_written, nwritten; - GConverterResult res; - gchar *out; - gboolean ret; - gsize out_size; - - if (inbuf == NULL || inbuf_size == 0) - { - return FALSE; - } - - err = NULL; - nread = 0; - nwritten = 0; - out_size = inbuf_size * 4; - out = g_malloc (out_size); - - do - { - res = g_converter_convert (G_CONVERTER (converter), - (void *) ((gsize) inbuf + nread), - inbuf_size - nread, - out + nwritten, - out_size - nwritten, - G_CONVERTER_INPUT_AT_END, - &bytes_read, - &bytes_written, - &err); - - nread += bytes_read; - nwritten += bytes_written; - } while (res != G_CONVERTER_FINISHED && res != G_CONVERTER_ERROR && err == NULL); - - if (err != NULL) - { - if (err->code == G_CONVERT_ERROR_PARTIAL_INPUT) - { - /* FIXME We can get partial input while guessing the - encoding because we just take some amount of text - to guess from. */ - ret = TRUE; - } - else - { - ret = FALSE; - } - - g_error_free (err); - } - else - { - ret = TRUE; - } - - /* FIXME: Check the remainder? */ - if (ret == TRUE && !g_utf8_validate (out, nwritten, NULL)) - { - ret = FALSE; - } - - g_free (out); - - return ret; -} - -static GCharsetConverter * -guess_encoding (XedSmartCharsetConverter *smart, - const void *inbuf, - gsize inbuf_size) -{ - GCharsetConverter *conv = NULL; - - if (inbuf == NULL || inbuf_size == 0) - { - smart->priv->is_utf8 = TRUE; - return NULL; - } - - if (smart->priv->encodings != NULL && - smart->priv->encodings->next == NULL) - smart->priv->use_first = TRUE; - - /* We just check the first block */ - while (TRUE) - { - const XedEncoding *enc; - - if (conv != NULL) - { - g_object_unref (conv); - conv = NULL; - } - - /* We get an encoding from the list */ - enc = get_encoding (smart); - - /* if it is NULL we didn't guess anything */ - if (enc == NULL) - { - break; - } - - xed_debug_message (DEBUG_UTILS, "trying charset: %s", - xed_encoding_get_charset (smart->priv->current_encoding->data)); - - if (enc == xed_encoding_get_utf8 ()) - { - gsize remainder; - const gchar *end; - - if (g_utf8_validate (inbuf, inbuf_size, &end) || - smart->priv->use_first) - { - smart->priv->is_utf8 = TRUE; - break; - } - - /* Check if the end is less than one char */ - remainder = inbuf_size - (end - (gchar *)inbuf); - if (remainder < 6) - { - smart->priv->is_utf8 = TRUE; - break; - } - - continue; - } - - conv = g_charset_converter_new ("UTF-8", - xed_encoding_get_charset (enc), - NULL); - - /* If we tried all encodings we use the first one */ - if (smart->priv->use_first) - { - break; - } - - /* Try to convert */ - if (try_convert (conv, inbuf, inbuf_size)) - { - break; - } - } - - if (conv != NULL) - { - g_converter_reset (G_CONVERTER (conv)); - - /* FIXME: uncomment this when we want to use the fallback - g_charset_converter_set_use_fallback (conv, TRUE);*/ - } - - return conv; -} - -static GConverterResult -xed_smart_charset_converter_convert (GConverter *converter, - const void *inbuf, - gsize inbuf_size, - void *outbuf, - gsize outbuf_size, - GConverterFlags flags, - gsize *bytes_read, - gsize *bytes_written, - GError **error) -{ - XedSmartCharsetConverter *smart = XED_SMART_CHARSET_CONVERTER (converter); - - /* Guess the encoding if we didn't make it yet */ - if (smart->priv->charset_conv == NULL && - !smart->priv->is_utf8) - { - smart->priv->charset_conv = guess_encoding (smart, inbuf, inbuf_size); - - /* If we still have the previous case is that we didn't guess - anything */ - if (smart->priv->charset_conv == NULL && - !smart->priv->is_utf8) - { - /* FIXME: Add a different domain when we kill xed_convert */ - g_set_error_literal (error, XED_DOCUMENT_ERROR, - XED_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED, - _("It is not possible to detect the encoding automatically")); - return G_CONVERTER_ERROR; - } - } - - /* Now if the encoding is utf8 just redirect the input to the output */ - if (smart->priv->is_utf8) - { - gsize size; - GConverterResult ret; - - size = MIN (inbuf_size, outbuf_size); - - memcpy (outbuf, inbuf, size); - *bytes_read = size; - *bytes_written = size; - - ret = G_CONVERTER_CONVERTED; - - if (flags & G_CONVERTER_INPUT_AT_END) - ret = G_CONVERTER_FINISHED; - else if (flags & G_CONVERTER_FLUSH) - ret = G_CONVERTER_FLUSHED; - - return ret; - } - - /* If we reached here is because we need to convert the text so, we - convert it with the charset converter */ - return g_converter_convert (G_CONVERTER (smart->priv->charset_conv), - inbuf, - inbuf_size, - outbuf, - outbuf_size, - flags, - bytes_read, - bytes_written, - error); -} - -static void -xed_smart_charset_converter_reset (GConverter *converter) -{ - XedSmartCharsetConverter *smart = XED_SMART_CHARSET_CONVERTER (converter); - - smart->priv->current_encoding = NULL; - smart->priv->is_utf8 = FALSE; - - if (smart->priv->charset_conv != NULL) - { - g_object_unref (smart->priv->charset_conv); - smart->priv->charset_conv = NULL; - } -} - -static void -xed_smart_charset_converter_iface_init (GConverterIface *iface) -{ - iface->convert = xed_smart_charset_converter_convert; - iface->reset = xed_smart_charset_converter_reset; -} - -XedSmartCharsetConverter * -xed_smart_charset_converter_new (GSList *candidate_encodings) -{ - XedSmartCharsetConverter *smart; - - g_return_val_if_fail (candidate_encodings != NULL, NULL); - - smart = g_object_new (XED_TYPE_SMART_CHARSET_CONVERTER, NULL); - - smart->priv->encodings = g_slist_copy (candidate_encodings); - - return smart; -} - -const XedEncoding * -xed_smart_charset_converter_get_guessed (XedSmartCharsetConverter *smart) -{ - g_return_val_if_fail (XED_IS_SMART_CHARSET_CONVERTER (smart), NULL); - - if (smart->priv->current_encoding != NULL) - { - return (const XedEncoding *)smart->priv->current_encoding->data; - } - else if (smart->priv->is_utf8) - { - return xed_encoding_get_utf8 (); - } - - return NULL; -} - -guint -xed_smart_charset_converter_get_num_fallbacks (XedSmartCharsetConverter *smart) -{ - g_return_val_if_fail (XED_IS_SMART_CHARSET_CONVERTER (smart), FALSE); - - if (smart->priv->charset_conv == NULL) - return FALSE; - - return g_charset_converter_get_num_fallbacks (smart->priv->charset_conv) != 0; -} - diff --git a/xed/xed-smart-charset-converter.h b/xed/xed-smart-charset-converter.h deleted file mode 100644 index 3239879..0000000 --- a/xed/xed-smart-charset-converter.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * xed-smart-charset-converter.h - * This file is part of xed - * - * Copyright (C) 2009 - Ignacio Casal Quinteiro - * - * xed is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xed is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xed; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#ifndef __XED_SMART_CHARSET_CONVERTER_H__ -#define __XED_SMART_CHARSET_CONVERTER_H__ - -#include - -#include "xed-encodings.h" - -G_BEGIN_DECLS - -#define XED_TYPE_SMART_CHARSET_CONVERTER (xed_smart_charset_converter_get_type ()) -#define XED_SMART_CHARSET_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_SMART_CHARSET_CONVERTER, XedSmartCharsetConverter)) -#define XED_SMART_CHARSET_CONVERTER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_SMART_CHARSET_CONVERTER, XedSmartCharsetConverter const)) -#define XED_SMART_CHARSET_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_SMART_CHARSET_CONVERTER, XedSmartCharsetConverterClass)) -#define XED_IS_SMART_CHARSET_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_SMART_CHARSET_CONVERTER)) -#define XED_IS_SMART_CHARSET_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_SMART_CHARSET_CONVERTER)) -#define XED_SMART_CHARSET_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_SMART_CHARSET_CONVERTER, XedSmartCharsetConverterClass)) - -typedef struct _XedSmartCharsetConverter XedSmartCharsetConverter; -typedef struct _XedSmartCharsetConverterClass XedSmartCharsetConverterClass; -typedef struct _XedSmartCharsetConverterPrivate XedSmartCharsetConverterPrivate; - -struct _XedSmartCharsetConverter -{ - GObject parent; - - XedSmartCharsetConverterPrivate *priv; -}; - -struct _XedSmartCharsetConverterClass -{ - GObjectClass parent_class; -}; - -GType xed_smart_charset_converter_get_type (void) G_GNUC_CONST; - -XedSmartCharsetConverter *xed_smart_charset_converter_new (GSList *candidate_encodings); - -const XedEncoding *xed_smart_charset_converter_get_guessed (XedSmartCharsetConverter *smart); - -guint xed_smart_charset_converter_get_num_fallbacks(XedSmartCharsetConverter *smart); - -G_END_DECLS - -#endif /* __XED_SMART_CHARSET_CONVERTER_H__ */ diff --git a/xed/xed-status-combo-box.c b/xed/xed-status-combo-box.c index b2b5bf3..d27d112 100644 --- a/xed/xed-status-combo-box.c +++ b/xed/xed-status-combo-box.c @@ -36,7 +36,7 @@ struct _XedStatusComboBoxPrivate GtkWidget *label; GtkWidget *item; GtkWidget *arrow; - + GtkWidget *menu; GtkWidget *current_item; }; @@ -54,10 +54,10 @@ enum }; /* Properties */ -enum +enum { PROP_0, - + PROP_LABEL }; @@ -74,9 +74,9 @@ xed_status_combo_box_finalize (GObject *object) static void xed_status_combo_box_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { XedStatusComboBox *obj = XED_STATUS_COMBO_BOX (object); @@ -93,9 +93,9 @@ xed_status_combo_box_get_property (GObject *object, static void xed_status_combo_box_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { XedStatusComboBox *obj = XED_STATUS_COMBO_BOX (object); @@ -117,9 +117,7 @@ xed_status_combo_box_destroy (GtkWidget *widget) if (combo->priv->menu) { - g_signal_handlers_disconnect_by_func (combo->priv->menu, - menu_deactivate, - combo); + g_signal_handlers_disconnect_by_func (combo->priv->menu, menu_deactivate, combo); gtk_menu_detach (GTK_MENU (combo->priv->menu)); } @@ -128,10 +126,10 @@ xed_status_combo_box_destroy (GtkWidget *widget) static void xed_status_combo_box_changed (XedStatusComboBox *combo, - GtkMenuItem *item) + GtkMenuItem *item) { const gchar *text; - + text = g_object_get_data (G_OBJECT (item), COMBO_BOX_TEXT_DATA); if (text != NULL) @@ -153,15 +151,15 @@ xed_status_combo_box_class_init (XedStatusComboBoxClass *klass) "-GtkButton-inner-border: 0;\n" "-GtkWidget-focus-line-width : 0;\n" "-GtkWidget-focus-padding : 0;\n" - "padding: 0;\n" + "padding: 2px;\n" "}"; - + object_class->finalize = xed_status_combo_box_finalize; object_class->get_property = xed_status_combo_box_get_property; object_class->set_property = xed_status_combo_box_set_property; widget_class->destroy = xed_status_combo_box_destroy; - + klass->changed = xed_status_combo_box_changed; signals[CHANGED] = @@ -172,7 +170,7 @@ xed_status_combo_box_class_init (XedStatusComboBoxClass *klass) changed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_MENU_ITEM); - + g_object_class_install_property (object_class, PROP_LABEL, g_param_spec_string ("label", "LABEL", @@ -189,22 +187,22 @@ xed_status_combo_box_class_init (XedStatusComboBoxClass *klass) } static void -menu_deactivate (GtkMenu *menu, +menu_deactivate (GtkMenu *menu, XedStatusComboBox *combo) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (combo->priv->button), FALSE); } static void -menu_position_func (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, +menu_position_func (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, XedStatusComboBox *combo) { GtkRequisition request; GtkAllocation allocation; - + *push_in = FALSE; gtk_widget_get_preferred_size (gtk_widget_get_toplevel (GTK_WIDGET (menu)), &request, NULL); @@ -212,28 +210,27 @@ menu_position_func (GtkMenu *menu, /* get the origin... */ gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (combo)), x, y); gtk_widget_get_allocation (GTK_WIDGET (combo), &allocation); - + /* make the menu as wide as the widget */ if (request.width < allocation.width) { gtk_widget_set_size_request (GTK_WIDGET (menu), allocation.width, -1); } - + /* position it above the widget */ *y -= request.height; } static void show_menu (XedStatusComboBox *combo, - guint button, - guint32 time) + guint button, + guint32 time) { GtkRequisition request; gint max_height; GtkAllocation allocation; - gtk_widget_get_preferred_size (combo->priv->menu, - &request, NULL); + gtk_widget_get_preferred_size (combo->priv->menu, &request, NULL); /* do something relative to our own height here, maybe we can do better */ gtk_widget_get_allocation (GTK_WIDGET (combo), &allocation); @@ -257,8 +254,7 @@ show_menu (XedStatusComboBox *combo, if (combo->priv->current_item) { - gtk_menu_shell_select_item (GTK_MENU_SHELL (combo->priv->menu), - combo->priv->current_item); + gtk_menu_shell_select_item (GTK_MENU_SHELL (combo->priv->menu), combo->priv->current_item); } } @@ -274,8 +270,8 @@ menu_detached (GtkWidget *widget, } static gboolean -button_press_event (GtkWidget *widget, - GdkEventButton *event, +button_press_event (GtkWidget *widget, + GdkEventButton *event, XedStatusComboBox *combo) { if (event->type == GDK_BUTTON_PRESS && event->button == 1) @@ -310,12 +306,12 @@ xed_status_combo_box_init (XedStatusComboBox *self) GtkStyleContext *context; self->priv = XED_STATUS_COMBO_BOX_GET_PRIVATE (self); - + gtk_event_box_set_visible_window (GTK_EVENT_BOX (self), TRUE); self->priv->frame = gtk_frame_new (NULL); gtk_widget_show (self->priv->frame); - + self->priv->button = gtk_toggle_button_new (); gtk_button_set_relief (GTK_BUTTON (self->priv->button), GTK_RELIEF_NONE); gtk_widget_show (self->priv->button); @@ -324,48 +320,42 @@ xed_status_combo_box_init (XedStatusComboBox *self) self->priv->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); gtk_widget_show (self->priv->hbox); - + gtk_container_add (GTK_CONTAINER (self), self->priv->frame); gtk_container_add (GTK_CONTAINER (self->priv->frame), self->priv->button); gtk_container_add (GTK_CONTAINER (self->priv->button), self->priv->hbox); - + self->priv->label = gtk_label_new (""); gtk_widget_show (self->priv->label); - + gtk_label_set_single_line_mode (GTK_LABEL (self->priv->label), TRUE); gtk_widget_set_halign (GTK_WIDGET (self->priv->label), GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (self->priv->hbox), self->priv->label, FALSE, TRUE, 0); - + self->priv->item = gtk_label_new (""); gtk_widget_show (self->priv->item); - + gtk_label_set_single_line_mode (GTK_LABEL (self->priv->item), TRUE); gtk_widget_set_halign (self->priv->item, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (self->priv->hbox), self->priv->item, TRUE, TRUE, 0); - - self->priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); + + self->priv->arrow = gtk_image_new_from_icon_name ("pan-down-symbolic", GTK_ICON_SIZE_MENU); gtk_widget_show (self->priv->arrow); gtk_widget_set_halign (self->priv->arrow, GTK_ALIGN_CENTER); gtk_widget_set_valign (self->priv->arrow, GTK_ALIGN_CENTER); gtk_box_pack_start (GTK_BOX (self->priv->hbox), self->priv->arrow, FALSE, TRUE, 0); - - self->priv->menu = gtk_menu_new (); - gtk_menu_attach_to_widget (GTK_MENU (self->priv->menu), - GTK_WIDGET (self), - menu_detached); - g_signal_connect (self->priv->button, - "button-press-event", - G_CALLBACK (button_press_event), - self); - g_signal_connect (self->priv->menu, - "deactivate", - G_CALLBACK (menu_deactivate), - self); + self->priv->menu = gtk_menu_new (); + gtk_menu_attach_to_widget (GTK_MENU (self->priv->menu), GTK_WIDGET (self), menu_detached); + + g_signal_connect (self->priv->button, "button-press-event", + G_CALLBACK (button_press_event), self); + g_signal_connect (self->priv->menu, "deactivate", + G_CALLBACK (menu_deactivate), self); context = gtk_widget_get_style_context (GTK_WIDGET (self->priv->button)); gtk_style_context_add_provider (context, @@ -395,13 +385,13 @@ xed_status_combo_box_new (const gchar *label) * @label: (allow-none): */ void -xed_status_combo_box_set_label (XedStatusComboBox *combo, - const gchar *label) +xed_status_combo_box_set_label (XedStatusComboBox *combo, + const gchar *label) { gchar *text; g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); - + text = g_strconcat (" ", label, ": ", NULL); gtk_label_set_markup (GTK_LABEL (combo->priv->label), text); g_free (text); @@ -416,7 +406,7 @@ xed_status_combo_box_get_label (XedStatusComboBox *combo) } static void -item_activated (GtkMenuItem *item, +item_activated (GtkMenuItem *item, XedStatusComboBox *combo) { xed_status_combo_box_set_item (combo, item); @@ -430,29 +420,35 @@ item_activated (GtkMenuItem *item, */ void xed_status_combo_box_add_item (XedStatusComboBox *combo, - GtkMenuItem *item, - const gchar *text) + GtkMenuItem *item, + const gchar *text) { g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); g_return_if_fail (GTK_IS_MENU_ITEM (item)); gtk_menu_shell_append (GTK_MENU_SHELL (combo->priv->menu), GTK_WIDGET (item)); - + xed_status_combo_box_set_item_text (combo, item, text); g_signal_connect (item, "activate", G_CALLBACK (item_activated), combo); } void xed_status_combo_box_remove_item (XedStatusComboBox *combo, - GtkMenuItem *item) + GtkMenuItem *item) { g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); g_return_if_fail (GTK_IS_MENU_ITEM (item)); - gtk_container_remove (GTK_CONTAINER (combo->priv->menu), - GTK_WIDGET (item)); + gtk_container_remove (GTK_CONTAINER (combo->priv->menu), GTK_WIDGET (item)); } + +/** + * xed_status_combo_box_get_items: + * @combo: + * + * Returns: (element-type Gtk.Widget) (transfer container): + */ GList * xed_status_combo_box_get_items (XedStatusComboBox *combo) { @@ -463,15 +459,15 @@ xed_status_combo_box_get_items (XedStatusComboBox *combo) const gchar * xed_status_combo_box_get_item_text (XedStatusComboBox *combo, - GtkMenuItem *item) + GtkMenuItem *item) { const gchar *ret = NULL; - + g_return_val_if_fail (XED_IS_STATUS_COMBO_BOX (combo), NULL); g_return_val_if_fail (GTK_IS_MENU_ITEM (item), NULL); - + ret = g_object_get_data (G_OBJECT (item), COMBO_BOX_TEXT_DATA); - + return ret; } @@ -481,23 +477,21 @@ xed_status_combo_box_get_item_text (XedStatusComboBox *combo, * @item: * @text: (allow-none): */ -void +void xed_status_combo_box_set_item_text (XedStatusComboBox *combo, - GtkMenuItem *item, - const gchar *text) + GtkMenuItem *item, + const gchar *text) { g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); g_return_if_fail (GTK_IS_MENU_ITEM (item)); - g_object_set_data_full (G_OBJECT (item), - COMBO_BOX_TEXT_DATA, - g_strdup (text), - (GDestroyNotify)g_free); + g_object_set_data_full (G_OBJECT (item), COMBO_BOX_TEXT_DATA, + g_strdup (text), (GDestroyNotify)g_free); } void xed_status_combo_box_set_item (XedStatusComboBox *combo, - GtkMenuItem *item) + GtkMenuItem *item) { g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); g_return_if_fail (GTK_IS_MENU_ITEM (item)); @@ -509,7 +503,7 @@ GtkLabel * xed_status_combo_box_get_item_label (XedStatusComboBox *combo) { g_return_val_if_fail (XED_IS_STATUS_COMBO_BOX (combo), NULL); - + return GTK_LABEL (combo->priv->item); } diff --git a/xed/xed-statusbar.c b/xed/xed-statusbar.c index b287acc..d27dbc8 100644 --- a/xed/xed-statusbar.c +++ b/xed/xed-statusbar.c @@ -39,26 +39,26 @@ #include "xed-statusbar.h" #define XED_STATUSBAR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object),\ - XED_TYPE_STATUSBAR,\ - XedStatusbarPrivate)) + XED_TYPE_STATUSBAR,\ + XedStatusbarPrivate)) struct _XedStatusbarPrivate { - GtkWidget *overwrite_mode_label; - GtkWidget *cursor_position_label; + GtkWidget *overwrite_mode_label; + GtkWidget *cursor_position_label; - GtkWidget *state_frame; - GtkWidget *load_image; - GtkWidget *save_image; - GtkWidget *print_image; + GtkWidget *state_frame; + GtkWidget *load_image; + GtkWidget *save_image; + GtkWidget *print_image; - GtkWidget *error_frame; - GtkWidget *error_event_box; + GtkWidget *error_frame; + GtkWidget *error_event_box; /* tmp flash timeout data */ - guint flash_timeout; - guint flash_context_id; - guint flash_message_id; + guint flash_timeout; + guint flash_context_id; + guint flash_message_id; }; G_DEFINE_TYPE(XedStatusbar, xed_statusbar, GTK_TYPE_STATUSBAR) @@ -114,24 +114,18 @@ xed_statusbar_init (XedStatusbar *statusbar) gtk_widget_set_margin_bottom (GTK_WIDGET (statusbar), 0); statusbar->priv->overwrite_mode_label = gtk_label_new (NULL); - gtk_label_set_width_chars (GTK_LABEL (statusbar->priv->overwrite_mode_label), - get_overwrite_mode_length ()); + gtk_label_set_width_chars (GTK_LABEL (statusbar->priv->overwrite_mode_label), get_overwrite_mode_length ()); gtk_widget_show (statusbar->priv->overwrite_mode_label); - gtk_box_pack_end (GTK_BOX (statusbar), - statusbar->priv->overwrite_mode_label, - FALSE, TRUE, 0); + gtk_box_pack_end (GTK_BOX (statusbar), statusbar->priv->overwrite_mode_label, FALSE, TRUE, 0); + gtk_widget_set_margin_end (GTK_WIDGET (statusbar->priv->overwrite_mode_label), 6); statusbar->priv->cursor_position_label = gtk_label_new (NULL); - gtk_label_set_width_chars (GTK_LABEL (statusbar->priv->cursor_position_label), - CURSOR_POSITION_LABEL_WIDTH_CHARS); + gtk_label_set_width_chars (GTK_LABEL (statusbar->priv->cursor_position_label), CURSOR_POSITION_LABEL_WIDTH_CHARS); gtk_widget_show (statusbar->priv->cursor_position_label); - gtk_box_pack_end (GTK_BOX (statusbar), - statusbar->priv->cursor_position_label, - FALSE, TRUE, 0); + gtk_box_pack_end (GTK_BOX (statusbar), statusbar->priv->cursor_position_label, FALSE, TRUE, 0); statusbar->priv->state_frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (statusbar->priv->state_frame), - GTK_SHADOW_IN); + gtk_frame_set_shadow_type (GTK_FRAME (statusbar->priv->state_frame), GTK_SHADOW_IN); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_container_add (GTK_CONTAINER (statusbar->priv->state_frame), hbox); @@ -142,47 +136,32 @@ xed_statusbar_init (XedStatusbar *statusbar) gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (hbox), - statusbar->priv->load_image, - FALSE, TRUE, 4); - gtk_box_pack_start (GTK_BOX (hbox), - statusbar->priv->save_image, - FALSE, TRUE, 4); - gtk_box_pack_start (GTK_BOX (hbox), - statusbar->priv->print_image, - FALSE, TRUE, 4); + gtk_box_pack_start (GTK_BOX (hbox), statusbar->priv->load_image, FALSE, TRUE, 4); + gtk_box_pack_start (GTK_BOX (hbox), statusbar->priv->save_image, FALSE, TRUE, 4); + gtk_box_pack_start (GTK_BOX (hbox), statusbar->priv->print_image, FALSE, TRUE, 4); - gtk_box_pack_start (GTK_BOX (statusbar), - statusbar->priv->state_frame, - FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (statusbar), statusbar->priv->state_frame, FALSE, TRUE, 0); statusbar->priv->error_frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (statusbar->priv->error_frame), GTK_SHADOW_IN); error_image = gtk_image_new_from_icon_name ("dialog-error", GTK_ICON_SIZE_MENU); - gtk_widget_set_margin_left (error_image, 4); - gtk_widget_set_margin_right (error_image, 4); + gtk_widget_set_margin_start (error_image, 4); + gtk_widget_set_margin_end (error_image, 4); gtk_widget_set_margin_top (error_image, 0); gtk_widget_set_margin_bottom (error_image, 0); statusbar->priv->error_event_box = gtk_event_box_new (); - gtk_event_box_set_visible_window (GTK_EVENT_BOX (statusbar->priv->error_event_box), - FALSE); + gtk_event_box_set_visible_window (GTK_EVENT_BOX (statusbar->priv->error_event_box), FALSE); gtk_widget_show (statusbar->priv->error_event_box); - gtk_container_add (GTK_CONTAINER (statusbar->priv->error_frame), - statusbar->priv->error_event_box); - gtk_container_add (GTK_CONTAINER (statusbar->priv->error_event_box), - error_image); + gtk_container_add (GTK_CONTAINER (statusbar->priv->error_frame), statusbar->priv->error_event_box); + gtk_container_add (GTK_CONTAINER (statusbar->priv->error_event_box), error_image); - gtk_box_pack_start (GTK_BOX (statusbar), - statusbar->priv->error_frame, - FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (statusbar), statusbar->priv->error_frame, FALSE, TRUE, 0); - gtk_box_reorder_child (GTK_BOX (statusbar), - statusbar->priv->error_frame, - 0); + gtk_style_context_add_class (gtk_widget_get_style_context GTK_WIDGET (statusbar), "xed-statusbar"); } /** @@ -207,7 +186,7 @@ xed_statusbar_new (void) **/ void xed_statusbar_set_overwrite (XedStatusbar *statusbar, - gboolean overwrite) + gboolean overwrite) { gchar *msg; @@ -238,8 +217,8 @@ xed_statusbar_clear_overwrite (XedStatusbar *statusbar) **/ void xed_statusbar_set_cursor_position (XedStatusbar *statusbar, - gint line, - gint col) + gint line, + gint col) { gchar *msg = NULL; @@ -280,8 +259,8 @@ remove_message_timeout (XedStatusbar *statusbar) */ void xed_statusbar_flash_message (XedStatusbar *statusbar, - guint context_id, - const gchar *format, ...) + guint context_id, + const gchar *format, ...) { const guint32 flash_length = 3000; /* three seconds */ va_list args; @@ -306,9 +285,7 @@ xed_statusbar_flash_message (XedStatusbar *statusbar, } statusbar->priv->flash_context_id = context_id; - statusbar->priv->flash_message_id = gtk_statusbar_push (GTK_STATUSBAR (statusbar), - context_id, - msg); + statusbar->priv->flash_message_id = gtk_statusbar_push (GTK_STATUSBAR (statusbar), context_id, msg); statusbar->priv->flash_timeout = g_timeout_add (flash_length, (GSourceFunc) remove_message_timeout, @@ -319,8 +296,8 @@ xed_statusbar_flash_message (XedStatusbar *statusbar, void xed_statusbar_set_window_state (XedStatusbar *statusbar, - XedWindowState state, - gint num_of_errors) + XedWindowState state, + gint num_of_errors) { g_return_if_fail (XED_IS_STATUSBAR (statusbar)); @@ -355,8 +332,7 @@ xed_statusbar_set_window_state (XedStatusbar *statusbar, num_of_errors), num_of_errors); - gtk_widget_set_tooltip_text (statusbar->priv->error_event_box, - tip); + gtk_widget_set_tooltip_text (statusbar->priv->error_event_box, tip); g_free (tip); gtk_widget_show (statusbar->priv->error_frame); diff --git a/xed/xed-statusbar.h b/xed/xed-statusbar.h index cda2537..47c8002 100644 --- a/xed/xed-statusbar.h +++ b/xed/xed-statusbar.h @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ #ifndef XED_STATUSBAR_H @@ -34,22 +34,22 @@ G_BEGIN_DECLS -#define XED_TYPE_STATUSBAR (xed_statusbar_get_type ()) -#define XED_STATUSBAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_STATUSBAR, XedStatusbar)) -#define XED_STATUSBAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_STATUSBAR, XedStatusbarClass)) -#define XED_IS_STATUSBAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_STATUSBAR)) -#define XED_IS_STATUSBAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_STATUSBAR)) -#define XED_STATUSBAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_STATUSBAR, XedStatusbarClass)) +#define XED_TYPE_STATUSBAR (xed_statusbar_get_type ()) +#define XED_STATUSBAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_STATUSBAR, XedStatusbar)) +#define XED_STATUSBAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_STATUSBAR, XedStatusbarClass)) +#define XED_IS_STATUSBAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_STATUSBAR)) +#define XED_IS_STATUSBAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_STATUSBAR)) +#define XED_STATUSBAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_STATUSBAR, XedStatusbarClass)) -typedef struct _XedStatusbar XedStatusbar; -typedef struct _XedStatusbarPrivate XedStatusbarPrivate; -typedef struct _XedStatusbarClass XedStatusbarClass; +typedef struct _XedStatusbar XedStatusbar; +typedef struct _XedStatusbarPrivate XedStatusbarPrivate; +typedef struct _XedStatusbarClass XedStatusbarClass; struct _XedStatusbar { GtkStatusbar parent; - /* */ + /* */ XedStatusbarPrivate *priv; }; @@ -58,29 +58,29 @@ struct _XedStatusbarClass GtkStatusbarClass parent_class; }; -GType xed_statusbar_get_type (void) G_GNUC_CONST; +GType xed_statusbar_get_type (void) G_GNUC_CONST; -GtkWidget *xed_statusbar_new (void); +GtkWidget *xed_statusbar_new (void); /* FIXME: status is not defined in any .h */ #define XedStatus gint -void xed_statusbar_set_window_state (XedStatusbar *statusbar, - XedWindowState state, - gint num_of_errors); +void xed_statusbar_set_window_state (XedStatusbar *statusbar, + XedWindowState state, + gint num_of_errors); -void xed_statusbar_set_overwrite (XedStatusbar *statusbar, - gboolean overwrite); +void xed_statusbar_set_overwrite (XedStatusbar *statusbar, + gboolean overwrite); -void xed_statusbar_set_cursor_position (XedStatusbar *statusbar, - gint line, - gint col); +void xed_statusbar_set_cursor_position (XedStatusbar *statusbar, + gint line, + gint col); -void xed_statusbar_clear_overwrite (XedStatusbar *statusbar); +void xed_statusbar_clear_overwrite (XedStatusbar *statusbar); -void xed_statusbar_flash_message (XedStatusbar *statusbar, - guint context_id, - const gchar *format, - ...) G_GNUC_PRINTF(3, 4); +void xed_statusbar_flash_message (XedStatusbar *statusbar, + guint context_id, + const gchar *format, + ...) G_GNUC_PRINTF(3, 4); G_END_DECLS diff --git a/xed/xed-style-scheme-manager.c b/xed/xed-style-scheme-manager.c deleted file mode 100644 index 82ea3b5..0000000 --- a/xed/xed-style-scheme-manager.c +++ /dev/null @@ -1,373 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-source-style-manager.c - * - * Copyright (C) 2007 - Paolo Borelli and Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2007. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include -#include - -#include -#include - -#include "xed-style-scheme-manager.h" -#include "xed-prefs-manager.h" -#include "xed-dirs.h" - -static GtkSourceStyleSchemeManager *style_scheme_manager = NULL; - -static gchar * -get_xed_styles_path (void) -{ - gchar *config_dir; - gchar *dir = NULL; - - config_dir = xed_dirs_get_user_config_dir (); - - if (config_dir != NULL) - { - dir = g_build_filename (config_dir, - "styles", - NULL); - g_free (config_dir); - } - - return dir; -} - -static void -add_xed_styles_path (GtkSourceStyleSchemeManager *mgr) -{ - gchar *dir; - - dir = get_xed_styles_path(); - - if (dir != NULL) - { - gtk_source_style_scheme_manager_append_search_path (mgr, dir); - g_free (dir); - } -} - -GtkSourceStyleSchemeManager * -xed_get_style_scheme_manager (void) -{ - if (style_scheme_manager == NULL) - { - style_scheme_manager = gtk_source_style_scheme_manager_new (); - add_xed_styles_path (style_scheme_manager); - } - - return style_scheme_manager; -} - -static gint -schemes_compare (gconstpointer a, gconstpointer b) -{ - GtkSourceStyleScheme *scheme_a = (GtkSourceStyleScheme *)a; - GtkSourceStyleScheme *scheme_b = (GtkSourceStyleScheme *)b; - - const gchar *name_a = gtk_source_style_scheme_get_name (scheme_a); - const gchar *name_b = gtk_source_style_scheme_get_name (scheme_b); - - return g_utf8_collate (name_a, name_b); -} - -GSList * -xed_style_scheme_manager_list_schemes_sorted (GtkSourceStyleSchemeManager *manager) -{ - const gchar * const * scheme_ids; - GSList *schemes = NULL; - - g_return_val_if_fail (GTK_SOURCE_IS_STYLE_SCHEME_MANAGER (manager), NULL); - - scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager); - - while (*scheme_ids != NULL) - { - GtkSourceStyleScheme *scheme; - - scheme = gtk_source_style_scheme_manager_get_scheme (manager, - *scheme_ids); - - schemes = g_slist_prepend (schemes, scheme); - - ++scheme_ids; - } - - if (schemes != NULL) - schemes = g_slist_sort (schemes, (GCompareFunc)schemes_compare); - - return schemes; -} - -gboolean -_xed_style_scheme_manager_scheme_is_xed_user_scheme (GtkSourceStyleSchemeManager *manager, - const gchar *scheme_id) -{ - GtkSourceStyleScheme *scheme; - const gchar *filename; - gchar *dir; - gboolean res = FALSE; - - scheme = gtk_source_style_scheme_manager_get_scheme (manager, scheme_id); - if (scheme == NULL) - return FALSE; - - filename = gtk_source_style_scheme_get_filename (scheme); - if (filename == NULL) - return FALSE; - - dir = get_xed_styles_path (); - - res = g_str_has_prefix (filename, dir); - - g_free (dir); - - return res; -} - -/** - * file_copy: - * @name: a pointer to a %NULL-terminated string, that names - * the file to be copied, in the GLib file name encoding - * @dest_name: a pointer to a %NULL-terminated string, that is the - * name for the destination file, in the GLib file name encoding - * @error: return location for a #GError, or %NULL - * - * Copies file @name to @dest_name. - * - * If the call was successful, it returns %TRUE. If the call was not - * successful, it returns %FALSE and sets @error. The error domain - * is #G_FILE_ERROR. Possible error - * codes are those in the #GFileError enumeration. - * - * Return value: %TRUE on success, %FALSE otherwise. - */ -static gboolean -file_copy (const gchar *name, - const gchar *dest_name, - GError **error) -{ - gchar *contents; - gsize length; - gchar *dest_dir; - - /* FIXME - Paolo (Aug. 13, 2007): - * Since the style scheme files are relatively small, we can implement - * file copy getting all the content of the source file in a buffer and - * then write the content to the destination file. In this way we - * can use the g_file_get_contents and g_file_set_contents and avoid to - * write custom code to copy the file (with sane error management). - * If needed we can improve this code later. */ - - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (dest_name != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* Note: we allow to copy a file to itself since this is not a problem - * in our use case */ - - /* Ensure the destination directory exists */ - dest_dir = g_path_get_dirname (dest_name); - - errno = 0; - if (g_mkdir_with_parents (dest_dir, 0755) != 0) - { - gint save_errno = errno; - gchar *display_filename = g_filename_display_name (dest_dir); - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Directory '%s' could not be created: g_mkdir_with_parents() failed: %s"), - display_filename, - g_strerror (save_errno)); - - g_free (dest_dir); - g_free (display_filename); - - return FALSE; - } - - g_free (dest_dir); - - if (!g_file_get_contents (name, &contents, &length, error)) - return FALSE; - - if (!g_file_set_contents (dest_name, contents, length, error)) - return FALSE; - - g_free (contents); - - return TRUE; -} - -/** - * _xed_style_scheme_manager_install_scheme: - * @manager: a #GtkSourceStyleSchemeManager - * @fname: the file name of the style scheme to be installed - * - * Install a new user scheme. - * This function copies @fname in #XED_STYLES_DIR and ask the style manager to - * recompute the list of available style schemes. It then checks if a style - * scheme with the right file name exists. - * - * If the call was succesful, it returns the id of the installed scheme - * otherwise %NULL. - * - * Return value: the id of the installed scheme, %NULL otherwise. - */ -const gchar * -_xed_style_scheme_manager_install_scheme (GtkSourceStyleSchemeManager *manager, - const gchar *fname) -{ - gchar *new_file_name = NULL; - gchar *dirname; - gchar *styles_dir; - GError *error = NULL; - gboolean copied = FALSE; - - const gchar* const *ids; - - g_return_val_if_fail (GTK_SOURCE_IS_STYLE_SCHEME_MANAGER (manager), NULL); - g_return_val_if_fail (fname != NULL, NULL); - - dirname = g_path_get_dirname (fname); - styles_dir = get_xed_styles_path(); - - if (strcmp (dirname, styles_dir) != 0) - { - gchar *basename; - - basename = g_path_get_basename (fname); - new_file_name = g_build_filename (styles_dir, basename, NULL); - g_free (basename); - - /* Copy the style scheme file into XED_STYLES_DIR */ - if (!file_copy (fname, new_file_name, &error)) - { - g_free (new_file_name); - - g_message ("Cannot install style scheme:\n%s", - error->message); - - g_free (dirname); - g_free (styles_dir); - return NULL; - } - - copied = TRUE; - } - else - { - new_file_name = g_strdup (fname); - } - - g_free (dirname); - g_free (styles_dir); - - /* Reload the available style schemes */ - gtk_source_style_scheme_manager_force_rescan (manager); - - /* Check the new style scheme has been actually installed */ - ids = gtk_source_style_scheme_manager_get_scheme_ids (manager); - - while (*ids != NULL) - { - GtkSourceStyleScheme *scheme; - const gchar *filename; - - scheme = gtk_source_style_scheme_manager_get_scheme ( - xed_get_style_scheme_manager (), *ids); - - filename = gtk_source_style_scheme_get_filename (scheme); - - if (filename && (strcmp (filename, new_file_name) == 0)) - { - /* The style scheme has been correctly installed */ - g_free (new_file_name); - - return gtk_source_style_scheme_get_id (scheme); - } - ++ids; - } - - /* The style scheme has not been correctly installed */ - if (copied) - g_unlink (new_file_name); - - g_free (new_file_name); - - return NULL; -} - -/** - * _xed_style_scheme_manager_uninstall_scheme: - * @manager: a #GtkSourceStyleSchemeManager - * @id: the id of the style scheme to be uninstalled - * - * Uninstall a user scheme. - * - * If the call was succesful, it returns %TRUE - * otherwise %FALSE. - * - * Return value: %TRUE on success, %FALSE otherwise. - */ -gboolean -_xed_style_scheme_manager_uninstall_scheme (GtkSourceStyleSchemeManager *manager, - const gchar *id) -{ - GtkSourceStyleScheme *scheme; - const gchar *filename; - - g_return_val_if_fail (GTK_SOURCE_IS_STYLE_SCHEME_MANAGER (manager), FALSE); - g_return_val_if_fail (id != NULL, FALSE); - - scheme = gtk_source_style_scheme_manager_get_scheme (manager, id); - if (scheme == NULL) - return FALSE; - - filename = gtk_source_style_scheme_get_filename (scheme); - if (filename == NULL) - return FALSE; - - if (g_unlink (filename) == -1) - return FALSE; - - /* Reload the available style schemes */ - gtk_source_style_scheme_manager_force_rescan (manager); - - return TRUE; -} diff --git a/xed/xed-style-scheme-manager.h b/xed/xed-style-scheme-manager.h deleted file mode 100644 index 60d7718..0000000 --- a/xed/xed-style-scheme-manager.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-style-scheme-manager.h - * - * Copyright (C) 2007 - Paolo Borelli - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * $Id: xed-source-style-manager.h 5598 2007-04-15 13:16:24Z pborelli $ - */ - -#ifndef __XED_STYLE_SCHEME_MANAGER_H__ -#define __XED_STYLE_SCHEME_MANAGER_H__ - -#include - -G_BEGIN_DECLS - -GtkSourceStyleSchemeManager * - xed_get_style_scheme_manager (void); - -/* Returns a sorted list of style schemes */ -GSList *xed_style_scheme_manager_list_schemes_sorted - (GtkSourceStyleSchemeManager *manager); - -/* - * Non exported functions - */ -gboolean _xed_style_scheme_manager_scheme_is_xed_user_scheme - (GtkSourceStyleSchemeManager *manager, - const gchar *scheme_id); - -const gchar *_xed_style_scheme_manager_install_scheme - (GtkSourceStyleSchemeManager *manager, - const gchar *fname); - -gboolean _xed_style_scheme_manager_uninstall_scheme - (GtkSourceStyleSchemeManager *manager, - const gchar *id); - -G_END_DECLS - -#endif /* __XED_STYLE_SCHEME_MANAGER_H__ */ diff --git a/xed/xed-tab-label.c b/xed/xed-tab-label.c index 22bd3ec..02a1754 100644 --- a/xed/xed-tab-label.c +++ b/xed/xed-tab-label.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ @@ -34,27 +34,27 @@ /* Signals */ enum { - CLOSE_CLICKED, - LAST_SIGNAL + CLOSE_CLICKED, + LAST_SIGNAL }; enum { - PROP_0, - PROP_TAB + PROP_0, + PROP_TAB }; struct _XedTabLabelPrivate { - XedTab *tab; + XedTab *tab; - GtkWidget *ebox; - GtkWidget *close_button; - GtkWidget *spinner; - GtkWidget *icon; - GtkWidget *label; + GtkWidget *ebox; + GtkWidget *close_button; + GtkWidget *spinner; + GtkWidget *icon; + GtkWidget *label; - gboolean close_button_sensitive; + gboolean close_button_sensitive; }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -64,298 +64,301 @@ G_DEFINE_TYPE (XedTabLabel, xed_tab_label, GTK_TYPE_BOX) static void xed_tab_label_finalize (GObject *object) { - G_OBJECT_CLASS (xed_tab_label_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_tab_label_parent_class)->finalize (object); } static void xed_tab_label_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedTabLabel *tab_label = XED_TAB_LABEL (object); + XedTabLabel *tab_label = XED_TAB_LABEL (object); - switch (prop_id) - { - case PROP_TAB: - tab_label->priv->tab = XED_TAB (g_value_get_object (value)); - break; + switch (prop_id) + { + case PROP_TAB: + tab_label->priv->tab = XED_TAB (g_value_get_object (value)); + break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_tab_label_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedTabLabel *tab_label = XED_TAB_LABEL (object); + XedTabLabel *tab_label = XED_TAB_LABEL (object); - switch (prop_id) - { - case PROP_TAB: - g_value_set_object (value, tab_label->priv->tab); - break; + switch (prop_id) + { + case PROP_TAB: + g_value_set_object (value, tab_label->priv->tab); + break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -close_button_clicked_cb (GtkWidget *widget, - XedTabLabel *tab_label) +close_button_clicked_cb (GtkWidget *widget, + XedTabLabel *tab_label) { - g_signal_emit (tab_label, signals[CLOSE_CLICKED], 0, NULL); + g_signal_emit (tab_label, signals[CLOSE_CLICKED], 0, NULL); } static void -sync_tip (XedTab *tab, XedTabLabel *tab_label) +sync_tip (XedTab *tab, + XedTabLabel *tab_label) { - gchar *str; + gchar *str; - str = _xed_tab_get_tooltips (tab); - g_return_if_fail (str != NULL); + str = _xed_tab_get_tooltips (tab); + g_return_if_fail (str != NULL); - gtk_widget_set_tooltip_markup (tab_label->priv->ebox, str); - g_free (str); + gtk_widget_set_tooltip_markup (tab_label->priv->ebox, str); + g_free (str); } static void -sync_name (XedTab *tab, GParamSpec *pspec, XedTabLabel *tab_label) +sync_name (XedTab *tab, + GParamSpec *pspec, + XedTabLabel *tab_label) { - gchar *str; + gchar *str; - g_return_if_fail (tab == tab_label->priv->tab); + g_return_if_fail (tab == tab_label->priv->tab); - str = _xed_tab_get_name (tab); - g_return_if_fail (str != NULL); + str = _xed_tab_get_name (tab); + g_return_if_fail (str != NULL); - gtk_label_set_text (GTK_LABEL (tab_label->priv->label), str); - g_free (str); + gtk_label_set_text (GTK_LABEL (tab_label->priv->label), str); + g_free (str); - sync_tip (tab, tab_label); + sync_tip (tab, tab_label); } static void -sync_state (XedTab *tab, GParamSpec *pspec, XedTabLabel *tab_label) +sync_state (XedTab *tab, + GParamSpec *pspec, + XedTabLabel *tab_label) { - XedTabState state; + XedTabState state; - g_return_if_fail (tab == tab_label->priv->tab); + g_return_if_fail (tab == tab_label->priv->tab); - state = xed_tab_get_state (tab); + state = xed_tab_get_state (tab); - gtk_widget_set_sensitive (tab_label->priv->close_button, - tab_label->priv->close_button_sensitive && - (state != XED_TAB_STATE_CLOSING) && - (state != XED_TAB_STATE_SAVING) && - (state != XED_TAB_STATE_SHOWING_PRINT_PREVIEW) && - (state != XED_TAB_STATE_SAVING_ERROR)); + gtk_widget_set_sensitive (tab_label->priv->close_button, + tab_label->priv->close_button_sensitive && + (state != XED_TAB_STATE_CLOSING) && + (state != XED_TAB_STATE_SAVING) && + (state != XED_TAB_STATE_SHOWING_PRINT_PREVIEW) && + (state != XED_TAB_STATE_SAVING_ERROR)); - if ((state == XED_TAB_STATE_LOADING) || - (state == XED_TAB_STATE_SAVING) || - (state == XED_TAB_STATE_REVERTING)) - { - gtk_widget_hide (tab_label->priv->icon); + if ((state == XED_TAB_STATE_LOADING) || + (state == XED_TAB_STATE_SAVING) || + (state == XED_TAB_STATE_REVERTING)) + { + gtk_widget_hide (tab_label->priv->icon); - gtk_widget_show (tab_label->priv->spinner); - gtk_spinner_start (GTK_SPINNER (tab_label->priv->spinner)); - } - else - { - GdkPixbuf *pixbuf; + gtk_widget_show (tab_label->priv->spinner); + gtk_spinner_start (GTK_SPINNER (tab_label->priv->spinner)); + } + else + { + GdkPixbuf *pixbuf; - pixbuf = _xed_tab_get_icon (tab); - gtk_image_set_from_pixbuf (GTK_IMAGE (tab_label->priv->icon), pixbuf); + pixbuf = _xed_tab_get_icon (tab); - if (pixbuf != NULL) - g_object_unref (pixbuf); + if (pixbuf != NULL) + { + gtk_image_set_from_pixbuf (GTK_IMAGE (tab_label->priv->icon), pixbuf); + g_clear_object (&pixbuf); + gtk_widget_show (tab_label->priv->icon); + } + else + { + gtk_widget_hide (tab_label->priv->icon); + } - gtk_widget_show (tab_label->priv->icon); + gtk_widget_hide (tab_label->priv->spinner); + gtk_spinner_stop (GTK_SPINNER (tab_label->priv->spinner)); + } - gtk_widget_hide (tab_label->priv->spinner); - gtk_spinner_stop (GTK_SPINNER (tab_label->priv->spinner)); - } - - /* sync tip since encoding is known only after load/save end */ - sync_tip (tab, tab_label); + /* sync tip since encoding is known only after load/save end */ + sync_tip (tab, tab_label); } static void xed_tab_label_constructed (GObject *object) { - XedTabLabel *tab_label = XED_TAB_LABEL (object); + XedTabLabel *tab_label = XED_TAB_LABEL (object); - if (!tab_label->priv->tab) - { - g_critical ("The tab label was not properly constructed"); - return; - } + if (!tab_label->priv->tab) + { + g_critical ("The tab label was not properly constructed"); + return; + } - sync_name (tab_label->priv->tab, NULL, tab_label); - sync_state (tab_label->priv->tab, NULL, tab_label); + sync_name (tab_label->priv->tab, NULL, tab_label); + sync_state (tab_label->priv->tab, NULL, tab_label); - g_signal_connect_object (tab_label->priv->tab, - "notify::name", - G_CALLBACK (sync_name), - tab_label, - 0); + g_signal_connect_object (tab_label->priv->tab, "notify::name", + G_CALLBACK (sync_name), tab_label, 0); - g_signal_connect_object (tab_label->priv->tab, - "notify::state", - G_CALLBACK (sync_state), - tab_label, - 0); + g_signal_connect_object (tab_label->priv->tab, "notify::state", + G_CALLBACK (sync_state), tab_label, 0); } static void xed_tab_label_class_init (XedTabLabelClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = xed_tab_label_finalize; - object_class->set_property = xed_tab_label_set_property; - object_class->get_property = xed_tab_label_get_property; - object_class->constructed = xed_tab_label_constructed; + GObjectClass *object_class = G_OBJECT_CLASS (klass); - signals[CLOSE_CLICKED] = - g_signal_new ("close-clicked", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedTabLabelClass, close_clicked), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); + object_class->finalize = xed_tab_label_finalize; + object_class->set_property = xed_tab_label_set_property; + object_class->get_property = xed_tab_label_get_property; + object_class->constructed = xed_tab_label_constructed; - g_object_class_install_property (object_class, - PROP_TAB, - g_param_spec_object ("tab", - "Tab", - "The XedTab", - XED_TYPE_TAB, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); + signals[CLOSE_CLICKED] = + g_signal_new ("close-clicked", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XedTabLabelClass, close_clicked), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); - g_type_class_add_private (object_class, sizeof(XedTabLabelPrivate)); + g_object_class_install_property (object_class, + PROP_TAB, + g_param_spec_object ("tab", + "Tab", + "The XedTab", + XED_TYPE_TAB, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_type_class_add_private (object_class, sizeof(XedTabLabelPrivate)); } static void xed_tab_label_init (XedTabLabel *tab_label) { - GtkWidget *ebox; - GtkWidget *hbox; - GtkWidget *close_button; - GtkWidget *spinner; - GtkWidget *icon; - GtkWidget *label; - GtkWidget *dummy_label; + GtkWidget *ebox; + GtkWidget *hbox; + GtkWidget *close_button; + GtkWidget *spinner; + GtkWidget *icon; + GtkWidget *label; + GtkWidget *dummy_label; - tab_label->priv = XED_TAB_LABEL_GET_PRIVATE (tab_label); + tab_label->priv = XED_TAB_LABEL_GET_PRIVATE (tab_label); - tab_label->priv->close_button_sensitive = TRUE; + tab_label->priv->close_button_sensitive = TRUE; - gtk_orientable_set_orientation (GTK_ORIENTABLE (tab_label), - GTK_ORIENTATION_HORIZONTAL); - ebox = gtk_event_box_new (); - gtk_event_box_set_visible_window (GTK_EVENT_BOX (ebox), FALSE); - gtk_box_pack_start (GTK_BOX (tab_label), ebox, TRUE, TRUE, 0); - tab_label->priv->ebox = ebox; + gtk_orientable_set_orientation (GTK_ORIENTABLE (tab_label), GTK_ORIENTATION_HORIZONTAL); + ebox = gtk_event_box_new (); + gtk_event_box_set_visible_window (GTK_EVENT_BOX (ebox), FALSE); + gtk_box_pack_start (GTK_BOX (tab_label), ebox, TRUE, TRUE, 0); + tab_label->priv->ebox = ebox; - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); - gtk_container_add (GTK_CONTAINER (ebox), hbox); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_container_add (GTK_CONTAINER (ebox), hbox); - close_button = xed_close_button_new (); - gtk_widget_set_tooltip_text (close_button, _("Close document")); - gtk_box_pack_start (GTK_BOX (tab_label), close_button, FALSE, FALSE, 0); - tab_label->priv->close_button = close_button; + close_button = xed_close_button_new (); + gtk_widget_set_tooltip_text (close_button, _("Close document")); + gtk_box_pack_start (GTK_BOX (tab_label), close_button, FALSE, FALSE, 0); + tab_label->priv->close_button = close_button; - g_signal_connect (close_button, - "clicked", - G_CALLBACK (close_button_clicked_cb), - tab_label); + g_signal_connect (close_button, "clicked", + G_CALLBACK (close_button_clicked_cb), tab_label); - spinner = gtk_spinner_new (); - gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, FALSE, 0); - tab_label->priv->spinner = spinner; + spinner = gtk_spinner_new (); + gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, FALSE, 0); + tab_label->priv->spinner = spinner; - /* setup icon, empty by default */ - icon = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0); - tab_label->priv->icon = icon; + /* setup icon, empty by default */ + icon = gtk_image_new (); + gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0); + tab_label->priv->icon = icon; - label = gtk_label_new (""); + label = gtk_label_new (""); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_set_margin_left (label, 0); - gtk_widget_set_margin_right (label, 0); - gtk_widget_set_margin_top (label, 0); - gtk_widget_set_margin_bottom (label, 0); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_widget_set_margin_start (label, 0); + gtk_widget_set_margin_end (label, 0); + gtk_widget_set_margin_top (label, 0); + gtk_widget_set_margin_bottom (label, 0); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - tab_label->priv->label = label; + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + tab_label->priv->label = label; - dummy_label = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (hbox), dummy_label, TRUE, TRUE, 0); + dummy_label = gtk_label_new (""); + gtk_box_pack_start (GTK_BOX (hbox), dummy_label, TRUE, TRUE, 0); - gtk_widget_show (ebox); - gtk_widget_show (hbox); - gtk_widget_show (close_button); - gtk_widget_show (icon); - gtk_widget_show (label); - gtk_widget_show (dummy_label); + gtk_widget_show (ebox); + gtk_widget_show (hbox); + gtk_widget_show (close_button); + gtk_widget_show (icon); + gtk_widget_show (label); + gtk_widget_show (dummy_label); } void xed_tab_label_set_close_button_sensitive (XedTabLabel *tab_label, - gboolean sensitive) + gboolean sensitive) { - XedTabState state; + XedTabState state; - g_return_if_fail (XED_IS_TAB_LABEL (tab_label)); + g_return_if_fail (XED_IS_TAB_LABEL (tab_label)); - sensitive = (sensitive != FALSE); + sensitive = (sensitive != FALSE); - if (sensitive == tab_label->priv->close_button_sensitive) - return; + if (sensitive == tab_label->priv->close_button_sensitive) + { + return; + } - tab_label->priv->close_button_sensitive = sensitive; + tab_label->priv->close_button_sensitive = sensitive; - state = xed_tab_get_state (tab_label->priv->tab); + state = xed_tab_get_state (tab_label->priv->tab); - gtk_widget_set_sensitive (tab_label->priv->close_button, - tab_label->priv->close_button_sensitive && - (state != XED_TAB_STATE_CLOSING) && - (state != XED_TAB_STATE_SAVING) && - (state != XED_TAB_STATE_SHOWING_PRINT_PREVIEW) && - (state != XED_TAB_STATE_PRINTING) && - (state != XED_TAB_STATE_PRINT_PREVIEWING) && - (state != XED_TAB_STATE_SAVING_ERROR)); + gtk_widget_set_sensitive (tab_label->priv->close_button, + tab_label->priv->close_button_sensitive && + (state != XED_TAB_STATE_CLOSING) && + (state != XED_TAB_STATE_SAVING) && + (state != XED_TAB_STATE_SHOWING_PRINT_PREVIEW) && + (state != XED_TAB_STATE_PRINTING) && + (state != XED_TAB_STATE_PRINT_PREVIEWING) && + (state != XED_TAB_STATE_SAVING_ERROR)); } XedTab * xed_tab_label_get_tab (XedTabLabel *tab_label) { - g_return_val_if_fail (XED_IS_TAB_LABEL (tab_label), NULL); + g_return_val_if_fail (XED_IS_TAB_LABEL (tab_label), NULL); - return tab_label->priv->tab; + return tab_label->priv->tab; } GtkWidget * xed_tab_label_new (XedTab *tab) { - XedTabLabel *tab_label; + XedTabLabel *tab_label; - tab_label = g_object_new (XED_TYPE_TAB_LABEL, - "homogeneous", FALSE, - "tab", tab, - NULL); + tab_label = g_object_new (XED_TYPE_TAB_LABEL, + "homogeneous", FALSE, + "tab", tab, + NULL); - return GTK_WIDGET (tab_label); + return GTK_WIDGET (tab_label); } diff --git a/xed/xed-tab-label.h b/xed/xed-tab-label.h index 768996e..d35f839 100644 --- a/xed/xed-tab-label.h +++ b/xed/xed-tab-label.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ @@ -28,38 +28,38 @@ G_BEGIN_DECLS -#define XED_TYPE_TAB_LABEL (xed_tab_label_get_type ()) -#define XED_TAB_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_TAB_LABEL, XedTabLabel)) -#define XED_TAB_LABEL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_TAB_LABEL, XedTabLabel const)) -#define XED_TAB_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_TAB_LABEL, XedTabLabelClass)) -#define XED_IS_TAB_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_TAB_LABEL)) -#define XED_IS_TAB_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_TAB_LABEL)) -#define XED_TAB_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_TAB_LABEL, XedTabLabelClass)) +#define XED_TYPE_TAB_LABEL (xed_tab_label_get_type ()) +#define XED_TAB_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_TAB_LABEL, XedTabLabel)) +#define XED_TAB_LABEL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_TAB_LABEL, XedTabLabel const)) +#define XED_TAB_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_TAB_LABEL, XedTabLabelClass)) +#define XED_IS_TAB_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_TAB_LABEL)) +#define XED_IS_TAB_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_TAB_LABEL)) +#define XED_TAB_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_TAB_LABEL, XedTabLabelClass)) -typedef struct _XedTabLabel XedTabLabel; -typedef struct _XedTabLabelClass XedTabLabelClass; -typedef struct _XedTabLabelPrivate XedTabLabelPrivate; +typedef struct _XedTabLabel XedTabLabel; +typedef struct _XedTabLabelClass XedTabLabelClass; +typedef struct _XedTabLabelPrivate XedTabLabelPrivate; struct _XedTabLabel { - GtkBox parent; + GtkBox parent; - XedTabLabelPrivate *priv; + XedTabLabelPrivate *priv; }; struct _XedTabLabelClass { - GtkBoxClass parent_class; + GtkBoxClass parent_class; - void (* close_clicked) (XedTabLabel *tab_label); + void (* close_clicked) (XedTabLabel *tab_label); }; -GType xed_tab_label_get_type (void) G_GNUC_CONST; +GType xed_tab_label_get_type (void) G_GNUC_CONST; -GtkWidget *xed_tab_label_new (XedTab *tab); +GtkWidget *xed_tab_label_new (XedTab *tab); -XedTab *xed_tab_label_get_tab (XedTabLabel *tab_label); +XedTab *xed_tab_label_get_tab (XedTabLabel *tab_label); -void xed_tab_label_set_close_button_sensitive (XedTabLabel *tab_label, - gboolean sensitive); +void xed_tab_label_set_close_button_sensitive (XedTabLabel *tab_label, + gboolean sensitive); G_END_DECLS diff --git a/xed/xed-tab.c b/xed/xed-tab.c index ddf6c7a..5237267 100644 --- a/xed/xed-tab.c +++ b/xed/xed-tab.c @@ -2,7 +2,7 @@ * xed-tab.c * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,20 +16,21 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. */ #ifdef HAVE_CONFIG_H #include #endif +#include #include #include @@ -37,13 +38,14 @@ #include "xed-notebook.h" #include "xed-tab.h" #include "xed-utils.h" -#include "xed-io-error-message-area.h" +#include "xed-io-error-info-bar.h" #include "xed-print-job.h" #include "xed-print-preview.h" -#include "xed-progress-message-area.h" +#include "xed-progress-info-bar.h" #include "xed-debug.h" -#include "xed-prefs-manager-app.h" #include "xed-enum-types.h" +#include "xed-settings.h" +#include "xed-view-frame.h" #define XED_TAB_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_TAB, XedTabPrivate)) @@ -51,240 +53,299 @@ struct _XedTabPrivate { - XedTabState state; - - GtkWidget *view; - GtkWidget *view_scrolled_window; + GSettings *editor; - GtkWidget *message_area; - GtkWidget *print_preview; + XedTabState state; - XedPrintJob *print_job; + XedViewFrame *frame; - /* tmp data for saving */ - gchar *tmp_save_uri; + GtkWidget *info_bar; + GtkWidget *print_preview; - /* tmp data for loading */ - gint tmp_line_pos; - const XedEncoding *tmp_encoding; - - GTimer *timer; - guint times_called; + XedPrintJob *print_job; - XedDocumentSaveFlags save_flags; + GTask *task_saver; + GtkSourceFileSaverFlags save_flags; - gint auto_save_interval; - guint auto_save_timeout; - - gint not_editable : 1; - gint auto_save : 1; + /* tmp data for loading */ + GtkSourceFileLoader *loader; + GCancellable *cancellable; + gint tmp_line_pos; + guint idle_scroll; - gint ask_if_externally_modified : 1; + GTimer *timer; + guint times_called; + + guint auto_save_interval; + guint auto_save_timeout; + + gint editable : 1; + gint auto_save : 1; + + gint ask_if_externally_modified : 1; + + /*tmp data for loading */ + guint user_requested_encoding : 1; +}; + +typedef struct _SaverData SaverData; + +struct _SaverData +{ + GtkSourceFileSaver *saver; + + /* Notes about the create_backup saver flag: + * - At the beginning of a new file saving, force_no_backup is FALSE. + * The create_backup flag is set to the saver if it is enabled in + * GSettings and if it isn't an auto-save. + * - If creating the backup gives an error, and if the user wants to + * save the file without the backup, force_no_backup is set to TRUE + * and the create_backup flag is removed from the saver. + * force_no_backup as TRUE means that the create_backup flag should + * never be added again to the saver (for the current file saving). + * - When another error occurs and if the user explicitly retry again + * the file saving, the create_backup flag is added to the saver if + * (1) it is enabled in GSettings, (2) if force_no_backup is FALSE. + * - The create_backup flag is added when the user expressed his or her + * willing to save the file, by pressing a button for example. For an + * auto-save, the create_backup flag is thus not added initially, but + * can be added later when an error occurs and the user clicks on a + * button in the info bar to retry the file saving. + */ + guint force_no_backup : 1; }; G_DEFINE_TYPE(XedTab, xed_tab, GTK_TYPE_BOX) enum { - PROP_0, - PROP_NAME, - PROP_STATE, - PROP_AUTO_SAVE, - PROP_AUTO_SAVE_INTERVAL + PROP_0, + PROP_NAME, + PROP_STATE, + PROP_AUTO_SAVE, + PROP_AUTO_SAVE_INTERVAL }; static gboolean xed_tab_auto_save (XedTab *tab); +static void load (XedTab *tab, + const GtkSourceEncoding *encoding, + gint line_pos); + +static void save (XedTab *tab); + +static SaverData * +saver_data_new (void) +{ + return g_slice_new0 (SaverData); +} + +static void +saver_data_free (SaverData *data) +{ + if (data != NULL) + { + if (data->saver != NULL) + { + g_object_unref (data->saver); + } + + g_slice_free (SaverData, data); + } +} + static void install_auto_save_timeout (XedTab *tab) { - gint timeout; + if (tab->priv->auto_save_timeout == 0) + { + g_return_if_fail (tab->priv->auto_save_interval > 0); - xed_debug (DEBUG_TAB); - - g_return_if_fail (tab->priv->auto_save_timeout <= 0); - g_return_if_fail (tab->priv->auto_save); - g_return_if_fail (tab->priv->auto_save_interval > 0); - - g_return_if_fail (tab->priv->state != XED_TAB_STATE_LOADING); - g_return_if_fail (tab->priv->state != XED_TAB_STATE_SAVING); - g_return_if_fail (tab->priv->state != XED_TAB_STATE_REVERTING); - g_return_if_fail (tab->priv->state != XED_TAB_STATE_LOADING_ERROR); - g_return_if_fail (tab->priv->state != XED_TAB_STATE_SAVING_ERROR); - g_return_if_fail (tab->priv->state != XED_TAB_STATE_SAVING_ERROR); - g_return_if_fail (tab->priv->state != XED_TAB_STATE_REVERTING_ERROR); - - /* Add a new timeout */ - timeout = g_timeout_add_seconds (tab->priv->auto_save_interval * 60, - (GSourceFunc) xed_tab_auto_save, - tab); - - tab->priv->auto_save_timeout = timeout; -} - -static gboolean -install_auto_save_timeout_if_needed (XedTab *tab) -{ - XedDocument *doc; - - xed_debug (DEBUG_TAB); - - g_return_val_if_fail (tab->priv->auto_save_timeout <= 0, FALSE); - g_return_val_if_fail ((tab->priv->state == XED_TAB_STATE_NORMAL) || - (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) || - (tab->priv->state == XED_TAB_STATE_CLOSING), FALSE); - - if (tab->priv->state == XED_TAB_STATE_CLOSING) - return FALSE; - - doc = xed_tab_get_document (tab); - - if (tab->priv->auto_save && - !xed_document_is_untitled (doc) && - !xed_document_get_readonly (doc)) - { - install_auto_save_timeout (tab); - - return TRUE; - } - - return FALSE; + tab->priv->auto_save_timeout = g_timeout_add_seconds (tab->priv->auto_save_interval * 60, + (GSourceFunc) xed_tab_auto_save, + tab); + } } static void remove_auto_save_timeout (XedTab *tab) { - xed_debug (DEBUG_TAB); + xed_debug (DEBUG_TAB); - /* FIXME: check sugli stati */ - - g_return_if_fail (tab->priv->auto_save_timeout > 0); - - g_source_remove (tab->priv->auto_save_timeout); - tab->priv->auto_save_timeout = 0; + if (tab->priv->auto_save_timeout > 0) + { + g_source_remove (tab->priv->auto_save_timeout); + tab->priv->auto_save_timeout = 0; + } +} + +static void +update_auto_save_timeout (XedTab *tab) +{ + gboolean good_state; + XedDocument *doc; + + xed_debug (DEBUG_TAB); + + good_state = (tab->priv->state == XED_TAB_STATE_NORMAL || + tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW); + + doc = xed_tab_get_document (tab); + + if (good_state && + tab->priv->auto_save && + !xed_document_is_untitled (doc) && + !xed_document_get_readonly (doc)) + { + install_auto_save_timeout (tab); + } + else + { + remove_auto_save_timeout (tab); + } } static void xed_tab_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - XedTab *tab = XED_TAB (object); + XedTab *tab = XED_TAB (object); - switch (prop_id) - { - case PROP_NAME: - g_value_take_string (value, - _xed_tab_get_name (tab)); - break; - case PROP_STATE: - g_value_set_enum (value, - xed_tab_get_state (tab)); - break; - case PROP_AUTO_SAVE: - g_value_set_boolean (value, - xed_tab_get_auto_save_enabled (tab)); - break; - case PROP_AUTO_SAVE_INTERVAL: - g_value_set_int (value, - xed_tab_get_auto_save_interval (tab)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_NAME: + g_value_take_string (value, _xed_tab_get_name (tab)); + break; + case PROP_STATE: + g_value_set_enum (value, xed_tab_get_state (tab)); + break; + case PROP_AUTO_SAVE: + g_value_set_boolean (value, xed_tab_get_auto_save_enabled (tab)); + break; + case PROP_AUTO_SAVE_INTERVAL: + g_value_set_int (value, xed_tab_get_auto_save_interval (tab)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void xed_tab_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - XedTab *tab = XED_TAB (object); + XedTab *tab = XED_TAB (object); - switch (prop_id) - { - case PROP_AUTO_SAVE: - xed_tab_set_auto_save_enabled (tab, - g_value_get_boolean (value)); - break; - case PROP_AUTO_SAVE_INTERVAL: - xed_tab_set_auto_save_interval (tab, - g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case PROP_AUTO_SAVE: + xed_tab_set_auto_save_enabled (tab, g_value_get_boolean (value)); + break; + case PROP_AUTO_SAVE_INTERVAL: + xed_tab_set_auto_save_interval (tab, g_value_get_int (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clear_loading (XedTab *tab) +{ + g_clear_object (&tab->priv->loader); + g_clear_object (&tab->priv->cancellable); +} + +static void +xed_tab_dispose (GObject *object) +{ + XedTab *tab = XED_TAB (object); + + g_clear_object (&tab->priv->editor); + g_clear_object (&tab->priv->task_saver); + + clear_loading (tab); + + G_OBJECT_CLASS (xed_tab_parent_class)->dispose (object); } static void xed_tab_finalize (GObject *object) { - XedTab *tab = XED_TAB (object); + XedTab *tab = XED_TAB (object); - if (tab->priv->timer != NULL) - g_timer_destroy (tab->priv->timer); + if (tab->priv->timer != NULL) + { + g_timer_destroy (tab->priv->timer); + } - g_free (tab->priv->tmp_save_uri); + remove_auto_save_timeout (tab); - if (tab->priv->auto_save_timeout > 0) - remove_auto_save_timeout (tab); + if (tab->priv->idle_scroll != 0) + { + g_source_remove (tab->priv->idle_scroll); + tab->priv->idle_scroll = 0; + } - G_OBJECT_CLASS (xed_tab_parent_class)->finalize (object); + G_OBJECT_CLASS (xed_tab_parent_class)->finalize (object); } -static void +static void xed_tab_class_init (XedTabClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xed_tab_finalize; - object_class->get_property = xed_tab_get_property; - object_class->set_property = xed_tab_set_property; - - g_object_class_install_property (object_class, - PROP_NAME, - g_param_spec_string ("name", - "Name", - "The tab's name", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + object_class->dispose = xed_tab_dispose; + object_class->finalize = xed_tab_finalize; + object_class->get_property = xed_tab_get_property; + object_class->set_property = xed_tab_set_property; - g_object_class_install_property (object_class, - PROP_STATE, - g_param_spec_enum ("state", - "State", - "The tab's state", - XED_TYPE_TAB_STATE, - XED_TAB_STATE_NORMAL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "The tab's name", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, - PROP_AUTO_SAVE, - g_param_spec_boolean ("autosave", - "Autosave", - "Autosave feature", - TRUE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_STATE, + g_param_spec_enum ("state", + "State", + "The tab's state", + XED_TYPE_TAB_STATE, + XED_TAB_STATE_NORMAL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, - PROP_AUTO_SAVE_INTERVAL, - g_param_spec_int ("autosave-interval", - "AutosaveInterval", - "Time between two autosaves", - 0, - G_MAXINT, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_AUTO_SAVE, + g_param_spec_boolean ("autosave", + "Autosave", + "Autosave feature", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); - g_type_class_add_private (object_class, sizeof (XedTabPrivate)); + g_object_class_install_property (object_class, + PROP_AUTO_SAVE_INTERVAL, + g_param_spec_int ("autosave-interval", + "AutosaveInterval", + "Time between two autosaves", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private (object_class, sizeof (XedTabPrivate)); } /** @@ -298,1293 +359,873 @@ xed_tab_class_init (XedTabClass *klass) XedTabState xed_tab_get_state (XedTab *tab) { - g_return_val_if_fail (XED_IS_TAB (tab), XED_TAB_STATE_NORMAL); - - return tab->priv->state; + g_return_val_if_fail (XED_IS_TAB (tab), XED_TAB_STATE_NORMAL); + + return tab->priv->state; } static void -set_cursor_according_to_state (GtkTextView *view, - XedTabState state) +set_cursor_according_to_state (GtkTextView *view, + XedTabState state) { - GdkCursor *cursor; - GdkWindow *text_window; - GdkWindow *left_window; + GdkCursor *cursor; + GdkWindow *text_window; + GdkWindow *left_window; - text_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_TEXT); - left_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_LEFT); + text_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_TEXT); + left_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_LEFT); - if ((state == XED_TAB_STATE_LOADING) || - (state == XED_TAB_STATE_REVERTING) || - (state == XED_TAB_STATE_SAVING) || - (state == XED_TAB_STATE_PRINTING) || - (state == XED_TAB_STATE_PRINT_PREVIEWING) || - (state == XED_TAB_STATE_CLOSING)) - { - cursor = gdk_cursor_new_for_display ( - gtk_widget_get_display (GTK_WIDGET (view)), - GDK_WATCH); + if ((state == XED_TAB_STATE_LOADING) || + (state == XED_TAB_STATE_REVERTING) || + (state == XED_TAB_STATE_SAVING) || + (state == XED_TAB_STATE_PRINTING) || + (state == XED_TAB_STATE_PRINT_PREVIEWING) || + (state == XED_TAB_STATE_CLOSING)) + { + cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (view)), GDK_WATCH); - if (text_window != NULL) - gdk_window_set_cursor (text_window, cursor); - if (left_window != NULL) - gdk_window_set_cursor (left_window, cursor); + if (text_window != NULL) + { + gdk_window_set_cursor (text_window, cursor); + } + if (left_window != NULL) + { + gdk_window_set_cursor (left_window, cursor); + } - g_object_unref (cursor); - } - else - { - cursor = gdk_cursor_new_for_display ( - gtk_widget_get_display (GTK_WIDGET (view)), - GDK_XTERM); + g_object_unref (cursor); + } + else + { + cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (view)), GDK_XTERM); - if (text_window != NULL) - gdk_window_set_cursor (text_window, cursor); - if (left_window != NULL) - gdk_window_set_cursor (left_window, NULL); + if (text_window != NULL) + { + gdk_window_set_cursor (text_window, cursor); + } + if (left_window != NULL) + { + gdk_window_set_cursor (left_window, NULL); + } - g_object_unref (cursor); - } + g_object_unref (cursor); + } } static void view_realized (GtkTextView *view, - XedTab *tab) + XedTab *tab) { - set_cursor_according_to_state (view, tab->priv->state); + set_cursor_according_to_state (view, tab->priv->state); } static void set_view_properties_according_to_state (XedTab *tab, - XedTabState state) + XedTabState state) { - gboolean val; + XedView *view; + gboolean val; + gboolean hl_current_line; - val = ((state == XED_TAB_STATE_NORMAL) && - (tab->priv->print_preview == NULL) && - !tab->priv->not_editable); - gtk_text_view_set_editable (GTK_TEXT_VIEW (tab->priv->view), val); + hl_current_line = g_settings_get_boolean (tab->priv->editor, XED_SETTINGS_HIGHLIGHT_CURRENT_LINE); + view = xed_view_frame_get_view (tab->priv->frame); + val = ((state == XED_TAB_STATE_NORMAL) && (tab->priv->print_preview == NULL) && tab->priv->editable); + gtk_text_view_set_editable (GTK_TEXT_VIEW (view), val); - val = ((state != XED_TAB_STATE_LOADING) && - (state != XED_TAB_STATE_CLOSING)); - gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (tab->priv->view), val); + val = ((state != XED_TAB_STATE_LOADING) && (state != XED_TAB_STATE_CLOSING)); + gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), val); - val = ((state != XED_TAB_STATE_LOADING) && - (state != XED_TAB_STATE_CLOSING) && - (xed_prefs_manager_get_highlight_current_line ())); - gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW (tab->priv->view), val); + val = ((state != XED_TAB_STATE_LOADING) && + (state != XED_TAB_STATE_CLOSING) && + (hl_current_line)); + gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW (view), val); } static void xed_tab_set_state (XedTab *tab, - XedTabState state) + XedTabState state) { - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail ((state >= 0) && (state < XED_TAB_NUM_OF_STATES)); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail ((state >= 0) && (state < XED_TAB_NUM_OF_STATES)); - if (tab->priv->state == state) - return; + if (tab->priv->state == state) + { + return; + } - tab->priv->state = state; + tab->priv->state = state; - set_view_properties_according_to_state (tab, state); + set_view_properties_according_to_state (tab, state); - if ((state == XED_TAB_STATE_LOADING_ERROR) || /* FIXME: add other states if needed */ - (state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW)) - { - gtk_widget_hide (tab->priv->view_scrolled_window); - } - else - { - if (tab->priv->print_preview == NULL) - gtk_widget_show (tab->priv->view_scrolled_window); - } + if ((state == XED_TAB_STATE_LOADING_ERROR) || /* FIXME: add other states if needed */ + (state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW)) + { + gtk_widget_hide (GTK_WIDGET (tab->priv->frame)); + } + else + { + if (tab->priv->print_preview == NULL) + { + gtk_widget_show (GTK_WIDGET (tab->priv->frame)); + } + } - set_cursor_according_to_state (GTK_TEXT_VIEW (tab->priv->view), - state); + set_cursor_according_to_state (GTK_TEXT_VIEW (xed_view_frame_get_view (tab->priv->frame)), state); - g_object_notify (G_OBJECT (tab), "state"); + update_auto_save_timeout (tab); + + g_object_notify (G_OBJECT (tab), "state"); } -static void -document_uri_notify_handler (XedDocument *document, - GParamSpec *pspec, - XedTab *tab) +static void +document_location_notify_handler (GtkSourceFile *file, + GParamSpec *pspec, + XedTab *tab) { - xed_debug (DEBUG_TAB); - - /* Notify the change in the URI */ - g_object_notify (G_OBJECT (tab), "name"); + xed_debug (DEBUG_TAB); + + /* Notify the change in the location */ + g_object_notify (G_OBJECT (tab), "name"); } -static void +static void document_shortname_notify_handler (XedDocument *document, - GParamSpec *pspec, - XedTab *tab) + GParamSpec *pspec, + XedTab *tab) { - xed_debug (DEBUG_TAB); - - /* Notify the change in the shortname */ - g_object_notify (G_OBJECT (tab), "name"); + xed_debug (DEBUG_TAB); + + /* Notify the change in the shortname */ + g_object_notify (G_OBJECT (tab), "name"); } static void document_modified_changed (GtkTextBuffer *document, - XedTab *tab) + XedTab *tab) { - g_object_notify (G_OBJECT (tab), "name"); + g_object_notify (G_OBJECT (tab), "name"); } static void -set_message_area (XedTab *tab, - GtkWidget *message_area) +set_info_bar (XedTab *tab, + GtkWidget *info_bar) { - if (tab->priv->message_area == message_area) - return; + if (tab->priv->info_bar == info_bar) + { + return; + } - if (tab->priv->message_area != NULL) - gtk_widget_destroy (tab->priv->message_area); + if (tab->priv->info_bar != NULL) + { + gtk_widget_destroy (tab->priv->info_bar); + } - tab->priv->message_area = message_area; + tab->priv->info_bar = info_bar; - if (message_area == NULL) - return; + if (info_bar == NULL) + { + return; + } - gtk_box_pack_start (GTK_BOX (tab), - tab->priv->message_area, - FALSE, - FALSE, - 0); + gtk_box_pack_start (GTK_BOX (tab), tab->priv->info_bar, FALSE, FALSE, 0); - g_object_add_weak_pointer (G_OBJECT (tab->priv->message_area), - (gpointer *)&tab->priv->message_area); + g_object_add_weak_pointer (G_OBJECT (tab->priv->info_bar), (gpointer *)&tab->priv->info_bar); } static void remove_tab (XedTab *tab) { - XedNotebook *notebook; + XedNotebook *notebook; - notebook = XED_NOTEBOOK (gtk_widget_get_parent (GTK_WIDGET (tab))); + notebook = XED_NOTEBOOK (gtk_widget_get_parent (GTK_WIDGET (tab))); - xed_notebook_remove_tab (notebook, tab); -} - -static void -io_loading_error_message_area_response (GtkWidget *message_area, - gint response_id, - XedTab *tab) -{ - XedDocument *doc; - XedView *view; - gchar *uri; - const XedEncoding *encoding; - - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); - - view = xed_tab_get_view (tab); - g_return_if_fail (XED_IS_VIEW (view)); - - uri = xed_document_get_uri (doc); - g_return_if_fail (uri != NULL); - - switch (response_id) - { - case GTK_RESPONSE_OK: - encoding = xed_conversion_error_message_area_get_encoding ( - GTK_WIDGET (message_area)); - - if (encoding != NULL) - { - tab->priv->tmp_encoding = encoding; - } - - set_message_area (tab, NULL); - xed_tab_set_state (tab, XED_TAB_STATE_LOADING); - - g_return_if_fail (tab->priv->auto_save_timeout <= 0); - - xed_document_load (doc, - uri, - tab->priv->tmp_encoding, - tab->priv->tmp_line_pos, - FALSE); - break; - case GTK_RESPONSE_YES: - /* This means that we want to edit the document anyway */ - set_message_area (tab, NULL); - _xed_document_set_readonly (doc, FALSE); - break; - case GTK_RESPONSE_NO: - /* We don't want to edit the document just show it */ - set_message_area (tab, NULL); - break; - default: - _xed_recent_remove (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), uri); - - remove_tab (tab); - break; - } - - g_free (uri); -} - -static void -file_already_open_warning_message_area_response (GtkWidget *message_area, - gint response_id, - XedTab *tab) -{ - XedView *view; - - view = xed_tab_get_view (tab); - - if (response_id == GTK_RESPONSE_YES) - { - tab->priv->not_editable = FALSE; - - gtk_text_view_set_editable (GTK_TEXT_VIEW (view), - TRUE); - } - - gtk_widget_destroy (message_area); - - gtk_widget_grab_focus (GTK_WIDGET (view)); + xed_notebook_remove_tab (notebook, tab); } static void -load_cancelled (GtkWidget *area, - gint response_id, - XedTab *tab) +io_loading_error_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) { - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area)); - - g_object_ref (tab); - xed_document_load_cancel (xed_tab_get_document (tab)); - g_object_unref (tab); + XedView *view; + GFile *location; + const GtkSourceEncoding *encoding; + + g_return_if_fail (tab->priv->loader != NULL); + + view = xed_tab_get_view (tab); + location = gtk_source_file_loader_get_location (tab->priv->loader); + + switch (response_id) + { + case GTK_RESPONSE_OK: + encoding = xed_conversion_error_info_bar_get_encoding (GTK_WIDGET (info_bar)); + + set_info_bar (tab, NULL); + xed_tab_set_state (tab, XED_TAB_STATE_LOADING); + + load (tab, encoding, tab->priv->tmp_line_pos); + break; + + case GTK_RESPONSE_YES: + /* This means that we want to edit the document anyway */ + tab->priv->editable = TRUE; + gtk_text_view_set_editable (GTK_TEXT_VIEW (view), TRUE); + set_info_bar (tab, NULL); + clear_loading (tab); + break; + + default: + _xed_recent_remove (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), location); + + remove_tab (tab); + break; + } } -static void -unrecoverable_reverting_error_message_area_response (GtkWidget *message_area, - gint response_id, - XedTab *tab) +static void +file_already_open_warning_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) { - XedView *view; - - xed_tab_set_state (tab, - XED_TAB_STATE_NORMAL); + XedView *view; - set_message_area (tab, NULL); + view = xed_tab_get_view (tab); - view = xed_tab_get_view (tab); + if (response_id == GTK_RESPONSE_YES) + { + tab->priv->editable = TRUE; + gtk_text_view_set_editable (GTK_TEXT_VIEW (view), TRUE); + } - gtk_widget_grab_focus (GTK_WIDGET (view)); - - install_auto_save_timeout_if_needed (tab); + gtk_widget_destroy (info_bar); + + gtk_widget_grab_focus (GTK_WIDGET (view)); +} + +static void +load_cancelled (GtkWidget *area, + gint response_id, + XedTab *tab) +{ + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (tab->priv->info_bar)); + g_return_if_fail (G_IS_CANCELLABLE (tab->priv->cancellable)); + + g_cancellable_cancel (tab->priv->cancellable); +} + +static void +unrecoverable_reverting_error_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) +{ + XedView *view; + + xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + + set_info_bar (tab, NULL); + + clear_loading (tab); + + view = xed_tab_get_view (tab); + gtk_widget_grab_focus (GTK_WIDGET (view)); } #define MAX_MSG_LENGTH 100 static void -show_loading_message_area (XedTab *tab) +show_loading_info_bar (XedTab *tab) { - GtkWidget *area; - XedDocument *doc = NULL; - gchar *name; - gchar *dirname = NULL; - gchar *msg = NULL; - gchar *name_markup; - gchar *dirname_markup; - gint len; + GtkWidget *bar; + XedDocument *doc = NULL; + gchar *name; + gchar *dirname = NULL; + gchar *msg = NULL; + gchar *name_markup; + gchar *dirname_markup; + gint len; - if (tab->priv->message_area != NULL) - return; + if (tab->priv->info_bar != NULL) + { + return; + } - xed_debug (DEBUG_TAB); - - doc = xed_tab_get_document (tab); - g_return_if_fail (doc != NULL); + xed_debug (DEBUG_TAB); - name = xed_document_get_short_name_for_display (doc); - len = g_utf8_strlen (name, -1); + doc = xed_tab_get_document (tab); + g_return_if_fail (doc != NULL); - /* if the name is awfully long, truncate it and be done with it, - * otherwise also show the directory (ellipsized if needed) - */ - if (len > MAX_MSG_LENGTH) - { - gchar *str; + name = xed_document_get_short_name_for_display (doc); + len = g_utf8_strlen (name, -1); - str = xed_utils_str_middle_truncate (name, MAX_MSG_LENGTH); - g_free (name); - name = str; - } - else - { - GFile *file; + /* if the name is awfully long, truncate it and be done with it, + * otherwise also show the directory (ellipsized if needed) + */ + if (len > MAX_MSG_LENGTH) + { + gchar *str; - file = xed_document_get_location (doc); - if (file != NULL) - { - gchar *str; + str = xed_utils_str_middle_truncate (name, MAX_MSG_LENGTH); + g_free (name); + name = str; + } + else + { + GtkSourceFile *file = xed_document_get_file (doc); + GFile *location = gtk_source_file_get_location (file); - str = xed_utils_location_get_dirname_for_display (file); - g_object_unref (file); + if (location != NULL) + { + gchar *str = xed_utils_location_get_dirname_for_display (location); - /* use the remaining space for the dir, but use a min of 20 chars - * so that we do not end up with a dirname like "(a...b)". - * This means that in the worst case when the filename is long 99 - * we have a title long 99 + 20, but I think it's a rare enough - * case to be acceptable. It's justa darn title afterall :) - */ - dirname = xed_utils_str_middle_truncate (str, - MAX (20, MAX_MSG_LENGTH - len)); - g_free (str); - } - } + /* use the remaining space for the dir, but use a min of 20 chars + * so that we do not end up with a dirname like "(a...b)". + * This means that in the worst case when the filename is long 99 + * we have a title long 99 + 20, but I think it's a rare enough + * case to be acceptable. It's justa darn title afterall :) + */ + dirname = xed_utils_str_middle_truncate (str, MAX (20, MAX_MSG_LENGTH - len)); + g_free (str); + } + } - name_markup = g_markup_printf_escaped ("%s", name); + name_markup = g_markup_printf_escaped ("%s", name); - if (tab->priv->state == XED_TAB_STATE_REVERTING) - { - if (dirname != NULL) - { - dirname_markup = g_markup_printf_escaped ("%s", dirname); + if (tab->priv->state == XED_TAB_STATE_REVERTING) + { + if (dirname != NULL) + { + dirname_markup = g_markup_printf_escaped ("%s", dirname); - /* Translators: the first %s is a file name (e.g. test.txt) the second one - is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */ - msg = g_strdup_printf (_("Reverting %s from %s"), - name_markup, - dirname_markup); - g_free (dirname_markup); - } - else - { - msg = g_strdup_printf (_("Reverting %s"), - name_markup); - } - - area = xed_progress_message_area_new (GTK_STOCK_REVERT_TO_SAVED, - msg, - TRUE); - } - else - { - if (dirname != NULL) - { - dirname_markup = g_markup_printf_escaped ("%s", dirname); + /* Translators: the first %s is a file name (e.g. test.txt) the second one + is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */ + msg = g_strdup_printf (_("Reverting %s from %s"), name_markup, dirname_markup); + g_free (dirname_markup); + } + else + { + msg = g_strdup_printf (_("Reverting %s"), name_markup); + } - /* Translators: the first %s is a file name (e.g. test.txt) the second one - is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */ - msg = g_strdup_printf (_("Loading %s from %s"), - name_markup, - dirname_markup); - g_free (dirname_markup); - } - else - { - msg = g_strdup_printf (_("Loading %s"), - name_markup); - } + bar = xed_progress_info_bar_new ("document-revert-symbolic", msg, TRUE); + } + else + { + if (dirname != NULL) + { + dirname_markup = g_markup_printf_escaped ("%s", dirname); - area = xed_progress_message_area_new (GTK_STOCK_OPEN, - msg, - TRUE); - } + /* Translators: the first %s is a file name (e.g. test.txt) the second one + is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */ + msg = g_strdup_printf (_("Loading %s from %s"), name_markup, dirname_markup); + g_free (dirname_markup); + } + else + { + msg = g_strdup_printf (_("Loading %s"), name_markup); + } - g_signal_connect (area, - "response", - G_CALLBACK (load_cancelled), - tab); - - gtk_widget_show (area); + bar = xed_progress_info_bar_new ("document-open-symbolic", msg, TRUE); + } - set_message_area (tab, area); + g_signal_connect (bar, "response", + G_CALLBACK (load_cancelled), tab); - g_free (msg); - g_free (name); - g_free (name_markup); - g_free (dirname); + gtk_widget_show (bar); + + set_info_bar (tab, bar); + + g_free (msg); + g_free (name); + g_free (name_markup); + g_free (dirname); } static void -show_saving_message_area (XedTab *tab) +show_saving_info_bar (XedTab *tab) { - GtkWidget *area; - XedDocument *doc = NULL; - gchar *short_name; - gchar *from; - gchar *to = NULL; - gchar *from_markup; - gchar *to_markup; - gchar *msg = NULL; - gint len; + GtkWidget *bar; + XedDocument *doc = NULL; + gchar *short_name; + gchar *from; + gchar *to = NULL; + gchar *from_markup; + gchar *to_markup; + gchar *msg = NULL; + gint len; - g_return_if_fail (tab->priv->tmp_save_uri != NULL); - - if (tab->priv->message_area != NULL) - return; - - xed_debug (DEBUG_TAB); - - doc = xed_tab_get_document (tab); - g_return_if_fail (doc != NULL); + g_return_if_fail (tab->priv->task_saver != NULL); - short_name = xed_document_get_short_name_for_display (doc); + if (tab->priv->info_bar != NULL) + { + return; + } - len = g_utf8_strlen (short_name, -1); + xed_debug (DEBUG_TAB); - /* if the name is awfully long, truncate it and be done with it, - * otherwise also show the directory (ellipsized if needed) - */ - if (len > MAX_MSG_LENGTH) - { - from = xed_utils_str_middle_truncate (short_name, - MAX_MSG_LENGTH); - g_free (short_name); - } - else - { - gchar *str; + doc = xed_tab_get_document (tab); + g_return_if_fail (doc != NULL); - from = short_name; + short_name = xed_document_get_short_name_for_display (doc); - to = xed_utils_uri_for_display (tab->priv->tmp_save_uri); + len = g_utf8_strlen (short_name, -1); - str = xed_utils_str_middle_truncate (to, - MAX (20, MAX_MSG_LENGTH - len)); - g_free (to); - - to = str; - } + /* if the name is awfully long, truncate it and be done with it, + * otherwise also show the directory (ellipsized if needed) + */ + if (len > MAX_MSG_LENGTH) + { + from = xed_utils_str_middle_truncate (short_name, MAX_MSG_LENGTH); + g_free (short_name); + } + else + { + gchar *str; + SaverData *data; + GFile *location; - from_markup = g_markup_printf_escaped ("%s", from); + data = g_task_get_task_data (tab->priv->task_saver); + location = gtk_source_file_saver_get_location (data->saver); - if (to != NULL) - { - to_markup = g_markup_printf_escaped ("%s", to); + from = short_name; + to = g_file_get_parse_name (location); + str = xed_utils_str_middle_truncate (to, MAX (20, MAX_MSG_LENGTH - len)); + g_free (to); - /* Translators: the first %s is a file name (e.g. test.txt) the second one - is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */ - msg = g_strdup_printf (_("Saving %s to %s"), - from_markup, - to_markup); - g_free (to_markup); - } - else - { - msg = g_strdup_printf (_("Saving %s"), from_markup); - } + to = str; + } - area = xed_progress_message_area_new (GTK_STOCK_SAVE, - msg, - FALSE); + from_markup = g_markup_printf_escaped ("%s", from); - gtk_widget_show (area); + if (to != NULL) + { + to_markup = g_markup_printf_escaped ("%s", to); - set_message_area (tab, area); + /* Translators: the first %s is a file name (e.g. test.txt) the second one + is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */ + msg = g_strdup_printf (_("Saving %s to %s"), from_markup, to_markup); + g_free (to_markup); + } + else + { + msg = g_strdup_printf (_("Saving %s"), from_markup); + } - g_free (msg); - g_free (to); - g_free (from); - g_free (from_markup); + bar = xed_progress_info_bar_new ("document-save-symbolic", msg, FALSE); + + gtk_widget_show (bar); + + set_info_bar (tab, bar); + + g_free (msg); + g_free (to); + g_free (from); + g_free (from_markup); } static void -message_area_set_progress (XedTab *tab, - goffset size, - goffset total_size) +info_bar_set_progress (XedTab *tab, + goffset size, + goffset total_size) { - if (tab->priv->message_area == NULL) - return; + if (tab->priv->info_bar == NULL) + { + return; + } - xed_debug_message (DEBUG_TAB, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size); + xed_debug_message (DEBUG_TAB, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size); - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area)); - - if (total_size == 0) - { - if (size != 0) - xed_progress_message_area_pulse ( - XED_PROGRESS_MESSAGE_AREA (tab->priv->message_area)); - else - xed_progress_message_area_set_fraction ( - XED_PROGRESS_MESSAGE_AREA (tab->priv->message_area), - 0); - } - else - { - gdouble frac; + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (tab->priv->info_bar)); - frac = (gdouble)size / (gdouble)total_size; + if (total_size == 0) + { + if (size != 0) + xed_progress_info_bar_pulse (XED_PROGRESS_INFO_BAR (tab->priv->info_bar)); + else + xed_progress_info_bar_set_fraction (XED_PROGRESS_INFO_BAR (tab->priv->info_bar), 0); + } + else + { + gdouble frac; - xed_progress_message_area_set_fraction ( - XED_PROGRESS_MESSAGE_AREA (tab->priv->message_area), - frac); - } -} + frac = (gdouble)size / (gdouble)total_size; -static void -document_loading (XedDocument *document, - goffset size, - goffset total_size, - XedTab *tab) -{ - gdouble et; - gdouble total_time; - - g_return_if_fail ((tab->priv->state == XED_TAB_STATE_LOADING) || - (tab->priv->state == XED_TAB_STATE_REVERTING)); - - xed_debug_message (DEBUG_TAB, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size); - - if (tab->priv->timer == NULL) - { - g_return_if_fail (tab->priv->times_called == 0); - tab->priv->timer = g_timer_new (); - } - - et = g_timer_elapsed (tab->priv->timer, NULL); - - /* et : total_time = size : total_size */ - total_time = (et * total_size) / size; - - if ((total_time - et) > 3.0) - { - show_loading_message_area (tab); - } - - message_area_set_progress (tab, size, total_size); + xed_progress_info_bar_set_fraction (XED_PROGRESS_INFO_BAR (tab->priv->info_bar), frac); + } } static gboolean -remove_tab_idle (XedTab *tab) +scroll_to_cursor (XedTab *tab) { - remove_tab (tab); + XedView *view; - return FALSE; + view = xed_tab_get_view (tab); + xed_view_scroll_to_cursor (view); + + tab->priv->idle_scroll = 0; + return G_SOURCE_REMOVE; } static void -document_loaded (XedDocument *document, - const GError *error, - XedTab *tab) +unrecoverable_saving_error_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) { - GtkWidget *emsg; - GFile *location; - gchar *uri; - const XedEncoding *encoding; + XedView *view; - g_return_if_fail ((tab->priv->state == XED_TAB_STATE_LOADING) || - (tab->priv->state == XED_TAB_STATE_REVERTING)); - g_return_if_fail (tab->priv->auto_save_timeout <= 0); + if (tab->priv->print_preview != NULL) + { + xed_tab_set_state (tab, XED_TAB_STATE_SHOWING_PRINT_PREVIEW); + } + else + { + xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + } - if (tab->priv->timer != NULL) - { - g_timer_destroy (tab->priv->timer); - tab->priv->timer = NULL; - } - tab->priv->times_called = 0; + set_info_bar (tab, NULL); - set_message_area (tab, NULL); + g_return_if_fail (tab->priv->task_saver != NULL); + g_task_return_boolean (tab->priv->task_saver, FALSE); - location = xed_document_get_location (document); - uri = xed_document_get_uri (document); + view = xed_tab_get_view (tab); - /* if the error is CONVERSION FALLBACK don't treat it as a normal error */ - if (error != NULL && - (error->domain != XED_DOCUMENT_ERROR || error->code != XED_DOCUMENT_ERROR_CONVERSION_FALLBACK)) - { - if (tab->priv->state == XED_TAB_STATE_LOADING) - xed_tab_set_state (tab, XED_TAB_STATE_LOADING_ERROR); - else - xed_tab_set_state (tab, XED_TAB_STATE_REVERTING_ERROR); + gtk_widget_grab_focus (GTK_WIDGET (view)); +} - encoding = xed_document_get_encoding (document); +/* Sets the save flags after an info bar response. */ +static void +response_set_save_flags (XedTab *tab, + GtkSourceFileSaverFlags save_flags) +{ + SaverData *data; + gboolean create_backup; - if (error->domain == G_IO_ERROR && - error->code == G_IO_ERROR_CANCELLED) - { - /* remove the tab, but in an idle handler, since - * we are in the handler of doc loaded and we - * don't want doc and tab to be finalized now. - */ - g_idle_add ((GSourceFunc) remove_tab_idle, tab); + data = g_task_get_task_data (tab->priv->task_saver); - goto end; - } - else - { - _xed_recent_remove (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), uri); + create_backup = g_settings_get_boolean (tab->priv->editor, XED_SETTINGS_CREATE_BACKUP_COPY); - if (tab->priv->state == XED_TAB_STATE_LOADING_ERROR) - { - emsg = xed_io_loading_error_message_area_new (uri, - tab->priv->tmp_encoding, - error); - g_signal_connect (emsg, - "response", - G_CALLBACK (io_loading_error_message_area_response), - tab); - } - else - { - g_return_if_fail (tab->priv->state == XED_TAB_STATE_REVERTING_ERROR); - - emsg = xed_unrecoverable_reverting_error_message_area_new (uri, - error); + /* If we are here, it means that the user expressed his or her willing + * to save the file, by pressing a button in the info bar. So even if + * the file saving was initially an auto-save, we set the create_backup + * flag (if the conditions are met). + */ + if (create_backup && !data->force_no_backup) + { + save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_CREATE_BACKUP; + } + else + { + save_flags &= ~GTK_SOURCE_FILE_SAVER_FLAGS_CREATE_BACKUP; + } - g_signal_connect (emsg, - "response", - G_CALLBACK (unrecoverable_reverting_error_message_area_response), - tab); - } - - set_message_area (tab, emsg); - } - - gtk_info_bar_set_default_response (GTK_INFO_BAR (emsg), - GTK_RESPONSE_CANCEL); - - gtk_widget_show (emsg); - - g_object_unref (location); - g_free (uri); - - return; - } - else - { - gchar *mime; - GList *all_documents; - GList *l; - - g_return_if_fail (uri != NULL); - - mime = xed_document_get_mime_type (document); - _xed_recent_add (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), - uri, - mime); - g_free (mime); - - if (error && - error->domain == XED_DOCUMENT_ERROR && - error->code == XED_DOCUMENT_ERROR_CONVERSION_FALLBACK) - { - GtkWidget *emsg; - - _xed_document_set_readonly (document, TRUE); - - emsg = xed_io_loading_error_message_area_new (uri, - tab->priv->tmp_encoding, - error); - - set_message_area (tab, emsg); - - g_signal_connect (emsg, - "response", - G_CALLBACK (io_loading_error_message_area_response), - tab); - - gtk_info_bar_set_default_response (GTK_INFO_BAR (emsg), - GTK_RESPONSE_CANCEL); - - gtk_widget_show (emsg); - } - - /* Scroll to the cursor when the document is loaded */ - xed_view_scroll_to_cursor (XED_VIEW (tab->priv->view)); - - all_documents = xed_app_get_documents (xed_app_get_default ()); - - for (l = all_documents; l != NULL; l = g_list_next (l)) - { - XedDocument *d = XED_DOCUMENT (l->data); - - if (d != document) - { - GFile *loc; - - loc = xed_document_get_location (d); - - if ((loc != NULL) && - g_file_equal (location, loc)) - { - GtkWidget *w; - XedView *view; - - view = xed_tab_get_view (tab); - - tab->priv->not_editable = TRUE; - - w = xed_file_already_open_warning_message_area_new (uri); - - set_message_area (tab, w); - - gtk_info_bar_set_default_response (GTK_INFO_BAR (w), - GTK_RESPONSE_CANCEL); - - gtk_widget_show (w); - - g_signal_connect (w, - "response", - G_CALLBACK (file_already_open_warning_message_area_response), - tab); - - g_object_unref (loc); - break; - } - - if (loc != NULL) - g_object_unref (loc); - } - } - - g_list_free (all_documents); - - xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); - - install_auto_save_timeout_if_needed (tab); - - tab->priv->ask_if_externally_modified = TRUE; - } - - end: - g_object_unref (location); - g_free (uri); - - tab->priv->tmp_line_pos = 0; - tab->priv->tmp_encoding = NULL; + gtk_source_file_saver_set_flags (data->saver, save_flags); } static void -document_saving (XedDocument *document, - goffset size, - goffset total_size, - XedTab *tab) +invalid_character_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) { - gdouble et; - gdouble total_time; + if (response_id == GTK_RESPONSE_YES) + { + SaverData *data; + GtkSourceFileSaverFlags save_flags; - g_return_if_fail (tab->priv->state == XED_TAB_STATE_SAVING); + set_info_bar (tab, NULL); - xed_debug_message (DEBUG_TAB, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size); + g_return_if_fail (tab->priv->task_saver != NULL); + data = g_task_get_task_data (tab->priv->task_saver); + /* Don't bug the user again with this... */ + tab->priv->save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS; - if (tab->priv->timer == NULL) - { - g_return_if_fail (tab->priv->times_called == 0); - tab->priv->timer = g_timer_new (); - } + save_flags = gtk_source_file_saver_get_flags (data->saver); + save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS; + response_set_save_flags (tab, save_flags); - et = g_timer_elapsed (tab->priv->timer, NULL); - - /* et : total_time = size : total_size */ - total_time = (et * total_size)/size; - - if ((total_time - et) > 3.0) - { - show_saving_message_area (tab); - } - - message_area_set_progress (tab, size, total_size); - - tab->priv->times_called++; + /* Force saving */ + save (tab); + } + else + { + unrecoverable_saving_error_info_bar_response (info_bar, response_id, tab); + } } static void -end_saving (XedTab *tab) +no_backup_error_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) { - /* Reset tmp data for saving */ - g_free (tab->priv->tmp_save_uri); - tab->priv->tmp_save_uri = NULL; - tab->priv->tmp_encoding = NULL; - - install_auto_save_timeout_if_needed (tab); -} + if (response_id == GTK_RESPONSE_YES) + { + SaverData *data; + GtkSourceFileSaverFlags save_flags; -static void -unrecoverable_saving_error_message_area_response (GtkWidget *message_area, - gint response_id, - XedTab *tab) -{ - XedView *view; - - if (tab->priv->print_preview != NULL) - xed_tab_set_state (tab, XED_TAB_STATE_SHOWING_PRINT_PREVIEW); - else - xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + set_info_bar (tab, NULL); - end_saving (tab); - - set_message_area (tab, NULL); + g_return_if_fail (tab->priv->task_saver != NULL); + data = g_task_get_task_data (tab->priv->task_saver); - view = xed_tab_get_view (tab); + data->force_no_backup = TRUE; + save_flags = gtk_source_file_saver_get_flags (data->saver); + response_set_save_flags (tab, save_flags); - gtk_widget_grab_focus (GTK_WIDGET (view)); -} - -static void -no_backup_error_message_area_response (GtkWidget *message_area, - gint response_id, - XedTab *tab) -{ - if (response_id == GTK_RESPONSE_YES) - { - XedDocument *doc; - - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); - - set_message_area (tab, NULL); - - g_return_if_fail (tab->priv->tmp_save_uri != NULL); - g_return_if_fail (tab->priv->tmp_encoding != NULL); - - xed_tab_set_state (tab, XED_TAB_STATE_SAVING); - - /* don't bug the user again with this... */ - tab->priv->save_flags |= XED_DOCUMENT_SAVE_IGNORE_BACKUP; - - g_return_if_fail (tab->priv->auto_save_timeout <= 0); - - /* Force saving */ - xed_document_save (doc, tab->priv->save_flags); - } - else - { - unrecoverable_saving_error_message_area_response (message_area, - response_id, - tab); - } + /* Force saving */ + save (tab); + } + else + { + unrecoverable_saving_error_info_bar_response (info_bar, response_id, tab); + } } static void -externally_modified_error_message_area_response (GtkWidget *message_area, - gint response_id, - XedTab *tab) +externally_modified_error_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) { - if (response_id == GTK_RESPONSE_YES) - { - XedDocument *doc; + if (response_id == GTK_RESPONSE_YES) + { + SaverData *data; + GtkSourceFileSaverFlags save_flags; - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); - - set_message_area (tab, NULL); + set_info_bar (tab, NULL); - g_return_if_fail (tab->priv->tmp_save_uri != NULL); - g_return_if_fail (tab->priv->tmp_encoding != NULL); + g_return_if_fail (tab->priv->task_saver != NULL); + data = g_task_get_task_data (tab->priv->task_saver); - xed_tab_set_state (tab, XED_TAB_STATE_SAVING); + /* ignore_modification_time should not be persisted in save + * flags across saves (i.e. priv->save_flags is not modified). + */ - g_return_if_fail (tab->priv->auto_save_timeout <= 0); - - /* ignore mtime should not be persisted in save flags across saves */ + save_flags = gtk_source_file_saver_get_flags (data->saver); + save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME; + response_set_save_flags (tab, save_flags); - /* Force saving */ - xed_document_save (doc, tab->priv->save_flags | XED_DOCUMENT_SAVE_IGNORE_MTIME); - } - else - { - unrecoverable_saving_error_message_area_response (message_area, - response_id, - tab); - } -} - -static void -recoverable_saving_error_message_area_response (GtkWidget *message_area, - gint response_id, - XedTab *tab) -{ - XedDocument *doc; - - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); - - if (response_id == GTK_RESPONSE_OK) - { - const XedEncoding *encoding; - - encoding = xed_conversion_error_message_area_get_encoding ( - GTK_WIDGET (message_area)); - - g_return_if_fail (encoding != NULL); - - set_message_area (tab, NULL); - - g_return_if_fail (tab->priv->tmp_save_uri != NULL); - - xed_tab_set_state (tab, XED_TAB_STATE_SAVING); - - tab->priv->tmp_encoding = encoding; - - xed_debug_message (DEBUG_TAB, "Force saving with URI '%s'", tab->priv->tmp_save_uri); - - g_return_if_fail (tab->priv->auto_save_timeout <= 0); - - xed_document_save_as (doc, - tab->priv->tmp_save_uri, - tab->priv->tmp_encoding, - tab->priv->save_flags); - } - else - { - unrecoverable_saving_error_message_area_response (message_area, - response_id, - tab); - } + /* Force saving */ + save (tab); + } + else + { + unrecoverable_saving_error_info_bar_response (info_bar, response_id, tab); + } } static void -document_saved (XedDocument *document, - const GError *error, - XedTab *tab) +recoverable_saving_error_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) { - GtkWidget *emsg; + if (response_id == GTK_RESPONSE_OK) + { + SaverData *data; + const GtkSourceEncoding *encoding; - g_return_if_fail (tab->priv->state == XED_TAB_STATE_SAVING); + set_info_bar (tab, NULL); - g_return_if_fail (tab->priv->tmp_save_uri != NULL); - g_return_if_fail (tab->priv->tmp_encoding != NULL); - g_return_if_fail (tab->priv->auto_save_timeout <= 0); - - g_timer_destroy (tab->priv->timer); - tab->priv->timer = NULL; - tab->priv->times_called = 0; - - set_message_area (tab, NULL); - - if (error != NULL) - { - xed_tab_set_state (tab, XED_TAB_STATE_SAVING_ERROR); - - if (error->domain == XED_DOCUMENT_ERROR && - error->code == XED_DOCUMENT_ERROR_EXTERNALLY_MODIFIED) - { - /* This error is recoverable */ - emsg = xed_externally_modified_saving_error_message_area_new ( - tab->priv->tmp_save_uri, - error); - g_return_if_fail (emsg != NULL); + g_return_if_fail (tab->priv->task_saver != NULL); + data = g_task_get_task_data (tab->priv->task_saver); - set_message_area (tab, emsg); + encoding = xed_conversion_error_info_bar_get_encoding (GTK_WIDGET (info_bar)); + g_return_if_fail (encoding != NULL); - g_signal_connect (emsg, - "response", - G_CALLBACK (externally_modified_error_message_area_response), - tab); - } - else if ((error->domain == XED_DOCUMENT_ERROR && - error->code == XED_DOCUMENT_ERROR_CANT_CREATE_BACKUP) || - (error->domain == G_IO_ERROR && - error->code == G_IO_ERROR_CANT_CREATE_BACKUP)) - { - /* This error is recoverable */ - emsg = xed_no_backup_saving_error_message_area_new ( - tab->priv->tmp_save_uri, - error); - g_return_if_fail (emsg != NULL); - - set_message_area (tab, emsg); - - g_signal_connect (emsg, - "response", - G_CALLBACK (no_backup_error_message_area_response), - tab); - } - else if (error->domain == XED_DOCUMENT_ERROR || - (error->domain == G_IO_ERROR && - error->code != G_IO_ERROR_INVALID_DATA && - error->code != G_IO_ERROR_PARTIAL_INPUT)) - { - /* These errors are _NOT_ recoverable */ - _xed_recent_remove (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), - tab->priv->tmp_save_uri); - - emsg = xed_unrecoverable_saving_error_message_area_new (tab->priv->tmp_save_uri, - error); - g_return_if_fail (emsg != NULL); - - set_message_area (tab, emsg); - - g_signal_connect (emsg, - "response", - G_CALLBACK (unrecoverable_saving_error_message_area_response), - tab); - } - else - { - /* This error is recoverable */ - g_return_if_fail (error->domain == G_CONVERT_ERROR || - error->domain == G_IO_ERROR); - - emsg = xed_conversion_error_while_saving_message_area_new ( - tab->priv->tmp_save_uri, - tab->priv->tmp_encoding, - error); - - set_message_area (tab, emsg); - - g_signal_connect (emsg, - "response", - G_CALLBACK (recoverable_saving_error_message_area_response), - tab); - } - - gtk_info_bar_set_default_response (GTK_INFO_BAR (emsg), - GTK_RESPONSE_CANCEL); - - gtk_widget_show (emsg); - } - else - { - gchar *mime = xed_document_get_mime_type (document); - - _xed_recent_add (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), - tab->priv->tmp_save_uri, - mime); - g_free (mime); - - if (tab->priv->print_preview != NULL) - xed_tab_set_state (tab, XED_TAB_STATE_SHOWING_PRINT_PREVIEW); - else - xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); - - tab->priv->ask_if_externally_modified = TRUE; - - end_saving (tab); - } + gtk_source_file_saver_set_encoding (data->saver, encoding); + save (tab); + } + else + { + unrecoverable_saving_error_info_bar_response (info_bar, response_id, tab); + } } -static void -externally_modified_notification_message_area_response (GtkWidget *message_area, - gint response_id, - XedTab *tab) +static void +externally_modified_notification_info_bar_response (GtkWidget *info_bar, + gint response_id, + XedTab *tab) { - XedView *view; + XedView *view; - set_message_area (tab, NULL); - view = xed_tab_get_view (tab); + set_info_bar (tab, NULL); + view = xed_tab_get_view (tab); - if (response_id == GTK_RESPONSE_OK) - { - _xed_tab_revert (tab); - } - else - { - tab->priv->ask_if_externally_modified = FALSE; + if (response_id == GTK_RESPONSE_OK) + { + _xed_tab_revert (tab); + } + else + { + tab->priv->ask_if_externally_modified = FALSE; - /* go back to normal state */ - xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); - } + /* go back to normal state */ + xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + } - gtk_widget_grab_focus (GTK_WIDGET (view)); + gtk_widget_grab_focus (GTK_WIDGET (view)); } static void display_externally_modified_notification (XedTab *tab) { - GtkWidget *message_area; - XedDocument *doc; - gchar *uri; - gboolean document_modified; + GtkWidget *info_bar; + XedDocument *doc; + GtkSourceFile *file; + GFile *location; + gboolean document_modified; - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); + doc = xed_tab_get_document (tab); + g_return_if_fail (XED_IS_DOCUMENT (doc)); + file = xed_document_get_file (doc); - /* uri cannot be NULL, we're here because - * the file we're editing changed on disk */ - uri = xed_document_get_uri (doc); - g_return_if_fail (uri != NULL); + /* we're here because the file we're editing changed on disk */ + location = gtk_source_file_get_location (file); + g_return_if_fail (location != NULL); - document_modified = gtk_text_buffer_get_modified (GTK_TEXT_BUFFER(doc)); - message_area = xed_externally_modified_message_area_new (uri, document_modified); - g_free (uri); + document_modified = gtk_text_buffer_get_modified (GTK_TEXT_BUFFER(doc)); + info_bar = xed_externally_modified_info_bar_new (location, document_modified); - tab->priv->message_area = NULL; - set_message_area (tab, message_area); - gtk_widget_show (message_area); + tab->priv->info_bar = NULL; + set_info_bar (tab, info_bar); + gtk_widget_show (info_bar); - g_signal_connect (message_area, - "response", - G_CALLBACK (externally_modified_notification_message_area_response), - tab); + g_signal_connect (info_bar, "response", + G_CALLBACK (externally_modified_notification_info_bar_response), tab); } static gboolean view_focused_in (GtkWidget *widget, GdkEventFocus *event, - XedTab *tab) + XedTab *tab) { - XedDocument *doc; + XedDocument *doc; - g_return_val_if_fail (XED_IS_TAB (tab), FALSE); + g_return_val_if_fail (XED_IS_TAB (tab), FALSE); - /* we try to detect file changes only in the normal state */ - if (tab->priv->state != XED_TAB_STATE_NORMAL) - { - return FALSE; - } + /* we try to detect file changes only in the normal state */ + if (tab->priv->state != XED_TAB_STATE_NORMAL) + { + return FALSE; + } - /* we already asked, don't bug the user again */ - if (!tab->priv->ask_if_externally_modified) - { - return FALSE; - } + /* we already asked, don't bug the user again */ + if (!tab->priv->ask_if_externally_modified) + { + return FALSE; + } - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); - /* If file was never saved or is remote we do not check */ - if (!xed_document_is_local (doc)) - { - return FALSE; - } + /* If file was never saved or is remote we do not check */ + if (!xed_document_is_local (doc)) + { + return FALSE; + } - if (_xed_document_check_externally_modified (doc)) - { - xed_tab_set_state (tab, XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION); + if (_xed_document_check_externally_modified (doc)) + { + xed_tab_set_state (tab, XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION); - display_externally_modified_notification (tab); + display_externally_modified_notification (tab); - return FALSE; - } + return FALSE; + } - return FALSE; -} - -static GMountOperation * -tab_mount_operation_factory (XedDocument *doc, - gpointer userdata) -{ - XedTab *tab = XED_TAB (userdata); - GtkWidget *window; - - window = gtk_widget_get_toplevel (GTK_WIDGET (tab)); - return gtk_mount_operation_new (GTK_WINDOW (window)); + return FALSE; } static void xed_tab_init (XedTab *tab) { - GtkWidget *sw; - XedDocument *doc; + gboolean auto_save; + guint auto_save_interval; + XedDocument *doc; + XedView *view; + GtkSourceFile *file; - tab->priv = XED_TAB_GET_PRIVATE (tab); + tab->priv = XED_TAB_GET_PRIVATE (tab); - tab->priv->state = XED_TAB_STATE_NORMAL; + tab->priv->editor = g_settings_new ("org.x.editor.preferences.editor"); + tab->priv->state = XED_TAB_STATE_NORMAL; + tab->priv->editable = TRUE; + tab->priv->ask_if_externally_modified = TRUE; - tab->priv->not_editable = FALSE; + gtk_orientable_set_orientation (GTK_ORIENTABLE (tab), GTK_ORIENTATION_VERTICAL); - tab->priv->save_flags = 0; + /* Manage auto save data */ + auto_save = g_settings_get_boolean (tab->priv->editor, XED_SETTINGS_AUTO_SAVE); + auto_save_interval = g_settings_get_uint (tab->priv->editor, XED_SETTINGS_AUTO_SAVE_INTERVAL); + tab->priv->auto_save = auto_save; + tab->priv->auto_save = (tab->priv->auto_save != FALSE); - tab->priv->ask_if_externally_modified = TRUE; + tab->priv->auto_save_interval = auto_save_interval; - gtk_orientable_set_orientation (GTK_ORIENTABLE (tab), - GTK_ORIENTATION_VERTICAL); - - /* Create the scrolled window */ - sw = gtk_scrolled_window_new (NULL, NULL); - tab->priv->view_scrolled_window = sw; + /* Create the frame */ + tab->priv->frame = xed_view_frame_new (); + gtk_widget_show (GTK_WIDGET (tab->priv->frame)); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); + gtk_box_pack_end (GTK_BOX (tab), GTK_WIDGET (tab->priv->frame), TRUE, TRUE, 0); - /* Manage auto save data */ - tab->priv->auto_save = xed_prefs_manager_get_auto_save (); - tab->priv->auto_save = (tab->priv->auto_save != FALSE); + doc = xed_view_frame_get_document (tab->priv->frame); + g_object_set_data (G_OBJECT (doc), XED_TAB_KEY, tab); - tab->priv->auto_save_interval = xed_prefs_manager_get_auto_save_interval (); - if (tab->priv->auto_save_interval <= 0) - tab->priv->auto_save_interval = GPM_DEFAULT_AUTO_SAVE_INTERVAL; + view = xed_view_frame_get_view (tab->priv->frame); + g_object_set_data (G_OBJECT (view), XED_TAB_KEY, tab); - /* Create the view */ - doc = xed_document_new (); - g_object_set_data (G_OBJECT (doc), XED_TAB_KEY, tab); + file = xed_document_get_file (doc); - _xed_document_set_mount_operation_factory (doc, - tab_mount_operation_factory, - tab); + g_signal_connect_object (file, "notify::location", + G_CALLBACK (document_location_notify_handler), tab, 0); + g_signal_connect (doc, "notify::shortname", + G_CALLBACK (document_shortname_notify_handler), tab); + g_signal_connect (doc, "modified_changed", + G_CALLBACK (document_modified_changed), tab); - tab->priv->view = xed_view_new (doc); - g_object_unref (doc); - gtk_widget_show (tab->priv->view); - g_object_set_data (G_OBJECT (tab->priv->view), XED_TAB_KEY, tab); - - gtk_box_pack_end (GTK_BOX (tab), sw, TRUE, TRUE, 0); - gtk_container_add (GTK_CONTAINER (sw), tab->priv->view); - gtk_widget_show (sw); - - g_signal_connect (doc, - "notify::uri", - G_CALLBACK (document_uri_notify_handler), - tab); - g_signal_connect (doc, - "notify::shortname", - G_CALLBACK (document_shortname_notify_handler), - tab); - g_signal_connect (doc, - "modified_changed", - G_CALLBACK (document_modified_changed), - tab); - g_signal_connect (doc, - "loading", - G_CALLBACK (document_loading), - tab); - g_signal_connect (doc, - "loaded", - G_CALLBACK (document_loaded), - tab); - g_signal_connect (doc, - "saving", - G_CALLBACK (document_saving), - tab); - g_signal_connect (doc, - "saved", - G_CALLBACK (document_saved), - tab); - - g_signal_connect_after (tab->priv->view, - "focus-in-event", - G_CALLBACK (view_focused_in), - tab); - - g_signal_connect_after (tab->priv->view, - "realize", - G_CALLBACK (view_realized), - tab); + g_signal_connect_after (view, "focus-in-event", + G_CALLBACK (view_focused_in), tab); + g_signal_connect_after (view, "realize", + G_CALLBACK (view_realized), tab); } GtkWidget * _xed_tab_new (void) { - return GTK_WIDGET (g_object_new (XED_TYPE_TAB, NULL)); + return GTK_WIDGET (g_object_new (XED_TYPE_TAB, NULL)); } -/* Whether create is TRUE, creates a new empty document if location does +/* Whether create is TRUE, creates a new empty document if location does not refer to an existing file */ GtkWidget * -_xed_tab_new_from_uri (const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create) +_xed_tab_new_from_location (GFile *location, + const GtkSourceEncoding *encoding, + gint line_pos, + gboolean create) { - XedTab *tab; + XedTab *tab; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (G_IS_FILE (location), NULL); - tab = XED_TAB (_xed_tab_new ()); + tab = XED_TAB (_xed_tab_new ()); - _xed_tab_load (tab, - uri, - encoding, - line_pos, - create); + _xed_tab_load (tab, location, encoding, line_pos, create); - return GTK_WIDGET (tab); -} + return GTK_WIDGET (tab); +} + +GtkWidget * +_xed_tab_new_from_stream (GInputStream *stream, + const GtkSourceEncoding *encoding, + gint line_pos) +{ + GtkWidget *tab; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL); + + tab = _xed_tab_new (); + + _xed_tab_load_stream (XED_TAB (tab), stream, encoding, line_pos); + + return tab; +} /** * xed_tab_get_view: @@ -1592,12 +1233,14 @@ _xed_tab_new_from_uri (const gchar *uri, * * Gets the #XedView inside @tab. * - * Returns: the #XedView inside @tab + * Returns: (transfer none): the #XedView inside @tab */ XedView * xed_tab_get_view (XedTab *tab) { - return XED_VIEW (tab->priv->view); + g_return_val_if_fail (XED_IS_TAB (tab), NULL); + + return xed_view_frame_get_view (tab->priv->frame); } /** @@ -1606,13 +1249,14 @@ xed_tab_get_view (XedTab *tab) * * Gets the #XedDocument associated to @tab. * - * Returns: the #XedDocument associated to @tab + * Returns: (transfer none): the #XedDocument associated to @tab */ XedDocument * xed_tab_get_document (XedTab *tab) { - return XED_DOCUMENT (gtk_text_view_get_buffer ( - GTK_TEXT_VIEW (tab->priv->view))); + g_return_val_if_fail (XED_IS_TAB (tab), NULL); + + return xed_view_frame_get_document (tab->priv->frame); } #define MAX_DOC_NAME_LENGTH 40 @@ -1620,224 +1264,186 @@ xed_tab_get_document (XedTab *tab) gchar * _xed_tab_get_name (XedTab *tab) { - XedDocument *doc; - gchar *name; - gchar *docname; - gchar *tab_name; + XedDocument *doc; + gchar *name; + gchar *docname; + gchar *tab_name; - g_return_val_if_fail (XED_IS_TAB (tab), NULL); + g_return_val_if_fail (XED_IS_TAB (tab), NULL); - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); - name = xed_document_get_short_name_for_display (doc); + name = xed_document_get_short_name_for_display (doc); - /* Truncate the name so it doesn't get insanely wide. */ - docname = xed_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH); + /* Truncate the name so it doesn't get insanely wide. */ + docname = xed_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH); - if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc))) - { - tab_name = g_strdup_printf ("*%s", docname); - } - else - { - #if 0 - if (xed_document_get_readonly (doc)) - { - tab_name = g_strdup_printf ("%s [%s]", docname, - /*Read only*/ _("RO")); - } - else - { - tab_name = g_strdup_printf ("%s", docname); - } + if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc))) + { + tab_name = g_strdup_printf ("*%s", docname); + } + else + { + #if 0 + if (xed_document_get_readonly (doc)) + { + tab_name = g_strdup_printf ("%s [%s]", docname, + /*Read only*/ _("RO")); + } + else + { + tab_name = g_strdup_printf ("%s", docname); + } #endif - tab_name = g_strdup (docname); - } - - g_free (docname); - g_free (name); + tab_name = g_strdup (docname); + } - return tab_name; + g_free (docname); + g_free (name); + + return tab_name; } gchar * -_xed_tab_get_tooltips (XedTab *tab) +_xed_tab_get_tooltips (XedTab *tab) { - XedDocument *doc; - gchar *tip; - gchar *uri; - gchar *ruri; - gchar *ruri_markup; + XedDocument *doc; + gchar *tip; + gchar *uri; + gchar *ruri; + gchar *ruri_markup; - g_return_val_if_fail (XED_IS_TAB (tab), NULL); + g_return_val_if_fail (XED_IS_TAB (tab), NULL); - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); - uri = xed_document_get_uri_for_display (doc); - g_return_val_if_fail (uri != NULL, NULL); + uri = xed_document_get_uri_for_display (doc); + g_return_val_if_fail (uri != NULL, NULL); - ruri = xed_utils_replace_home_dir_with_tilde (uri); - g_free (uri); + ruri = xed_utils_replace_home_dir_with_tilde (uri); + g_free (uri); - ruri_markup = g_markup_printf_escaped ("%s", ruri); + ruri_markup = g_markup_printf_escaped ("%s", ruri); - switch (tab->priv->state) - { - gchar *content_type; - gchar *mime_type; - gchar *content_description; - gchar *content_full_description; - gchar *encoding; - const XedEncoding *enc; + switch (tab->priv->state) + { + gchar *content_type; + gchar *mime_type; + gchar *content_description; + gchar *content_full_description; + gchar *encoding; + GtkSourceFile *file; + const GtkSourceEncoding *enc; - case XED_TAB_STATE_LOADING_ERROR: - tip = g_strdup_printf (_("Error opening file %s"), - ruri_markup); - break; + case XED_TAB_STATE_LOADING_ERROR: + tip = g_strdup_printf (_("Error opening file %s"), ruri_markup); + break; - case XED_TAB_STATE_REVERTING_ERROR: - tip = g_strdup_printf (_("Error reverting file %s"), - ruri_markup); - break; + case XED_TAB_STATE_REVERTING_ERROR: + tip = g_strdup_printf (_("Error reverting file %s"), ruri_markup); + break; - case XED_TAB_STATE_SAVING_ERROR: - tip = g_strdup_printf (_("Error saving file %s"), - ruri_markup); - break; - default: - content_type = xed_document_get_content_type (doc); - mime_type = xed_document_get_mime_type (doc); - content_description = g_content_type_get_description (content_type); + case XED_TAB_STATE_SAVING_ERROR: + tip = g_strdup_printf (_("Error saving file %s"), ruri_markup); + break; + default: + content_type = xed_document_get_content_type (doc); + mime_type = xed_document_get_mime_type (doc); + content_description = g_content_type_get_description (content_type); - if (content_description == NULL) - content_full_description = g_strdup (mime_type); - else - content_full_description = g_strdup_printf ("%s (%s)", - content_description, mime_type); + if (content_description == NULL) + { + content_full_description = g_strdup (mime_type); + } + else + { + content_full_description = g_strdup_printf ("%s (%s)", content_description, mime_type); + } - g_free (content_type); - g_free (mime_type); - g_free (content_description); + g_free (content_type); + g_free (mime_type); + g_free (content_description); - enc = xed_document_get_encoding (doc); + file = xed_document_get_file (doc); + enc = gtk_source_file_get_encoding (file); - if (enc == NULL) - encoding = g_strdup (_("Unicode (UTF-8)")); - else - encoding = xed_encoding_to_string (enc); + if (enc == NULL) + { + enc = gtk_source_encoding_get_utf8 (); + } - tip = g_markup_printf_escaped ("%s %s\n\n" - "%s %s\n" - "%s %s", - _("Name:"), ruri, - _("MIME Type:"), content_full_description, - _("Encoding:"), encoding); + encoding = gtk_source_encoding_to_string (enc); - g_free (encoding); - g_free (content_full_description); + tip = g_markup_printf_escaped ("%s %s\n\n" + "%s %s\n" + "%s %s", + _("Name:"), ruri, + _("MIME Type:"), content_full_description, + _("Encoding:"), encoding); - break; - } + g_free (encoding); + g_free (content_full_description); - g_free (ruri); - g_free (ruri_markup); - - return tip; + break; + } + + g_free (ruri); + g_free (ruri_markup); + + return tip; } static GdkPixbuf * -resize_icon (GdkPixbuf *pixbuf, - gint size) +get_icon (GtkIconTheme *theme, + GFile *location, + gint size) { - gint width, height; + GdkPixbuf *pixbuf; + GtkIconInfo *icon_info; + GFileInfo *info; + GIcon *gicon; - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); + if (location == NULL) + { + return gtk_icon_theme_load_icon (theme, "text-x-generic", size, 0, NULL); + } - /* if the icon is larger than the nominal size, scale down */ - if (MAX (width, height) > size) - { - GdkPixbuf *scaled_pixbuf; - - if (width > height) - { - height = height * size / width; - width = size; - } - else - { - width = width * size / height; - height = size; - } - - scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, - width, - height, - GDK_INTERP_BILINEAR); - g_object_unref (pixbuf); - pixbuf = scaled_pixbuf; - } + /* FIXME: Doing a sync stat is bad, this should be fixed */ + info = g_file_query_info (location, + G_FILE_ATTRIBUTE_STANDARD_ICON, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + if (info == NULL) + { + return gtk_icon_theme_load_icon (theme, "text-x-generic", size, 0, NULL); + } - return pixbuf; -} + gicon = g_file_info_get_icon (info); -static GdkPixbuf * -get_stock_icon (GtkIconTheme *theme, - const gchar *stock, - gint size) -{ - GdkPixbuf *pixbuf; - - pixbuf = gtk_icon_theme_load_icon (theme, stock, size, 0, NULL); - if (pixbuf == NULL) - return NULL; - - return resize_icon (pixbuf, size); -} + if (gicon == NULL) + { + g_object_unref (info); + return gtk_icon_theme_load_icon (theme, "text-x-generic", size, 0, NULL); + } -static GdkPixbuf * -get_icon (GtkIconTheme *theme, - GFile *location, - gint size) -{ - GdkPixbuf *pixbuf; - GtkIconInfo *icon_info; - GFileInfo *info; - GIcon *gicon; + icon_info = gtk_icon_theme_lookup_by_gicon (theme, gicon, size, 0); + g_object_unref (info); - if (location == NULL) - return get_stock_icon (theme, GTK_STOCK_FILE, size); + if (icon_info == NULL) + { + return gtk_icon_theme_load_icon (theme, "text-x-generic", size, 0, NULL); + } - /* FIXME: Doing a sync stat is bad, this should be fixed */ - info = g_file_query_info (location, - G_FILE_ATTRIBUTE_STANDARD_ICON, - G_FILE_QUERY_INFO_NONE, - NULL, - NULL); - if (info == NULL) - return get_stock_icon (theme, GTK_STOCK_FILE, size); + pixbuf = gtk_icon_info_load_icon (icon_info, NULL); + g_object_unref (icon_info); - gicon = g_file_info_get_icon (info); + if (pixbuf == NULL) + { + return gtk_icon_theme_load_icon (theme, "text-x-generic", size, 0, NULL); + } - if (gicon == NULL) - { - g_object_unref (info); - return get_stock_icon (theme, GTK_STOCK_FILE, size); - } - - icon_info = gtk_icon_theme_lookup_by_gicon (theme, gicon, size, 0); - g_object_unref (info); - - if (icon_info == NULL) - return get_stock_icon (theme, GTK_STOCK_FILE, size); - - pixbuf = gtk_icon_info_load_icon (icon_info, NULL); - gtk_icon_info_free (icon_info); - - if (pixbuf == NULL) - return get_stock_icon (theme, GTK_STOCK_FILE, size); - - return resize_icon (pixbuf, size); + return pixbuf; } /* FIXME: add support for theme changed. I think it should be as easy as @@ -1845,84 +1451,73 @@ get_icon (GtkIconTheme *theme, GdkPixbuf * _xed_tab_get_icon (XedTab *tab) { - GdkPixbuf *pixbuf; - GtkIconTheme *theme; - GdkScreen *screen; - gint icon_size; + GdkScreen *screen; + GtkIconTheme *theme; + gint icon_size; + const gchar *icon_name; + GdkPixbuf *pixbuf = NULL; - g_return_val_if_fail (XED_IS_TAB (tab), NULL); + g_return_val_if_fail (XED_IS_TAB (tab), NULL); - screen = gtk_widget_get_screen (GTK_WIDGET (tab)); + screen = gtk_widget_get_screen (GTK_WIDGET (tab)); + theme = gtk_icon_theme_get_for_screen (screen); + g_return_val_if_fail (theme != NULL, NULL); - theme = gtk_icon_theme_get_for_screen (screen); - g_return_val_if_fail (theme != NULL, NULL); + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_size); - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_size); + switch (tab->priv->state) + { + case XED_TAB_STATE_LOADING: + icon_name = "document-open-symbolic"; + break; - switch (tab->priv->state) - { - case XED_TAB_STATE_LOADING: - pixbuf = get_stock_icon (theme, - GTK_STOCK_OPEN, - icon_size); - break; + case XED_TAB_STATE_REVERTING: + icon_name = "document-revert-symbolic"; + break; - case XED_TAB_STATE_REVERTING: - pixbuf = get_stock_icon (theme, - GTK_STOCK_REVERT_TO_SAVED, - icon_size); - break; + case XED_TAB_STATE_SAVING: + icon_name = "document-save-symbolic"; + break; - case XED_TAB_STATE_SAVING: - pixbuf = get_stock_icon (theme, - GTK_STOCK_SAVE, - icon_size); - break; + case XED_TAB_STATE_PRINTING: + icon_name = "printer-printing-symbolic"; + break; - case XED_TAB_STATE_PRINTING: - pixbuf = get_stock_icon (theme, - GTK_STOCK_PRINT, - icon_size); - break; + case XED_TAB_STATE_PRINT_PREVIEWING: + case XED_TAB_STATE_SHOWING_PRINT_PREVIEW: + icon_name = "printer-symbolic"; + break; - case XED_TAB_STATE_PRINT_PREVIEWING: - case XED_TAB_STATE_SHOWING_PRINT_PREVIEW: - pixbuf = get_stock_icon (theme, - GTK_STOCK_PRINT_PREVIEW, - icon_size); - break; + case XED_TAB_STATE_LOADING_ERROR: + case XED_TAB_STATE_REVERTING_ERROR: + case XED_TAB_STATE_SAVING_ERROR: + case XED_TAB_STATE_GENERIC_ERROR: + icon_name = "dialog-error-symbolic"; + break; - case XED_TAB_STATE_LOADING_ERROR: - case XED_TAB_STATE_REVERTING_ERROR: - case XED_TAB_STATE_SAVING_ERROR: - case XED_TAB_STATE_GENERIC_ERROR: - pixbuf = get_stock_icon (theme, - GTK_STOCK_DIALOG_ERROR, - icon_size); - break; + case XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION: + icon_name = "dialog-warning-symbolic"; + break; - case XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION: - pixbuf = get_stock_icon (theme, - GTK_STOCK_DIALOG_WARNING, - icon_size); - break; + default: + icon_name = NULL; + } - default: - { - GFile *location; - XedDocument *doc; + if (icon_name != NULL) + { + pixbuf = gtk_icon_theme_load_icon (theme, icon_name, icon_size, 0, NULL); + } + else + { + GFile *location; + XedDocument *doc; - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); + location = xed_document_get_location (doc); + pixbuf = get_icon (theme, location, icon_size); + } - location = xed_document_get_location (doc); - pixbuf = get_icon (theme, location, icon_size); - - if (location) - g_object_unref (location); - } - } - - return pixbuf; + return pixbuf; } /** @@ -1931,253 +1526,920 @@ _xed_tab_get_icon (XedTab *tab) * * Gets the #XedTab associated with @doc. * - * Returns: the #XedTab associated with @doc + * Returns: (transfer none): the #XedTab associated with @doc */ XedTab * xed_tab_get_from_document (XedDocument *doc) { - gpointer res; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - - res = g_object_get_data (G_OBJECT (doc), XED_TAB_KEY); - - return (res != NULL) ? XED_TAB (res) : NULL; + gpointer res; + + g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); + + res = g_object_get_data (G_OBJECT (doc), XED_TAB_KEY); + + return (res != NULL) ? XED_TAB (res) : NULL; +} + +static void +loader_progress_cb (goffset size, + goffset total_size, + XedTab *tab) +{ + gdouble elapsed_time; + gdouble total_time; + gdouble remaining_time; + + g_return_if_fail (tab->priv->state == XED_TAB_STATE_LOADING || + tab->priv->state == XED_TAB_STATE_REVERTING); + + if (tab->priv->timer == NULL) + { + tab->priv->timer = g_timer_new (); + } + + elapsed_time = g_timer_elapsed (tab->priv->timer, NULL); + + /* elapsed_time / total_time = size / total_size */ + total_time = (elapsed_time * total_size) / size; + + remaining_time = total_time - elapsed_time; + + /* Approximately more than 3 seconds remaining. */ + if (remaining_time > 3.0) + { + show_loading_info_bar (tab); + } + + info_bar_set_progress (tab, size, total_size); +} + +static void +goto_line (XedTab *tab) +{ + XedDocument *doc = xed_tab_get_document (tab); + GtkTextIter iter; + + /* Move the cursor at the requested line if any. */ + if (tab->priv->tmp_line_pos > 0) + { + xed_document_goto_line_offset (doc, tab->priv->tmp_line_pos - 1, 0); + return; + } + + /* If enabled, move to the position stored in the metadata. */ + if (g_settings_get_boolean (tab->priv->editor, XED_SETTINGS_RESTORE_CURSOR_POSITION)) + { + gchar *pos; + gint offset; + + pos = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_POSITION); + + offset = pos != NULL ? atoi (pos) : 0; + g_free (pos); + + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &iter, MAX (0, offset)); + + /* make sure it's a valid position, if the file + * changed we may have ended up in the middle of + * a utf8 character cluster */ + if (!gtk_text_iter_is_cursor_position (&iter)) + { + gtk_text_iter_set_line_offset (&iter, 0); + } + } + + /* Otherwise to the top. */ + else + { + gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc), &iter); + } + + gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter); +} + +static void +load_cb (GtkSourceFileLoader *loader, + GAsyncResult *result, + XedTab *tab) +{ + XedDocument *doc = xed_tab_get_document (tab); + GFile *location = gtk_source_file_loader_get_location (loader); + gboolean create_named_new_doc; + GError *error = NULL; + + g_return_if_fail (tab->priv->state == XED_TAB_STATE_LOADING || + tab->priv->state == XED_TAB_STATE_REVERTING); + + gtk_source_file_loader_load_finish (loader, result, &error); + + if (error != NULL) + { + xed_debug_message (DEBUG_TAB, "File loading error: %s", error->message); + } + + if (tab->priv->timer != NULL) + { + g_timer_destroy (tab->priv->timer); + tab->priv->timer = NULL; + } + + set_info_bar (tab, NULL); + + /* Load was successful. */ + if (error == NULL || + (error->domain == GTK_SOURCE_FILE_LOADER_ERROR && + error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK)) + { + if (tab->priv->user_requested_encoding) + { + const GtkSourceEncoding *encoding = gtk_source_file_loader_get_encoding (loader); + const gchar *charset = gtk_source_encoding_get_charset (encoding); + + xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_ENCODING, charset, NULL); + } + + goto_line (tab); + } + + /* Special case creating a named new doc. */ + create_named_new_doc = (_xed_document_get_create (doc) && + error != NULL && + error->domain == G_IO_ERROR && + error->code == G_IO_ERROR_NOT_FOUND && + g_file_has_uri_scheme (location, "file")); + + if (create_named_new_doc) + { + g_error_free (error); + error = NULL; + } + + /* If the error is CONVERSION FALLBACK don't treat it as a normal error. */ + if (error != NULL && + (error->domain != GTK_SOURCE_FILE_LOADER_ERROR || + error->code != GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK)) + { + if (tab->priv->state == XED_TAB_STATE_LOADING) + { + xed_tab_set_state (tab, XED_TAB_STATE_LOADING_ERROR); + } + else + { + xed_tab_set_state (tab, XED_TAB_STATE_REVERTING_ERROR); + } + + if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED) + { + remove_tab (tab); + } + else + { + GtkWidget *info_bar; + + if (location != NULL) + { + _xed_recent_remove (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), location); + } + + if (tab->priv->state == XED_TAB_STATE_LOADING_ERROR) + { + const GtkSourceEncoding *encoding; + + encoding = gtk_source_file_loader_get_encoding (loader); + + info_bar = xed_io_loading_error_info_bar_new (location, encoding, error); + + g_signal_connect (info_bar, "response", + G_CALLBACK (io_loading_error_info_bar_response), tab); + } + else + { + g_return_if_fail (tab->priv->state == XED_TAB_STATE_REVERTING_ERROR); + + info_bar = xed_unrecoverable_reverting_error_info_bar_new (location, error); + + g_signal_connect (info_bar, "response", + G_CALLBACK (unrecoverable_reverting_error_info_bar_response), tab); + } + + set_info_bar (tab, info_bar); + gtk_info_bar_set_default_response (GTK_INFO_BAR (info_bar), GTK_RESPONSE_CANCEL); + gtk_widget_show (info_bar); + } + + goto end; + } + + if (location != NULL && !create_named_new_doc) + { + gchar *mime = xed_document_get_mime_type (doc); + + _xed_recent_add (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), location, mime); + g_free (mime); + } + + if (error != NULL && + error->domain == GTK_SOURCE_FILE_LOADER_ERROR && + error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK) + { + GtkWidget *info_bar; + const GtkSourceEncoding *encoding; + + /* Set the tab as not editable as we have an error, the user can + * decide to make it editable again. + */ + tab->priv->editable = FALSE; + + encoding = gtk_source_file_loader_get_encoding (loader); + + info_bar = xed_io_loading_error_info_bar_new (location, encoding, error); + + g_signal_connect (info_bar, "response", + G_CALLBACK (io_loading_error_info_bar_response), tab); + + set_info_bar (tab, info_bar); + gtk_info_bar_set_default_response (GTK_INFO_BAR (info_bar), GTK_RESPONSE_CANCEL); + gtk_widget_show (info_bar); + } + + /* Scroll to the cursor when the document is loaded, we need to do it in + * an idle as after the document is loaded the textview is still + * redrawing and relocating its internals. + */ + if (tab->priv->idle_scroll == 0) + { + tab->priv->idle_scroll = g_idle_add ((GSourceFunc)scroll_to_cursor, tab); + } + + /* If the document is readonly we don't care how many times the document + * is opened. + */ + if (!xed_document_get_readonly (doc)) + { + GList *all_documents; + GList *l; + + all_documents = xed_app_get_documents (XED_APP (g_application_get_default ())); + + for (l = all_documents; l != NULL; l = g_list_next (l)) + { + XedDocument *cur_doc = l->data; + + if (cur_doc != doc) + { + GtkSourceFile *cur_file = xed_document_get_file (cur_doc); + GFile *cur_location = gtk_source_file_get_location (cur_file); + + if (cur_location != NULL && location != NULL && g_file_equal (location, cur_location)) + { + GtkWidget *info_bar; + + tab->priv->editable = FALSE; + + info_bar = xed_file_already_open_warning_info_bar_new (location); + + g_signal_connect (info_bar, "response", + G_CALLBACK (file_already_open_warning_info_bar_response), tab); + + set_info_bar (tab, info_bar); + gtk_info_bar_set_default_response (GTK_INFO_BAR (info_bar), GTK_RESPONSE_CANCEL); + gtk_widget_show (info_bar); + + break; + } + } + } + + g_list_free (all_documents); + } + + xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + + if (location == NULL) + { + /* FIXME: hackish */ + gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), TRUE); + } + + tab->priv->ask_if_externally_modified = TRUE; + + if (error == NULL) + { + clear_loading (tab); + } + + g_signal_emit_by_name (doc, "loaded"); + +end: + /* Async operation finished. */ + g_object_unref (tab); + + if (error != NULL) + { + g_error_free (error); + } +} + +static GSList * +get_candidate_encodings (XedTab *tab) +{ + XedDocument *doc; + GSettings *enc_settings; + gchar **enc_strv; + gchar *metadata_charset; + GtkSourceFile *file; + const GtkSourceEncoding *file_encoding; + GSList *encodings; + + enc_settings = g_settings_new ("org.x.editor.preferences.encodings"); + + enc_strv = g_settings_get_strv (enc_settings, XED_SETTINGS_ENCODING_AUTO_DETECTED); + + encodings = _xed_utils_encoding_strv_to_list ((const gchar * const *)enc_strv); + + doc = xed_tab_get_document (tab); + metadata_charset = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_ENCODING); + + if (metadata_charset != NULL) + { + const GtkSourceEncoding *metadata_enc; + + metadata_enc = gtk_source_encoding_get_from_charset (metadata_charset); + + if (metadata_enc != NULL) + { + encodings = g_slist_prepend (encodings, (gpointer)metadata_enc); + } + } + + file = xed_document_get_file (doc); + file_encoding = gtk_source_file_get_encoding (file); + + if (file_encoding != NULL) + { + encodings = g_slist_prepend (encodings, (gpointer)file_encoding); + } + + g_object_unref (enc_settings); + g_strfreev (enc_strv); + g_free (metadata_charset); + + return encodings; +} + +static void +load (XedTab *tab, + const GtkSourceEncoding *encoding, + gint line_pos) +{ + GSList *candidate_encodings = NULL; + XedDocument *doc; + + g_return_if_fail (GTK_SOURCE_IS_FILE_LOADER (tab->priv->loader)); + + if (encoding != NULL) + { + tab->priv->user_requested_encoding = TRUE; + candidate_encodings = g_slist_append (NULL, (gpointer) encoding); + } + else + { + tab->priv->user_requested_encoding = FALSE; + candidate_encodings = get_candidate_encodings (tab); + } + + gtk_source_file_loader_set_candidate_encodings (tab->priv->loader, candidate_encodings); + g_slist_free (candidate_encodings); + + tab->priv->tmp_line_pos = line_pos; + + g_clear_object (&tab->priv->cancellable); + tab->priv->cancellable = g_cancellable_new (); + + doc = xed_tab_get_document (tab); + g_signal_emit_by_name (doc, "load"); + + /* Keep the tab alive during the async operation. */ + g_object_ref (tab); + + gtk_source_file_loader_load_async (tab->priv->loader, + G_PRIORITY_DEFAULT, + tab->priv->cancellable, + (GFileProgressCallback) loader_progress_cb, + tab, + NULL, + (GAsyncReadyCallback) load_cb, + tab); } void -_xed_tab_load (XedTab *tab, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create) +_xed_tab_load (XedTab *tab, + GFile *location, + const GtkSourceEncoding *encoding, + gint line_pos, + gboolean create) { - XedDocument *doc; + XedDocument *doc; + GtkSourceFile *file; - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (G_IS_FILE (location)); + g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL); - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); + xed_tab_set_state (tab, XED_TAB_STATE_LOADING); - xed_tab_set_state (tab, XED_TAB_STATE_LOADING); + doc = xed_tab_get_document (tab); + file = xed_document_get_file (doc); - tab->priv->tmp_line_pos = line_pos; - tab->priv->tmp_encoding = encoding; + if (tab->priv->loader != NULL) + { + g_warning ("XedTab: file loader already exists."); + g_object_unref (tab->priv->loader); + } - if (tab->priv->auto_save_timeout > 0) - remove_auto_save_timeout (tab); + gtk_source_file_set_location (file, location); + tab->priv->loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (doc), file); - xed_document_load (doc, - uri, - encoding, - line_pos, - create); + _xed_document_set_create (doc, create); + + load (tab, encoding, line_pos); +} + +void +_xed_tab_load_stream (XedTab *tab, + GInputStream *stream, + const GtkSourceEncoding *encoding, + gint line_pos) +{ + XedDocument *doc; + GtkSourceFile *file; + + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL); + + xed_tab_set_state (tab, XED_TAB_STATE_LOADING); + + doc = xed_tab_get_document (tab); + file = xed_document_get_file (doc); + + if (tab->priv->loader != NULL) + { + g_warning ("XedTab: file loader already exists."); + g_object_unref (tab->priv->loader); + } + + gtk_source_file_set_location (file, NULL); + + tab->priv->loader = gtk_source_file_loader_new_from_stream (GTK_SOURCE_BUFFER (doc), file, stream); + + _xed_document_set_create (doc, FALSE); + + load (tab, encoding, line_pos); } void _xed_tab_revert (XedTab *tab) { - XedDocument *doc; - gchar *uri; + XedDocument *doc; + GtkSourceFile *file; + GFile *location; - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail ((tab->priv->state == XED_TAB_STATE_NORMAL) || - (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL || + tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION); - if (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) - { - set_message_area (tab, NULL); - } + if (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) + { + set_info_bar (tab, NULL); + } - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); + doc = xed_tab_get_document (tab); + file = xed_document_get_file (doc); + location = gtk_source_file_get_location (file); + g_return_if_fail (location != NULL); - xed_tab_set_state (tab, XED_TAB_STATE_REVERTING); + xed_tab_set_state (tab, XED_TAB_STATE_REVERTING); - uri = xed_document_get_uri (doc); - g_return_if_fail (uri != NULL); + if (tab->priv->loader != NULL) + { + g_warning ("XedTab: file loader already exists."); + g_object_unref (tab->priv->loader); + } - tab->priv->tmp_line_pos = 0; - tab->priv->tmp_encoding = xed_document_get_encoding (doc); + tab->priv->loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (doc), file); - if (tab->priv->auto_save_timeout > 0) - remove_auto_save_timeout (tab); + load (tab, NULL, 0); +} - xed_document_load (doc, - uri, - tab->priv->tmp_encoding, - 0, - FALSE); +static void +saver_progress_cb (goffset size, + goffset total_size, + XedTab *tab) +{ + gdouble elapsed_time; + gdouble total_time; + gdouble remaining_time; - g_free (uri); + g_return_if_fail (tab->priv->state == XED_TAB_STATE_SAVING); + + if (tab->priv->timer == NULL) + { + tab->priv->timer = g_timer_new (); + } + + elapsed_time = g_timer_elapsed (tab->priv->timer, NULL); + + /* elapsed_time / total_time = size / total_size */ + total_time = (elapsed_time * total_size) / size; + + remaining_time = total_time - elapsed_time; + + /* Approximately more than 3 seconds remaining. */ + if (remaining_time > 3.0) + { + show_saving_info_bar (tab); + } + + info_bar_set_progress (tab, size, total_size); +} + +static void +save_cb (GtkSourceFileSaver *saver, + GAsyncResult *result, + XedTab *tab) +{ + XedDocument *doc = xed_tab_get_document (tab); + GFile *location = gtk_source_file_saver_get_location (saver); + GError *error = NULL; + + g_return_if_fail (tab->priv->task_saver != NULL); + + gtk_source_file_saver_save_finish (saver, result, &error); + + if (error != NULL) + { + xed_debug_message (DEBUG_TAB, "File saving error: %s", error->message); + } + + if (tab->priv->timer != NULL) + { + g_timer_destroy (tab->priv->timer); + tab->priv->timer = NULL; + } + + set_info_bar (tab, NULL); + + if (error != NULL) + { + GtkWidget *info_bar; + + xed_tab_set_state (tab, XED_TAB_STATE_SAVING_ERROR); + + if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR && + error->code == GTK_SOURCE_FILE_SAVER_ERROR_EXTERNALLY_MODIFIED) + { + /* This error is recoverable */ + info_bar = xed_externally_modified_saving_error_info_bar_new (location, error); + g_return_if_fail (info_bar != NULL); + + g_signal_connect (info_bar, "response", + G_CALLBACK (externally_modified_error_info_bar_response), tab); + } + else if (error->domain == G_IO_ERROR && + error->code == G_IO_ERROR_CANT_CREATE_BACKUP) + { + /* This error is recoverable */ + info_bar = xed_no_backup_saving_error_info_bar_new (location, error); + g_return_if_fail (info_bar != NULL); + + g_signal_connect (info_bar, "response", + G_CALLBACK (no_backup_error_info_bar_response), tab); + } + else if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR && + error->code == GTK_SOURCE_FILE_SAVER_ERROR_INVALID_CHARS) + { + /* If we have any invalid char in the document we must warn the user + * as it can make the document useless if it is saved. + */ + info_bar = xed_invalid_character_info_bar_new (location); + g_return_if_fail (info_bar != NULL); + + g_signal_connect (info_bar, "response", + G_CALLBACK (invalid_character_info_bar_response), tab); + } + else if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR || + (error->domain == G_IO_ERROR && + error->code != G_IO_ERROR_INVALID_DATA && + error->code != G_IO_ERROR_PARTIAL_INPUT)) + { + /* These errors are _NOT_ recoverable */ + _xed_recent_remove (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), location); + + info_bar = xed_unrecoverable_saving_error_info_bar_new (location, error); + g_return_if_fail (info_bar != NULL); + + g_signal_connect (info_bar, "response", + G_CALLBACK (unrecoverable_saving_error_info_bar_response), tab); + } + else + { + const GtkSourceEncoding *encoding; + + /* This error is recoverable */ + g_return_if_fail (error->domain == G_CONVERT_ERROR || error->domain == G_IO_ERROR); + + encoding = gtk_source_file_saver_get_encoding (saver); + + info_bar = xed_conversion_error_while_saving_info_bar_new (location, encoding, error); + g_return_if_fail (info_bar != NULL); + + g_signal_connect (info_bar, "response", + G_CALLBACK (recoverable_saving_error_info_bar_response), tab); + } + + set_info_bar (tab, info_bar); + gtk_info_bar_set_default_response (GTK_INFO_BAR (info_bar), GTK_RESPONSE_CANCEL); + gtk_widget_show (info_bar); + } + else + { + gchar *mime = xed_document_get_mime_type (doc); + + _xed_recent_add (XED_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), location, mime); + g_free (mime); + + if (tab->priv->print_preview != NULL) + { + xed_tab_set_state (tab, XED_TAB_STATE_SHOWING_PRINT_PREVIEW); + } + else + { + xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + } + + tab->priv->ask_if_externally_modified = TRUE; + + g_signal_emit_by_name (doc, "saved"); + g_task_return_boolean (tab->priv->task_saver, TRUE); + } + + if (error != NULL) + { + g_error_free (error); + } +} + +static void +save (XedTab *tab) +{ + XedDocument *doc; + SaverData *data; + + g_return_if_fail (G_IS_TASK (tab->priv->task_saver)); + + xed_tab_set_state (tab, XED_TAB_STATE_SAVING); + + doc = xed_tab_get_document (tab); + g_signal_emit_by_name (doc, "save"); + + data = g_task_get_task_data (tab->priv->task_saver); + + gtk_source_file_saver_save_async (data->saver, + G_PRIORITY_DEFAULT, + g_task_get_cancellable (tab->priv->task_saver), + (GFileProgressCallback) saver_progress_cb, + tab, + NULL, + (GAsyncReadyCallback) save_cb, + tab); +} + +/* Gets the initial save flags, when launching a new FileSaver. */ +static GtkSourceFileSaverFlags +get_initial_save_flags (XedTab *tab, + gboolean auto_save) +{ + GtkSourceFileSaverFlags save_flags; + gboolean create_backup; + + save_flags = tab->priv->save_flags; + + create_backup = g_settings_get_boolean (tab->priv->editor, XED_SETTINGS_CREATE_BACKUP_COPY); + + /* In case of autosaving, we need to preserve the backup that was produced + * the last time the user "manually" saved the file. So we don't set the + * CREATE_BACKUP flag for an automatic file saving. + */ + if (create_backup && !auto_save) + { + save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_CREATE_BACKUP; + } + + return save_flags; } void -_xed_tab_save (XedTab *tab) +_xed_tab_save_async (XedTab *tab, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - XedDocument *doc; - XedDocumentSaveFlags save_flags; + SaverData *data; + XedDocument *doc; + GtkSourceFile *file; + GtkSourceFileSaverFlags save_flags; - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail ((tab->priv->state == XED_TAB_STATE_NORMAL) || - (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) || - (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW)); - g_return_if_fail (tab->priv->tmp_save_uri == NULL); - g_return_if_fail (tab->priv->tmp_encoding == NULL); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail ((tab->priv->state == XED_TAB_STATE_NORMAL) || + (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) || + (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW)); - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (!xed_document_is_untitled (doc)); + if (tab->priv->task_saver != NULL) + { + g_warning ("XedTab: file saver already exists."); + return; + } - if (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) - { - /* We already told the user about the external - * modification: hide the message area and set - * the save flag. - */ + doc = xed_tab_get_document (tab); + // g_return_if_fail (XED_IS_DOCUMENT (doc)); + g_return_if_fail (!xed_document_is_untitled (doc)); - set_message_area (tab, NULL); - save_flags = tab->priv->save_flags | XED_DOCUMENT_SAVE_IGNORE_MTIME; - } - else - { - save_flags = tab->priv->save_flags; - } + tab->priv->task_saver = g_task_new (tab, cancellable, callback, user_data); - xed_tab_set_state (tab, XED_TAB_STATE_SAVING); + data = saver_data_new (); + g_task_set_task_data (tab->priv->task_saver, + data, + (GDestroyNotify) saver_data_free); - /* uri used in error messages, will be freed in document_saved */ - tab->priv->tmp_save_uri = xed_document_get_uri (doc); - tab->priv->tmp_encoding = xed_document_get_encoding (doc); + save_flags = get_initial_save_flags (tab, FALSE); - if (tab->priv->auto_save_timeout > 0) - remove_auto_save_timeout (tab); - - xed_document_save (doc, save_flags); + if (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) + { + /* We already told the user about the external modification: + * hide the message bar and set the save flag. + */ + + set_info_bar (tab, NULL); + save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME; + } + + file = xed_document_get_file (doc); + + data->saver = gtk_source_file_saver_new (GTK_SOURCE_BUFFER (doc), file); + gtk_source_file_saver_set_flags (data->saver, save_flags); + + save (tab); +} + +gboolean +_xed_tab_save_finish (XedTab *tab, + GAsyncResult *result) +{ + gboolean success; + + g_return_val_if_fail (g_task_is_valid (result, tab), FALSE); + g_return_val_if_fail (tab->priv->task_saver == G_TASK (result), FALSE); + + success = g_task_propagate_boolean (tab->priv->task_saver, NULL); + g_clear_object (&tab->priv->task_saver); + + return success; +} + +static void +auto_save_finished_cb (XedTab *tab, + GAsyncResult *result, + gpointer user_data) +{ + _xed_tab_save_finish (tab, result); } static gboolean xed_tab_auto_save (XedTab *tab) { - XedDocument *doc; + SaverData *data; + XedDocument *doc; + GtkSourceFile *file; + GtkSourceFileSaverFlags save_flags; - xed_debug (DEBUG_TAB); - - g_return_val_if_fail (tab->priv->tmp_save_uri == NULL, FALSE); - g_return_val_if_fail (tab->priv->tmp_encoding == NULL, FALSE); - - doc = xed_tab_get_document (tab); - - g_return_val_if_fail (!xed_document_is_untitled (doc), FALSE); - g_return_val_if_fail (!xed_document_get_readonly (doc), FALSE); + xed_debug (DEBUG_TAB); - g_return_val_if_fail (tab->priv->auto_save_timeout > 0, FALSE); - g_return_val_if_fail (tab->priv->auto_save, FALSE); - g_return_val_if_fail (tab->priv->auto_save_interval > 0, FALSE); + doc = xed_tab_get_document (tab); + g_return_val_if_fail (!xed_document_is_untitled (doc), G_SOURCE_REMOVE); + g_return_val_if_fail (!xed_document_get_readonly (doc), G_SOURCE_REMOVE); - if (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER(doc))) - { - xed_debug_message (DEBUG_TAB, "Document not modified"); + if (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc))) + { + xed_debug_message (DEBUG_TAB, "Document not modified"); - return TRUE; - } - - if ((tab->priv->state != XED_TAB_STATE_NORMAL) && - (tab->priv->state != XED_TAB_STATE_SHOWING_PRINT_PREVIEW)) - { - /* Retry after 30 seconds */ - guint timeout; + return G_SOURCE_CONTINUE; + } - xed_debug_message (DEBUG_TAB, "Retry after 30 seconds"); + if ((tab->priv->state != XED_TAB_STATE_NORMAL) && (tab->priv->state != XED_TAB_STATE_SHOWING_PRINT_PREVIEW)) + { + xed_debug_message (DEBUG_TAB, "Retry after 30 seconds"); - /* Add a new timeout */ - timeout = g_timeout_add_seconds (30, - (GSourceFunc) xed_tab_auto_save, - tab); + tab->priv->auto_save_timeout = g_timeout_add_seconds (30, (GSourceFunc) xed_tab_auto_save, tab); - tab->priv->auto_save_timeout = timeout; + /* Destroy the old timeout */ + return G_SOURCE_REMOVE; + } - /* Returns FALSE so the old timeout is "destroyed" */ - return FALSE; - } - - xed_tab_set_state (tab, XED_TAB_STATE_SAVING); + /* Set auto_save_timeout to 0 since the timeout is going to be destroyed */ + tab->priv->auto_save_timeout = 0; - /* uri used in error messages, will be freed in document_saved */ - tab->priv->tmp_save_uri = xed_document_get_uri (doc); - tab->priv->tmp_encoding = xed_document_get_encoding (doc); + if (tab->priv->task_saver != NULL) + { + g_warning ("XedTab: file saver already exists."); + return G_SOURCE_REMOVE; + } - /* Set auto_save_timeout to 0 since the timeout is going to be destroyed */ - tab->priv->auto_save_timeout = 0; + tab->priv->task_saver = g_task_new (tab, + NULL, + (GAsyncReadyCallback) auto_save_finished_cb, + NULL); - /* Since we are autosaving, we need to preserve the backup that was produced - the last time the user "manually" saved the file. In the case a recoverable - error happens while saving, the last backup is not preserved since the user - expressed his willing of saving the file */ - xed_document_save (doc, tab->priv->save_flags | XED_DOCUMENT_SAVE_PRESERVE_BACKUP); - - xed_debug_message (DEBUG_TAB, "Done"); - - /* Returns FALSE so the old timeout is "destroyed" */ - return FALSE; + data = saver_data_new (); + g_task_set_task_data (tab->priv->task_saver, + data, + (GDestroyNotify) saver_data_free); + + file = xed_document_get_file (doc); + + data->saver = gtk_source_file_saver_new (GTK_SOURCE_BUFFER (doc), file); + + save_flags = get_initial_save_flags (tab, TRUE); + gtk_source_file_saver_set_flags (data->saver, save_flags); + + save (tab); + + return G_SOURCE_REMOVE; } +/* Call _xed_tab_save_finish() in @callback, there is no + * _xed_tab_save_as_finish(). + */ void -_xed_tab_save_as (XedTab *tab, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentNewlineType newline_type) +_xed_tab_save_as_async (XedTab *tab, + GFile *location, + const GtkSourceEncoding *encoding, + GtkSourceNewlineType newline_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - XedDocument *doc; - XedDocumentSaveFlags save_flags; + SaverData *data; + XedDocument *doc; + GtkSourceFile *file; + GtkSourceFileSaverFlags save_flags; - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail ((tab->priv->state == XED_TAB_STATE_NORMAL) || - (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) || - (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW)); - g_return_if_fail (encoding != NULL); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail ((tab->priv->state == XED_TAB_STATE_NORMAL) || + (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) || + (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW)); + g_return_if_fail (G_IS_FILE (location)); + g_return_if_fail (encoding != NULL); - g_return_if_fail (tab->priv->tmp_save_uri == NULL); - g_return_if_fail (tab->priv->tmp_encoding == NULL); + if (tab->priv->task_saver != NULL) + { + g_warning ("XedTab: file saver already exists."); + return; + } - doc = xed_tab_get_document (tab); - g_return_if_fail (XED_IS_DOCUMENT (doc)); + tab->priv->task_saver = g_task_new (tab, cancellable, callback, user_data); - /* reset the save flags, when saving as */ - tab->priv->save_flags = 0; + data = saver_data_new (); + g_task_set_task_data (tab->priv->task_saver, + data, + (GDestroyNotify) saver_data_free); - if (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) - { - /* We already told the user about the external - * modification: hide the message area and set - * the save flag. - */ + doc = xed_tab_get_document (tab); + g_return_if_fail (XED_IS_DOCUMENT (doc)); - set_message_area (tab, NULL); - save_flags = tab->priv->save_flags | XED_DOCUMENT_SAVE_IGNORE_MTIME; - } - else - { - save_flags = tab->priv->save_flags; - } + /* reset the save flags, when saving as */ + tab->priv->save_flags = GTK_SOURCE_FILE_SAVER_FLAGS_NONE; + save_flags = get_initial_save_flags (tab, FALSE); - xed_tab_set_state (tab, XED_TAB_STATE_SAVING); + if (tab->priv->state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) + { + /* We already told the user about the external modification: + * hide the message bar and set the save flag. + */ - /* uri used in error messages... strdup because errors are async - * and the string can go away, will be freed in document_saved */ - tab->priv->tmp_save_uri = g_strdup (uri); - tab->priv->tmp_encoding = encoding; + set_info_bar (tab, NULL); + save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME; + } - if (tab->priv->auto_save_timeout > 0) - remove_auto_save_timeout (tab); + file = xed_document_get_file (doc); - /* FIXME: this should behave the same as encoding, setting it here - makes it persistent (if save fails, it's remembered). It's not - a very big deal, but would be nice to have them follow the - same pattern. This can be changed once we break API for 3.0 */ - xed_document_set_newline_type (doc, newline_type); - xed_document_save_as (doc, uri, encoding, tab->priv->save_flags); + data->saver = gtk_source_file_saver_new_with_target (GTK_SOURCE_BUFFER (doc), file, location); + + gtk_source_file_saver_set_encoding (data->saver, encoding); + gtk_source_file_saver_set_newline_type (data->saver, newline_type); + gtk_source_file_saver_set_flags (data->saver, save_flags); + + save (tab); } #define XED_PAGE_SETUP_KEY "xed-page-setup-key" @@ -2186,579 +2448,521 @@ _xed_tab_save_as (XedTab *tab, static GtkPageSetup * get_page_setup (XedTab *tab) { - gpointer data; - XedDocument *doc; + gpointer data; + XedDocument *doc; - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); + data = g_object_get_data (G_OBJECT (doc), XED_PAGE_SETUP_KEY); - data = g_object_get_data (G_OBJECT (doc), - XED_PAGE_SETUP_KEY); - - if (data == NULL) - { - return _xed_app_get_default_page_setup (xed_app_get_default()); - } - else - { - return gtk_page_setup_copy (GTK_PAGE_SETUP (data)); - } + if (data == NULL) + { + return _xed_app_get_default_page_setup (XED_APP (g_application_get_default ())); + } + else + { + return gtk_page_setup_copy (GTK_PAGE_SETUP (data)); + } } static GtkPrintSettings * get_print_settings (XedTab *tab) { - gpointer data; - XedDocument *doc; - GtkPrintSettings *settings; - gchar *uri, *name; + gpointer data; + XedDocument *doc; + GtkPrintSettings *settings; + gchar *uri, *name; - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); - data = g_object_get_data (G_OBJECT (doc), - XED_PRINT_SETTINGS_KEY); + data = g_object_get_data (G_OBJECT (doc), XED_PRINT_SETTINGS_KEY); - if (data == NULL) - { - settings = _xed_app_get_default_print_settings (xed_app_get_default()); - } - else - { - settings = gtk_print_settings_copy (GTK_PRINT_SETTINGS (data)); - } + if (data == NULL) + { + settings = _xed_app_get_default_print_settings (XED_APP (g_application_get_default ())); + } + else + { + settings = gtk_print_settings_copy (GTK_PRINT_SETTINGS (data)); + } - name = xed_document_get_short_name_for_display (doc); - uri = g_strconcat ("file://", - g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS), - "/", name, ".pdf", NULL); + name = xed_document_get_short_name_for_display (doc); + uri = g_strconcat ("file://", + g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS), + "/", name, ".pdf", NULL); - gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_URI, uri); + gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_URI, uri); - g_free (uri); - g_free (name); + g_free (uri); + g_free (name); - return settings; + return settings; } /* FIXME: show the message area only if the operation will be "long" */ static void printing_cb (XedPrintJob *job, - XedPrintJobStatus status, - XedTab *tab) + XedPrintJobStatus status, + XedTab *tab) { - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area)); + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (tab->priv->info_bar)); - gtk_widget_show (tab->priv->message_area); + gtk_widget_show (tab->priv->info_bar); - xed_progress_message_area_set_text (XED_PROGRESS_MESSAGE_AREA (tab->priv->message_area), - xed_print_job_get_status_string (job)); + xed_progress_info_bar_set_text (XED_PROGRESS_INFO_BAR (tab->priv->info_bar), + xed_print_job_get_status_string (job)); - xed_progress_message_area_set_fraction (XED_PROGRESS_MESSAGE_AREA (tab->priv->message_area), - xed_print_job_get_progress (job)); + xed_progress_info_bar_set_fraction (XED_PROGRESS_INFO_BAR (tab->priv->info_bar), + xed_print_job_get_progress (job)); } static void store_print_settings (XedTab *tab, - XedPrintJob *job) + XedPrintJob *job) { - XedDocument *doc; - GtkPrintSettings *settings; - GtkPageSetup *page_setup; + XedDocument *doc; + GtkPrintSettings *settings; + GtkPageSetup *page_setup; - doc = xed_tab_get_document (tab); + doc = xed_tab_get_document (tab); - settings = xed_print_job_get_print_settings (job); + settings = xed_print_job_get_print_settings (job); - /* clear n-copies settings since we do not want to - * persist that one */ - gtk_print_settings_unset (settings, - GTK_PRINT_SETTINGS_N_COPIES); + /* clear n-copies settings since we do not want to + * persist that one */ + gtk_print_settings_unset (settings, GTK_PRINT_SETTINGS_N_COPIES); - /* remember settings for this document */ - g_object_set_data_full (G_OBJECT (doc), - XED_PRINT_SETTINGS_KEY, - g_object_ref (settings), - (GDestroyNotify)g_object_unref); + /* remember settings for this document */ + g_object_set_data_full (G_OBJECT (doc), XED_PRINT_SETTINGS_KEY, + g_object_ref (settings), (GDestroyNotify)g_object_unref); - /* make them the default */ - _xed_app_set_default_print_settings (xed_app_get_default (), - settings); + /* make them the default */ + _xed_app_set_default_print_settings (XED_APP (g_application_get_default ()), settings); - page_setup = xed_print_job_get_page_setup (job); + page_setup = xed_print_job_get_page_setup (job); - /* remember page setup for this document */ - g_object_set_data_full (G_OBJECT (doc), - XED_PAGE_SETUP_KEY, - g_object_ref (page_setup), - (GDestroyNotify)g_object_unref); + /* remember page setup for this document */ + g_object_set_data_full (G_OBJECT (doc), XED_PAGE_SETUP_KEY, + g_object_ref (page_setup), (GDestroyNotify)g_object_unref); - /* make it the default */ - _xed_app_set_default_page_setup (xed_app_get_default (), - page_setup); + /* make it the default */ + _xed_app_set_default_page_setup (XED_APP (g_application_get_default ()), page_setup); } static void done_printing_cb (XedPrintJob *job, - XedPrintJobResult result, - const GError *error, - XedTab *tab) + XedPrintJobResult result, + const GError *error, + XedTab *tab) { - XedView *view; + XedView *view; - g_return_if_fail (tab->priv->state == XED_TAB_STATE_PRINT_PREVIEWING || - tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW || - tab->priv->state == XED_TAB_STATE_PRINTING); + g_return_if_fail (tab->priv->state == XED_TAB_STATE_PRINT_PREVIEWING || + tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW || + tab->priv->state == XED_TAB_STATE_PRINTING); - if (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) - { - /* print preview has been destroyed... */ - tab->priv->print_preview = NULL; - } - else - { - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area)); + if (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) + { + /* print preview has been destroyed... */ + tab->priv->print_preview = NULL; + } + else + { + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (tab->priv->info_bar)); - set_message_area (tab, NULL); /* destroy the message area */ - } + set_info_bar (tab, NULL); /* destroy the message area */ + } - // TODO: check status and error + // TODO: check status and error - if (result == XED_PRINT_JOB_RESULT_OK) - { - store_print_settings (tab, job); - } + if (result == XED_PRINT_JOB_RESULT_OK) + { + store_print_settings (tab, job); + } #if 0 - if (tab->priv->print_preview != NULL) - { - /* If we were printing while showing the print preview, - see bug #352658 */ - gtk_widget_destroy (tab->priv->print_preview); - g_return_if_fail (tab->priv->state == XED_TAB_STATE_PRINTING); - } + if (tab->priv->print_preview != NULL) + { + /* If we were printing while showing the print preview, + see bug #352658 */ + gtk_widget_destroy (tab->priv->print_preview); + g_return_if_fail (tab->priv->state == XED_TAB_STATE_PRINTING); + } #endif - xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); - view = xed_tab_get_view (tab); - gtk_widget_grab_focus (GTK_WIDGET (view)); + view = xed_tab_get_view (tab); + gtk_widget_grab_focus (GTK_WIDGET (view)); - g_object_unref (tab->priv->print_job); - tab->priv->print_job = NULL; + g_object_unref (tab->priv->print_job); + tab->priv->print_job = NULL; } #if 0 static void print_preview_destroyed (GtkWidget *preview, - XedTab *tab) + XedTab *tab) { - tab->priv->print_preview = NULL; + tab->priv->print_preview = NULL; - if (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) - { - XedView *view; + if (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) + { + XedView *view; - xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); - view = xed_tab_get_view (tab); - gtk_widget_grab_focus (GTK_WIDGET (view)); - } - else - { - /* This should happen only when printing while showing the print - * preview. In this case let us continue whithout changing - * the state and show the document. See bug #352658 */ - gtk_widget_show (tab->priv->view_scrolled_window); - - g_return_if_fail (tab->priv->state == XED_TAB_STATE_PRINTING); - } + view = xed_tab_get_view (tab); + gtk_widget_grab_focus (GTK_WIDGET (view)); + } + else + { + /* This should happen only when printing while showing the print + * preview. In this case let us continue whithout changing + * the state and show the document. See bug #352658 */ + gtk_widget_show (tab->priv->view_scrolled_window); + + g_return_if_fail (tab->priv->state == XED_TAB_STATE_PRINTING); + } } #endif static void -show_preview_cb (XedPrintJob *job, - XedPrintPreview *preview, - XedTab *tab) +show_preview_cb (XedPrintJob *job, + XedPrintPreview *preview, + XedTab *tab) { -// g_return_if_fail (tab->priv->state == XED_TAB_STATE_PRINT_PREVIEWING); - g_return_if_fail (tab->priv->print_preview == NULL); +// g_return_if_fail (tab->priv->state == XED_TAB_STATE_PRINT_PREVIEWING); + g_return_if_fail (tab->priv->print_preview == NULL); - set_message_area (tab, NULL); /* destroy the message area */ + set_info_bar (tab, NULL); /* destroy the message area */ - tab->priv->print_preview = GTK_WIDGET (preview); - gtk_box_pack_end (GTK_BOX (tab), - tab->priv->print_preview, - TRUE, - TRUE, - 0); - gtk_widget_show (tab->priv->print_preview); - gtk_widget_grab_focus (tab->priv->print_preview); + tab->priv->print_preview = GTK_WIDGET (preview); + gtk_box_pack_end (GTK_BOX (tab), tab->priv->print_preview, TRUE, TRUE, 0); + gtk_widget_show (tab->priv->print_preview); + gtk_widget_grab_focus (tab->priv->print_preview); /* when the preview gets destroyed we get "done" signal - g_signal_connect (tab->priv->print_preview, - "destroy", - G_CALLBACK (print_preview_destroyed), - tab); + g_signal_connect (tab->priv->print_preview, + "destroy", + G_CALLBACK (print_preview_destroyed), + tab); */ - xed_tab_set_state (tab, XED_TAB_STATE_SHOWING_PRINT_PREVIEW); + xed_tab_set_state (tab, XED_TAB_STATE_SHOWING_PRINT_PREVIEW); } #if 0 static void set_print_preview (XedTab *tab, - GtkWidget *print_preview) + GtkWidget *print_preview) { - if (tab->priv->print_preview == print_preview) - return; - - if (tab->priv->print_preview != NULL) - gtk_widget_destroy (tab->priv->print_preview); + if (tab->priv->print_preview == print_preview) + return; - tab->priv->print_preview = print_preview; + if (tab->priv->print_preview != NULL) + gtk_widget_destroy (tab->priv->print_preview); - gtk_box_pack_end (GTK_BOX (tab), - tab->priv->print_preview, - TRUE, - TRUE, - 0); + tab->priv->print_preview = print_preview; - gtk_widget_grab_focus (tab->priv->print_preview); + gtk_box_pack_end (GTK_BOX (tab), + tab->priv->print_preview, + TRUE, + TRUE, + 0); - g_signal_connect (tab->priv->print_preview, - "destroy", - G_CALLBACK (print_preview_destroyed), - tab); + gtk_widget_grab_focus (tab->priv->print_preview); + + g_signal_connect (tab->priv->print_preview, + "destroy", + G_CALLBACK (print_preview_destroyed), + tab); } static void preview_finished_cb (GtkSourcePrintJob *pjob, XedTab *tab) { - MatePrintJob *gjob; - GtkWidget *preview = NULL; + MatePrintJob *gjob; + GtkWidget *preview = NULL; - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area)); - set_message_area (tab, NULL); /* destroy the message area */ - - gjob = gtk_source_print_job_get_print_job (pjob); + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (tab->priv->info_bar)); + set_info_bar (tab, NULL); /* destroy the message area */ - preview = xed_print_job_preview_new (gjob); - g_object_unref (gjob); - - set_print_preview (tab, preview); - - gtk_widget_show (preview); - g_object_unref (pjob); - - xed_tab_set_state (tab, XED_TAB_STATE_SHOWING_PRINT_PREVIEW); + gjob = gtk_source_print_job_get_print_job (pjob); + + preview = xed_print_job_preview_new (gjob); + g_object_unref (gjob); + + set_print_preview (tab, preview); + + gtk_widget_show (preview); + g_object_unref (pjob); + + xed_tab_set_state (tab, XED_TAB_STATE_SHOWING_PRINT_PREVIEW); } #endif static void -print_cancelled (GtkWidget *area, - gint response_id, - XedTab *tab) +print_cancelled (GtkWidget *area, + gint response_id, + XedTab *tab) { - g_return_if_fail (XED_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area)); + g_return_if_fail (XED_IS_PROGRESS_INFO_BAR (tab->priv->info_bar)); - xed_print_job_cancel (tab->priv->print_job); + xed_print_job_cancel (tab->priv->print_job); - g_debug ("print_cancelled"); + g_debug ("print_cancelled"); } static void -show_printing_message_area (XedTab *tab, gboolean preview) +show_printing_info_bar (XedTab *tab, + gboolean preview) { - GtkWidget *area; + GtkWidget *area; - if (preview) - area = xed_progress_message_area_new (GTK_STOCK_PRINT_PREVIEW, - "", - TRUE); - else - area = xed_progress_message_area_new (GTK_STOCK_PRINT, - "", - TRUE); + if (preview) + { + area = xed_progress_info_bar_new ("document-print-preview-symbolic", "", TRUE); + } + else + { + area = xed_progress_info_bar_new ("document-print-symbolic", "", TRUE); + } - g_signal_connect (area, - "response", - G_CALLBACK (print_cancelled), - tab); - - set_message_area (tab, area); + g_signal_connect (area, "response", + G_CALLBACK (print_cancelled), tab); + + set_info_bar (tab, area); } static void -xed_tab_print_or_print_preview (XedTab *tab, - GtkPrintOperationAction print_action) +xed_tab_print_or_print_preview (XedTab *tab, + GtkPrintOperationAction print_action) { - XedView *view; - gboolean is_preview; - GtkPageSetup *setup; - GtkPrintSettings *settings; - GtkPrintOperationResult res; - GError *error = NULL; + XedView *view; + gboolean is_preview; + GtkPageSetup *setup; + GtkPrintSettings *settings; + GtkPrintOperationResult res; + GError *error = NULL; - g_return_if_fail (tab->priv->print_job == NULL); - g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL); + g_return_if_fail (tab->priv->print_job == NULL); + g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL); - view = xed_tab_get_view (tab); + view = xed_tab_get_view (tab); - is_preview = (print_action == GTK_PRINT_OPERATION_ACTION_PREVIEW); + is_preview = (print_action == GTK_PRINT_OPERATION_ACTION_PREVIEW); - tab->priv->print_job = xed_print_job_new (view); - g_object_add_weak_pointer (G_OBJECT (tab->priv->print_job), - (gpointer *) &tab->priv->print_job); + tab->priv->print_job = xed_print_job_new (view); + g_object_add_weak_pointer (G_OBJECT (tab->priv->print_job), (gpointer *) &tab->priv->print_job); - show_printing_message_area (tab, is_preview); + show_printing_info_bar (tab, is_preview); - g_signal_connect (tab->priv->print_job, - "printing", - G_CALLBACK (printing_cb), - tab); - g_signal_connect (tab->priv->print_job, - "show-preview", - G_CALLBACK (show_preview_cb), - tab); - g_signal_connect (tab->priv->print_job, - "done", - G_CALLBACK (done_printing_cb), - tab); + g_signal_connect (tab->priv->print_job, "printing", + G_CALLBACK (printing_cb), tab); + g_signal_connect (tab->priv->print_job, "show-preview", + G_CALLBACK (show_preview_cb), tab); + g_signal_connect (tab->priv->print_job, "done", + G_CALLBACK (done_printing_cb), tab); - if (is_preview) - xed_tab_set_state (tab, XED_TAB_STATE_PRINT_PREVIEWING); - else - xed_tab_set_state (tab, XED_TAB_STATE_PRINTING); + if (is_preview) + { + xed_tab_set_state (tab, XED_TAB_STATE_PRINT_PREVIEWING); + } + else + { + xed_tab_set_state (tab, XED_TAB_STATE_PRINTING); + } - setup = get_page_setup (tab); - settings = get_print_settings (tab); + setup = get_page_setup (tab); + settings = get_print_settings (tab); - res = xed_print_job_print (tab->priv->print_job, - print_action, - setup, - settings, - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), - &error); + res = xed_print_job_print (tab->priv->print_job, + print_action, + setup, + settings, + GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), + &error); - // TODO: manage res in the correct way - if (res == GTK_PRINT_OPERATION_RESULT_ERROR) - { - /* FIXME: go in error state */ - xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); - g_warning ("Async print preview failed (%s)", error->message); - g_object_unref (tab->priv->print_job); - g_error_free (error); - } -} - -void -_xed_tab_print (XedTab *tab) -{ - g_return_if_fail (XED_IS_TAB (tab)); - - /* FIXME: currently we can have just one printoperation going on - * at a given time, so before starting the print we close the preview. - * Would be nice to handle it properly though */ - if (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) - { - gtk_widget_destroy (tab->priv->print_preview); - } - - xed_tab_print_or_print_preview (tab, - GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); + // TODO: manage res in the correct way + if (res == GTK_PRINT_OPERATION_RESULT_ERROR) + { + /* FIXME: go in error state */ + xed_tab_set_state (tab, XED_TAB_STATE_NORMAL); + g_warning ("Async print preview failed (%s)", error->message); + g_object_unref (tab->priv->print_job); + g_error_free (error); + } } void -_xed_tab_print_preview (XedTab *tab) +_xed_tab_print (XedTab *tab) { - g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (XED_IS_TAB (tab)); - xed_tab_print_or_print_preview (tab, - GTK_PRINT_OPERATION_ACTION_PREVIEW); + /* FIXME: currently we can have just one printoperation going on + * at a given time, so before starting the print we close the preview. + * Would be nice to handle it properly though */ + if (tab->priv->state == XED_TAB_STATE_SHOWING_PRINT_PREVIEW) + { + gtk_widget_destroy (tab->priv->print_preview); + } + + xed_tab_print_or_print_preview (tab, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); } -void +void +_xed_tab_print_preview (XedTab *tab) +{ + g_return_if_fail (XED_IS_TAB (tab)); + + xed_tab_print_or_print_preview (tab, GTK_PRINT_OPERATION_ACTION_PREVIEW); +} + +void _xed_tab_mark_for_closing (XedTab *tab) { - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL); - - xed_tab_set_state (tab, XED_TAB_STATE_CLOSING); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (tab->priv->state == XED_TAB_STATE_NORMAL); + + xed_tab_set_state (tab, XED_TAB_STATE_CLOSING); } gboolean _xed_tab_can_close (XedTab *tab) { - XedDocument *doc; - XedTabState ts; + XedDocument *doc; + XedTabState ts; - g_return_val_if_fail (XED_IS_TAB (tab), FALSE); + g_return_val_if_fail (XED_IS_TAB (tab), FALSE); - ts = xed_tab_get_state (tab); + ts = xed_tab_get_state (tab); - /* if we are loading or reverting, the tab can be closed */ - if ((ts == XED_TAB_STATE_LOADING) || - (ts == XED_TAB_STATE_LOADING_ERROR) || - (ts == XED_TAB_STATE_REVERTING) || - (ts == XED_TAB_STATE_REVERTING_ERROR)) /* CHECK: I'm not sure this is the right behavior for REVERTING ERROR */ - return TRUE; + /* if we are loading or reverting, the tab can be closed */ + if ((ts == XED_TAB_STATE_LOADING) || + (ts == XED_TAB_STATE_LOADING_ERROR) || + (ts == XED_TAB_STATE_REVERTING) || + (ts == XED_TAB_STATE_REVERTING_ERROR)) /* CHECK: I'm not sure this is the right behavior for REVERTING ERROR */ + { + return TRUE; + } - /* Do not close tab with saving errors */ - if (ts == XED_TAB_STATE_SAVING_ERROR) - return FALSE; - - doc = xed_tab_get_document (tab); + /* Do not close tab with saving errors */ + if (ts == XED_TAB_STATE_SAVING_ERROR) + { + return FALSE; + } - /* TODO: we need to save the file also if it has been externally - modified - Paolo (Oct 10, 2005) */ + doc = xed_tab_get_document (tab); - return (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)) && - !xed_document_get_deleted (doc)); + if (_xed_document_needs_saving (doc)) + { + return FALSE; + } + + return TRUE; } /** * xed_tab_get_auto_save_enabled: * @tab: a #XedTab - * + * * Gets the current state for the autosave feature - * + * * Return value: %TRUE if the autosave is enabled, else %FALSE **/ gboolean -xed_tab_get_auto_save_enabled (XedTab *tab) +xed_tab_get_auto_save_enabled (XedTab *tab) { - xed_debug (DEBUG_TAB); + xed_debug (DEBUG_TAB); - g_return_val_if_fail (XED_IS_TAB (tab), FALSE); + g_return_val_if_fail (XED_IS_TAB (tab), FALSE); - return tab->priv->auto_save; + return tab->priv->auto_save; } /** * xed_tab_set_auto_save_enabled: * @tab: a #XedTab * @enable: enable (%TRUE) or disable (%FALSE) auto save - * + * * Enables or disables the autosave feature. It does not install an * autosave timeout if the document is new or is read-only **/ void -xed_tab_set_auto_save_enabled (XedTab *tab, - gboolean enable) +xed_tab_set_auto_save_enabled (XedTab *tab, + gboolean enable) { - XedDocument *doc = NULL; - xed_debug (DEBUG_TAB); + xed_debug (DEBUG_TAB); - g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (XED_IS_TAB (tab)); - doc = xed_tab_get_document (tab); + enable = enable != FALSE; - if (tab->priv->auto_save == enable) - return; - - tab->priv->auto_save = enable; - - if (enable && - (tab->priv->auto_save_timeout <=0) && - !xed_document_is_untitled (doc) && - !xed_document_get_readonly (doc)) - { - if ((tab->priv->state != XED_TAB_STATE_LOADING) && - (tab->priv->state != XED_TAB_STATE_SAVING) && - (tab->priv->state != XED_TAB_STATE_REVERTING) && - (tab->priv->state != XED_TAB_STATE_LOADING_ERROR) && - (tab->priv->state != XED_TAB_STATE_SAVING_ERROR) && - (tab->priv->state != XED_TAB_STATE_REVERTING_ERROR)) - { - install_auto_save_timeout (tab); - } - /* else: the timeout will be installed when loading/saving/reverting - will terminate */ - - return; - } - - if (!enable && (tab->priv->auto_save_timeout > 0)) - { - remove_auto_save_timeout (tab); - - return; - } - - g_return_if_fail ((!enable && (tab->priv->auto_save_timeout <= 0)) || - xed_document_is_untitled (doc) || xed_document_get_readonly (doc)); + if (tab->priv->auto_save != enable) + { + tab->priv->auto_save = enable; + update_auto_save_timeout (tab); + return; + } } /** * xed_tab_get_auto_save_interval: * @tab: a #XedTab - * + * * Gets the current interval for the autosaves - * + * * Return value: the value of the autosave **/ -gint +gint xed_tab_get_auto_save_interval (XedTab *tab) { - xed_debug (DEBUG_TAB); + xed_debug (DEBUG_TAB); - g_return_val_if_fail (XED_IS_TAB (tab), 0); + g_return_val_if_fail (XED_IS_TAB (tab), 0); - return tab->priv->auto_save_interval; + return tab->priv->auto_save_interval; } /** * xed_tab_set_auto_save_interval: * @tab: a #XedTab * @interval: the new interval - * - * Sets the interval for the autosave feature. It does nothing if the - * interval is the same as the one already present. It removes the old - * interval timeout and adds a new one with the autosave passed as - * argument. + * + * Sets the interval for the autosave feature. **/ -void -xed_tab_set_auto_save_interval (XedTab *tab, - gint interval) +void +xed_tab_set_auto_save_interval (XedTab *tab, + gint interval) { - XedDocument *doc = NULL; - - xed_debug (DEBUG_TAB); - - g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (interval > 0); - doc = xed_tab_get_document(tab); + xed_debug (DEBUG_TAB); - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (interval > 0); - - if (tab->priv->auto_save_interval == interval) - return; - - tab->priv->auto_save_interval = interval; - - if (!tab->priv->auto_save) - return; - - if (tab->priv->auto_save_timeout > 0) - { - g_return_if_fail (!xed_document_is_untitled (doc)); - g_return_if_fail (!xed_document_get_readonly (doc)); - - remove_auto_save_timeout (tab); - - install_auto_save_timeout (tab); - } + if (tab->priv->auto_save_interval != interval) + { + tab->priv->auto_save_interval = interval; + remove_auto_save_timeout (tab); + update_auto_save_timeout (tab); + } } void -xed_tab_set_info_bar (XedTab *tab, - GtkWidget *info_bar) +xed_tab_set_info_bar (XedTab *tab, + GtkWidget *info_bar) { - g_return_if_fail (XED_IS_TAB (tab)); - g_return_if_fail (info_bar == NULL || GTK_IS_WIDGET (info_bar)); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail (info_bar == NULL || GTK_IS_WIDGET (info_bar)); - /* FIXME: this can cause problems with the tab state machine */ - set_message_area (tab, info_bar); + /* FIXME: this can cause problems with the tab state machine */ + set_info_bar (tab, info_bar); +} + +GtkWidget * +_xed_tab_get_view_frame (XedTab *tab) +{ + return GTK_WIDGET (tab->priv->frame); } diff --git a/xed/xed-tab.h b/xed/xed-tab.h index cce9ec6..43f0cf2 100644 --- a/xed/xed-tab.h +++ b/xed/xed-tab.h @@ -2,7 +2,7 @@ * xed-tab.h * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -31,8 +31,7 @@ #ifndef __XED_TAB_H__ #define __XED_TAB_H__ -#include - +#include #include #include @@ -40,26 +39,23 @@ G_BEGIN_DECLS typedef enum { - XED_TAB_STATE_NORMAL = 0, - XED_TAB_STATE_LOADING, - XED_TAB_STATE_REVERTING, - XED_TAB_STATE_SAVING, - XED_TAB_STATE_PRINTING, - XED_TAB_STATE_PRINT_PREVIEWING, - XED_TAB_STATE_SHOWING_PRINT_PREVIEW, - XED_TAB_STATE_GENERIC_NOT_EDITABLE, - XED_TAB_STATE_LOADING_ERROR, - XED_TAB_STATE_REVERTING_ERROR, - XED_TAB_STATE_SAVING_ERROR, - XED_TAB_STATE_GENERIC_ERROR, - XED_TAB_STATE_CLOSING, - XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION, - XED_TAB_NUM_OF_STATES /* This is not a valid state */ + XED_TAB_STATE_NORMAL = 0, + XED_TAB_STATE_LOADING, + XED_TAB_STATE_REVERTING, + XED_TAB_STATE_SAVING, + XED_TAB_STATE_PRINTING, + XED_TAB_STATE_PRINT_PREVIEWING, + XED_TAB_STATE_SHOWING_PRINT_PREVIEW, + XED_TAB_STATE_GENERIC_NOT_EDITABLE, + XED_TAB_STATE_LOADING_ERROR, + XED_TAB_STATE_REVERTING_ERROR, + XED_TAB_STATE_SAVING_ERROR, + XED_TAB_STATE_GENERIC_ERROR, + XED_TAB_STATE_CLOSING, + XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION, + XED_TAB_NUM_OF_STATES /* This is not a valid state */ } XedTabState; -/* - * Type checking and casting macros - */ #define XED_TYPE_TAB (xed_tab_get_type()) #define XED_TAB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_TAB, XedTab)) #define XED_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_TAB, XedTabClass)) @@ -67,95 +63,101 @@ typedef enum #define XED_IS_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_TAB)) #define XED_TAB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_TAB, XedTabClass)) -/* Private structure type */ -typedef struct _XedTabPrivate XedTabPrivate; +typedef struct _XedTab XedTab; +typedef struct _XedTabPrivate XedTabPrivate; +typedef struct _XedTabClass XedTabClass; -/* - * Main object structure - */ -typedef struct _XedTab XedTab; - -struct _XedTab +struct _XedTab { - GtkBox vbox; + GtkBox vbox; - /*< private > */ - XedTabPrivate *priv; + /*< private > */ + XedTabPrivate *priv; }; -/* - * Class definition - */ -typedef struct _XedTabClass XedTabClass; - -struct _XedTabClass +struct _XedTabClass { - GtkBoxClass parent_class; + GtkBoxClass parent_class; }; -/* - * Public methods - */ -GType xed_tab_get_type (void) G_GNUC_CONST; +GType xed_tab_get_type (void) G_GNUC_CONST; -XedView *xed_tab_get_view (XedTab *tab); +XedView *xed_tab_get_view (XedTab *tab); /* This is only an helper function */ -XedDocument *xed_tab_get_document (XedTab *tab); +XedDocument *xed_tab_get_document (XedTab *tab); +XedTab *xed_tab_get_from_document (XedDocument *doc); -XedTab *xed_tab_get_from_document (XedDocument *doc); +XedTabState xed_tab_get_state (XedTab *tab); -XedTabState xed_tab_get_state (XedTab *tab); +gboolean xed_tab_get_auto_save_enabled (XedTab *tab); +void xed_tab_set_auto_save_enabled (XedTab *tab, + gboolean enable); -gboolean xed_tab_get_auto_save_enabled - (XedTab *tab); +gint xed_tab_get_auto_save_interval (XedTab *tab); +void xed_tab_set_auto_save_interval (XedTab *tab, + gint interval); -void xed_tab_set_auto_save_enabled - (XedTab *tab, - gboolean enable); - -gint xed_tab_get_auto_save_interval - (XedTab *tab); - -void xed_tab_set_auto_save_interval - (XedTab *tab, - gint interval); - -void xed_tab_set_info_bar (XedTab *tab, - GtkWidget *info_bar); +void xed_tab_set_info_bar (XedTab *tab, + GtkWidget *info_bar); /* * Non exported methods */ -GtkWidget *_xed_tab_new (void); +GtkWidget *_xed_tab_new (void); -/* Whether create is TRUE, creates a new empty document if location does +/* Whether create is TRUE, creates a new empty document if location does not refer to an existing file */ -GtkWidget *_xed_tab_new_from_uri (const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create); -gchar *_xed_tab_get_name (XedTab *tab); -gchar *_xed_tab_get_tooltips (XedTab *tab); -GdkPixbuf *_xed_tab_get_icon (XedTab *tab); -void _xed_tab_load (XedTab *tab, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create); -void _xed_tab_revert (XedTab *tab); -void _xed_tab_save (XedTab *tab); -void _xed_tab_save_as (XedTab *tab, - const gchar *uri, - const XedEncoding *encoding, - XedDocumentNewlineType newline_type); +GtkWidget *_xed_tab_new_from_location (GFile *location, + const GtkSourceEncoding *encoding, + gint line_pos, + gboolean create); -void _xed_tab_print (XedTab *tab); -void _xed_tab_print_preview (XedTab *tab); +GtkWidget *_xed_tab_new_from_stream (GInputStream *stream, + const GtkSourceEncoding *encoding, + gint line_pos); -void _xed_tab_mark_for_closing (XedTab *tab); +gchar *_xed_tab_get_name (XedTab *tab); -gboolean _xed_tab_can_close (XedTab *tab); +gchar *_xed_tab_get_tooltips (XedTab *tab); + +GdkPixbuf *_xed_tab_get_icon (XedTab *tab); + +void _xed_tab_load (XedTab *tab, + GFile *location, + const GtkSourceEncoding *encoding, + gint line_pos, + gboolean create); + +void _xed_tab_load_stream (XedTab *tab, + GInputStream *location, + const GtkSourceEncoding *encoding, + gint line_pos); + +void _xed_tab_revert (XedTab *tab); + +void _xed_tab_save_async (XedTab *tab, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + +gboolean _xed_tab_save_finish (XedTab *tab, + GAsyncResult *result); + +void _xed_tab_save_as_async (XedTab *tab, + GFile *location, + const GtkSourceEncoding *encoding, + GtkSourceNewlineType newline_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +void _xed_tab_print (XedTab *tab); +void _xed_tab_print_preview (XedTab *tab); +void _xed_tab_mark_for_closing (XedTab *tab); +gboolean _xed_tab_can_close (XedTab *tab); +GtkWidget *_xed_tab_get_view_frame (XedTab *tab); G_END_DECLS diff --git a/xed/xed-ui.h b/xed/xed-ui.h index 321597a..acefb5e 100644 --- a/xed/xed-ui.h +++ b/xed/xed-ui.h @@ -2,7 +2,7 @@ * xed-ui.h * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -67,7 +67,7 @@ static const GtkActionEntry xed_always_sensitive_menu_entries[] = N_("Open the xed manual"), G_CALLBACK (_xed_cmd_help_contents) }, { "HelpAbout", "help-about-symbolic", N_("_About"), NULL, N_("About this application"), G_CALLBACK (_xed_cmd_help_about) }, - + /* Fullscreen toolbar */ { "LeaveFullscreen", "view-restore-symbolic", NULL, NULL, N_("Leave fullscreen mode"), @@ -156,7 +156,10 @@ static const GtkToggleActionEntry xed_always_sensitive_toggle_menu_entries[] = G_CALLBACK (_xed_cmd_view_show_statusbar), TRUE }, { "ViewFullscreen", GTK_STOCK_FULLSCREEN, NULL, "F11", N_("Edit text in fullscreen"), - G_CALLBACK (_xed_cmd_view_toggle_fullscreen_mode), FALSE } + G_CALLBACK (_xed_cmd_view_toggle_fullscreen_mode), FALSE }, + { "ViewWordWrap", NULL, N_("_Word wrap"), NULL, + N_("Set word wrap for the current document"), + G_CALLBACK (_xed_cmd_view_toggle_word_wrap), FALSE } }; /* separate group, should be always sensitive except when there are no panes */ diff --git a/xed/xed-utils.c b/xed/xed-utils.c index 600ff50..10cb13e 100644 --- a/xed/xed-utils.c +++ b/xed/xed-utils.c @@ -3,8 +3,8 @@ * This file is part of xed * * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence - * Copyright (C) 2000, 2002 Chema Celorio, Paolo Maggi - * Copyright (C) 2003-2005 Paolo Maggi + * Copyright (C) 2000, 2002 Chema Celorio, Paolo Maggi + * Copyright (C) 2003-2005 Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,14 +18,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 1998-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 1998-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -44,11 +44,11 @@ #include #include #include +#include #include "xed-utils.h" #include "xed-document.h" -#include "xed-prefs-manager.h" #include "xed-debug.h" /* For the workspace/viewport stuff */ @@ -61,235 +61,150 @@ #define STDIN_DELAY_MICROSECONDS 100000 -/** - * xed_utils_uris_has_file_scheme - * - * Returns: %TRUE if @uri is a file: uri and is not a chained uri - */ -gboolean -xed_utils_uri_has_file_scheme (const gchar *uri) -{ - GFile *gfile; - gboolean res; - - gfile = g_file_new_for_uri (uri); - res = g_file_has_uri_scheme (gfile, "file"); - - g_object_unref (gfile); - return res; -} - -/* FIXME: we should check for chained URIs */ -gboolean -xed_utils_uri_has_writable_scheme (const gchar *uri) -{ - GFile *gfile; - gchar *scheme; - GSList *writable_schemes; - gboolean res; - - gfile = g_file_new_for_uri (uri); - scheme = g_file_get_uri_scheme (gfile); - - g_return_val_if_fail (scheme != NULL, FALSE); - - g_object_unref (gfile); - - writable_schemes = xed_prefs_manager_get_writable_vfs_schemes (); - - /* CHECK: should we use g_ascii_strcasecmp? - Paolo (Nov 6, 2005) */ - res = (g_slist_find_custom (writable_schemes, - scheme, - (GCompareFunc)strcmp) != NULL); - - g_slist_foreach (writable_schemes, (GFunc)g_free, NULL); - g_slist_free (writable_schemes); - - g_free (scheme); - - return res; -} - static void -widget_get_origin (GtkWidget *widget, gint *x, gint *y) +widget_get_origin (GtkWidget *widget, + gint *x, + gint *y) { - GdkWindow *window; + GdkWindow *window; - window = gtk_widget_get_window (widget); - gdk_window_get_origin (window, x, y); + window = gtk_widget_get_window (widget); + gdk_window_get_origin (window, x, y); } void xed_utils_menu_position_under_widget (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data) + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data) { - GtkWidget *widget; - GtkRequisition requisition; - GtkAllocation allocation; + GtkWidget *widget; + GtkRequisition requisition; + GtkAllocation allocation; - widget = GTK_WIDGET (user_data); - widget_get_origin (widget, x, y); + widget = GTK_WIDGET (user_data); + widget_get_origin (widget, x, y); - gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &requisition); + gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &requisition); - gtk_widget_get_allocation (widget, &allocation); + gtk_widget_get_allocation (widget, &allocation); - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - { - *x += allocation.x + allocation.width - requisition.width; - } - else - { - *x += allocation.x; - } + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + { + *x += allocation.x + allocation.width - requisition.width; + } + else + { + *x += allocation.x; + } - *y += allocation.y + allocation.height; + *y += allocation.y + allocation.height; - *push_in = TRUE; + *push_in = TRUE; } void xed_utils_menu_position_under_tree_view (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data) + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data) { - GtkTreeView *tree = GTK_TREE_VIEW (user_data); - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - - model = gtk_tree_view_get_model (tree); - g_return_if_fail (model != NULL); + GtkTreeView *tree = GTK_TREE_VIEW (user_data); + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; - selection = gtk_tree_view_get_selection (tree); - g_return_if_fail (selection != NULL); + model = gtk_tree_view_get_model (tree); + g_return_if_fail (model != NULL); - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - GtkTreePath *path; - GdkRectangle rect; + selection = gtk_tree_view_get_selection (tree); + g_return_if_fail (selection != NULL); - widget_get_origin (GTK_WIDGET (tree), x, y); - - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_view_get_cell_area (tree, path, - gtk_tree_view_get_column (tree, 0), /* FIXME 0 for RTL ? */ - &rect); - gtk_tree_path_free (path); - - *x += rect.x; - *y += rect.y + rect.height; - - if (gtk_widget_get_direction (GTK_WIDGET (tree)) == GTK_TEXT_DIR_RTL) - { - GtkRequisition requisition; - gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &requisition); + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + GtkTreePath *path; + GdkRectangle rect; - *x += rect.width - requisition.width; - } - } - else - { - /* no selection -> regular "under widget" positioning */ - xed_utils_menu_position_under_widget (menu, - x, y, push_in, - tree); - } + widget_get_origin (GTK_WIDGET (tree), x, y); + + path = gtk_tree_model_get_path (model, &iter); + gtk_tree_view_get_cell_area (tree, path, + gtk_tree_view_get_column (tree, 0), /* FIXME 0 for RTL ? */ + &rect); + gtk_tree_path_free (path); + + *x += rect.x; + *y += rect.y + rect.height; + + if (gtk_widget_get_direction (GTK_WIDGET (tree)) == GTK_TEXT_DIR_RTL) + { + GtkRequisition requisition; + gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &requisition); + + *x += rect.width - requisition.width; + } + } + else + { + /* no selection -> regular "under widget" positioning */ + xed_utils_menu_position_under_widget (menu, x, y, push_in, tree); + } } /* FIXME: remove this with gtk 2.12, it has gdk_color_to_string */ -gchar * +gchar * xed_gdk_color_to_string (GdkColor color) { - return g_strdup_printf ("#%04x%04x%04x", - color.red, - color.green, - color.blue); -} - -GtkWidget * -xed_gtk_button_new_with_stock_icon (const gchar *label, - const gchar *stock_id) -{ - GtkWidget *button; - - button = gtk_button_new_with_mnemonic (label); - gtk_button_set_image (GTK_BUTTON (button), - gtk_image_new_from_stock (stock_id, - GTK_ICON_SIZE_BUTTON)); - - return button; -} - -GtkWidget * -xed_dialog_add_button (GtkDialog *dialog, - const gchar *text, - const gchar *stock_id, - gint response_id) -{ - GtkWidget *button; - - g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL); - g_return_val_if_fail (text != NULL, NULL); - g_return_val_if_fail (stock_id != NULL, NULL); - - button = xed_gtk_button_new_with_stock_icon (text, stock_id); - g_return_val_if_fail (button != NULL, NULL); - - gtk_widget_set_can_default (button, TRUE); - - gtk_widget_show (button); - - gtk_dialog_add_action_widget (dialog, button, response_id); - - return button; + return g_strdup_printf ("#%04x%04x%04x", color.red, color.green, color.blue); } /* * n: len of the string in bytes */ -gboolean -g_utf8_caselessnmatch (const char *s1, const char *s2, gssize n1, gssize n2) +gboolean +g_utf8_caselessnmatch (const char *s1, + const char *s2, + gssize n1, + gssize n2) { - gchar *casefold; - gchar *normalized_s1; - gchar *normalized_s2; - gint len_s1; - gint len_s2; - gboolean ret = FALSE; + gchar *casefold; + gchar *normalized_s1; + gchar *normalized_s2; + gint len_s1; + gint len_s2; + gboolean ret = FALSE; - g_return_val_if_fail (s1 != NULL, FALSE); - g_return_val_if_fail (s2 != NULL, FALSE); - g_return_val_if_fail (n1 > 0, FALSE); - g_return_val_if_fail (n2 > 0, FALSE); + g_return_val_if_fail (s1 != NULL, FALSE); + g_return_val_if_fail (s2 != NULL, FALSE); + g_return_val_if_fail (n1 > 0, FALSE); + g_return_val_if_fail (n2 > 0, FALSE); - casefold = g_utf8_casefold (s1, n1); - normalized_s1 = g_utf8_normalize (casefold, -1, G_NORMALIZE_NFD); - g_free (casefold); + casefold = g_utf8_casefold (s1, n1); + normalized_s1 = g_utf8_normalize (casefold, -1, G_NORMALIZE_NFD); + g_free (casefold); - casefold = g_utf8_casefold (s2, n2); - normalized_s2 = g_utf8_normalize (casefold, -1, G_NORMALIZE_NFD); - g_free (casefold); + casefold = g_utf8_casefold (s2, n2); + normalized_s2 = g_utf8_normalize (casefold, -1, G_NORMALIZE_NFD); + g_free (casefold); - len_s1 = strlen (normalized_s1); - len_s2 = strlen (normalized_s2); + len_s1 = strlen (normalized_s1); + len_s2 = strlen (normalized_s2); - if (len_s1 < len_s2) - goto finally_2; + if (len_s1 < len_s2) + { + goto finally_2; + } + + ret = (strncmp (normalized_s1, normalized_s2, len_s2) == 0); - ret = (strncmp (normalized_s1, normalized_s2, len_s2) == 0); - finally_2: - g_free (normalized_s1); - g_free (normalized_s2); + g_free (normalized_s1); + g_free (normalized_s2); - return ret; + return ret; } /** @@ -302,22 +217,28 @@ finally_2: * for a specified gtk widget. */ void -xed_utils_set_atk_name_description (GtkWidget *widget, - const gchar *name, - const gchar *description) +xed_utils_set_atk_name_description (GtkWidget *widget, + const gchar *name, + const gchar *description) { - AtkObject *aobj; + AtkObject *aobj; - aobj = gtk_widget_get_accessible (widget); + aobj = gtk_widget_get_accessible (widget); - if (!(GTK_IS_ACCESSIBLE (aobj))) - return; + if (!(GTK_IS_ACCESSIBLE (aobj))) + { + return; + } - if(name) - atk_object_set_name (aobj, name); + if (name) + { + atk_object_set_name (aobj, name); + } - if(description) - atk_object_set_description (aobj, description); + if (description) + { + atk_object_set_description (aobj, description); + } } /** @@ -330,375 +251,236 @@ xed_utils_set_atk_name_description (GtkWidget *widget, * between 2 specified widgets. */ void -xed_utils_set_atk_relation (GtkWidget *obj1, - GtkWidget *obj2, - AtkRelationType rel_type ) +xed_utils_set_atk_relation (GtkWidget *obj1, + GtkWidget *obj2, + AtkRelationType rel_type ) { - AtkObject *atk_obj1, *atk_obj2; - AtkRelationSet *relation_set; - AtkObject *targets[1]; - AtkRelation *relation; + AtkObject *atk_obj1, *atk_obj2; + AtkRelationSet *relation_set; + AtkObject *targets[1]; + AtkRelation *relation; - atk_obj1 = gtk_widget_get_accessible (obj1); - atk_obj2 = gtk_widget_get_accessible (obj2); + atk_obj1 = gtk_widget_get_accessible (obj1); + atk_obj2 = gtk_widget_get_accessible (obj2); - if (!(GTK_IS_ACCESSIBLE (atk_obj1)) || !(GTK_IS_ACCESSIBLE (atk_obj2))) - return; + if (!(GTK_IS_ACCESSIBLE (atk_obj1)) || !(GTK_IS_ACCESSIBLE (atk_obj2))) + { + return; + } - relation_set = atk_object_ref_relation_set (atk_obj1); - targets[0] = atk_obj2; + relation_set = atk_object_ref_relation_set (atk_obj1); + targets[0] = atk_obj2; - relation = atk_relation_new (targets, 1, rel_type); - atk_relation_set_add (relation_set, relation); + relation = atk_relation_new (targets, 1, rel_type); + atk_relation_set_add (relation_set, relation); - g_object_unref (G_OBJECT (relation)); + g_object_unref (G_OBJECT (relation)); } -gboolean -xed_utils_uri_exists (const gchar* text_uri) +void +xed_warning (GtkWindow *parent, + const gchar *format, + ...) { - GFile *gfile; - gboolean res; - - g_return_val_if_fail (text_uri != NULL, FALSE); - - xed_debug_message (DEBUG_UTILS, "text_uri: %s", text_uri); + va_list args; + gchar *str; + GtkWidget *dialog; + GtkWindowGroup *wg = NULL; - gfile = g_file_new_for_uri (text_uri); - res = g_file_query_exists (gfile, NULL); + g_return_if_fail (format != NULL); - g_object_unref (gfile); + if (parent != NULL) + { + wg = gtk_window_get_group (parent); + } - xed_debug_message (DEBUG_UTILS, res ? "TRUE" : "FALSE"); + va_start (args, format); + str = g_strdup_vprintf (format, args); + va_end (args); - return res; -} + dialog = gtk_message_dialog_new_with_markup (parent, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "%s", str); -gchar * -xed_utils_escape_search_text (const gchar* text) -{ - GString *str; - gint length; - const gchar *p; - const gchar *end; + g_free (str); - if (text == NULL) - return NULL; + if (wg != NULL) + { + gtk_window_group_add_window (wg, GTK_WINDOW (dialog)); + } - xed_debug_message (DEBUG_SEARCH, "Text: %s", text); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - length = strlen (text); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - /* no escape when typing. - * The short circuit works only for ascii, but we only - * care about not escaping a single '\' */ - if (length == 1) - return g_strdup (text); + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (gtk_widget_destroy), NULL); - str = g_string_new (""); - - p = text; - end = text + length; - - while (p != end) - { - const gchar *next; - next = g_utf8_next_char (p); - - switch (*p) - { - case '\n': - g_string_append (str, "\\n"); - break; - case '\r': - g_string_append (str, "\\r"); - break; - case '\t': - g_string_append (str, "\\t"); - break; - case '\\': - g_string_append (str, "\\\\"); - break; - default: - g_string_append_len (str, p, next - p); - break; - } - - p = next; - } - - return g_string_free (str, FALSE); -} - -gchar * -xed_utils_unescape_search_text (const gchar *text) -{ - GString *str; - gint length; - gboolean drop_prev = FALSE; - const gchar *cur; - const gchar *end; - const gchar *prev; - - if (text == NULL) - return NULL; - - length = strlen (text); - - str = g_string_new (""); - - cur = text; - end = text + length; - prev = NULL; - - while (cur != end) - { - const gchar *next; - next = g_utf8_next_char (cur); - - if (prev && (*prev == '\\')) - { - switch (*cur) - { - case 'n': - str = g_string_append (str, "\n"); - break; - case 'r': - str = g_string_append (str, "\r"); - break; - case 't': - str = g_string_append (str, "\t"); - break; - case '\\': - str = g_string_append (str, "\\"); - drop_prev = TRUE; - break; - default: - str = g_string_append (str, "\\"); - str = g_string_append_len (str, cur, next - cur); - break; - } - } - else if (*cur != '\\') - { - str = g_string_append_len (str, cur, next - cur); - } - else if ((next == end) && (*cur == '\\')) - { - str = g_string_append (str, "\\"); - } - - if (!drop_prev) - { - prev = cur; - } - else - { - prev = NULL; - drop_prev = FALSE; - } - - cur = next; - } - - return g_string_free (str, FALSE); -} - -void -xed_warning (GtkWindow *parent, const gchar *format, ...) -{ - va_list args; - gchar *str; - GtkWidget *dialog; - GtkWindowGroup *wg = NULL; - - g_return_if_fail (format != NULL); - - if (parent != NULL) - wg = gtk_window_get_group (parent); - - va_start (args, format); - str = g_strdup_vprintf (format, args); - va_end (args); - - dialog = gtk_message_dialog_new_with_markup ( - parent, - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "%s", str); - - g_free (str); - - if (wg != NULL) - gtk_window_group_add_window (wg, GTK_WINDOW (dialog)); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - - g_signal_connect (G_OBJECT (dialog), - "response", - G_CALLBACK (gtk_widget_destroy), - NULL); - - gtk_widget_show (dialog); + gtk_widget_show (dialog); } /* * Doubles underscore to avoid spurious menu accels. */ -gchar * +gchar * xed_utils_escape_underscores (const gchar* text, - gssize length) + gssize length) { - GString *str; - const gchar *p; - const gchar *end; + GString *str; + const gchar *p; + const gchar *end; - g_return_val_if_fail (text != NULL, NULL); + g_return_val_if_fail (text != NULL, NULL); - if (length < 0) - length = strlen (text); + if (length < 0) + { + length = strlen (text); + } - str = g_string_sized_new (length); + str = g_string_sized_new (length); - p = text; - end = text + length; + p = text; + end = text + length; - while (p != end) - { - const gchar *next; - next = g_utf8_next_char (p); + while (p != end) + { + const gchar *next; + next = g_utf8_next_char (p); - switch (*p) - { - case '_': - g_string_append (str, "__"); - break; - default: - g_string_append_len (str, p, next - p); - break; - } + switch (*p) + { + case '_': + g_string_append (str, "__"); + break; + default: + g_string_append_len (str, p, next - p); + break; + } - p = next; - } + p = next; + } - return g_string_free (str, FALSE); + return g_string_free (str, FALSE); } /* the following functions are taken from eel */ static gchar * xed_utils_str_truncate (const gchar *string, - guint truncate_length, - gboolean middle) + guint truncate_length, + gboolean middle) { - GString *truncated; - guint length; - guint n_chars; - guint num_left_chars; - guint right_offset; - guint delimiter_length; - const gchar *delimiter = "\342\200\246"; + GString *truncated; + guint length; + guint n_chars; + guint num_left_chars; + guint right_offset; + guint delimiter_length; + const gchar *delimiter = "\342\200\246"; - g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); - length = strlen (string); + length = strlen (string); - g_return_val_if_fail (g_utf8_validate (string, length, NULL), NULL); + g_return_val_if_fail (g_utf8_validate (string, length, NULL), NULL); - /* It doesnt make sense to truncate strings to less than - * the size of the delimiter plus 2 characters (one on each - * side) - */ - delimiter_length = g_utf8_strlen (delimiter, -1); - if (truncate_length < (delimiter_length + 2)) { - return g_strdup (string); - } + /* It doesnt make sense to truncate strings to less than + * the size of the delimiter plus 2 characters (one on each + * side) + */ + delimiter_length = g_utf8_strlen (delimiter, -1); + if (truncate_length < (delimiter_length + 2)) + { + return g_strdup (string); + } - n_chars = g_utf8_strlen (string, length); + n_chars = g_utf8_strlen (string, length); - /* Make sure the string is not already small enough. */ - if (n_chars <= truncate_length) { - return g_strdup (string); - } + /* Make sure the string is not already small enough. */ + if (n_chars <= truncate_length) + { + return g_strdup (string); + } - /* Find the 'middle' where the truncation will occur. */ - if (middle) - { - num_left_chars = (truncate_length - delimiter_length) / 2; - right_offset = n_chars - truncate_length + num_left_chars + delimiter_length; + /* Find the 'middle' where the truncation will occur. */ + if (middle) + { + num_left_chars = (truncate_length - delimiter_length) / 2; + right_offset = n_chars - truncate_length + num_left_chars + delimiter_length; - truncated = g_string_new_len (string, - g_utf8_offset_to_pointer (string, num_left_chars) - string); - g_string_append (truncated, delimiter); - g_string_append (truncated, g_utf8_offset_to_pointer (string, right_offset)); - } - else - { - num_left_chars = truncate_length - delimiter_length; - truncated = g_string_new_len (string, - g_utf8_offset_to_pointer (string, num_left_chars) - string); - g_string_append (truncated, delimiter); - } - - return g_string_free (truncated, FALSE); + truncated = g_string_new_len (string, g_utf8_offset_to_pointer (string, num_left_chars) - string); + g_string_append (truncated, delimiter); + g_string_append (truncated, g_utf8_offset_to_pointer (string, right_offset)); + } + else + { + num_left_chars = truncate_length - delimiter_length; + truncated = g_string_new_len (string, g_utf8_offset_to_pointer (string, num_left_chars) - string); + g_string_append (truncated, delimiter); + } + + return g_string_free (truncated, FALSE); } gchar * xed_utils_str_middle_truncate (const gchar *string, - guint truncate_length) + guint truncate_length) { - return xed_utils_str_truncate (string, truncate_length, TRUE); + return xed_utils_str_truncate (string, truncate_length, TRUE); } gchar * xed_utils_str_end_truncate (const gchar *string, - guint truncate_length) + guint truncate_length) { - return xed_utils_str_truncate (string, truncate_length, FALSE); + return xed_utils_str_truncate (string, truncate_length, FALSE); } gchar * xed_utils_make_valid_utf8 (const char *name) { - GString *string; - const char *remainder, *invalid; - int remaining_bytes, valid_bytes; + GString *string; + const char *remainder, *invalid; + int remaining_bytes, valid_bytes; - g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); - string = NULL; - remainder = name; - remaining_bytes = strlen (name); + string = NULL; + remainder = name; + remaining_bytes = strlen (name); - while (remaining_bytes != 0) { - if (g_utf8_validate (remainder, remaining_bytes, &invalid)) { - break; - } - valid_bytes = invalid - remainder; + while (remaining_bytes != 0) + { + if (g_utf8_validate (remainder, remaining_bytes, &invalid)) + { + break; + } + valid_bytes = invalid - remainder; - if (string == NULL) { - string = g_string_sized_new (remaining_bytes); - } - g_string_append_len (string, remainder, valid_bytes); - /* append U+FFFD REPLACEMENT CHARACTER */ - g_string_append (string, "\357\277\275"); + if (string == NULL) + { + string = g_string_sized_new (remaining_bytes); + } + g_string_append_len (string, remainder, valid_bytes); + /* append U+FFFD REPLACEMENT CHARACTER */ + g_string_append (string, "\357\277\275"); - remaining_bytes -= valid_bytes + 1; - remainder = invalid + 1; - } + remaining_bytes -= valid_bytes + 1; + remainder = invalid + 1; + } - if (string == NULL) { - return g_strdup (name); - } + if (string == NULL) + { + return g_strdup (name); + } - g_string_append (string, remainder); - - g_assert (g_utf8_validate (string->str, -1, NULL)); + g_string_append (string, remainder); - return g_string_free (string, FALSE); + g_assert (g_utf8_validate (string->str, -1, NULL)); + + return g_string_free (string, FALSE); } /** @@ -709,27 +491,27 @@ xed_utils_make_valid_utf8 (const char *name) gchar * xed_utils_uri_get_dirname (const gchar *uri) { - gchar *res; - gchar *str; + gchar *res; + gchar *str; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); - /* CHECK: does it work with uri chaining? - Paolo */ - str = g_path_get_dirname (uri); - g_return_val_if_fail (str != NULL, g_strdup (".")); + /* CHECK: does it work with uri chaining? - Paolo */ + str = g_path_get_dirname (uri); + g_return_val_if_fail (str != NULL, g_strdup (".")); - if ((strlen (str) == 1) && (*str == '.')) - { - g_free (str); - - return NULL; - } + if ((strlen (str) == 1) && (*str == '.')) + { + g_free (str); - res = xed_utils_replace_home_dir_with_tilde (str); + return NULL; + } - g_free (str); - - return res; + res = xed_utils_replace_home_dir_with_tilde (str); + + g_free (str); + + return res; } /** @@ -746,109 +528,113 @@ xed_utils_uri_get_dirname (const gchar *uri) gchar * xed_utils_location_get_dirname_for_display (GFile *location) { - gchar *uri; - gchar *res; - GMount *mount; + gchar *uri; + gchar *res; + GMount *mount; - g_return_val_if_fail (location != NULL, NULL); + g_return_val_if_fail (location != NULL, NULL); - /* we use the parse name, that is either the local path - * or an uri but which is utf8 safe */ - uri = g_file_get_parse_name (location); + /* we use the parse name, that is either the local path + * or an uri but which is utf8 safe */ + uri = g_file_get_parse_name (location); - /* FIXME: this is sync... is it a problem? */ - mount = g_file_find_enclosing_mount (location, NULL, NULL); - if (mount != NULL) - { - gchar *mount_name; - gchar *path = NULL; - gchar *dirname; + /* FIXME: this is sync... is it a problem? */ + mount = g_file_find_enclosing_mount (location, NULL, NULL); + if (mount != NULL) + { + gchar *mount_name; + gchar *path = NULL; + gchar *dirname; - mount_name = g_mount_get_name (mount); - g_object_unref (mount); + mount_name = g_mount_get_name (mount); + g_object_unref (mount); - /* obtain the "path" part of the uri */ - xed_utils_decode_uri (uri, - NULL, NULL, - NULL, NULL, - &path); + /* obtain the "path" part of the uri */ + xed_utils_decode_uri (uri, + NULL, NULL, + NULL, NULL, + &path); - if (path == NULL) - { - dirname = xed_utils_uri_get_dirname (uri); - } - else - { - dirname = xed_utils_uri_get_dirname (path); - } + if (path == NULL) + { + dirname = xed_utils_uri_get_dirname (uri); + } + else + { + dirname = xed_utils_uri_get_dirname (path); + } - if (dirname == NULL || strcmp (dirname, ".") == 0) - { - res = mount_name; - } - else - { - res = g_strdup_printf ("%s %s", mount_name, dirname); - g_free (mount_name); - } + if (dirname == NULL || strcmp (dirname, ".") == 0) + { + res = mount_name; + } + else + { + res = g_strdup_printf ("%s %s", mount_name, dirname); + g_free (mount_name); + } - g_free (path); - g_free (dirname); - } - else - { - /* fallback for local files or uris without mounts */ - res = xed_utils_uri_get_dirname (uri); - } + g_free (path); + g_free (dirname); + } + else + { + /* fallback for local files or uris without mounts */ + res = xed_utils_uri_get_dirname (uri); + } - g_free (uri); + g_free (uri); - return res; + return res; } gchar * xed_utils_replace_home_dir_with_tilde (const gchar *uri) { - gchar *tmp; - gchar *home; + gchar *tmp; + gchar *home; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); - /* Note that g_get_home_dir returns a const string */ - tmp = (gchar *)g_get_home_dir (); + /* Note that g_get_home_dir returns a const string */ + tmp = (gchar *)g_get_home_dir (); - if (tmp == NULL) - return g_strdup (uri); + if (tmp == NULL) + { + return g_strdup (uri); + } - home = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL); - if (home == NULL) - return g_strdup (uri); + home = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL); + if (home == NULL) + { + return g_strdup (uri); + } - if (strcmp (uri, home) == 0) - { - g_free (home); - - return g_strdup ("~"); - } + if (strcmp (uri, home) == 0) + { + g_free (home); - tmp = home; - home = g_strdup_printf ("%s/", tmp); - g_free (tmp); + return g_strdup ("~"); + } - if (g_str_has_prefix (uri, home)) - { - gchar *res; + tmp = home; + home = g_strdup_printf ("%s/", tmp); + g_free (tmp); - res = g_strdup_printf ("~/%s", uri + strlen (home)); + if (g_str_has_prefix (uri, home)) + { + gchar *res; - g_free (home); - - return res; - } + res = g_strdup_printf ("~/%s", uri + strlen (home)); - g_free (home); + g_free (home); - return g_strdup (uri); + return res; + } + + g_free (home); + + return g_strdup (uri); } /* the following two functions are courtesy of galeon */ @@ -867,40 +653,44 @@ guint xed_utils_get_current_workspace (GdkScreen *screen) { #ifdef GDK_WINDOWING_X11 - GdkWindow *root_win; - GdkDisplay *display; - Atom type; - gint format; - gulong nitems; - gulong bytes_after; - guint *current_desktop; - gint err, result; - guint ret = 0; + GdkWindow *root_win; + GdkDisplay *display; + Atom type; + gint format; + gulong nitems; + gulong bytes_after; + guint *current_desktop; + gint err, result; + guint ret = 0; - g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); - root_win = gdk_screen_get_root_window (screen); - display = gdk_screen_get_display (screen); + root_win = gdk_screen_get_root_window (screen); + display = gdk_screen_get_display (screen); - gdk_error_trap_push (); - result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (root_win), - gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"), - 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, - &bytes_after, (gpointer) ¤t_desktop); - err = gdk_error_trap_pop (); + gdk_error_trap_push (); + result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (root_win), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"), + 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, + &bytes_after, (gpointer) ¤t_desktop); + err = gdk_error_trap_pop (); - if (err != Success || result != Success) - return ret; + if (err != Success || result != Success) + { + return ret; + } - if (type == XA_CARDINAL && format == 32 && nitems > 0) - ret = current_desktop[0]; + if (type == XA_CARDINAL && format == 32 && nitems > 0) + { + ret = current_desktop[0]; + } - XFree (current_desktop); - return ret; + XFree (current_desktop); + return ret; #else - /* FIXME: on mac etc proably there are native APIs - * to get the current workspace etc */ - return 0; + /* FIXME: on mac etc proably there are native APIs + * to get the current workspace etc */ + return 0; #endif } @@ -917,41 +707,45 @@ guint xed_utils_get_window_workspace (GtkWindow *gtkwindow) { #ifdef GDK_WINDOWING_X11 - GdkWindow *window; - GdkDisplay *display; - Atom type; - gint format; - gulong nitems; - gulong bytes_after; - guint *workspace; - gint err, result; - guint ret = XED_ALL_WORKSPACES; + GdkWindow *window; + GdkDisplay *display; + Atom type; + gint format; + gulong nitems; + gulong bytes_after; + guint *workspace; + gint err, result; + guint ret = XED_ALL_WORKSPACES; - g_return_val_if_fail (GTK_IS_WINDOW (gtkwindow), 0); - g_return_val_if_fail (gtk_widget_get_realized (GTK_WIDGET (gtkwindow)), 0); + g_return_val_if_fail (GTK_IS_WINDOW (gtkwindow), 0); + g_return_val_if_fail (gtk_widget_get_realized (GTK_WIDGET (gtkwindow)), 0); - window = gtk_widget_get_window (GTK_WIDGET (gtkwindow)); - display = gdk_window_get_display (window); + window = gtk_widget_get_window (GTK_WIDGET (gtkwindow)); + display = gdk_window_get_display (window); - gdk_error_trap_push (); - result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"), - 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, - &bytes_after, (gpointer) &workspace); - err = gdk_error_trap_pop (); + gdk_error_trap_push (); + result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"), + 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, + &bytes_after, (gpointer) &workspace); + err = gdk_error_trap_pop (); - if (err != Success || result != Success) - return ret; + if (err != Success || result != Success) + { + return ret; + } - if (type == XA_CARDINAL && format == 32 && nitems > 0) - ret = workspace[0]; + if (type == XA_CARDINAL && format == 32 && nitems > 0) + { + ret = workspace[0]; + } - XFree (workspace); - return ret; + XFree (workspace); + return ret; #else - /* FIXME: on mac etc proably there are native APIs - * to get the current workspace etc */ - return 0; + /* FIXME: on mac etc proably there are native APIs + * to get the current workspace etc */ + return 0; #endif } @@ -966,144 +760,172 @@ xed_utils_get_window_workspace (GtkWindow *gtkwindow) */ void xed_utils_get_current_viewport (GdkScreen *screen, - gint *x, - gint *y) + gint *x, + gint *y) { #ifdef GDK_WINDOWING_X11 - GdkWindow *root_win; - GdkDisplay *display; - Atom type; - gint format; - gulong nitems; - gulong bytes_after; - gulong *coordinates; - gint err, result; + GdkWindow *root_win; + GdkDisplay *display; + Atom type; + gint format; + gulong nitems; + gulong bytes_after; + gulong *coordinates; + gint err, result; - g_return_if_fail (GDK_IS_SCREEN (screen)); - g_return_if_fail (x != NULL && y != NULL); + g_return_if_fail (GDK_IS_SCREEN (screen)); + g_return_if_fail (x != NULL && y != NULL); - /* Default values for the viewport origin */ - *x = 0; - *y = 0; + /* Default values for the viewport origin */ + *x = 0; + *y = 0; - root_win = gdk_screen_get_root_window (screen); - display = gdk_screen_get_display (screen); + root_win = gdk_screen_get_root_window (screen); + display = gdk_screen_get_display (screen); - gdk_error_trap_push (); - result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (root_win), - gdk_x11_get_xatom_by_name_for_display (display, "_NET_DESKTOP_VIEWPORT"), - 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, - &bytes_after, (void*) &coordinates); - err = gdk_error_trap_pop (); + gdk_error_trap_push (); + result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (root_win), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_DESKTOP_VIEWPORT"), + 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, + &bytes_after, (void*) &coordinates); + err = gdk_error_trap_pop (); - if (err != Success || result != Success) - return; + if (err != Success || result != Success) + { + return; + } - if (type != XA_CARDINAL || format != 32 || nitems < 2) - { - XFree (coordinates); - return; - } + if (type != XA_CARDINAL || format != 32 || nitems < 2) + { + XFree (coordinates); + return; + } - *x = coordinates[0]; - *y = coordinates[1]; - XFree (coordinates); + *x = coordinates[0]; + *y = coordinates[1]; + XFree (coordinates); #else - /* FIXME: on mac etc proably there are native APIs - * to get the current workspace etc */ - *x = 0; - *y = 0; + /* FIXME: on mac etc proably there are native APIs + * to get the current workspace etc */ + *x = 0; + *y = 0; #endif } static gboolean is_valid_scheme_character (gchar c) { - return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.'; + return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.'; } static gboolean has_valid_scheme (const gchar *uri) { - const gchar *p; + const gchar *p; - p = uri; + p = uri; - if (!is_valid_scheme_character (*p)) { - return FALSE; - } + if (!is_valid_scheme_character (*p)) + { + return FALSE; + } - do { - p++; - } while (is_valid_scheme_character (*p)); + do + { + p++; + } while (is_valid_scheme_character (*p)); - return *p == ':'; + return *p == ':'; } gboolean -xed_utils_is_valid_uri (const gchar *uri) +xed_utils_is_valid_location (GFile *location) { - const guchar *p; + const guchar *p; + gchar *uri; + gboolean is_valid; - if (uri == NULL) - return FALSE; + if (location == NULL) + { + return FALSE; + } - if (!has_valid_scheme (uri)) - return FALSE; + uri = g_file_get_uri (location); - /* We expect to have a fully valid set of characters */ - for (p = (const guchar *)uri; *p; p++) { - if (*p == '%') - { - ++p; - if (!g_ascii_isxdigit (*p)) - return FALSE; + if (!has_valid_scheme (uri)) + { + g_free (uri); + return FALSE; + } - ++p; - if (!g_ascii_isxdigit (*p)) - return FALSE; - } - else - { - if (*p <= 32 || *p >= 128) - return FALSE; - } - } + is_valid = TRUE; - return TRUE; + /* We expect to have a fully valid set of characters */ + for (p = (const guchar *)uri; *p; p++) + { + if (*p == '%') + { + ++p; + if (!g_ascii_isxdigit (*p)) + { + is_valid = FALSE; + break; + } + + ++p; + if (!g_ascii_isxdigit (*p)) + { + is_valid = FALSE; + break; + } + } + else + { + if (*p <= 32 || *p >= 128) + { + is_valid = FALSE; + break; + } + } + } + + g_free (uri); + + return is_valid; } static GtkWidget * -handle_builder_error (const gchar *message, ...) +handle_builder_error (const gchar *message, + ...) { - GtkWidget *label; - gchar *msg; - gchar *msg_plain; - va_list args; + GtkWidget *label; + gchar *msg; + gchar *msg_plain; + va_list args; - va_start (args, message); - msg_plain = g_strdup_vprintf (message, args); - va_end (args); + va_start (args, message); + msg_plain = g_strdup_vprintf (message, args); + va_end (args); - label = gtk_label_new (NULL); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + label = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - msg = g_strconcat ("", - msg_plain, "\n\n", - _("Please check your installation."), - NULL); + msg = g_strconcat ("", + msg_plain, "\n\n", + _("Please check your installation."), + NULL); - gtk_label_set_markup (GTK_LABEL (label), msg); + gtk_label_set_markup (GTK_LABEL (label), msg); - g_free (msg_plain); - g_free (msg); + g_free (msg_plain); + g_free (msg); - gtk_widget_set_margin_left (label, 5); - gtk_widget_set_margin_right (label, 5); - gtk_widget_set_margin_top (label, 5); - gtk_widget_set_margin_bottom (label, 5); + gtk_widget_set_margin_start (label, 5); + gtk_widget_set_margin_end (label, 5); + gtk_widget_set_margin_top (label, 5); + gtk_widget_set_margin_bottom (label, 5); - return label; + return label; } /* FIXME this is an issue for introspection */ @@ -1125,129 +947,126 @@ handle_builder_error (const gchar *message, ...) */ gboolean xed_utils_get_ui_objects (const gchar *filename, - gchar **root_objects, - GtkWidget **error_widget, - const gchar *object_name, - ...) + gchar **root_objects, + GtkWidget **error_widget, + const gchar *object_name, + ...) { - GtkBuilder *builder; - va_list args; - const gchar *name; - GError *error = NULL; - gchar *filename_markup; - gboolean ret = TRUE; + GtkBuilder *builder; + va_list args; + const gchar *name; + GError *error = NULL; + gchar *filename_markup; + gboolean ret = TRUE; - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (error_widget != NULL, FALSE); - g_return_val_if_fail (object_name != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error_widget != NULL, FALSE); + g_return_val_if_fail (object_name != NULL, FALSE); - filename_markup = g_markup_printf_escaped ("%s", filename); - *error_widget = NULL; + filename_markup = g_markup_printf_escaped ("%s", filename); + *error_widget = NULL; - builder = gtk_builder_new (); - - if (root_objects != NULL) - { - gtk_builder_add_objects_from_file (builder, - filename, - root_objects, - &error); - } - else - { - gtk_builder_add_from_file (builder, - filename, - &error); - } + builder = gtk_builder_new (); - if (error != NULL) - { - *error_widget = handle_builder_error (_("Unable to open UI file %s. Error: %s"), - filename_markup, - error->message); - g_error_free (error); - g_free (filename_markup); - g_object_unref (builder); + if (root_objects != NULL) + { + gtk_builder_add_objects_from_file (builder, filename, root_objects, &error); + } + else + { + gtk_builder_add_from_file (builder, filename, &error); + } - return FALSE; - } + if (error != NULL) + { + *error_widget = handle_builder_error (_("Unable to open UI file %s. Error: %s"), + filename_markup, + error->message); + g_error_free (error); + g_free (filename_markup); + g_object_unref (builder); - va_start (args, object_name); - for (name = object_name; name; name = va_arg (args, const gchar *) ) - { - GObject **gobj; + return FALSE; + } - gobj = va_arg (args, GObject **); - *gobj = gtk_builder_get_object (builder, name); + va_start (args, object_name); + for (name = object_name; name; name = va_arg (args, const gchar *) ) + { + GObject **gobj; - if (!*gobj) - { - *error_widget = handle_builder_error (_("Unable to find the object '%s' inside file %s."), - name, - filename_markup), - ret = FALSE; - break; - } + gobj = va_arg (args, GObject **); + *gobj = gtk_builder_get_object (builder, name); - /* we return a new ref for the root objects, - * the others are already reffed by their parent root object */ - if (root_objects != NULL) - { - gint i; + if (!*gobj) + { + *error_widget = handle_builder_error (_("Unable to find the object '%s' inside file %s."), + name, + filename_markup), + ret = FALSE; + break; + } - for (i = 0; root_objects[i] != NULL; ++i) - { - if ((strcmp (name, root_objects[i]) == 0)) - { - g_object_ref (*gobj); - } - } - } - } - va_end (args); + /* we return a new ref for the root objects, + * the others are already reffed by their parent root object */ + if (root_objects != NULL) + { + gint i; - g_free (filename_markup); - g_object_unref (builder); + for (i = 0; root_objects[i] != NULL; ++i) + { + if ((strcmp (name, root_objects[i]) == 0)) + { + g_object_ref (*gobj); + } + } + } + } + va_end (args); - return ret; + g_free (filename_markup); + g_object_unref (builder); + + return ret; } gchar * xed_utils_make_canonical_uri_from_shell_arg (const gchar *str) -{ - GFile *gfile; - gchar *uri; +{ + GFile *gfile; + gchar *uri; - g_return_val_if_fail (str != NULL, NULL); - g_return_val_if_fail (*str != '\0', NULL); - - /* Note for the future: - * FIXME: is still still relevant? - * - * paolo: and flame whoever tells - * you that file:///mate/test_files/hëllò - * doesn't work --- that's not a valid URI - * - * federico: well, another solution that - * does not requires patch to _from_shell_args - * is to check that the string returned by it - * contains only ASCII chars - * paolo: hmmmm, isn't there - * mate_vfs_is_uri_valid() or something? - * : I will use xed_utils_is_valid_uri () - * - */ + g_return_val_if_fail (str != NULL, NULL); + g_return_val_if_fail (*str != '\0', NULL); - gfile = g_file_new_for_commandline_arg (str); - uri = g_file_get_uri (gfile); - g_object_unref (gfile); + /* Note for the future: + * FIXME: is still still relevant? + * + * paolo: and flame whoever tells + * you that file:///mate/test_files/hëllò + * doesn't work --- that's not a valid URI + * + * federico: well, another solution that + * does not requires patch to _from_shell_args + * is to check that the string returned by it + * contains only ASCII chars + * paolo: hmmmm, isn't there + * mate_vfs_is_uri_valid() or something? + * : I will use xed_utils_is_valid_uri () + * + */ - if (xed_utils_is_valid_uri (uri)) - return uri; - - g_free (uri); - return NULL; + gfile = g_file_new_for_commandline_arg (str); + + if (xed_utils_is_valid_location (gfile)) + { + uri = g_file_get_uri (gfile); + g_object_unref (gfile); + return uri; + } + + g_object_unref (gfile); + return NULL; } /** @@ -1260,122 +1079,104 @@ xed_utils_make_canonical_uri_from_shell_arg (const gchar *str) gboolean xed_utils_file_has_parent (GFile *gfile) { - GFile *parent; - gboolean ret; - - parent = g_file_get_parent (gfile); - ret = parent != NULL; - - if (parent) - g_object_unref (parent); - - return ret; + GFile *parent; + gboolean ret; + + parent = g_file_get_parent (gfile); + ret = parent != NULL; + + if (parent) + { + g_object_unref (parent); + } + + return ret; } /** * xed_utils_basename_for_display: - * @uri: uri for which the basename should be displayed + * @location: location for which the basename should be displayed * * Return the basename of a file suitable for display to users. */ gchar * -xed_utils_basename_for_display (gchar const *uri) +xed_utils_basename_for_display (GFile *location) { - gchar *name; - GFile *gfile; - gchar *hn; + gchar *name; + gchar *hn; + gchar *uri; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (G_IS_FILE (location), NULL); - gfile = g_file_new_for_uri (uri); + uri = g_file_get_uri (location); - /* First, try to query the display name, but only on local files */ - if (g_file_has_uri_scheme (gfile, "file")) - { - GFileInfo *info; - info = g_file_query_info (gfile, - G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, - G_FILE_QUERY_INFO_NONE, - NULL, - NULL); + /* First, try to query the display name, but only on local files */ + if (g_file_has_uri_scheme (location, "file")) + { + GFileInfo *info; + info = g_file_query_info (location, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); - if (info) - { - /* Simply get the display name to use as the basename */ - name = g_strdup (g_file_info_get_display_name (info)); - g_object_unref (info); - } - else - { - /* This is a local file, and therefore we will use - * g_filename_display_basename on the local path */ - gchar *local_path; - - local_path = g_file_get_path (gfile); - name = g_filename_display_basename (local_path); - g_free (local_path); - } - } - else if (xed_utils_file_has_parent (gfile) || !xed_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL)) - { - /* For remote files with a parent (so not just http://foo.com) - or remote file for which the decoding of the host name fails, - use the _parse_name and take basename of that */ - gchar *parse_name; - gchar *base; + if (info) + { + /* Simply get the display name to use as the basename */ + name = g_strdup (g_file_info_get_display_name (info)); + g_object_unref (info); + } + else + { + /* This is a local file, and therefore we will use + * g_filename_display_basename on the local path */ + gchar *local_path; - parse_name = g_file_get_parse_name (gfile); - base = g_filename_display_basename (parse_name); - name = g_uri_unescape_string (base, NULL); - - g_free (base); - g_free (parse_name); - } - else - { - /* display '/ on ' using the decoded host */ - gchar *hn_utf8; + local_path = g_file_get_path (location); + name = g_filename_display_basename (local_path); + g_free (local_path); + } + } + else if (xed_utils_file_has_parent (location) || !xed_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL)) + { + /* For remote files with a parent (so not just http://foo.com) + or remote file for which the decoding of the host name fails, + use the _parse_name and take basename of that */ + gchar *parse_name; + gchar *base; - if (hn != NULL) - hn_utf8 = xed_utils_make_valid_utf8 (hn); - else - /* we should never get here */ - hn_utf8 = g_strdup ("?"); + parse_name = g_file_get_parse_name (location); + base = g_filename_display_basename (parse_name); + name = g_uri_unescape_string (base, NULL); - /* Translators: '/ on ' */ - name = g_strdup_printf (_("/ on %s"), hn_utf8); + g_free (base); + g_free (parse_name); + } + else + { + /* display '/ on ' using the decoded host */ + gchar *hn_utf8; - g_free (hn_utf8); - g_free (hn); - } + if (hn != NULL) + { + hn_utf8 = xed_utils_make_valid_utf8 (hn); + } + else + { + /* we should never get here */ + hn_utf8 = g_strdup ("?"); + } - g_object_unref (gfile); + /* Translators: '/ on ' */ + name = g_strdup_printf (_("/ on %s"), hn_utf8); - return name; -} + g_free (hn_utf8); + g_free (hn); + } -/** - * xed_utils_uri_for_display: - * @uri: uri to be displayed. - * - * Filter, modify, unescape and change @uri to make it appropriate - * for display to users. - * - * This function is a convenient wrapper for g_file_get_parse_name - * - * Return value: a string which represents @uri and can be displayed. - */ -gchar * -xed_utils_uri_for_display (const gchar *uri) -{ - GFile *gfile; - gchar *parse_name; + g_free (uri); - gfile = g_file_new_for_uri (uri); - parse_name = g_file_get_parse_name (gfile); - g_object_unref (gfile); - - return parse_name; + return name; } /** @@ -1383,49 +1184,53 @@ xed_utils_uri_for_display (const gchar *uri) * @selection_data: the #GtkSelectionData from drag_data_received * * Create a list of valid uri's from a uri-list drop. - * - * Return value: a string array which will hold the uris or %NULL if there - * were no valid uris. g_strfreev should be used when the - * string array is no longer used + * + * Return value: (transfer full): a string array which will hold the uris or %NULL if there + * were no valid uris. g_strfreev should be used when the + * string array is no longer used */ gchar ** xed_utils_drop_get_uris (GtkSelectionData *selection_data) { - gchar **uris; - gint i; - gint p = 0; - gchar **uri_list; + gchar **uris; + gint i; + gint p = 0; + gchar **uri_list; - uris = g_uri_list_extract_uris ((gchar *) gtk_selection_data_get_data (selection_data)); - uri_list = g_new0(gchar *, g_strv_length (uris) + 1); + uris = g_uri_list_extract_uris ((gchar *) gtk_selection_data_get_data (selection_data)); + uri_list = g_new0(gchar *, g_strv_length (uris) + 1); - for (i = 0; uris[i] != NULL; i++) - { - gchar *uri; - - uri = xed_utils_make_canonical_uri_from_shell_arg (uris[i]); - - /* Silently ignore malformed URI/filename */ - if (uri != NULL) - uri_list[p++] = uri; - } + for (i = 0; uris[i] != NULL; i++) + { + gchar *uri; - g_strfreev (uris); + uri = xed_utils_make_canonical_uri_from_shell_arg (uris[i]); - if (*uri_list == NULL) - { - g_free(uri_list); - return NULL; - } + /* Silently ignore malformed URI/filename */ + if (uri != NULL) + { + uri_list[p++] = uri; + } + } - return uri_list; + g_strfreev (uris); + + if (*uri_list == NULL) + { + g_free(uri_list); + return NULL; + } + + return uri_list; } static void null_ptr (gchar **ptr) { - if (ptr) - *ptr = NULL; + if (ptr) + { + *ptr = NULL; + } } /** @@ -1442,133 +1247,221 @@ null_ptr (gchar **ptr) * scheme, user info, port, host and path. The return value pointer can be * %NULL to ignore certain parts of the uri. If the function returns %TRUE, then * all return value pointers should be freed using g_free - * + * * Return value: %TRUE if the uri could be properly decoded, %FALSE otherwise. */ gboolean xed_utils_decode_uri (const gchar *uri, - gchar **scheme, - gchar **user, - gchar **host, - gchar **port, - gchar **path + gchar **scheme, + gchar **user, + gchar **host, + gchar **port, + gchar **path ) { - /* Largely copied from glib/gio/gdummyfile.c:_g_decode_uri. This - * functionality should be in glib/gio, but for now we implement it - * ourselves (see bug #546182) */ + /* Largely copied from glib/gio/gdummyfile.c:_g_decode_uri. This + * functionality should be in glib/gio, but for now we implement it + * ourselves (see bug #546182) */ - const char *p, *in, *hier_part_start, *hier_part_end; - char *out; - char c; + const char *p, *in, *hier_part_start, *hier_part_end; + char *out; + char c; - /* From RFC 3986 Decodes: - * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] - */ + /* From RFC 3986 Decodes: + * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + */ - p = uri; - - null_ptr (scheme); - null_ptr (user); - null_ptr (port); - null_ptr (host); - null_ptr (path); + p = uri; - /* Decode scheme: - * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) - */ + null_ptr (scheme); + null_ptr (user); + null_ptr (port); + null_ptr (host); + null_ptr (path); - if (!g_ascii_isalpha (*p)) - return FALSE; + /* Decode scheme: + * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ - while (1) - { - c = *p++; + if (!g_ascii_isalpha (*p)) + { + return FALSE; + } - if (c == ':') - break; + while (1) + { + c = *p++; - if (!(g_ascii_isalnum(c) || - c == '+' || - c == '-' || - c == '.')) - return FALSE; - } - - if (scheme) - { - *scheme = g_malloc (p - uri); - out = *scheme; - - for (in = uri; in < p - 1; in++) - *out++ = g_ascii_tolower (*in); - - *out = '\0'; - } - - hier_part_start = p; - hier_part_end = p + strlen (p); - - if (hier_part_start[0] == '/' && hier_part_start[1] == '/') - { - const char *authority_start, *authority_end; - const char *userinfo_start, *userinfo_end; - const char *host_start, *host_end; - const char *port_start; - - authority_start = hier_part_start + 2; - /* authority is always followed by / or nothing */ - authority_end = memchr (authority_start, '/', hier_part_end - authority_start); - - if (authority_end == NULL) - authority_end = hier_part_end; + if (c == ':') + { + break; + } - /* 3.2: - * authority = [ userinfo "@" ] host [ ":" port ] - */ + if (!(g_ascii_isalnum(c) || c == '+' || c == '-' || c == '.')) + { + return FALSE; + } + } - userinfo_end = memchr (authority_start, '@', authority_end - authority_start); - - if (userinfo_end) - { - userinfo_start = authority_start; - - if (user) - *user = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL); - - if (user && *user == NULL) - { - if (scheme) - g_free (*scheme); + if (scheme) + { + *scheme = g_malloc (p - uri); + out = *scheme; - return FALSE; - } - - host_start = userinfo_end + 1; - } - else - host_start = authority_start; + for (in = uri; in < p - 1; in++) + { + *out++ = g_ascii_tolower (*in); + } - port_start = memchr (host_start, ':', authority_end - host_start); + *out = '\0'; + } - if (port_start) - { - host_end = port_start++; + hier_part_start = p; + hier_part_end = p + strlen (p); - if (port) - *port = g_strndup (port_start, authority_end - port_start); - } - else - host_end = authority_end; + if (hier_part_start[0] == '/' && hier_part_start[1] == '/') + { + const char *authority_start, *authority_end; + const char *userinfo_start, *userinfo_end; + const char *host_start, *host_end; + const char *port_start; - if (host) - *host = g_strndup (host_start, host_end - host_start); + authority_start = hier_part_start + 2; + /* authority is always followed by / or nothing */ + authority_end = memchr (authority_start, '/', hier_part_end - authority_start); - hier_part_start = authority_end; - } + if (authority_end == NULL) + { + authority_end = hier_part_end; + } - if (path) - *path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/"); - - return TRUE; + /* 3.2: + * authority = [ userinfo "@" ] host [ ":" port ] + */ + + userinfo_end = memchr (authority_start, '@', authority_end - authority_start); + + if (userinfo_end) + { + userinfo_start = authority_start; + + if (user) + { + *user = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL); + } + + if (user && *user == NULL) + { + if (scheme) + { + g_free (*scheme); + } + + return FALSE; + } + + host_start = userinfo_end + 1; + } + else + { + host_start = authority_start; + } + + port_start = memchr (host_start, ':', authority_end - host_start); + + if (port_start) + { + host_end = port_start++; + + if (port) + { + *port = g_strndup (port_start, authority_end - port_start); + } + } + else + { + host_end = authority_end; + } + + if (host) + { + *host = g_strndup (host_start, host_end - host_start); + } + + hier_part_start = authority_end; + } + + if (path) + { + *path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/"); + } + + return TRUE; +} + +static gboolean +data_exists (GSList *list, + const gpointer data) +{ + for (; list != NULL; list = g_slist_next (list)) + { + if (list->data == data) + { + return TRUE; + } + } + + return FALSE; +} + +GSList * +_xed_utils_encoding_strv_to_list (const gchar * const *enc_str) +{ + GSList *res = NULL; + gchar **p; + + for (p = (gchar **)enc_str; p != NULL && *p != NULL; p++) + { + const gchar *charset = *p; + const GtkSourceEncoding *enc; + + if (g_str_equal (charset, "CURRENT")) + { + g_get_charset (&charset); + } + + g_return_val_if_fail (charset != NULL, NULL); + enc = gtk_source_encoding_get_from_charset (charset); + + if (enc != NULL && + !data_exists (res, (gpointer)enc)) + { + res = g_slist_prepend (res, (gpointer)enc); + } + } + + return g_slist_reverse (res); +} + +gchar ** +_xed_utils_encoding_list_to_strv (const GSList *enc_list) +{ + GSList *l; + GPtrArray *array; + + array = g_ptr_array_sized_new (g_slist_length ((GSList *)enc_list) + 1); + + for (l = (GSList *)enc_list; l != NULL; l = g_slist_next (l)) + { + const GtkSourceEncoding *enc = l->data; + const gchar *charset = gtk_source_encoding_get_charset (enc); + + g_return_val_if_fail (charset != NULL, NULL); + + g_ptr_array_add (array, g_strdup (charset)); + } + + g_ptr_array_add (array, NULL); + + return (gchar **)g_ptr_array_free (array, FALSE); } diff --git a/xed/xed-utils.h b/xed/xed-utils.h index c1c30f5..bada300 100644 --- a/xed/xed-utils.h +++ b/xed/xed-utils.h @@ -18,14 +18,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 1998-2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 1998-2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -36,7 +36,7 @@ #include #include #include -#include +#include G_BEGIN_DECLS @@ -48,108 +48,93 @@ G_BEGIN_DECLS enum { XED_ALL_WORKSPACES = 0xffffffff }; -gboolean xed_utils_uri_has_writable_scheme (const gchar *uri); -gboolean xed_utils_uri_has_file_scheme (const gchar *uri); +void xed_utils_menu_position_under_widget (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data); -void xed_utils_menu_position_under_widget (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data); +void xed_utils_menu_position_under_tree_view (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data); -void xed_utils_menu_position_under_tree_view - (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data); +gchar *xed_gdk_color_to_string (GdkColor color); -gchar *xed_gdk_color_to_string (GdkColor color); +gchar *xed_utils_escape_underscores (const gchar *text, + gssize length); -GtkWidget *xed_gtk_button_new_with_stock_icon (const gchar *label, - const gchar *stock_id); +gchar *xed_utils_str_middle_truncate (const gchar *string, + guint truncate_length); -GtkWidget *xed_dialog_add_button (GtkDialog *dialog, - const gchar *text, - const gchar *stock_id, - gint response_id); +gchar *xed_utils_str_end_truncate (const gchar *string, + guint truncate_length); -gchar *xed_utils_escape_underscores (const gchar *text, - gssize length); +gboolean g_utf8_caselessnmatch (const char *s1, + const char *s2, + gssize n1, + gssize n2); -gchar *xed_utils_str_middle_truncate (const gchar *string, - guint truncate_length); +void xed_utils_set_atk_name_description (GtkWidget *widget, + const gchar *name, + const gchar *description); -gchar *xed_utils_str_end_truncate (const gchar *string, - guint truncate_length); +void xed_utils_set_atk_relation (GtkWidget *obj1, + GtkWidget *obj2, + AtkRelationType rel_type); -gboolean g_utf8_caselessnmatch (const char *s1, - const char *s2, - gssize n1, - gssize n2); +void xed_warning (GtkWindow *parent, + const gchar *format, + ...) G_GNUC_PRINTF(2, 3); -void xed_utils_set_atk_name_description (GtkWidget *widget, - const gchar *name, - const gchar *description); - -void xed_utils_set_atk_relation (GtkWidget *obj1, - GtkWidget *obj2, - AtkRelationType rel_type); - -gboolean xed_utils_uri_exists (const gchar* text_uri); - -gchar *xed_utils_escape_search_text (const gchar *text); - -gchar *xed_utils_unescape_search_text (const gchar *text); - -void xed_warning (GtkWindow *parent, - const gchar *format, - ...) G_GNUC_PRINTF(2, 3); - -gchar *xed_utils_make_valid_utf8 (const char *name); +gchar *xed_utils_make_valid_utf8 (const char *name); /* Note that this function replace home dir with ~ */ -gchar *xed_utils_uri_get_dirname (const char *uri); +gchar *xed_utils_uri_get_dirname (const char *uri); -gchar *xed_utils_location_get_dirname_for_display - (GFile *location); +gchar *xed_utils_location_get_dirname_for_display (GFile *location); -gchar *xed_utils_replace_home_dir_with_tilde (const gchar *uri); +gchar *xed_utils_replace_home_dir_with_tilde (const gchar *uri); -guint xed_utils_get_current_workspace (GdkScreen *screen); +guint xed_utils_get_current_workspace (GdkScreen *screen); -guint xed_utils_get_window_workspace (GtkWindow *gtkwindow); +guint xed_utils_get_window_workspace (GtkWindow *gtkwindow); -void xed_utils_get_current_viewport (GdkScreen *screen, - gint *x, - gint *y); +void xed_utils_get_current_viewport (GdkScreen *screen, + gint *x, + gint *y); -gboolean xed_utils_is_valid_uri (const gchar *uri); +gboolean xed_utils_is_valid_location (GFile *location); -gboolean xed_utils_get_ui_objects (const gchar *filename, - gchar **root_objects, - GtkWidget **error_widget, - const gchar *object_name, - ...) G_GNUC_NULL_TERMINATED; +gboolean xed_utils_get_ui_objects (const gchar *filename, + gchar **root_objects, + GtkWidget **error_widget, + const gchar *object_name, + ...) G_GNUC_NULL_TERMINATED; -gboolean xed_utils_file_has_parent (GFile *gfile); +gboolean xed_utils_file_has_parent (GFile *gfile); /* Return NULL if str is not a valid URI and/or filename */ -gchar *xed_utils_make_canonical_uri_from_shell_arg - (const gchar *str); - -gchar *xed_utils_uri_for_display (const gchar *uri); -gchar *xed_utils_basename_for_display (const gchar *uri); -gboolean xed_utils_decode_uri (const gchar *uri, - gchar **scheme, - gchar **user, - gchar **port, - gchar **host, - gchar **path); +gchar *xed_utils_make_canonical_uri_from_shell_arg (const gchar *str); + +gchar *xed_utils_basename_for_display (GFile *location); + +gboolean xed_utils_decode_uri (const gchar *uri, + gchar **scheme, + gchar **user, + gchar **port, + gchar **host, + gchar **path); /* Turns data from a drop into a list of well formatted uris */ -gchar **xed_utils_drop_get_uris (GtkSelectionData *selection_data); +gchar **xed_utils_drop_get_uris (GtkSelectionData *selection_data); + +/* Private */ +GSList *_xed_utils_encoding_strv_to_list (const gchar * const *enc_str); + +gchar **_xed_utils_encoding_list_to_strv (const GSList *enc_list); G_END_DECLS diff --git a/xed/xed-view-activatable.c b/xed/xed-view-activatable.c new file mode 100644 index 0000000..ea51699 --- /dev/null +++ b/xed/xed-view-activatable.c @@ -0,0 +1,96 @@ +/* + * xed-view-activatable.h + * This file is part of xed + * + * Copyright (C) 2010 Steve Frécinaux + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xed-view-activatable.h" +#include "xed-view.h" + +/** + * SECTION:xed-view-activatable + * @short_description: Interface for activatable extensions on views + * @see_also: #PeasExtensionSet + * + * #XedViewActivatable is an interface which should be implemented by + * extensions that should be activated on a xed view. + **/ +G_DEFINE_INTERFACE(XedViewActivatable, xed_view_activatable, G_TYPE_OBJECT) + +void +xed_view_activatable_default_init (XedViewActivatableInterface *iface) +{ + /** + * XedViewActivatable:view: + * + * The window property contains the xed window for this + * #XedViewActivatable instance. + */ + g_object_interface_install_property (iface, + g_param_spec_object ("view", + "view", + "A xed view", + XED_TYPE_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +/** + * xed_view_activatable_activate: + * @activatable: A #XedViewActivatable. + * + * Activates the extension on the window property. + */ +void +xed_view_activatable_activate (XedViewActivatable *activatable) +{ + XedViewActivatableInterface *iface; + + g_return_if_fail (XED_IS_VIEW_ACTIVATABLE (activatable)); + + iface = XED_VIEW_ACTIVATABLE_GET_IFACE (activatable); + if (iface->activate != NULL) + { + iface->activate (activatable); + } +} + +/** + * xed_view_activatable_deactivate: + * @activatable: A #XedViewActivatable. + * + * Deactivates the extension on the window property. + */ +void +xed_view_activatable_deactivate (XedViewActivatable *activatable) +{ + XedViewActivatableInterface *iface; + + g_return_if_fail (XED_IS_VIEW_ACTIVATABLE (activatable)); + + iface = XED_VIEW_ACTIVATABLE_GET_IFACE (activatable); + if (iface->deactivate != NULL) + { + iface->deactivate (activatable); + } +} diff --git a/xed/xed-view-activatable.h b/xed/xed-view-activatable.h new file mode 100644 index 0000000..b160680 --- /dev/null +++ b/xed/xed-view-activatable.h @@ -0,0 +1,60 @@ +/* + * xed-view-activatable.h + * This file is part of xed + * + * Copyright (C) 2010 - Steve Frécinaux + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __XED_VIEW_ACTIVATABLE_H__ +#define __XED_VIEW_ACTIVATABLE_H__ + +#include + +G_BEGIN_DECLS + +/* + * Type checking and casting macros + */ +#define XED_TYPE_VIEW_ACTIVATABLE (xed_view_activatable_get_type ()) +#define XED_VIEW_ACTIVATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_VIEW_ACTIVATABLE, XedViewActivatable)) +#define XED_VIEW_ACTIVATABLE_IFACE(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), XED_TYPE_VIEW_ACTIVATABLE, XedViewActivatableInterface)) +#define XED_IS_VIEW_ACTIVATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_VIEW_ACTIVATABLE)) +#define XED_VIEW_ACTIVATABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), XED_TYPE_VIEW_ACTIVATABLE, XedViewActivatableInterface)) + +typedef struct _XedViewActivatable XedViewActivatable; /* dummy typedef */ +typedef struct _XedViewActivatableInterface XedViewActivatableInterface; + +struct _XedViewActivatableInterface +{ + GTypeInterface g_iface; + + /* Virtual public methods */ + void (*activate) (XedViewActivatable *activatable); + void (*deactivate) (XedViewActivatable *activatable); +}; + +/* + * Public methods + */ +GType xed_view_activatable_get_type (void) G_GNUC_CONST; + +void xed_view_activatable_activate (XedViewActivatable *activatable); +void xed_view_activatable_deactivate (XedViewActivatable *activatable); + +G_END_DECLS + +#endif /* __XED_VIEW_ACTIVATABLE_H__ */ diff --git a/xed/xed-view-frame.c b/xed/xed-view-frame.c new file mode 100644 index 0000000..eba0299 --- /dev/null +++ b/xed/xed-view-frame.c @@ -0,0 +1,576 @@ +/* + * xed-view-frame.c + * This file is part of xed + * + * Copyright (C) 2010 - Ignacio Casal Quinteiro + * + * xed is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xed; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xed-view-frame.h" +#include "xed-marshal.h" +#include "xed-debug.h" +#include "xed-utils.h" + +#include +#include +#include + +#define XED_VIEW_FRAME_SEARCH_DIALOG_TIMEOUT (30*1000) /* 30 seconds */ + +#define SEARCH_POPUP_MARGIN 12 + +struct _XedViewFramePrivate +{ + GtkWidget *view; + + GtkTextMark *start_mark; + + GtkWidget *revealer; + GtkWidget *search_entry; + + guint flush_timeout_id; + glong search_entry_focus_out_id; + glong search_entry_changed_id; + gboolean disable_popdown; +}; + +enum +{ + PROP_0, + PROP_DOCUMENT, + PROP_VIEW +}; + +typedef enum +{ + SEARCH_STATE_NORMAL, + SEARCH_STATE_NOT_FOUND +} SearchState; + +G_DEFINE_TYPE_WITH_PRIVATE (XedViewFrame, xed_view_frame, GTK_TYPE_OVERLAY) + +static void +xed_view_frame_finalize (GObject *object) +{ + G_OBJECT_CLASS (xed_view_frame_parent_class)->finalize (object); +} + +static void +xed_view_frame_dispose (GObject *object) +{ + XedViewFrame *frame = XED_VIEW_FRAME (object); + GtkTextBuffer *buffer = NULL; + + if (frame->priv->view != NULL) + { + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view)); + } + + if (frame->priv->flush_timeout_id != 0) + { + g_source_remove (frame->priv->flush_timeout_id); + frame->priv->flush_timeout_id = 0; + } + + if (buffer != NULL) + { + GtkSourceFile *file = xed_document_get_file (XED_DOCUMENT (buffer)); + gtk_source_file_set_mount_operation_factory (file, NULL, NULL, NULL); + } + + G_OBJECT_CLASS (xed_view_frame_parent_class)->dispose (object); +} + +static void +xed_view_frame_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XedViewFrame *frame = XED_VIEW_FRAME (object); + + switch (prop_id) + { + case PROP_DOCUMENT: + g_value_set_object (value, xed_view_frame_get_document (frame)); + break; + case PROP_VIEW: + g_value_set_object (value, xed_view_frame_get_view (frame)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +hide_search_widget (XedViewFrame *frame, + gboolean cancel) +{ + GtkTextBuffer *buffer; + + g_signal_handler_block (frame->priv->search_entry, frame->priv->search_entry_focus_out_id); + + if (frame->priv->flush_timeout_id != 0) + { + g_source_remove (frame->priv->flush_timeout_id); + frame->priv->flush_timeout_id = 0; + } + + gtk_revealer_set_reveal_child (GTK_REVEALER (frame->priv->revealer), FALSE); + + if (cancel) + { + GtkTextBuffer *buffer; + GtkTextIter iter; + + buffer = GTK_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view))); + gtk_text_buffer_get_iter_at_mark (buffer, &iter, frame->priv->start_mark); + gtk_text_buffer_place_cursor (buffer, &iter); + + xed_view_scroll_to_cursor (XED_VIEW (frame->priv->view)); + } + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view)); + gtk_text_buffer_delete_mark (buffer, frame->priv->start_mark); + + /* Make sure the view is the one who has the focus when we destroy + the search widget */ + gtk_widget_grab_focus (frame->priv->view); + + g_signal_handler_unblock (frame->priv->search_entry, frame->priv->search_entry_focus_out_id); +} + +static gboolean +search_entry_flush_timeout (XedViewFrame *frame) +{ + frame->priv->flush_timeout_id = 0; + hide_search_widget (frame, FALSE); + + return FALSE; +} + +static void +set_search_state (XedViewFrame *frame, + SearchState state) +{ + GtkStyleContext *context; + + context = gtk_widget_get_style_context (GTK_WIDGET (frame->priv->search_entry)); + + if (state == SEARCH_STATE_NOT_FOUND) + { + gtk_style_context_add_class (context, GTK_STYLE_CLASS_ERROR); + } + else + { + gtk_style_context_remove_class (context, GTK_STYLE_CLASS_ERROR); + } +} + +static gboolean +search_widget_key_press_event (GtkWidget *widget, + GdkEventKey *event, + XedViewFrame *frame) +{ + if (event->keyval == GDK_KEY_Escape) + { + + hide_search_widget (frame, TRUE); + return GDK_EVENT_STOP; + } + + return GDK_EVENT_PROPAGATE; +} + +static void +search_entry_activate (GtkEntry *entry, + XedViewFrame *frame) +{ + hide_search_widget (frame, FALSE); +} + +static void +search_entry_insert_text (GtkEditable *editable, + const gchar *text, + gint length, + gint *position, + XedViewFrame *frame) +{ + gunichar c; + const gchar *p; + const gchar *end; + const gchar *next; + + p = text; + end = text + length; + + if (p == end) + return; + + c = g_utf8_get_char (p); + + if (((c == '-' || c == '+') && *position == 0) || + (c == ':' && *position != 0)) + { + gchar *s = NULL; + + if (c == ':') + { + s = gtk_editable_get_chars (editable, 0, -1); + s = g_utf8_strchr (s, -1, ':'); + } + + if (s == NULL || s == p) + { + next = g_utf8_next_char (p); + p = next; + } + + g_free (s); + } + + while (p != end) + { + next = g_utf8_next_char (p); + + c = g_utf8_get_char (p); + + if (!g_unichar_isdigit (c)) + { + g_signal_stop_emission_by_name (editable, "insert_text"); + gtk_widget_error_bell (frame->priv->search_entry); + break; + } + + p = next; + } +} + +static void +search_init (GtkWidget *entry, + XedViewFrame *frame) +{ + const gchar *entry_text; + + /* renew the flush timeout */ + if (frame->priv->flush_timeout_id != 0) + { + g_source_remove (frame->priv->flush_timeout_id); + frame->priv->flush_timeout_id = g_timeout_add (XED_VIEW_FRAME_SEARCH_DIALOG_TIMEOUT, + (GSourceFunc)search_entry_flush_timeout, frame); + } + + entry_text = gtk_entry_get_text (GTK_ENTRY (entry)); + + if (*entry_text != '\0') + { + gboolean moved, moved_offset; + gint line; + gint offset_line = 0; + gint line_offset = 0; + gchar **split_text = NULL; + const gchar *text; + GtkTextIter iter; + XedDocument *doc; + + doc = xed_view_frame_get_document (frame); + gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &iter, frame->priv->start_mark); + split_text = g_strsplit (entry_text, ":", -1); + + if (g_strv_length (split_text) > 1) + { + text = split_text[0]; + } + else + { + text = entry_text; + } + + if (*text == '-') + { + gint cur_line = gtk_text_iter_get_line (&iter); + + if (*(text + 1) != '\0') + { + offset_line = MAX (atoi (text + 1), 0); + } + + line = MAX (cur_line - offset_line, 0); + } + else if (*entry_text == '+') + { + gint cur_line = gtk_text_iter_get_line (&iter); + + if (*(text + 1) != '\0') + { + offset_line = MAX (atoi (text + 1), 0); + } + + line = cur_line + offset_line; + } + else + { + line = MAX (atoi (text) - 1, 0); + } + + if (split_text[1] != NULL) + { + line_offset = atoi (split_text[1]); + } + + g_strfreev (split_text); + + moved = xed_document_goto_line (doc, line); + moved_offset = xed_document_goto_line_offset (doc, line, line_offset); + + xed_view_scroll_to_cursor (XED_VIEW (frame->priv->view)); + + if (!moved || !moved_offset) + { + set_search_state (frame, SEARCH_STATE_NOT_FOUND); + } + else + { + set_search_state (frame, SEARCH_STATE_NORMAL); + } + } +} + +static gboolean +search_entry_focus_out_event (GtkWidget *widget, + GdkEventFocus *event, + XedViewFrame *frame) +{ + if (frame->priv->disable_popdown) + { + return GDK_EVENT_STOP; + } + + hide_search_widget (frame, FALSE); + return GDK_EVENT_PROPAGATE; +} + +static void +search_enable_popdown (GtkWidget *widget, + XedViewFrame *frame) +{ + frame->priv->disable_popdown = FALSE; +} + +static void +search_entry_populate_popup (GtkEntry *entry, + GtkMenu *menu, + XedViewFrame *frame) +{ + frame->priv->disable_popdown = TRUE; + g_signal_connect (menu, "hide", + G_CALLBACK (search_enable_popdown), frame); +} + +static void +setup_search_widget (XedViewFrame *frame) +{ + g_signal_connect (frame->priv->revealer, "key-press-event", + G_CALLBACK (search_widget_key_press_event), frame); + + /* add entry */ + // frame->priv->search_entry = gtk_entry_new (); + // gtk_widget_set_tooltip_text (frame->priv->search_entry, _("Line you want to move the cursor to")); + // gtk_entry_set_icon_from_icon_name (GTK_ENTRY (frame->priv->search_entry), + // GTK_ENTRY_ICON_PRIMARY, "go-jump-symbolic"); + // gtk_widget_show (frame->priv->search_entry); + + g_signal_connect (frame->priv->search_entry, "activate", + G_CALLBACK (search_entry_activate), frame); + g_signal_connect (frame->priv->search_entry, "insert_text", + G_CALLBACK (search_entry_insert_text), frame); + g_signal_connect (frame->priv->search_entry, "populate-popup", + G_CALLBACK (search_entry_populate_popup), frame); + frame->priv->search_entry_changed_id = g_signal_connect (frame->priv->search_entry, "changed", + G_CALLBACK (search_init), frame); + frame->priv->search_entry_focus_out_id = g_signal_connect (frame->priv->search_entry, "focus-out-event", + G_CALLBACK (search_entry_focus_out_event), frame); +} + +static void +init_search_entry (XedViewFrame *frame) +{ + GtkTextBuffer *buffer; + gint line; + gchar *line_str; + GtkTextIter iter; + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view)); + gtk_text_buffer_get_iter_at_mark (buffer, &iter, frame->priv->start_mark); + line = gtk_text_iter_get_line (&iter); + line_str = g_strdup_printf ("%d", line + 1); + + gtk_entry_set_text (GTK_ENTRY (frame->priv->search_entry), line_str); + gtk_editable_select_region (GTK_EDITABLE (frame->priv->search_entry), 0, -1); + + g_free (line_str); + + return; +} + +static void +start_interactive_search_real (XedViewFrame *frame) +{ + GtkTextBuffer *buffer; + GtkTextIter iter; + GtkTextMark *mark; + + if (gtk_revealer_get_reveal_child (GTK_REVEALER (frame->priv->revealer))) + { + gtk_editable_select_region (GTK_EDITABLE (frame->priv->search_entry), 0, -1); + return; + } + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view)); + + mark = gtk_text_buffer_get_insert (buffer); + gtk_text_buffer_get_iter_at_mark (buffer, &iter, mark); + + frame->priv->start_mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, FALSE); + + gtk_revealer_set_reveal_child (GTK_REVEALER (frame->priv->revealer), TRUE); + + /* NOTE: we must be very careful here to not have any text before + focusing the entry because when the entry is focused the text is + selected, and gtk+ doesn't allow us to have more than one selection + active */ + g_signal_handler_block (frame->priv->search_entry, frame->priv->search_entry_changed_id); + gtk_entry_set_text (GTK_ENTRY (frame->priv->search_entry), ""); + g_signal_handler_unblock (frame->priv->search_entry, frame->priv->search_entry_changed_id); + + /* We need to grab the focus after the widget has been added */ + gtk_widget_grab_focus (frame->priv->search_entry); + + init_search_entry (frame); + + frame->priv->flush_timeout_id = g_timeout_add (XED_VIEW_FRAME_SEARCH_DIALOG_TIMEOUT, + (GSourceFunc) search_entry_flush_timeout, frame); +} + +static void +xed_view_frame_class_init (XedViewFrameClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = xed_view_frame_finalize; + object_class->dispose = xed_view_frame_dispose; + object_class->get_property = xed_view_frame_get_property; + + g_object_class_install_property (object_class, PROP_DOCUMENT, + g_param_spec_object ("document", + "Document", + "The Document", + XED_TYPE_DOCUMENT, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_VIEW, + g_param_spec_object ("view", + "View", + "The View", + XED_TYPE_VIEW, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + gtk_widget_class_set_template_from_resource (widget_class, "/org/x/editor/ui/xed-view-frame.ui"); + gtk_widget_class_bind_template_child_private (widget_class, XedViewFrame, view); + gtk_widget_class_bind_template_child_private (widget_class, XedViewFrame, revealer); + gtk_widget_class_bind_template_child_private (widget_class, XedViewFrame, search_entry); +} + +static GMountOperation * +view_frame_mount_operation_factory (GtkSourceFile *file, + gpointer user_data) +{ + GtkWidget *view_frame = user_data; + GtkWidget *window = gtk_widget_get_toplevel (view_frame); + + return gtk_mount_operation_new (GTK_WINDOW (window)); +} + +static void +xed_view_frame_init (XedViewFrame *frame) +{ + XedDocument *doc; + GtkSourceFile *file; + GdkRGBA transparent = {0, 0, 0, 0}; + + frame->priv = xed_view_frame_get_instance_private (frame); + + gtk_widget_init_template (GTK_WIDGET (frame)); + + gtk_widget_override_background_color (GTK_WIDGET (frame), 0, &transparent); + + doc = xed_view_frame_get_document (frame); + file = xed_document_get_file (doc); + + gtk_source_file_set_mount_operation_factory (file, view_frame_mount_operation_factory, frame, NULL); + + setup_search_widget (frame); + + gtk_widget_set_margin_end (frame->priv->revealer, SEARCH_POPUP_MARGIN); + gtk_widget_set_margin_start (frame->priv->revealer, SEARCH_POPUP_MARGIN); +} + +XedViewFrame * +xed_view_frame_new () +{ + return g_object_new (XED_TYPE_VIEW_FRAME, NULL); +} + +XedDocument * +xed_view_frame_get_document (XedViewFrame *frame) +{ + g_return_val_if_fail (XED_IS_VIEW_FRAME (frame), NULL); + + return XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view))); +} + +XedView * +xed_view_frame_get_view (XedViewFrame *frame) +{ + g_return_val_if_fail (XED_IS_VIEW_FRAME (frame), NULL); + + return XED_VIEW (frame->priv->view); +} + +void +xed_view_frame_popup_goto_line (XedViewFrame *frame) +{ + g_return_if_fail (XED_IS_VIEW_FRAME (frame)); + + start_interactive_search_real (frame); +} + +gboolean +xed_view_frame_get_search_popup_visible (XedViewFrame *frame) +{ + g_return_val_if_fail (XED_IS_VIEW_FRAME (frame), FALSE); + + return gtk_revealer_get_child_revealed (GTK_REVEALER (frame->priv->revealer)); +} diff --git a/xed/xed-view-frame.h b/xed/xed-view-frame.h new file mode 100644 index 0000000..1cb6d12 --- /dev/null +++ b/xed/xed-view-frame.h @@ -0,0 +1,70 @@ +/* + * xed-view-frame.h + * This file is part of xed + * + * Copyright (C) 2010 - Ignacio Casal Quinteiro + * + * xed is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xed; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __XED_VIEW_FRAME_H__ +#define __XED_VIEW_FRAME_H__ + +#include +#include "xed-document.h" +#include "xed-view.h" + +G_BEGIN_DECLS + +#define XED_TYPE_VIEW_FRAME (xed_view_frame_get_type ()) +#define XED_VIEW_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_VIEW_FRAME, XedViewFrame)) +#define XED_VIEW_FRAME_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_VIEW_FRAME, XedViewFrame const)) +#define XED_VIEW_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_VIEW_FRAME, XedViewFrameClass)) +#define XED_IS_VIEW_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_VIEW_FRAME)) +#define XED_IS_VIEW_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_VIEW_FRAME)) +#define XED_VIEW_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_VIEW_FRAME, XedViewFrameClass)) + +typedef struct _XedViewFrame XedViewFrame; +typedef struct _XedViewFrameClass XedViewFrameClass; +typedef struct _XedViewFramePrivate XedViewFramePrivate; + +struct _XedViewFrame +{ + GtkOverlay parent; + + XedViewFramePrivate *priv; +}; + +struct _XedViewFrameClass +{ + GtkOverlayClass parent_class; +}; + +GType xed_view_frame_get_type (void) G_GNUC_CONST; + +XedViewFrame *xed_view_frame_new (void); + +XedDocument *xed_view_frame_get_document (XedViewFrame *frame); + +XedView *xed_view_frame_get_view (XedViewFrame *frame); + +void xed_view_frame_popup_goto_line (XedViewFrame *frame); + +gboolean xed_view_frame_get_search_popup_visible (XedViewFrame *frame); + +G_END_DECLS + +#endif /* __XED_VIEW_FRAME_H__ */ diff --git a/xed/xed-view-gutter-renderer.c b/xed/xed-view-gutter-renderer.c new file mode 100644 index 0000000..f516543 --- /dev/null +++ b/xed/xed-view-gutter-renderer.c @@ -0,0 +1,16 @@ +#include "xed-view-gutter-renderer.h" + +#define XED_VIEW_GUTTER_RENDERER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XED_VIEW_GUTTER_RENDERER, XedViewGutterRendererPrivate)) + +G_DEFINE_TYPE (XedViewGutterRenderer, xed_view_gutter_renderer, GTK_SOURCE_TYPE_GUTTER_RENDERER) + +static void +xed_view_gutter_renderer_class_init (XedViewGutterRendererClass *klass) +{ + GtkSourceGutterRendererClass *renderer_class = GTK_SOURCE_GUTTER_RENDERER_CLASS (klass); +} + +static void +xed_view_gutter_renderer_init (XedViewGutterRenderer *self) +{ +} diff --git a/xed/xed-view-gutter-renderer.h b/xed/xed-view-gutter-renderer.h new file mode 100644 index 0000000..e863817 --- /dev/null +++ b/xed/xed-view-gutter-renderer.h @@ -0,0 +1,35 @@ +#ifndef __XED_VIEW_GUTTER_RENDERER_H__ +#define __XED_VIEW_GUTTER_RENDERER_H__ + +#include + +G_BEGIN_DECLS + +#define XED_TYPE_VIEW_GUTTER_RENDERER (xed_view_gutter_renderer_get_type ()) +#define XED_VIEW_GUTTER_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_VIEW_GUTTER_RENDERER, XedViewGutterRenderer)) +#define XED_VIEW_GUTTER_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_VIEW_GUTTER_RENDERER, XedViewGutterRendererClass)) +#define XED_IS_VIEW_GUTTER_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_VIEW_GUTTER_RENDERER)) +#define XED_IS_VIEW_GUTTER_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_VIEW_GUTTER_RENDERER)) +#define XED_VIEW_GUTTER_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_VIEW_GUTTER_RENDERER, XedViewGutterRendererClass)) + +typedef struct _XedViewGutterRenderer XedViewGutterRenderer; +typedef struct _XedViewGutterRendererClass XedViewGutterRendererClass; +typedef struct _XedViewGutterRendererPrivate XedViewGutterRendererPrivate; + +struct _XedViewGutterRenderer +{ + GtkSourceGutterRenderer parent; + + XedViewGutterRendererPrivate *priv; +}; + +struct _XedViewGutterRendererClass +{ + GtkSourceGutterRendererClass parent_instance; +}; + +GType xed_view_gutter_renderer_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __XED_VIEW_GUTTER_RENDERER_H__ */ \ No newline at end of file diff --git a/xed/xed-view.c b/xed/xed-view.c index 01129a8..551e91a 100644 --- a/xed/xed-view.c +++ b/xed/xed-view.c @@ -6,17 +6,20 @@ #include #include #include +#include #include #include "xed-view.h" +#include "xed-view-gutter-renderer.h" +#include "xed-view-activatable.h" +#include "xed-plugins-engine.h" #include "xed-debug.h" -#include "xed-prefs-manager.h" -#include "xed-prefs-manager-app.h" #include "xed-marshal.h" #include "xed-utils.h" +#include "xed-settings.h" +#include "xed-app.h" #define XED_VIEW_SCROLL_MARGIN 0.02 -#define XED_VIEW_SEARCH_DIALOG_TIMEOUT (30*1000) /* 30 seconds */ #define XED_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_VIEW, XedViewPrivate)) @@ -27,67 +30,535 @@ enum struct _XedViewPrivate { - GtkTextIter start_search_iter; - GtkWidget *search_window; - GtkWidget *search_entry; - guint typeselect_flush_timeout; - guint search_entry_changed_id; - gboolean disable_popdown; + GSettings *editor_settings; GtkTextBuffer *current_buffer; + PeasExtensionSet *extensions; + GtkSourceGutterRenderer *renderer; + guint view_realized : 1; }; -static void xed_view_dispose (GObject *object); -static void xed_view_finalize (GObject *object); -static gint xed_view_focus_out (GtkWidget *widget, GdkEventFocus *event); -static gboolean xed_view_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint timestamp); -static void xed_view_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, - GtkSelectionData *selection_data, guint info, guint timestamp); -static gboolean xed_view_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint timestamp); -static gboolean xed_view_button_press_event (GtkWidget *widget, GdkEventButton *event); -static gboolean start_interactive_goto_line (XedView *view); -static void hide_search_window (XedView *view, gboolean cancel); -static gboolean xed_view_draw (GtkWidget *widget, cairo_t *cr); -static void search_highlight_updated_cb (XedDocument *doc, GtkTextIter *start, GtkTextIter *end, XedView *view); -static void xed_view_delete_from_cursor (GtkTextView *text_view, GtkDeleteType type, gint count); - -G_DEFINE_TYPE(XedView, xed_view, GTK_SOURCE_TYPE_VIEW) +G_DEFINE_TYPE (XedView, xed_view, GTK_SOURCE_TYPE_VIEW) /* Signals */ enum { - START_INTERACTIVE_GOTO_LINE, DROP_URIS, LAST_SIGNAL + DROP_URIS, + LAST_SIGNAL }; static guint view_signals[LAST_SIGNAL] = { 0 }; -typedef enum -{ - XED_SEARCH_ENTRY_NORMAL, XED_SEARCH_ENTRY_NOT_FOUND -} XedSearchEntryState; - static void document_read_only_notify_handler (XedDocument *document, GParamSpec *pspec, XedView *view) { xed_debug (DEBUG_VIEW); - gtk_text_view_set_editable (GTK_TEXT_VIEW(view), !xed_document_get_readonly (document)); + gtk_text_view_set_editable (GTK_TEXT_VIEW (view), !xed_document_get_readonly (document)); +} + +static void +current_buffer_removed (XedView *view) +{ + if (view->priv->current_buffer != NULL) + { + g_signal_handlers_disconnect_by_func(view->priv->current_buffer, document_read_only_notify_handler, view); + g_object_unref (view->priv->current_buffer); + view->priv->current_buffer = NULL; + } +} + +static void +extension_added (PeasExtensionSet *extensions, + PeasPluginInfo *info, + PeasExtension *exten, + XedView *view) +{ + peas_extension_call (exten, "activate"); +} + +static void +extension_removed (PeasExtensionSet *extensions, + PeasPluginInfo *info, + PeasExtension *exten, + XedView *view) +{ + peas_extension_call (exten, "deactivate"); +} + +static void +on_notify_buffer_cb (XedView *view, + GParamSpec *arg1, + gpointer userdata) +{ + GtkTextBuffer *buffer; + + current_buffer_removed (view); + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); + + if (buffer == NULL || !XED_IS_DOCUMENT (buffer)) + { + return; + } + + view->priv->current_buffer = g_object_ref (buffer); + g_signal_connect(buffer, "notify::read-only", G_CALLBACK (document_read_only_notify_handler), view); + + gtk_text_view_set_editable (GTK_TEXT_VIEW (view), !xed_document_get_readonly (XED_DOCUMENT(buffer))); +} + +static void +xed_view_init (XedView *view) +{ + GtkTargetList *tl; + + xed_debug (DEBUG_VIEW); + + view->priv = XED_VIEW_GET_PRIVATE (view); + + view->priv->editor_settings = g_settings_new ("org.x.editor.preferences.editor"); + + /* Drag and drop support */ + tl = gtk_drag_dest_get_target_list (GTK_WIDGET(view)); + + if (tl != NULL) + { + gtk_target_list_add_uri_targets (tl, TARGET_URI_LIST); + } + + view->priv->extensions = peas_extension_set_new (PEAS_ENGINE (xed_plugins_engine_get_default ()), + XED_TYPE_VIEW_ACTIVATABLE, "view", view, NULL); + + g_signal_connect (view->priv->extensions, "extension-added", + G_CALLBACK (extension_added), view); + g_signal_connect (view->priv->extensions, "extension-removed", + G_CALLBACK (extension_removed), view); + + /* Act on buffer change */ + g_signal_connect(view, "notify::buffer", G_CALLBACK (on_notify_buffer_cb), NULL); +} + +static void +xed_view_dispose (GObject *object) +{ + XedView *view = XED_VIEW (object); + + g_clear_object (&view->priv->extensions); + g_clear_object (&view->priv->editor_settings); + g_clear_object (&view->priv->renderer); + + current_buffer_removed (view); + + /* Disconnect notify buffer because the destroy of the textview will set + * the buffer to NULL, and we call get_buffer in the notify which would + * reinstate a buffer which we don't want. + * There is no problem calling g_signal_handlers_disconnect_by_func() + * several times (if dispose() is called several times). + */ + g_signal_handlers_disconnect_by_func (view, on_notify_buffer_cb, NULL); + + G_OBJECT_CLASS (xed_view_parent_class)->dispose (object); +} + +static void +xed_view_constructed (GObject *object) +{ + XedView *view; + XedViewPrivate *priv; + gboolean use_default_font; + GtkSourceGutter *gutter; + + view = XED_VIEW (object); + priv = view->priv; + + /* Get setting values */ + use_default_font = g_settings_get_boolean (view->priv->editor_settings, XED_SETTINGS_USE_DEFAULT_FONT); + + /* + * Set tab, fonts, wrap mode, colors, etc. according to preferences + */ + if (!use_default_font) + { + gchar *editor_font; + + editor_font = g_settings_get_string (view->priv->editor_settings, XED_SETTINGS_EDITOR_FONT); + + xed_view_set_font (view, FALSE, editor_font); + + g_free (editor_font); + } + else + { + xed_view_set_font (view, TRUE, NULL); + } + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_DISPLAY_LINE_NUMBERS, + view, + "show-line-numbers", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_AUTO_INDENT, + view, + "auto-indent", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_TABS_SIZE, + view, + "tab-width", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_INSERT_SPACES, + view, + "insert-spaces-instead-of-tabs", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_DISPLAY_RIGHT_MARGIN, + view, + "show-right-margin", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_RIGHT_MARGIN_POSITION, + view, + "right-margin-position", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_HIGHLIGHT_CURRENT_LINE, + view, + "highlight-current-line", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_WRAP_MODE, + view, + "wrap-mode", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->editor_settings, + XED_SETTINGS_SMART_HOME_END, + view, + "smart-home-end", + G_SETTINGS_BIND_GET); + + g_object_set (G_OBJECT (view), + "indent_on_tab", TRUE, + NULL); + + gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (view), GTK_TEXT_WINDOW_LEFT); + priv->renderer = g_object_new (XED_TYPE_VIEW_GUTTER_RENDERER, + "size", 2, + NULL); + g_object_ref (priv->renderer); + gtk_source_gutter_insert (gutter, priv->renderer, 0); + + gtk_text_view_set_top_margin (GTK_TEXT_VIEW (view), 2); + + G_OBJECT_CLASS (xed_view_parent_class)->constructed (object); +} + +static gint +xed_view_focus_out (GtkWidget *widget, + GdkEventFocus *event) +{ + gtk_widget_queue_draw (widget); + + GTK_WIDGET_CLASS (xed_view_parent_class)->focus_out_event (widget, event); + + return FALSE; +} + +static GdkAtom +drag_get_uri_target (GtkWidget *widget, + GdkDragContext *context) +{ + GdkAtom target; + GtkTargetList *tl; + + tl = gtk_target_list_new (NULL, 0); + gtk_target_list_add_uri_targets (tl, 0); + + target = gtk_drag_dest_find_target (widget, context, tl); + gtk_target_list_unref (tl); + + return target; +} + +static gboolean +xed_view_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint timestamp) +{ + gboolean result; + + /* Chain up to allow textview to scroll and position dnd mark, note + * that this needs to be checked if gtksourceview or gtktextview + * changes drag_motion behaviour */ + result = GTK_WIDGET_CLASS (xed_view_parent_class)->drag_motion (widget, context, x, y, timestamp); + + /* If this is a URL, deal with it here */ + if (drag_get_uri_target (widget, context) != GDK_NONE) + { + gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), timestamp); + result = TRUE; + } + + return result; +} + +static void +xed_view_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint timestamp) +{ + gchar **uri_list; + + /* If this is an URL emit DROP_URIS, otherwise chain up the signal */ + if (info == TARGET_URI_LIST) + { + uri_list = xed_utils_drop_get_uris (selection_data); + + if (uri_list != NULL) + { + g_signal_emit (widget, view_signals[DROP_URIS], 0, uri_list); + g_strfreev (uri_list); + gtk_drag_finish (context, TRUE, FALSE, timestamp); + } + } + else + { + GTK_WIDGET_CLASS (xed_view_parent_class)->drag_data_received (widget, context, x, y, selection_data, info, + timestamp); + } +} + +static gboolean +xed_view_drag_drop (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint timestamp) +{ + gboolean result; + GdkAtom target; + + /* If this is a URL, just get the drag data */ + target = drag_get_uri_target (widget, context); + + if (target != GDK_NONE) + { + gtk_drag_get_data (widget, context, target, timestamp); + result = TRUE; + } + else + { + /* Chain up */ + result = GTK_WIDGET_CLASS (xed_view_parent_class)->drag_drop (widget, context, x, y, timestamp); + } + + return result; +} + +static GtkWidget * +create_line_numbers_menu (GtkWidget *view) +{ + GtkWidget *menu; + GtkWidget *item; + + menu = gtk_menu_new (); + + item = gtk_check_menu_item_new_with_mnemonic (_("_Display line numbers")); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(item), + gtk_source_view_get_show_line_numbers (GTK_SOURCE_VIEW(view))); + + g_settings_bind (XED_VIEW (view)->priv->editor_settings, + "active", + item, + XED_SETTINGS_DISPLAY_LINE_NUMBERS, + G_SETTINGS_BIND_SET); + + gtk_menu_shell_append (GTK_MENU_SHELL(menu), item); + + gtk_widget_show_all (menu); + + return menu; +} + +static void +show_line_numbers_menu (GtkWidget *view, + GdkEventButton *event) +{ + GtkWidget *menu; + + menu = create_line_numbers_menu (view); + gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time); +} + +static gboolean +xed_view_button_press_event (GtkWidget *widget, + GdkEventButton *event) +{ + if ((event->type == GDK_BUTTON_PRESS) && + (event->button == 3) && + (event->window == gtk_text_view_get_window (GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_LEFT))) + { + show_line_numbers_menu (widget, event); + return TRUE; + } + + return GTK_WIDGET_CLASS (xed_view_parent_class)->button_press_event (widget, event); +} + +static void +xed_view_realize (GtkWidget *widget) +{ + XedView *view = XED_VIEW (widget); + + if (!view->priv->view_realized) + { + peas_extension_set_call (view->priv->extensions, "activate"); + view->priv->view_realized = TRUE; + } + + GTK_WIDGET_CLASS (xed_view_parent_class)->realize (widget); +} + +static void +delete_line (GtkTextView *text_view, + gint count) +{ + GtkTextIter start; + GtkTextIter end; + GtkTextBuffer *buffer; + + buffer = gtk_text_view_get_buffer (text_view); + + gtk_text_view_reset_im_context (text_view); + + /* If there is a selection delete the selected lines and + * ignore count */ + if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) + { + gtk_text_iter_order (&start, &end); + if (gtk_text_iter_starts_line (&end)) + { + /* Do no delete the line with the cursor if the cursor + * is at the beginning of the line */ + count = 0; + } + else + { + count = 1; + } + } + + gtk_text_iter_set_line_offset (&start, 0); + + if (count > 0) + { + gtk_text_iter_forward_lines (&end, count); + if (gtk_text_iter_is_end (&end)) + { + if (gtk_text_iter_backward_line (&start) && !gtk_text_iter_ends_line (&start)) + { + gtk_text_iter_forward_to_line_end (&start); + } + } + } + else if (count < 0) + { + if (!gtk_text_iter_ends_line (&end)) + { + gtk_text_iter_forward_to_line_end (&end); + } + + while (count < 0) + { + if (!gtk_text_iter_backward_line (&start)) + { + break; + } + ++count; + } + + if (count == 0) + { + if (!gtk_text_iter_ends_line (&start)) + { + gtk_text_iter_forward_to_line_end (&start); + } + } + else + { + gtk_text_iter_forward_line (&end); + } + } + + if (!gtk_text_iter_equal (&start, &end)) + { + GtkTextIter cur = start; + gtk_text_iter_set_line_offset (&cur, 0); + gtk_text_buffer_begin_user_action (buffer); + gtk_text_buffer_place_cursor (buffer, &cur); + gtk_text_buffer_delete_interactive (buffer, &start, &end, gtk_text_view_get_editable (text_view)); + gtk_text_buffer_end_user_action (buffer); + gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_buffer_get_insert (buffer)); + } + else + { + gtk_widget_error_bell (GTK_WIDGET(text_view)); + } +} + +static void +xed_view_delete_from_cursor (GtkTextView *text_view, + GtkDeleteType type, + gint count) +{ + /* We override the standard handler for delete_from_cursor since + the GTK_DELETE_PARAGRAPHS case is not implemented as we like (i.e. it + does not remove the carriage return in the previous line) + */ + switch (type) + { + case GTK_DELETE_PARAGRAPHS: + delete_line (text_view, count); + break; + default: + GTK_TEXT_VIEW_CLASS (xed_view_parent_class)->delete_from_cursor (text_view, type, count); + break; + } +} + +static GtkTextBuffer * +xed_view_create_buffer (GtkTextView *text_view) +{ + return GTK_TEXT_BUFFER (xed_document_new ()); } static void xed_view_class_init (XedViewClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS(klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS(klass); - + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS (klass); GtkBindingSet *binding_set; object_class->dispose = xed_view_dispose; - object_class->finalize = xed_view_finalize; + object_class->constructed = xed_view_constructed; widget_class->focus_out_event = xed_view_focus_out; - widget_class->draw = xed_view_draw; /* * Override the gtk_text_view_drag_motion and drag_drop @@ -107,14 +578,10 @@ xed_view_class_init (XedViewClass *klass) widget_class->drag_data_received = xed_view_drag_data_received; widget_class->drag_drop = xed_view_drag_drop; widget_class->button_press_event = xed_view_button_press_event; - klass->start_interactive_goto_line = start_interactive_goto_line; + widget_class->realize = xed_view_realize; text_view_class->delete_from_cursor = xed_view_delete_from_cursor; - - view_signals[START_INTERACTIVE_GOTO_LINE] = g_signal_new ("start_interactive_goto_line", - G_TYPE_FROM_CLASS(object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(XedViewClass, start_interactive_goto_line), - NULL, NULL, xed_marshal_BOOLEAN__NONE, G_TYPE_BOOLEAN, 0); + text_view_class->create_buffer = xed_view_create_buffer; /* A new signal DROP_URIS has been added to allow plugins to intercept * the default dnd behaviour of 'text/uri-list'. XedView now handles @@ -125,164 +592,23 @@ xed_view_class_init (XedViewClass *klass) * default behaviour. They should _NOT_ use this signal because this * will not prevent xed from loading the uri */ - view_signals[DROP_URIS] = g_signal_new ("drop_uris", G_TYPE_FROM_CLASS(object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(XedViewClass, drop_uris), - NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, G_TYPE_STRV); + view_signals[DROP_URIS] = + g_signal_new ("drop_uris", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (XedViewClass, drop_uris), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, G_TYPE_STRV); - g_type_class_add_private (klass, sizeof(XedViewPrivate)); + g_type_class_add_private (klass, sizeof (XedViewPrivate)); binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_i, GDK_CONTROL_MASK, "start_interactive_goto_line", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_d, GDK_CONTROL_MASK, "delete_from_cursor", 2, G_TYPE_ENUM, GTK_DELETE_PARAGRAPHS, G_TYPE_INT, 1); } -static void -current_buffer_removed (XedView *view) -{ - if (view->priv->current_buffer) - { - g_signal_handlers_disconnect_by_func(view->priv->current_buffer, document_read_only_notify_handler, view); - g_signal_handlers_disconnect_by_func(view->priv->current_buffer, search_highlight_updated_cb, view); - g_object_unref (view->priv->current_buffer); - view->priv->current_buffer = NULL; - } -} - -static void -on_notify_buffer_cb (XedView *view, - GParamSpec *arg1, - gpointer userdata) -{ - GtkTextBuffer *buffer; - - current_buffer_removed (view); - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(view)); - - if (buffer == NULL || !XED_IS_DOCUMENT(buffer)) - { - return; - } - - view->priv->current_buffer = g_object_ref (buffer); - g_signal_connect(buffer, "notify::read-only", G_CALLBACK (document_read_only_notify_handler), view); - - gtk_text_view_set_editable (GTK_TEXT_VIEW(view), !xed_document_get_readonly (XED_DOCUMENT(buffer))); - - g_signal_connect(buffer, "search_highlight_updated", G_CALLBACK (search_highlight_updated_cb), view); -} - -static void -xed_view_init (XedView *view) -{ - GtkTargetList *tl; - - xed_debug (DEBUG_VIEW); - - view->priv = XED_VIEW_GET_PRIVATE(view); - - /* - * Set tab, fonts, wrap mode, colors, etc. according - * to preferences - */ - if (!xed_prefs_manager_get_use_default_font ()) - { - gchar *editor_font; - editor_font = xed_prefs_manager_get_editor_font (); - xed_view_set_font (view, FALSE, editor_font); - g_free (editor_font); - } - else - { - xed_view_set_font (view, TRUE, NULL); - } - - g_object_set (G_OBJECT(view), - "wrap_mode", xed_prefs_manager_get_wrap_mode (), - "show_line_numbers", xed_prefs_manager_get_display_line_numbers (), - "auto_indent", xed_prefs_manager_get_auto_indent (), - "tab_width", xed_prefs_manager_get_tabs_size (), - "insert_spaces_instead_of_tabs", xed_prefs_manager_get_insert_spaces (), - "show_right_margin", xed_prefs_manager_get_display_right_margin (), - "right_margin_position", xed_prefs_manager_get_right_margin_position (), - "highlight_current_line", xed_prefs_manager_get_highlight_current_line (), - "smart_home_end", xed_prefs_manager_get_smart_home_end (), - "indent_on_tab", TRUE, - NULL); - - view->priv->typeselect_flush_timeout = 0; - - /* Drag and drop support */ - tl = gtk_drag_dest_get_target_list (GTK_WIDGET(view)); - - if (tl != NULL) - { - gtk_target_list_add_uri_targets (tl, TARGET_URI_LIST); - } - - /* Act on buffer change */ - g_signal_connect(view, "notify::buffer", G_CALLBACK (on_notify_buffer_cb), NULL); -} - -static void -xed_view_dispose (GObject *object) -{ - XedView *view; - - view = XED_VIEW(object); - - if (view->priv->search_window != NULL) - { - gtk_widget_destroy (view->priv->search_window); - view->priv->search_window = NULL; - view->priv->search_entry = NULL; - if (view->priv->typeselect_flush_timeout != 0) - { - g_source_remove (view->priv->typeselect_flush_timeout); - view->priv->typeselect_flush_timeout = 0; - } - } - - /* Disconnect notify buffer because the destroy of the textview will - set the buffer to NULL, and we call get_buffer in the notify which - would reinstate a GtkTextBuffer which we don't want */ - current_buffer_removed (view); - g_signal_handlers_disconnect_by_func(view, on_notify_buffer_cb, NULL); - - (* G_OBJECT_CLASS (xed_view_parent_class)->dispose) (object); -} - -static void -xed_view_finalize (GObject *object) -{ - XedView *view; - view = XED_VIEW(object); - current_buffer_removed (view); - (* G_OBJECT_CLASS (xed_view_parent_class)->finalize) (object); -} - -static gint -xed_view_focus_out (GtkWidget *widget, - GdkEventFocus *event) -{ - XedView *view = XED_VIEW(widget); - - gtk_widget_queue_draw (widget); - - /* hide interactive search dialog */ - if (view->priv->search_window != NULL) - { - hide_search_window (view, FALSE); - } - - (* GTK_WIDGET_CLASS (xed_view_parent_class)->focus_out_event) (widget, event); - - return FALSE; -} - /** * xed_view_new: * @doc: a #XedDocument @@ -298,10 +624,15 @@ xed_view_new (XedDocument *doc) GtkWidget *view; xed_debug_message (DEBUG_VIEW, "START"); + g_return_val_if_fail(XED_IS_DOCUMENT (doc), NULL); + view = GTK_WIDGET(g_object_new (XED_TYPE_VIEW, "buffer", doc, NULL)); + xed_debug_message (DEBUG_VIEW, "END: %d", G_OBJECT (view)->ref_count); + gtk_widget_show_all (view); + return view; } @@ -445,8 +776,8 @@ xed_view_scroll_to_cursor (XedView *view) * otherwise sets it to @font_name. **/ void -xed_view_set_font (XedView *view, - gboolean def, +xed_view_set_font (XedView *view, + gboolean def, const gchar *font_name) { PangoFontDescription *font_desc = NULL; @@ -457,836 +788,22 @@ xed_view_set_font (XedView *view, if (def) { + GObject *settings; gchar *font; - font = xed_prefs_manager_get_system_font (); + + settings = _xed_app_get_settings (XED_APP (g_application_get_default ())); + font = xed_settings_get_system_font (XED_SETTINGS (settings)); font_desc = pango_font_description_from_string (font); + g_free (font); } else { - g_return_if_fail(font_name != NULL); + g_return_if_fail (font_name != NULL); font_desc = pango_font_description_from_string (font_name); } - g_return_if_fail(font_desc != NULL); - gtk_widget_modify_font (GTK_WIDGET(view), font_desc); + g_return_if_fail (font_desc != NULL); + gtk_widget_modify_font (GTK_WIDGET (view), font_desc); pango_font_description_free (font_desc); } - -static void -set_entry_state (GtkWidget *entry, - XedSearchEntryState state) -{ - GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET(entry)); - - if (state == XED_SEARCH_ENTRY_NOT_FOUND) - { - gtk_style_context_add_class (context, GTK_STYLE_CLASS_ERROR); - } - else - { - gtk_style_context_remove_class (context, GTK_STYLE_CLASS_ERROR); - } -} - -/* Cut and paste from gtkwindow.c */ -static void -send_focus_change (GtkWidget *widget, - gboolean in) -{ - GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE); - - g_object_ref (widget); - - fevent->focus_change.type = GDK_FOCUS_CHANGE; - fevent->focus_change.window = g_object_ref (gtk_widget_get_window (widget)); - fevent->focus_change.in = in; - - gtk_widget_event (widget, fevent); - - g_object_notify (G_OBJECT(widget), "has-focus"); - - g_object_unref (widget); - gdk_event_free (fevent); -} - -static void -hide_search_window (XedView *view, - gboolean cancel) -{ - if (view->priv->disable_popdown) - { - return; - } - - if (view->priv->search_entry_changed_id != 0) - { - g_signal_handler_disconnect (view->priv->search_entry, view->priv->search_entry_changed_id); - view->priv->search_entry_changed_id = 0; - } - - if (view->priv->typeselect_flush_timeout != 0) - { - g_source_remove (view->priv->typeselect_flush_timeout); - view->priv->typeselect_flush_timeout = 0; - } - - /* send focus-in event */ - send_focus_change (GTK_WIDGET(view->priv->search_entry), FALSE); - gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW(view), TRUE); - gtk_widget_hide (view->priv->search_window); - - if (cancel) - { - GtkTextBuffer *buffer; - buffer = GTK_TEXT_BUFFER(gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - gtk_text_buffer_place_cursor (buffer, &view->priv->start_search_iter); - xed_view_scroll_to_cursor (view); - } - - /* make sure a focus event is sent for the edit area */ - send_focus_change (GTK_WIDGET(view), TRUE); -} - -static gboolean -search_entry_flush_timeout (XedView *view) -{ - view->priv->typeselect_flush_timeout = 0; - hide_search_window (view, FALSE); - - return FALSE; -} - -static void -update_search_window_position (XedView *view) -{ - gint x, y; - gint view_x, view_y; - GdkWindow *view_window = gtk_widget_get_window (GTK_WIDGET(view)); - - gtk_widget_realize (view->priv->search_window); - gdk_window_get_origin (view_window, &view_x, &view_y); - - x = MAX(12, view_x + 12); - y = MAX(12, view_y - 12); - - gtk_window_move (GTK_WINDOW(view->priv->search_window), x, y); -} - -static gboolean -search_window_deleted (GtkWidget *widget, - GdkEventAny *event, - XedView *view) -{ - hide_search_window (view, FALSE); - return TRUE; -} - -static gboolean -search_window_button_pressed (GtkWidget *widget, - GdkEventButton *event, - XedView *view) -{ - hide_search_window (view, FALSE); - gtk_propagate_event (GTK_WIDGET(view), (GdkEvent *) event); - return FALSE; -} - -static gboolean -search_window_key_pressed (GtkWidget *widget, - GdkEventKey *event, - XedView *view) -{ - gboolean retval = FALSE; - guint modifiers; - - modifiers = gtk_accelerator_get_default_mod_mask (); - - /* Close window */ - if (event->keyval == GDK_KEY_Tab) - { - hide_search_window (view, FALSE); - retval = TRUE; - } - - /* Close window and cancel the search */ - if (event->keyval == GDK_KEY_Escape) - { - hide_search_window (view, TRUE); - retval = TRUE; - } - - return retval; -} - -static void -search_entry_activate (GtkEntry *entry, - XedView *view) -{ - hide_search_window (view, FALSE); -} - -static gboolean -real_search_enable_popdown (gpointer data) -{ - XedView *view = (XedView *) data; - view->priv->disable_popdown = FALSE; - return FALSE; -} - -static void -search_enable_popdown (GtkWidget *widget, - XedView *view) -{ - g_timeout_add (200, real_search_enable_popdown, view); - - /* renew the flush timeout */ - if (view->priv->typeselect_flush_timeout != 0) - { - g_source_remove (view->priv->typeselect_flush_timeout); - } - - view->priv->typeselect_flush_timeout = g_timeout_add (XED_VIEW_SEARCH_DIALOG_TIMEOUT, - (GSourceFunc) search_entry_flush_timeout, view); -} - -static void -search_entry_populate_popup (GtkEntry *entry, - GtkMenu *menu, - XedView *view) -{ - GtkWidget *menu_item; - view->priv->disable_popdown = TRUE; - g_signal_connect(menu, "hide", G_CALLBACK (search_enable_popdown), view); -} - -static void -search_entry_insert_text (GtkEditable *editable, - const gchar *text, - gint length, - gint *position, - XedView *view) -{ - gunichar c; - const gchar *p; - const gchar *end; - const gchar *next; - - p = text; - end = text + length; - - if (p == end) - { - return; - } - - c = g_utf8_get_char (p); - - if (((c == '-' || c == '+') && *position == 0) || (c == ':' && *position != 0)) - { - gchar *s = NULL; - if (c == ':') - { - s = gtk_editable_get_chars (editable, 0, -1); - s = g_utf8_strchr (s, -1, ':'); - } - if (s == NULL || s == p) - { - next = g_utf8_next_char(p); - p = next; - } - g_free (s); - } - - while (p != end) - { - next = g_utf8_next_char(p); - c = g_utf8_get_char (p); - if (!g_unichar_isdigit (c)) - { - g_signal_stop_emission_by_name (editable, "insert_text"); - gtk_widget_error_bell (view->priv->search_entry); - break; - } - p = next; - } -} - -static void -customize_for_search_mode (XedView *view) -{ - gtk_entry_set_icon_from_stock (GTK_ENTRY(view->priv->search_entry), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_JUMP_TO); - gtk_widget_set_tooltip_text (view->priv->search_entry, _("Line you want to move the cursor to")); -} - -static void -ensure_search_window (XedView *view) -{ - GtkWidget *frame; - GtkWidget *vbox; - GtkWidget *toplevel; - GtkWindowGroup *group; - GtkWindowGroup *search_group; - - toplevel = gtk_widget_get_toplevel (GTK_WIDGET(view)); - group = gtk_window_get_group (GTK_WINDOW(toplevel)); - if (view->priv->search_window != NULL) - { - search_group = gtk_window_get_group (GTK_WINDOW(view->priv->search_window)); - } - - if (view->priv->search_window != NULL) - { - if (group) - { - gtk_window_group_add_window (group, GTK_WINDOW(view->priv->search_window)); - } - else if (search_group) - { - gtk_window_group_remove_window (search_group, GTK_WINDOW(view->priv->search_window)); - } - customize_for_search_mode (view); - return; - } - - view->priv->search_window = gtk_window_new (GTK_WINDOW_POPUP); - - if (group) - { - gtk_window_group_add_window (group, GTK_WINDOW(view->priv->search_window)); - } - - gtk_window_set_modal (GTK_WINDOW(view->priv->search_window), TRUE); - - g_signal_connect(view->priv->search_window, "delete_event", G_CALLBACK (search_window_deleted), view); - g_signal_connect(view->priv->search_window, "key_press_event", G_CALLBACK (search_window_key_pressed), view); - g_signal_connect(view->priv->search_window, "button_press_event", G_CALLBACK (search_window_button_pressed), view); - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); - gtk_widget_show (frame); - gtk_container_add (GTK_CONTAINER(view->priv->search_window), frame); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_widget_show (vbox); - gtk_container_add (GTK_CONTAINER(frame), vbox); - gtk_container_set_border_width (GTK_CONTAINER(vbox), 3); - - /* add entry */ - view->priv->search_entry = gtk_entry_new (); - gtk_widget_show (view->priv->search_entry); - - g_signal_connect(view->priv->search_entry, "populate_popup", G_CALLBACK (search_entry_populate_popup), view); - g_signal_connect(view->priv->search_entry, "activate", G_CALLBACK (search_entry_activate), view); - g_signal_connect(view->priv->search_entry, "insert_text", G_CALLBACK (search_entry_insert_text), view); - - gtk_container_add (GTK_CONTAINER(vbox), view->priv->search_entry); - gtk_widget_realize (view->priv->search_entry); - - customize_for_search_mode (view); -} - -static gboolean -get_selected_text (GtkTextBuffer *doc, - gchar **selected_text, - gint *len) -{ - GtkTextIter start, end; - - g_return_val_if_fail(selected_text != NULL, FALSE); - g_return_val_if_fail(*selected_text == NULL, FALSE); - - if (!gtk_text_buffer_get_selection_bounds (doc, &start, &end)) - { - if (len != NULL) - { - len = 0; - } - return FALSE; - } - - *selected_text = gtk_text_buffer_get_slice (doc, &start, &end, TRUE); - - if (len != NULL) - { - *len = g_utf8_strlen (*selected_text, -1); - } - - return TRUE; -} - -static void -init_search_entry (XedView *view) -{ - gint line; - gchar *line_str; - - line = gtk_text_iter_get_line (&view->priv->start_search_iter); - line_str = g_strdup_printf ("%d", line + 1); - gtk_entry_set_text (GTK_ENTRY(view->priv->search_entry), line_str); - - g_free (line_str); - return; -} - -static void -search_init (GtkWidget *entry, - XedView *view) -{ - XedDocument *doc; - const gchar *entry_text; - - /* renew the flush timeout */ - if (view->priv->typeselect_flush_timeout != 0) - { - g_source_remove (view->priv->typeselect_flush_timeout); - view->priv->typeselect_flush_timeout = g_timeout_add (XED_VIEW_SEARCH_DIALOG_TIMEOUT, - (GSourceFunc) search_entry_flush_timeout, view); - } - doc = XED_DOCUMENT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - - entry_text = gtk_entry_get_text (GTK_ENTRY(entry)); - - if (*entry_text != '\0') - { - gboolean moved, moved_offset; - gint line; - gint offset_line = 0; - gint line_offset = 0; - gchar **split_text = NULL; - const gchar *text; - - split_text = g_strsplit (entry_text, ":", -1); - - if (g_strv_length (split_text) > 1) - { - text = split_text[0]; - } - else - { - text = entry_text; - } - - if (*text == '-') - { - gint cur_line = gtk_text_iter_get_line (&view->priv->start_search_iter); - - if (*(text + 1) != '\0') - { - offset_line = MAX(atoi (text + 1), 0); - } - - line = MAX(cur_line - offset_line, 0); - } - else if (*entry_text == '+') - { - gint cur_line = gtk_text_iter_get_line (&view->priv->start_search_iter); - - if (*(text + 1) != '\0') - { - offset_line = MAX(atoi (text + 1), 0); - } - - line = cur_line + offset_line; - } - else - { - line = MAX(atoi (text) - 1, 0); - } - - if (split_text[1] != NULL) - { - line_offset = atoi (split_text[1]); - } - - g_strfreev (split_text); - - moved = xed_document_goto_line (doc, line); - moved_offset = xed_document_goto_line_offset (doc, line, line_offset); - - xed_view_scroll_to_cursor (view); - - if (!moved || !moved_offset) - { - set_entry_state (view->priv->search_entry, XED_SEARCH_ENTRY_NOT_FOUND); - } - else - { - set_entry_state (view->priv->search_entry, XED_SEARCH_ENTRY_NORMAL); - } - } -} - -static gboolean -start_interactive_goto_line (XedView *view) -{ - GtkTextBuffer *buffer; - - if ((view->priv->search_window != NULL) && gtk_widget_get_visible (view->priv->search_window)) - { - return TRUE; - } - - if (!gtk_widget_has_focus (GTK_WIDGET(view))) - { - return FALSE; - } - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(view)); - - gtk_text_buffer_get_iter_at_mark (buffer, &view->priv->start_search_iter, gtk_text_buffer_get_insert (buffer)); - - ensure_search_window (view); - - /* done, show it */ - update_search_window_position (view); - gtk_widget_show (view->priv->search_window); - - if (view->priv->search_entry_changed_id == 0) - { - view->priv->search_entry_changed_id = g_signal_connect(view->priv->search_entry, "changed", - G_CALLBACK (search_init), view); - } - - init_search_entry (view); - - view->priv->typeselect_flush_timeout = g_timeout_add (XED_VIEW_SEARCH_DIALOG_TIMEOUT, - (GSourceFunc) search_entry_flush_timeout, view); - - gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW(view), FALSE); - gtk_widget_grab_focus (view->priv->search_entry); - - send_focus_change (view->priv->search_entry, TRUE); - - return TRUE; -} - -static gboolean -xed_view_draw (GtkWidget *widget, - cairo_t *cr) -{ - GtkTextView *text_view; - XedDocument *doc; - GdkWindow *window; - - text_view = GTK_TEXT_VIEW(widget); - - doc = XED_DOCUMENT(gtk_text_view_get_buffer (text_view)); - window = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT); - if (gtk_cairo_should_draw_window (cr, window) && xed_document_get_enable_search_highlighting (doc)) - { - GdkRectangle visible_rect; - GtkTextIter iter1, iter2; - - gtk_text_view_get_visible_rect (text_view, &visible_rect); - gtk_text_view_get_line_at_y (text_view, &iter1, visible_rect.y, NULL); - gtk_text_view_get_line_at_y (text_view, &iter2, visible_rect.y + visible_rect.height, NULL); - gtk_text_iter_forward_line (&iter2); - - _xed_document_search_region (doc, &iter1, &iter2); - } - - return GTK_WIDGET_CLASS (xed_view_parent_class)->draw (widget, cr); -} - -static GdkAtom -drag_get_uri_target (GtkWidget *widget, - GdkDragContext *context) -{ - GdkAtom target; - GtkTargetList *tl; - - tl = gtk_target_list_new (NULL, 0); - gtk_target_list_add_uri_targets (tl, 0); - target = gtk_drag_dest_find_target (widget, context, tl); - gtk_target_list_unref (tl); - - return target; -} - -static gboolean -xed_view_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint timestamp) -{ - gboolean result; - - /* Chain up to allow textview to scroll and position dnd mark, note - * that this needs to be checked if gtksourceview or gtktextview - * changes drag_motion behaviour */ - result = GTK_WIDGET_CLASS (xed_view_parent_class)->drag_motion (widget, context, x, y, timestamp); - - /* If this is a URL, deal with it here */ - if (drag_get_uri_target (widget, context) != GDK_NONE) - { - gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), timestamp); - result = TRUE; - } - - return result; -} - -static void -xed_view_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint timestamp) -{ - gchar **uri_list; - - /* If this is an URL emit DROP_URIS, otherwise chain up the signal */ - if (info == TARGET_URI_LIST) - { - uri_list = xed_utils_drop_get_uris (selection_data); - - if (uri_list != NULL) - { - g_signal_emit (widget, view_signals[DROP_URIS], 0, uri_list); - g_strfreev (uri_list); - gtk_drag_finish (context, TRUE, FALSE, timestamp); - } - } - else - { - GTK_WIDGET_CLASS (xed_view_parent_class)->drag_data_received (widget, context, x, y, selection_data, info, - timestamp); - } -} - -static gboolean -xed_view_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint timestamp) -{ - gboolean result; - GdkAtom target; - - /* If this is a URL, just get the drag data */ - target = drag_get_uri_target (widget, context); - - if (target != GDK_NONE) - { - gtk_drag_get_data (widget, context, target, timestamp); - result = TRUE; - } - else - { - /* Chain up */ - result = GTK_WIDGET_CLASS (xed_view_parent_class)->drag_drop (widget, context, x, y, timestamp); - } - - return result; -} - -static void -show_line_numbers_toggled (GtkMenu *menu, - XedView *view) -{ - gboolean show; - - show = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(menu)); - xed_prefs_manager_set_display_line_numbers (show); -} - -static GtkWidget * -create_line_numbers_menu (GtkWidget *view) -{ - GtkWidget *menu; - GtkWidget *item; - - menu = gtk_menu_new (); - - item = gtk_check_menu_item_new_with_mnemonic (_("_Display line numbers")); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(item), - gtk_source_view_get_show_line_numbers (GTK_SOURCE_VIEW(view))); - g_signal_connect(item, "toggled", G_CALLBACK (show_line_numbers_toggled), view); - gtk_menu_shell_append (GTK_MENU_SHELL(menu), item); - - gtk_widget_show_all (menu); - - return menu; -} - -static void -show_line_numbers_menu (GtkWidget *view, - GdkEventButton *event) -{ - GtkWidget *menu; - - menu = create_line_numbers_menu (view); - gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time); -} - -static gboolean -xed_view_button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - if ((event->type == GDK_BUTTON_PRESS) - && (event->button == 3) - && (event->window == gtk_text_view_get_window (GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_LEFT))) - { - - show_line_numbers_menu (widget, event); - - return TRUE; - } - - return GTK_WIDGET_CLASS (xed_view_parent_class)->button_press_event (widget, event); -} - -static void -search_highlight_updated_cb (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end, - XedView *view) -{ - GdkRectangle visible_rect; - GdkRectangle updated_rect; - GdkRectangle redraw_rect; - gint y; - gint height; - GtkTextView *text_view; - - text_view = GTK_TEXT_VIEW(view); - - g_return_if_fail(xed_document_get_enable_search_highlighting (XED_DOCUMENT (gtk_text_view_get_buffer (text_view)))); - - /* get visible area */ - gtk_text_view_get_visible_rect (text_view, &visible_rect); - - /* get updated rectangle */ - gtk_text_view_get_line_yrange (text_view, start, &y, &height); - updated_rect.y = y; - gtk_text_view_get_line_yrange (text_view, end, &y, &height); - updated_rect.height = y + height - updated_rect.y; - updated_rect.x = visible_rect.x; - updated_rect.width = visible_rect.width; - - /* intersect both rectangles to see whether we need to queue a redraw */ - if (gdk_rectangle_intersect (&updated_rect, &visible_rect, &redraw_rect)) - { - GdkRectangle widget_rect; - gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_WIDGET, redraw_rect.x, redraw_rect.y, - &widget_rect.x, &widget_rect.y); - - widget_rect.width = redraw_rect.width; - widget_rect.height = redraw_rect.height; - - gtk_widget_queue_draw_area (GTK_WIDGET(text_view), widget_rect.x, widget_rect.y, widget_rect.width, - widget_rect.height); - } -} - -static void -delete_line (GtkTextView *text_view, - gint count) -{ - GtkTextIter start; - GtkTextIter end; - GtkTextBuffer *buffer; - - buffer = gtk_text_view_get_buffer (text_view); - - gtk_text_view_reset_im_context (text_view); - - /* If there is a selection delete the selected lines and - * ignore count */ - if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) - { - gtk_text_iter_order (&start, &end); - if (gtk_text_iter_starts_line (&end)) - { - /* Do no delete the line with the cursor if the cursor - * is at the beginning of the line */ - count = 0; - } - else - { - count = 1; - } - } - - gtk_text_iter_set_line_offset (&start, 0); - - if (count > 0) - { - gtk_text_iter_forward_lines (&end, count); - if (gtk_text_iter_is_end (&end)) - { - if (gtk_text_iter_backward_line (&start) && !gtk_text_iter_ends_line (&start)) - { - gtk_text_iter_forward_to_line_end (&start); - } - } - } - else if (count < 0) - { - if (!gtk_text_iter_ends_line (&end)) - { - gtk_text_iter_forward_to_line_end (&end); - } - - while (count < 0) - { - if (!gtk_text_iter_backward_line (&start)) - { - break; - } - ++count; - } - - if (count == 0) - { - if (!gtk_text_iter_ends_line (&start)) - { - gtk_text_iter_forward_to_line_end (&start); - } - } - else - { - gtk_text_iter_forward_line (&end); - } - } - - if (!gtk_text_iter_equal (&start, &end)) - { - GtkTextIter cur = start; - gtk_text_iter_set_line_offset (&cur, 0); - gtk_text_buffer_begin_user_action (buffer); - gtk_text_buffer_place_cursor (buffer, &cur); - gtk_text_buffer_delete_interactive (buffer, &start, &end, gtk_text_view_get_editable (text_view)); - gtk_text_buffer_end_user_action (buffer); - gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_buffer_get_insert (buffer)); - } - else - { - gtk_widget_error_bell (GTK_WIDGET(text_view)); - } -} - -static void -xed_view_delete_from_cursor (GtkTextView *text_view, - GtkDeleteType type, - gint count) -{ - /* We override the standard handler for delete_from_cursor since - the GTK_DELETE_PARAGRAPHS case is not implemented as we like (i.e. it - does not remove the carriage return in the previous line) - */ - switch (type) - { - case GTK_DELETE_PARAGRAPHS: - delete_line (text_view, count); - break; - default: - GTK_TEXT_VIEW_CLASS (xed_view_parent_class)->delete_from_cursor (text_view, type, count); - break; - } -} diff --git a/xed/xed-view.h b/xed/xed-view.h index 368be30..eab7295 100644 --- a/xed/xed-view.h +++ b/xed/xed-view.h @@ -46,9 +46,6 @@ struct _XedViewClass /* FIXME: Do we need placeholders ? */ /* Key bindings */ - gboolean (* start_interactive_search) (XedView *view); - gboolean (* start_interactive_goto_line)(XedView *view); - gboolean (* reset_searched_text) (XedView *view); void (* drop_uris) (XedView *view, gchar **uri_list); }; diff --git a/xed/xed-window-activatable.c b/xed/xed-window-activatable.c new file mode 100644 index 0000000..e7b373b --- /dev/null +++ b/xed/xed-window-activatable.c @@ -0,0 +1,117 @@ +/* + * xed-window-activatable.h + * This file is part of xed + * + * Copyright (C) 2010 Steve Frécinaux + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xed-window-activatable.h" +#include "xed-window.h" + +/** + * SECTION:xed-window-activatable + * @short_description: Interface for activatable extensions on windows + * @see_also: #PeasExtensionSet + * + * #XedWindowActivatable is an interface which should be implemented by + * extensions that should be activated on a xed main window. + **/ +G_DEFINE_INTERFACE(XedWindowActivatable, xed_window_activatable, G_TYPE_OBJECT) + +void +xed_window_activatable_default_init (XedWindowActivatableInterface *iface) +{ + /** + * XedWindowActivatable:window: + * + * The window property contains the xed window for this + * #XedWindowActivatable instance. + */ + g_object_interface_install_property (iface, + g_param_spec_object ("window", + "Window", + "The xed window", + XED_TYPE_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +/** + * xed_window_activatable_activate: + * @activatable: A #XedWindowActivatable. + * + * Activates the extension on the window property. + */ +void +xed_window_activatable_activate (XedWindowActivatable *activatable) +{ + XedWindowActivatableInterface *iface; + + g_return_if_fail (XED_IS_WINDOW_ACTIVATABLE (activatable)); + + iface = XED_WINDOW_ACTIVATABLE_GET_IFACE (activatable); + if (iface->activate != NULL) + { + iface->activate (activatable); + } +} + +/** + * xed_window_activatable_deactivate: + * @activatable: A #XedWindowActivatable. + * + * Deactivates the extension on the window property. + */ +void +xed_window_activatable_deactivate (XedWindowActivatable *activatable) +{ + XedWindowActivatableInterface *iface; + + g_return_if_fail (XED_IS_WINDOW_ACTIVATABLE (activatable)); + + iface = XED_WINDOW_ACTIVATABLE_GET_IFACE (activatable); + if (iface->deactivate != NULL) + { + iface->deactivate (activatable); + } +} + +/** + * xed_window_activatable_update_state: + * @activatable: A #XedWindowActivatable. + * + * Triggers an update of the extension insternal state to take into account + * state changes in the window state, due to some event or user action. + */ +void +xed_window_activatable_update_state (XedWindowActivatable *activatable) +{ + XedWindowActivatableInterface *iface; + + g_return_if_fail (XED_IS_WINDOW_ACTIVATABLE (activatable)); + + iface = XED_WINDOW_ACTIVATABLE_GET_IFACE (activatable); + if (iface->update_state != NULL) + { + iface->update_state (activatable); + } +} diff --git a/xed/xed-window-activatable.h b/xed/xed-window-activatable.h new file mode 100644 index 0000000..3476e6a --- /dev/null +++ b/xed/xed-window-activatable.h @@ -0,0 +1,62 @@ +/* + * xed-window-activatable.h + * This file is part of xed + * + * Copyright (C) 2010 - Steve Frécinaux + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __XED_WINDOW_ACTIVATABLE_H__ +#define __XED_WINDOW_ACTIVATABLE_H__ + +#include + +G_BEGIN_DECLS + +/* + * Type checking and casting macros + */ +#define XED_TYPE_WINDOW_ACTIVATABLE (xed_window_activatable_get_type ()) +#define XED_WINDOW_ACTIVATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_WINDOW_ACTIVATABLE, XedWindowActivatable)) +#define XED_WINDOW_ACTIVATABLE_IFACE(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), XED_TYPE_WINDOW_ACTIVATABLE, XedWindowActivatableInterface)) +#define XED_IS_WINDOW_ACTIVATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_WINDOW_ACTIVATABLE)) +#define XED_WINDOW_ACTIVATABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), XED_TYPE_WINDOW_ACTIVATABLE, XedWindowActivatableInterface)) + +typedef struct _XedWindowActivatable XedWindowActivatable; /* dummy typedef */ +typedef struct _XedWindowActivatableInterface XedWindowActivatableInterface; + +struct _XedWindowActivatableInterface +{ + GTypeInterface g_iface; + + /* Virtual public methods */ + void (*activate) (XedWindowActivatable *activatable); + void (*deactivate) (XedWindowActivatable *activatable); + void (*update_state) (XedWindowActivatable *activatable); +}; + +/* + * Public methods + */ +GType xed_window_activatable_get_type (void) G_GNUC_CONST; + +void xed_window_activatable_activate (XedWindowActivatable *activatable); +void xed_window_activatable_deactivate (XedWindowActivatable *activatable); +void xed_window_activatable_update_state (XedWindowActivatable *activatable); + +G_END_DECLS + +#endif /* __XED_WINDOW_ACTIVATABLE_H__ */ diff --git a/xed/xed-window-private.h b/xed/xed-window-private.h index 0be7945..6796964 100644 --- a/xed/xed-window-private.h +++ b/xed/xed-window-private.h @@ -2,7 +2,7 @@ * xed-window-private.h * This file is part of xed * - * Copyright (C) 2005 - Paolo Maggi + * Copyright (C) 2005 - Paolo Maggi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /* - * Modified by the xed Team, 2005. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. + * Modified by the xed Team, 2005. See the AUTHORS file for a + * list of people on the xed Team. + * See the ChangeLog files for a list of changes. * * $Id$ */ @@ -31,9 +31,11 @@ #ifndef __XED_WINDOW_PRIVATE_H__ #define __XED_WINDOW_PRIVATE_H__ +#include + #include "xed/xed-window.h" -#include "xed-prefs-manager.h" #include "xed-message-bus.h" +#include "xed-settings.h" G_BEGIN_DECLS @@ -41,74 +43,83 @@ G_BEGIN_DECLS struct _XedWindowPrivate { - GtkWidget *notebook; + GSettings *editor_settings; + GSettings *ui_settings; + GSettings *window_settings; - GtkWidget *side_panel; - GtkWidget *bottom_panel; + GtkWidget *notebook; - GtkWidget *hpaned; - GtkWidget *vpaned; - - GtkWidget *tab_width_combo; - GtkWidget *language_combo; - - XedMessageBus *message_bus; + GtkWidget *side_panel; + GtkWidget *bottom_panel; - /* Widgets for fullscreen mode */ - GtkWidget *fullscreen_controls; - GtkWidget *fullscreen_controls_container; - guint fullscreen_animation_timeout_id; - gboolean fullscreen_animation_enter; + GtkWidget *hpaned; + GtkWidget *vpaned; - /* statusbar and context ids for statusbar messages */ - GtkWidget *statusbar; - GtkWidget *searchbar; - guint generic_message_cid; - guint tip_message_cid; - guint tab_width_id; - guint spaces_instead_of_tabs_id; - guint language_changed_id; + GtkWidget *tab_width_combo; + GtkWidget *language_combo; + GtkWidget *show_side_pane_button; + GtkWidget *show_bottom_pane_button; + GtkWidget *bottom_pane_button_revealer; - /* Menus & Toolbars */ - GtkUIManager *manager; - GtkActionGroup *action_group; - GtkActionGroup *always_sensitive_action_group; - GtkActionGroup *close_action_group; - GtkActionGroup *quit_action_group; - GtkActionGroup *panes_action_group; - GtkActionGroup *languages_action_group; - GtkActionGroup *documents_list_action_group; - guint documents_list_menu_ui_id; - GtkWidget *toolbar; - GtkWidget *menubar; + XedMessageBus *message_bus; + PeasExtensionSet *extensions; - /* recent files */ - GtkActionGroup *recents_action_group; - guint recents_menu_ui_id; - gulong recents_handler_id; + /* Widgets for fullscreen mode */ + GtkWidget *fullscreen_controls; + GtkWidget *fullscreen_controls_container; + guint fullscreen_animation_timeout_id; + gboolean fullscreen_animation_enter; - XedTab *active_tab; - gint num_tabs; + /* statusbar and context ids for statusbar messages */ + GtkWidget *statusbar; + GtkWidget *searchbar; + guint generic_message_cid; + guint tip_message_cid; + guint tab_width_id; + guint spaces_instead_of_tabs_id; + guint language_changed_id; + guint use_word_wrap_id; - gint num_tabs_with_error; + /* Menus & Toolbars */ + GtkUIManager *manager; + GtkActionGroup *action_group; + GtkActionGroup *always_sensitive_action_group; + GtkActionGroup *close_action_group; + GtkActionGroup *quit_action_group; + GtkActionGroup *panes_action_group; + GtkActionGroup *languages_action_group; + GtkActionGroup *documents_list_action_group; + guint documents_list_menu_ui_id; + GtkWidget *toolbar; + GtkWidget *menubar; - gint width; - gint height; - GdkWindowState window_state; + /* recent files */ + GtkActionGroup *recents_action_group; + guint recents_menu_ui_id; + gulong recents_handler_id; - gint side_panel_size; - gint bottom_panel_size; + XedTab *active_tab; + gint num_tabs; - XedWindowState state; + gint num_tabs_with_error; - gint bottom_panel_item_removed_handler_id; + gint width; + gint height; + GdkWindowState window_state; - GtkWindowGroup *window_group; + gint side_panel_size; + gint bottom_panel_size; - GFile *default_location; + XedWindowState state; - gboolean removing_tabs : 1; - gboolean dispose_has_run : 1; + gint bottom_panel_item_removed_handler_id; + + GtkWindowGroup *window_group; + + GFile *default_location; + + gboolean removing_tabs : 1; + gboolean dispose_has_run : 1; }; G_END_DECLS diff --git a/xed/xed-window.c b/xed/xed-window.c index 1b50c99..a378b01 100644 --- a/xed/xed-window.c +++ b/xed/xed-window.c @@ -6,9 +6,8 @@ #include #include #include -#include #include -#include +#include #include "xed-ui.h" #include "xed-window.h" @@ -17,38 +16,47 @@ #include "xed-notebook.h" #include "xed-statusbar.h" #include "xed-searchbar.h" +#include "xed-view-frame.h" #include "xed-utils.h" #include "xed-commands.h" #include "xed-debug.h" -#include "xed-language-manager.h" -#include "xed-prefs-manager-app.h" #include "xed-panel.h" #include "xed-documents-panel.h" #include "xed-plugins-engine.h" +#include "xed-window-activatable.h" #include "xed-enum-types.h" #include "xed-dirs.h" #include "xed-status-combo-box.h" +#include "xed-settings.h" #define LANGUAGE_NONE (const gchar *)"LangNone" -#define XED_UIFILE "xed-ui.xml" #define TAB_WIDTH_DATA "XedWindowTabWidthData" #define LANGUAGE_DATA "XedWindowLanguageData" #define FULLSCREEN_ANIMATION_SPEED 4 +#define XED_WINDOW_DEFAULT_WIDTH 650 +#define XED_WINDOW_DEFAULT_HEIGHT 500 + #define XED_WINDOW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_WINDOW, XedWindowPrivate)) /* Signals */ enum { - TAB_ADDED, TAB_REMOVED, TABS_REORDERED, ACTIVE_TAB_CHANGED, ACTIVE_TAB_STATE_CHANGED, LAST_SIGNAL + TAB_ADDED, + TAB_REMOVED, + TABS_REORDERED, + ACTIVE_TAB_CHANGED, + ACTIVE_TAB_STATE_CHANGED, + LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; enum { - PROP_0, PROP_STATE + PROP_0, + PROP_STATE }; enum @@ -56,14 +64,14 @@ enum TARGET_URI_LIST = 100 }; -G_DEFINE_TYPE(XedWindow, xed_window, GTK_TYPE_WINDOW) +G_DEFINE_TYPE(XedWindow, xed_window, GTK_TYPE_APPLICATION_WINDOW) static void recent_manager_changed (GtkRecentManager *manager, XedWindow *window); static void -xed_window_get_property (GObject *object, - guint prop_id, - GValue *value, +xed_window_get_property (GObject *object, + guint prop_id, + GValue *value, GParamSpec *pspec) { XedWindow *window = XED_WINDOW(object); @@ -82,41 +90,33 @@ xed_window_get_property (GObject *object, static void save_panes_state (XedWindow *window) { - gint pane_page; + gint panel_page; xed_debug (DEBUG_WINDOW); - if (xed_prefs_manager_window_size_can_set ()) + if (window->priv->side_panel_size > 0) { - xed_prefs_manager_set_window_size (window->priv->width, window->priv->height); + g_settings_set_int (window->priv->window_settings, XED_SETTINGS_SIDE_PANEL_SIZE, window->priv->side_panel_size); } - if (xed_prefs_manager_window_state_can_set ()) + panel_page = _xed_panel_get_active_item_id (XED_PANEL (window->priv->side_panel)); + if (panel_page != 0) { - xed_prefs_manager_set_window_state (window->priv->window_state); + g_settings_set_int (window->priv->window_settings, XED_SETTINGS_SIDE_PANEL_ACTIVE_PAGE, panel_page); } - if ((window->priv->side_panel_size > 0) && xed_prefs_manager_side_panel_size_can_set ()) + if (window->priv->bottom_panel_size > 0) { - xed_prefs_manager_set_side_panel_size (window->priv->side_panel_size); + g_settings_set_int (window->priv->window_settings, XED_SETTINGS_BOTTOM_PANEL_SIZE, window->priv->bottom_panel_size); } - pane_page = _xed_panel_get_active_item_id (XED_PANEL(window->priv->side_panel)); - if (pane_page != 0 && xed_prefs_manager_side_panel_active_page_can_set ()) + panel_page = _xed_panel_get_active_item_id (XED_PANEL(window->priv->bottom_panel)); + if (panel_page != 0) { - xed_prefs_manager_set_side_panel_active_page (pane_page); + g_settings_set_int (window->priv->window_settings, XED_SETTINGS_BOTTOM_PANEL_ACTIVE_PAGE, panel_page); } - if ((window->priv->bottom_panel_size > 0) && xed_prefs_manager_bottom_panel_size_can_set ()) - { - xed_prefs_manager_set_bottom_panel_size (window->priv->bottom_panel_size); - } - - pane_page = _xed_panel_get_active_item_id (XED_PANEL(window->priv->bottom_panel)); - if (pane_page != 0 && xed_prefs_manager_bottom_panel_active_page_can_set ()) - { - xed_prefs_manager_set_bottom_panel_active_page (pane_page); - } + g_settings_apply (window->priv->window_settings); } static gint @@ -124,13 +124,46 @@ on_key_pressed (GtkWidget *widget, GdkEventKey *event, XedWindow *window) { - gint handled = FALSE; if (event->keyval == GDK_KEY_Escape) { - xed_searchbar_hide (window->priv->searchbar); - handled = TRUE; + XedTab *tab; + XedViewFrame *frame; + + tab = xed_window_get_active_tab (window); + frame = XED_VIEW_FRAME (_xed_tab_get_view_frame (tab)); + + if (xed_view_frame_get_search_popup_visible (frame)) + { + return GDK_EVENT_PROPAGATE; + } + else + { + xed_searchbar_hide (XED_SEARCHBAR (window->priv->searchbar)); + return GDK_EVENT_STOP; + } + } + + return GDK_EVENT_PROPAGATE; +} + +static void +save_window_state (GtkWidget *widget) +{ + XedWindow *window = XED_WINDOW (widget); + + if ((window->priv->window_state & + (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0) + { + GtkAllocation allocation; + + gtk_widget_get_allocation (widget, &allocation); + + window->priv->width = allocation.width; + window->priv->height = allocation.height; + + g_settings_set (window->priv->window_settings, XED_SETTINGS_WINDOW_SIZE, + "(ii)", window->priv->width, window->priv->height); } - return handled; } static void @@ -140,7 +173,7 @@ xed_window_dispose (GObject *object) xed_debug (DEBUG_WINDOW); - window = XED_WINDOW(object); + window = XED_WINDOW (object); /* Stop tracking removal of panes otherwise we always * end up with thinking we had no pane active, since they @@ -154,14 +187,21 @@ xed_window_dispose (GObject *object) /* First of all, force collection so that plugins * really drop some of the references. */ - xed_plugins_engine_garbage_collect (xed_plugins_engine_get_default ()); + peas_engine_garbage_collect (PEAS_ENGINE (xed_plugins_engine_get_default())); /* save the panes position and make sure to deactivate plugins * for this window, but only once */ if (!window->priv->dispose_has_run) { + save_window_state (GTK_WIDGET (window)); save_panes_state (window); - xed_plugins_engine_deactivate_plugins (xed_plugins_engine_get_default (), window); + + /* Note that unreffing the extension will automatically remove + all extensions which in turn will deactivate the extension */ + g_object_unref (window->priv->extensions); + + peas_engine_garbage_collect (PEAS_ENGINE (xed_plugins_engine_get_default ())); + window->priv->dispose_has_run = TRUE; } @@ -185,27 +225,18 @@ xed_window_dispose (GObject *object) window->priv->recents_handler_id = 0; } - if (window->priv->manager != NULL) - { - g_object_unref (window->priv->manager); - window->priv->manager = NULL; - } + g_clear_object (&window->priv->manager); + g_clear_object (&window->priv->message_bus); + g_clear_object (&window->priv->window_group); + g_clear_object (&window->priv->default_location); - if (window->priv->message_bus != NULL) - { - g_object_unref (window->priv->message_bus); - window->priv->message_bus = NULL; - } + /* We must free the settings after saving the panels */ + g_clear_object (&window->priv->editor_settings); + g_clear_object (&window->priv->ui_settings); + g_clear_object (&window->priv->window_settings); - if (window->priv->window_group != NULL) - { - g_object_unref (window->priv->window_group); - window->priv->window_group = NULL; - } - - /* Now that there have broken some reference loops, force collection again. - */ - xed_plugins_engine_garbage_collect (xed_plugins_engine_get_default ()); + /* Now that there have broken some reference loops, force collection again. */ + peas_engine_garbage_collect (PEAS_ENGINE (xed_plugins_engine_get_default ())); G_OBJECT_CLASS (xed_window_parent_class)->dispose (object); } @@ -213,37 +244,35 @@ xed_window_dispose (GObject *object) static void xed_window_finalize (GObject *object) { - XedWindow *window; xed_debug (DEBUG_WINDOW); - window = XED_WINDOW(object); - if (window->priv->default_location != NULL) - { - g_object_unref (window->priv->default_location); - } + G_OBJECT_CLASS (xed_window_parent_class)->finalize (object); } static gboolean -xed_window_window_state_event (GtkWidget *widget, +xed_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event) { - XedWindow *window = XED_WINDOW(widget); + XedWindow *window = XED_WINDOW (widget); + window->priv->window_state = event->new_window_state; - if (event->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) - { - gboolean show; - show = !(event->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)); - } + g_settings_set_int (window->priv->window_settings, XED_SETTINGS_WINDOW_STATE, window->priv->state); + return FALSE; } static gboolean -xed_window_configure_event (GtkWidget *widget, +xed_window_configure_event (GtkWidget *widget, GdkEventConfigure *event) { - XedWindow *window = XED_WINDOW(widget); - window->priv->width = event->width; - window->priv->height = event->height; + XedWindow *window = XED_WINDOW (widget); + + if (gtk_widget_get_realized (widget) && + (window->priv->state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0) + { + save_window_state (widget); + } + return GTK_WIDGET_CLASS (xed_window_parent_class)->configure_event (widget, event); } @@ -293,7 +322,7 @@ static void xed_window_tab_removed (XedWindow *window, XedTab *tab) { - xed_plugins_engine_garbage_collect (xed_plugins_engine_get_default ()); + peas_engine_garbage_collect (PEAS_ENGINE (xed_plugins_engine_get_default ())); } static void @@ -403,7 +432,7 @@ set_toolbar_style (XedWindow *window, if (origin == NULL) { - visible = xed_prefs_manager_get_toolbar_visible (); + visible = g_settings_get_boolean (window->priv->ui_settings, XED_SETTINGS_TOOLBAR_VISIBLE); } else { @@ -422,9 +451,9 @@ set_toolbar_style (XedWindow *window, action = gtk_action_group_get_action (window->priv->always_sensitive_action_group, "ViewToolbar"); - if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action)) != visible) + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) != visible) { - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action), visible); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), visible); } return visible; @@ -529,7 +558,7 @@ set_paste_sensitivity_according_to_clipboard (XedWindow *window, static void set_sensitivity_according_to_tab (XedWindow *window, - XedTab *tab) + XedTab *tab) { XedDocument *doc; XedView *view; @@ -539,18 +568,21 @@ set_sensitivity_according_to_tab (XedWindow *window, gboolean editable; XedTabState state; GtkClipboard *clipboard; + gboolean enable_syntax_hl; - g_return_if_fail(XED_TAB (tab)); + g_return_if_fail (XED_TAB (tab)); xed_debug (DEBUG_WINDOW); + enable_syntax_hl = g_settings_get_boolean (window->priv->editor_settings, XED_SETTINGS_SYNTAX_HIGHLIGHTING); + state = xed_tab_get_state (tab); state_normal = (state == XED_TAB_STATE_NORMAL); view = xed_tab_get_view (tab); editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(view)); - doc = XED_DOCUMENT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); clipboard = gtk_widget_get_clipboard (GTK_WIDGET(window), GDK_SELECTION_CLIPBOARD); @@ -625,7 +657,7 @@ set_sensitivity_according_to_tab (XedWindow *window, action = gtk_action_group_get_action (window->priv->action_group, "SearchReplace"); gtk_action_set_sensitive (action, state_normal && editable); - b = xed_document_get_can_search_again (doc); + b = TRUE; action = gtk_action_group_get_action (window->priv->action_group, "SearchFindNext"); gtk_action_set_sensitive (action, (state_normal || state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) && b); @@ -636,12 +668,11 @@ set_sensitivity_according_to_tab (XedWindow *window, gtk_action_set_sensitive (action, (state_normal || state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)); action = gtk_action_group_get_action (window->priv->action_group, "ViewHighlightMode"); - gtk_action_set_sensitive (action, - (state != XED_TAB_STATE_CLOSING) && xed_prefs_manager_get_enable_syntax_highlighting ()); + gtk_action_set_sensitive (action, (state != XED_TAB_STATE_CLOSING) && enable_syntax_hl); update_next_prev_doc_sensitivity (window, tab); - xed_plugins_engine_update_plugins_ui (xed_plugins_engine_get_default (), window); + peas_extension_set_call (window->priv->extensions, "update_state"); } static void @@ -672,7 +703,7 @@ language_toggled (GtkToggleAction *action, } else { - lang = gtk_source_language_manager_get_language (xed_get_language_manager (), lang_id); + lang = gtk_source_language_manager_get_language (gtk_source_language_manager_get_default (), lang_id); if (lang == NULL) { g_warning("Could not get language %s\n", lang_id); @@ -764,6 +795,54 @@ create_language_menu_item (GtkSourceLanguage *lang, g_free (escaped_section); } +static gint +language_compare (GtkSourceLanguage *lang1, + GtkSourceLanguage *lang2) +{ + const gchar *section1, *section2, *name1, *name2; + gchar *tmp1, *tmp2; + gint ret; + + section1 = gtk_source_language_get_section (lang1); + section2 = gtk_source_language_get_section (lang2); + name1 = gtk_source_language_get_name (lang1); + name2 = gtk_source_language_get_name (lang2); + + /* we collate the concatenation so that they are + * sorted first by section and then by name */ + tmp1 = g_strconcat (section1, "::", name1, NULL); + tmp2 = g_strconcat (section2, "::", name2, NULL); + + ret = g_utf8_collate (tmp1, tmp2); + + g_free(tmp1); + g_free(tmp2); + + return ret; +} + +static GSList * +get_languages_sorted_by_section (XedWindow *window) +{ + GtkSourceLanguageManager *lm; + const gchar * const *ids; + gint i; + GSList *languages = NULL; + + lm = gtk_source_language_manager_get_default (); + ids = gtk_source_language_manager_get_language_ids (lm); + + for (i = 0; ids[i] != NULL; i++) + { + GtkSourceLanguage *lang; + + lang = gtk_source_language_manager_get_language (lm, ids[i]); + languages = g_slist_prepend (languages, lang); + } + + return g_slist_sort (languages, (GCompareFunc)language_compare); +} + static void create_languages_menu (XedWindow *window) { @@ -795,9 +874,9 @@ create_languages_menu (XedWindow *window) gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action_none), TRUE); /* now add all the known languages */ - languages = xed_language_manager_list_languages_sorted (xed_get_language_manager (), FALSE); + languages = get_languages_sorted_by_section (window); - for (l = languages, i = 0; l != NULL; l = l->next, ++i) + for (l = languages, i = 0; l != NULL; l = l->next) { create_language_menu_item (l->data, i, id, window); } @@ -852,12 +931,13 @@ update_languages_menu (XedWindow *window) } void -_xed_recent_add (XedWindow *window, - const gchar *uri, +_xed_recent_add (XedWindow *window, + GFile *location, const gchar *mime) { GtkRecentManager *recent_manager; GtkRecentData *recent_data; + gchar *uri; static gchar *groups[2] = { "xed", NULL }; @@ -873,8 +953,11 @@ _xed_recent_add (XedWindow *window, recent_data->groups = groups; recent_data->is_private = FALSE; + uri = g_file_get_uri (location); + gtk_recent_manager_add_full (recent_manager, uri, recent_data); + g_free (uri); g_free (recent_data->app_exec); g_slice_free(GtkRecentData, recent_data); @@ -882,29 +965,36 @@ _xed_recent_add (XedWindow *window, void _xed_recent_remove (XedWindow *window, - const gchar *uri) + GFile *location) { GtkRecentManager *recent_manager; + gchar *uri; recent_manager = gtk_recent_manager_get_default (); + uri = g_file_get_uri (location); gtk_recent_manager_remove_item (recent_manager, uri, NULL); + g_free (uri); } static void -open_recent_file (const gchar *uri, +open_recent_file (GFile *location, XedWindow *window) { - GSList *uris = NULL; + GSList *locations = NULL; + GSList *loaded = NULL; - uris = g_slist_prepend (uris, (gpointer) uri); + locations = g_slist_prepend (locations, (gpointer) location); - if (xed_commands_load_uris (window, uris, NULL, 0) != 1) + loaded = xed_commands_load_locations (window, locations, NULL, 0); + + if (!loaded || loaded->next) /* if it doesn't contain just 1 element */ { - _xed_recent_remove (window, uri); + _xed_recent_remove (window, location); } - g_slist_free (uris); + g_slist_free (locations); + g_slist_free (loaded); } static void @@ -912,14 +1002,20 @@ recents_menu_activate (GtkAction *action, XedWindow *window) { GtkRecentInfo *info; + GFile *location; const gchar *uri; - info = g_object_get_data (G_OBJECT(action), "gtk-recent-info"); - g_return_if_fail(info != NULL); + info = g_object_get_data (G_OBJECT (action), "gtk-recent-info"); + g_return_if_fail (info != NULL); uri = gtk_recent_info_get_uri (info); + location = g_file_new_for_uri (uri); - open_recent_file (uri, window); + if (location) + { + open_recent_file (location, window); + g_object_unref (location); + } } static gint @@ -952,11 +1048,11 @@ update_recent_files_menu (XedWindow *window) gint max_recents; GList *actions, *l, *items; GList *filtered_items = NULL; - gint i; + guint i; xed_debug (DEBUG_WINDOW); - max_recents = xed_prefs_manager_get_max_recents (); + max_recents = g_settings_get_uint (window->priv->ui_settings, XED_SETTINGS_MAX_RECENTS); g_return_if_fail(p->recents_action_group != NULL); @@ -1005,6 +1101,7 @@ update_recent_files_menu (XedWindow *window) gchar *tip; GtkAction *action; GtkRecentInfo *info = l->data; + GFile *location; /* clamp */ if (i >= max_recents) @@ -1028,7 +1125,9 @@ update_recent_files_menu (XedWindow *window) /* gtk_recent_info_get_uri_display (info) is buggy and * works only for local files */ - uri = xed_utils_uri_for_display (gtk_recent_info_get_uri (info)); + location = g_file_new_for_uri (gtk_recent_info_get_uri (info)); + uri = g_file_get_parse_name (location); + g_object_unref (location); ruri = xed_utils_replace_home_dir_with_tilde (uri); g_free (uri); @@ -1069,10 +1168,7 @@ toolbar_visibility_changed (GtkWidget *toolbar, visible = gtk_widget_get_visible (toolbar); - if (xed_prefs_manager_toolbar_visible_can_set ()) - { - xed_prefs_manager_set_toolbar_visible (visible); - } + g_settings_set_boolean (window->priv->ui_settings, XED_SETTINGS_TOOLBAR_VISIBLE, visible); action = gtk_action_group_get_action (window->priv->always_sensitive_action_group, "ViewToolbar"); @@ -1166,15 +1262,12 @@ create_menu_bar_and_toolbar (XedWindow *window, g_object_unref (action_group); window->priv->panes_action_group = action_group; - /* now load the UI definition */ - ui_file = xed_dirs_get_ui_file (XED_UIFILE); - gtk_ui_manager_add_ui_from_file (manager, ui_file, &error); + gtk_ui_manager_add_ui_from_resource (manager, "/org/x/editor/ui/xed-ui.xml", &error); if (error != NULL) { - g_warning("Could not merge %s: %s", ui_file, error->message); + g_warning ("Could not add ui definition: %s", error->message); g_error_free (error); } - g_free (ui_file); /* show tooltips in the statusbar */ g_signal_connect(manager, "connect_proxy", G_CALLBACK (connect_proxy_cb), window); @@ -1422,9 +1515,10 @@ set_statusbar_style (XedWindow *window, { GtkAction *action; gboolean visible; + if (origin == NULL) { - visible = xed_prefs_manager_get_statusbar_visible (); + visible = g_settings_get_boolean (window->priv->ui_settings, XED_SETTINGS_STATUSBAR_VISIBLE); } else { @@ -1459,10 +1553,7 @@ statusbar_visibility_changed (GtkWidget *statusbar, visible = gtk_widget_get_visible (statusbar); - if (xed_prefs_manager_statusbar_visible_can_set ()) - { - xed_prefs_manager_set_statusbar_visible (visible); - } + g_settings_set_boolean (window->priv->ui_settings, XED_SETTINGS_STATUSBAR_VISIBLE, visible); action = gtk_action_group_get_action (window->priv->always_sensitive_action_group, "ViewStatusbar"); @@ -1579,56 +1670,66 @@ fill_tab_width_combo (XedWindow *window) static void fill_language_combo (XedWindow *window) { - GtkSourceLanguageManager *manager; - GSList *languages; - GSList *item; - GtkWidget *menu_item; + GtkSourceLanguageManager *lm; + const gchar * const *ids; const gchar *name; - - manager = xed_get_language_manager (); - languages = xed_language_manager_list_languages_sorted (manager, FALSE); + GtkWidget *menu_item; + gint i; name = _("Plain Text"); menu_item = gtk_menu_item_new_with_label (name); gtk_widget_show (menu_item); g_object_set_data (G_OBJECT(menu_item), LANGUAGE_DATA, NULL); - xed_status_combo_box_add_item (XED_STATUS_COMBO_BOX(window->priv->language_combo), GTK_MENU_ITEM(menu_item), name); + xed_status_combo_box_add_item (XED_STATUS_COMBO_BOX (window->priv->language_combo), GTK_MENU_ITEM (menu_item), name); - for (item = languages; item; item = item->next) + lm = gtk_source_language_manager_get_default (); + ids = gtk_source_language_manager_get_language_ids (lm); + + for (i = 0; ids[i] != NULL; i++) { - GtkSourceLanguage *lang = GTK_SOURCE_LANGUAGE(item->data); + GtkSourceLanguage *lang; + + lang = gtk_source_language_manager_get_language (lm, ids[i]); name = gtk_source_language_get_name (lang); menu_item = gtk_menu_item_new_with_label (name); gtk_widget_show (menu_item); - g_object_set_data_full (G_OBJECT(menu_item), LANGUAGE_DATA, g_object_ref (lang), - (GDestroyNotify) g_object_unref); - xed_status_combo_box_add_item (XED_STATUS_COMBO_BOX(window->priv->language_combo), - GTK_MENU_ITEM(menu_item), name); - } - g_slist_free (languages); + g_object_set_data_full (G_OBJECT (menu_item), LANGUAGE_DATA, g_object_ref (lang), + (GDestroyNotify) g_object_unref); + xed_status_combo_box_add_item (XED_STATUS_COMBO_BOX (window->priv->language_combo), + GTK_MENU_ITEM (menu_item), name); + } } static void create_statusbar (XedWindow *window, GtkWidget *main_box) { + GtkWidget *image; + GtkWidget *button_box; + GtkAction *action; + xed_debug (DEBUG_WINDOW); window->priv->statusbar = xed_statusbar_new (); - window->priv->searchbar = xed_searchbar_new (window, TRUE); + window->priv->searchbar = xed_searchbar_new (GTK_WINDOW (window)); - window->priv->generic_message_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR(window->priv->statusbar), + window->priv->generic_message_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->priv->statusbar), "generic_message"); - window->priv->tip_message_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR(window->priv->statusbar), + window->priv->tip_message_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->priv->statusbar), "tip_message"); - gtk_box_pack_end (GTK_BOX(main_box), window->priv->statusbar, FALSE, TRUE, 0); + gtk_box_pack_end (GTK_BOX( main_box), window->priv->statusbar, FALSE, TRUE, 0); + + gtk_widget_set_margin_start (GTK_WIDGET (window->priv->statusbar), 0); + gtk_widget_set_margin_end (GTK_WIDGET (window->priv->statusbar), 0); window->priv->tab_width_combo = xed_status_combo_box_new (_("Tab Width")); gtk_widget_show (window->priv->tab_width_combo); - gtk_box_pack_end (GTK_BOX(window->priv->statusbar), window->priv->tab_width_combo, FALSE, TRUE, 0); + gtk_box_pack_end (GTK_BOX (window->priv->statusbar), window->priv->tab_width_combo, FALSE, FALSE, 0); + gtk_widget_set_margin_bottom (GTK_WIDGET (window->priv->tab_width_combo), 2); + gtk_widget_set_margin_top (GTK_WIDGET (window->priv->tab_width_combo), 2); fill_tab_width_combo (window); @@ -1637,13 +1738,48 @@ create_statusbar (XedWindow *window, window->priv->language_combo = xed_status_combo_box_new (NULL); gtk_widget_show (window->priv->language_combo); - gtk_box_pack_end (GTK_BOX(window->priv->statusbar), window->priv->language_combo, FALSE, TRUE, 0); + gtk_widget_set_margin_bottom (GTK_WIDGET (window->priv->language_combo), 2); + gtk_widget_set_margin_top (GTK_WIDGET (window->priv->language_combo), 2); + gtk_box_pack_end (GTK_BOX(window->priv->statusbar), window->priv->language_combo, FALSE, FALSE, 0); fill_language_combo (window); g_signal_connect(G_OBJECT (window->priv->language_combo), "changed", G_CALLBACK (language_combo_changed), window); + button_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_widget_set_margin_top (button_box, 4); + gtk_widget_set_margin_bottom (button_box, 4); + gtk_widget_set_margin_start (button_box, 6); + gtk_box_pack_start (GTK_BOX (window->priv->statusbar), button_box, FALSE, FALSE, 0); + + window->priv->show_side_pane_button = gtk_toggle_button_new (); + image = gtk_image_new_from_icon_name ("view-left-pane-symbolic", GTK_ICON_SIZE_INVALID); + gtk_image_set_pixel_size (GTK_IMAGE (image), 12); + gtk_container_add (GTK_CONTAINER (window->priv->show_side_pane_button), image); + gtk_box_pack_start (GTK_BOX (button_box), window->priv->show_side_pane_button, FALSE, FALSE, 0); + + action = gtk_action_group_get_action (window->priv->panes_action_group, "ViewSidePane"); + gtk_activatable_set_related_action (GTK_ACTIVATABLE (window->priv->show_side_pane_button), action); + gtk_widget_set_tooltip_text (window->priv->show_side_pane_button, gtk_action_get_tooltip (action)); + + window->priv->bottom_pane_button_revealer = gtk_revealer_new (); + gtk_revealer_set_transition_type (GTK_REVEALER (window->priv->bottom_pane_button_revealer), + GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT); + gtk_box_pack_start (GTK_BOX (button_box), window->priv->bottom_pane_button_revealer, FALSE, FALSE, 0); + + window->priv->show_bottom_pane_button = gtk_toggle_button_new (); + image = gtk_image_new_from_icon_name ("view-bottom-pane-symbolic", GTK_ICON_SIZE_INVALID); + gtk_image_set_pixel_size (GTK_IMAGE (image), 12); + gtk_container_add (GTK_CONTAINER (window->priv->show_bottom_pane_button), image); + gtk_container_add (GTK_CONTAINER (window->priv->bottom_pane_button_revealer), window->priv->show_bottom_pane_button); + + action = gtk_action_group_get_action (window->priv->panes_action_group, "ViewBottomPane"); + gtk_activatable_set_related_action (GTK_ACTIVATABLE (window->priv->show_bottom_pane_button), action); + gtk_widget_set_tooltip_text (window->priv->show_bottom_pane_button, gtk_action_get_tooltip (action)); + + gtk_widget_show_all (button_box); + g_signal_connect_after(G_OBJECT (window->priv->statusbar), "show", G_CALLBACK (statusbar_visibility_changed), window); @@ -1652,8 +1788,9 @@ create_statusbar (XedWindow *window, set_statusbar_style (window, NULL); - gtk_box_pack_end (GTK_BOX(main_box), window->priv->searchbar, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (main_box), window->priv->searchbar, FALSE, FALSE, 0); + gtk_box_reorder_child (GTK_BOX (window->priv->statusbar), button_box, 0); } static XedWindow * @@ -1666,22 +1803,20 @@ clone_window (XedWindow *origin) xed_debug (DEBUG_WINDOW); - app = xed_app_get_default (); + app = XED_APP (g_application_get_default ()); - screen = gtk_window_get_screen (GTK_WINDOW(origin)); + screen = gtk_window_get_screen (GTK_WINDOW (origin)); window = xed_app_create_window (app, screen); + gtk_window_set_default_size (GTK_WINDOW (window), origin->priv->width, origin->priv->height); + if ((origin->priv->window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0) { - gint w, h; - xed_prefs_manager_get_default_window_size (&w, &h); - gtk_window_set_default_size (GTK_WINDOW(window), w, h); - gtk_window_maximize (GTK_WINDOW(window)); + gtk_window_maximize (GTK_WINDOW (window)); } else { - gtk_window_set_default_size (GTK_WINDOW(window), origin->priv->width, origin->priv->height); - gtk_window_unmaximize (GTK_WINDOW(window)); + gtk_window_unmaximize (GTK_WINDOW (window)); } if ((origin->priv->window_state & GDK_WINDOW_STATE_STICKY) != 0) @@ -1778,7 +1913,7 @@ static void update_overwrite_mode_statusbar (GtkTextView *view, XedWindow *window) { - if (view != GTK_TEXT_VIEW(xed_window_get_active_view (window))) + if (view != GTK_TEXT_VIEW (xed_window_get_active_view (window))) { return; } @@ -1803,7 +1938,7 @@ set_title (XedWindow *window) if (window->priv->active_tab == NULL) { - gtk_window_set_title (GTK_WINDOW(window), "Xed"); + xed_app_set_window_title (XED_APP (g_application_get_default ()), window, "Xed"); return; } @@ -1826,13 +1961,12 @@ set_title (XedWindow *window) } else { - GFile *file; - file = xed_document_get_location (doc); - if (file != NULL) + GtkSourceFile *file = xed_document_get_file (doc); + GFile *location = gtk_source_file_get_location (file); + + if (location != NULL) { - gchar *str; - str = xed_utils_location_get_dirname_for_display (file); - g_object_unref (file); + gchar *str = xed_utils_location_get_dirname_for_display (location); /* use the remaining space for the dir, but use a min of 20 chars * so that we do not end up with a dirname like "(a...b)". @@ -1876,7 +2010,7 @@ set_title (XedWindow *window) } } - gtk_window_set_title (GTK_WINDOW(window), title); + xed_app_set_window_title (XED_APP (g_application_get_default ()), window, title); g_free (dirname); g_free (name); @@ -2000,6 +2134,34 @@ language_changed (GObject *object, g_list_free (items); } +static void +word_wrap_changed (GObject *object, + GParamSpec *pspec, + XedWindow *window) +{ + XedView *view; + GtkWrapMode wrap_mode; + GtkAction *action; + gboolean wrap_enabled; + + view = XED_VIEW (object); + wrap_mode = gtk_text_view_get_wrap_mode (GTK_TEXT_VIEW (view)); + action = gtk_action_group_get_action (window->priv->always_sensitive_action_group, "ViewWordWrap"); + + if (wrap_mode == GTK_WRAP_NONE) + { + wrap_enabled = FALSE; + } + else + { + wrap_enabled = TRUE; + } + + g_signal_handlers_block_by_func (action, G_CALLBACK (_xed_cmd_view_toggle_word_wrap), window); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), wrap_enabled); + g_signal_handlers_unblock_by_func (action, G_CALLBACK (_xed_cmd_view_toggle_word_wrap), window); +} + static void notebook_switch_page (GtkNotebook *book, GtkWidget *pg, @@ -2030,10 +2192,15 @@ notebook_switch_page (GtkNotebook *book, if (window->priv->spaces_instead_of_tabs_id) { - g_signal_handler_disconnect (xed_tab_get_view (window->priv->active_tab), - window->priv->spaces_instead_of_tabs_id); + g_signal_handler_disconnect (xed_tab_get_view (window->priv->active_tab), window->priv->spaces_instead_of_tabs_id); window->priv->spaces_instead_of_tabs_id = 0; } + + if (window->priv->use_word_wrap_id) + { + g_signal_handler_disconnect (xed_tab_get_view (window->priv->active_tab), window->priv->use_word_wrap_id); + window->priv->use_word_wrap_id = 0; + } } /* set the active tab */ @@ -2052,7 +2219,7 @@ notebook_switch_page (GtkNotebook *book, */ if (action != NULL) { - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action), TRUE); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); } g_free (action_name); @@ -2063,8 +2230,8 @@ notebook_switch_page (GtkNotebook *book, view = xed_tab_get_view (tab); /* sync the statusbar */ - update_cursor_position_statusbar (GTK_TEXT_BUFFER(xed_tab_get_document (tab)), window); - xed_statusbar_set_overwrite (XED_STATUSBAR(window->priv->statusbar), + update_cursor_position_statusbar (GTK_TEXT_BUFFER (xed_tab_get_document (tab)), window); + xed_statusbar_set_overwrite (XED_STATUSBAR (window->priv->statusbar), gtk_text_view_get_overwrite (GTK_TEXT_VIEW(view))); gtk_widget_show (window->priv->tab_width_combo); @@ -2078,12 +2245,16 @@ notebook_switch_page (GtkNotebook *book, window->priv->language_changed_id = g_signal_connect(xed_tab_get_document (tab), "notify::language", G_CALLBACK (language_changed), window); - /* call it for the first time */ - tab_width_changed (G_OBJECT(view), NULL, window); - spaces_instead_of_tabs_changed (G_OBJECT(view), NULL, window); - language_changed (G_OBJECT(xed_tab_get_document (tab)), NULL, window); + window->priv->use_word_wrap_id = g_signal_connect (view, "notify::wrap-mode", + G_CALLBACK (word_wrap_changed), window); - g_signal_emit (G_OBJECT(window), signals[ACTIVE_TAB_CHANGED], 0, window->priv->active_tab); + /* call it for the first time */ + tab_width_changed (G_OBJECT (view), NULL, window); + spaces_instead_of_tabs_changed (G_OBJECT (view), NULL, window); + language_changed (G_OBJECT (xed_tab_get_document (tab)), NULL, window); + word_wrap_changed (G_OBJECT (view), NULL, window); + + g_signal_emit (G_OBJECT (window), signals[ACTIVE_TAB_CHANGED], 0, window->priv->active_tab); } static void @@ -2289,7 +2460,7 @@ sync_name (XedTab *tab, g_free (escaped_name); g_free (tip); - xed_plugins_engine_update_plugins_ui (xed_plugins_engine_get_default (), window); + peas_extension_set_call (window->priv->extensions, "update_state"); } static XedWindow * @@ -2309,10 +2480,11 @@ get_drop_window (GtkWidget *widget) static void load_uris_from_drop (XedWindow *window, - gchar **uri_list) + gchar **uri_list) { - GSList *uris = NULL; + GSList *locations = NULL; gint i; + GSList *loaded; if (uri_list == NULL) { @@ -2321,13 +2493,16 @@ load_uris_from_drop (XedWindow *window, for (i = 0; uri_list[i] != NULL; ++i) { - uris = g_slist_prepend (uris, uri_list[i]); + locations = g_slist_prepend (locations, g_file_new_for_uri (uri_list[i])); } - uris = g_slist_reverse (uris); - xed_commands_load_uris (window, uris, NULL, 0); + locations = g_slist_reverse (locations); + loaded = xed_commands_load_locations (window, locations, NULL, 0); - g_slist_free (uris); + g_slist_free (loaded); + + g_slist_foreach (locations, (GFunc) g_object_unref, NULL); + g_slist_free (locations); } /* Handle drops on the XedWindow */ @@ -2530,7 +2705,7 @@ fullscreen_controls_build (XedWindow *window) priv->fullscreen_controls = gtk_window_new (GTK_WINDOW_POPUP); - gtk_window_set_transient_for (GTK_WINDOW(priv->fullscreen_controls), &window->window); + gtk_window_set_transient_for (GTK_WINDOW (priv->fullscreen_controls), GTK_WINDOW (&window->window)); window->priv->fullscreen_controls_container = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_set_border_width (GTK_CONTAINER (window->priv->fullscreen_controls_container), 6); @@ -2604,9 +2779,9 @@ fullscreen_controls_build (XedWindow *window) } static void -can_search_again (XedDocument *doc, - GParamSpec *pspec, - XedWindow *window) +search_text_notify_cb (XedDocument *doc, + GParamSpec *pspec, + XedWindow *window) { gboolean sensitive; GtkAction *action; @@ -2616,7 +2791,7 @@ can_search_again (XedDocument *doc, return; } - sensitive = xed_document_get_can_search_again (doc); + sensitive = TRUE; action = gtk_action_group_get_action (window->priv->action_group, "SearchFindNext"); gtk_action_set_sensitive (action, sensitive); @@ -2702,7 +2877,7 @@ selection_changed (XedDocument *doc, gtk_action_set_sensitive (action, state_normal && editable && gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER(doc))); - xed_plugins_engine_update_plugins_ui (xed_plugins_engine_get_default (), window); + peas_extension_set_call (window->priv->extensions, "update_state"); } static void @@ -2711,7 +2886,7 @@ sync_languages_menu (XedDocument *doc, XedWindow *window) { update_languages_menu (window); - xed_plugins_engine_update_plugins_ui (xed_plugins_engine_get_default (), window); + peas_extension_set_call (window->priv->extensions, "update_state"); } static void @@ -2721,7 +2896,7 @@ readonly_changed (XedDocument *doc, { set_sensitivity_according_to_tab (window, window->priv->active_tab); sync_name (window->priv->active_tab, NULL, window); - xed_plugins_engine_update_plugins_ui (xed_plugins_engine_get_default (), window); + peas_extension_set_call (window->priv->extensions, "update_state"); } static void @@ -2729,7 +2904,7 @@ editable_changed (XedView *view, GParamSpec *arg1, XedWindow *window) { - xed_plugins_engine_update_plugins_ui (xed_plugins_engine_get_default (), window); + peas_extension_set_call (window->priv->extensions, "update_state"); } static void @@ -2771,7 +2946,7 @@ notebook_tab_added (XedNotebook *notebook, g_signal_connect(tab, "notify::state", G_CALLBACK (sync_state), window); g_signal_connect(doc, "cursor-moved", G_CALLBACK (update_cursor_position_statusbar), window); - g_signal_connect(doc, "notify::can-search-again", G_CALLBACK (can_search_again), window); + g_signal_connect(doc, "notify::search-text", G_CALLBACK (search_text_notify_cb), window); g_signal_connect(doc, "notify::can-undo", G_CALLBACK (can_undo), window); g_signal_connect(doc, "notify::can-redo", G_CALLBACK (can_redo), window); g_signal_connect(doc, "notify::has-selection", G_CALLBACK (selection_changed), window); @@ -2809,7 +2984,7 @@ notebook_tab_removed (XedNotebook *notebook, g_signal_handlers_disconnect_by_func(tab, G_CALLBACK (sync_name), window); g_signal_handlers_disconnect_by_func(tab, G_CALLBACK (sync_state), window); g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (update_cursor_position_statusbar), window); - g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (can_search_again), window); + g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (search_text_notify_cb), window); g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (can_undo), window); g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (can_redo), window); g_signal_handlers_disconnect_by_func(doc, G_CALLBACK (selection_changed), window); @@ -2837,6 +3012,12 @@ notebook_tab_removed (XedNotebook *notebook, window->priv->language_changed_id = 0; } + if (window->priv->use_word_wrap_id && tab == xed_window_get_active_tab (window)) + { + g_signal_handler_disconnect (view, window->priv->use_word_wrap_id); + window->priv->use_word_wrap_id = 0; + } + g_return_if_fail(window->priv->num_tabs >= 0); if (window->priv->num_tabs == 0) { @@ -2871,7 +3052,7 @@ notebook_tab_removed (XedNotebook *notebook, if (window->priv->num_tabs == 0) { - xed_plugins_engine_update_plugins_ui (xed_plugins_engine_get_default (), window); + peas_extension_set_call (window->priv->extensions, "update_state"); } update_window_state (window); @@ -3051,10 +3232,7 @@ side_panel_visibility_changed (GtkWidget *side_panel, visible = gtk_widget_get_visible (side_panel); - if (xed_prefs_manager_side_pane_visible_can_set ()) - { - xed_prefs_manager_set_side_pane_visible (visible); - } + g_settings_set_boolean (window->priv->ui_settings, XED_SETTINGS_SIDE_PANEL_VISIBLE, visible); action = gtk_action_group_get_action (window->priv->panes_action_group, "ViewSidePane"); @@ -3078,16 +3256,13 @@ create_side_panel (XedWindow *window) window->priv->side_panel = xed_panel_new (GTK_ORIENTATION_VERTICAL); - gtk_paned_pack1 (GTK_PANED(window->priv->hpaned), window->priv->side_panel, - FALSE, - FALSE); + gtk_paned_pack1 (GTK_PANED (window->priv->hpaned), window->priv->side_panel, FALSE, FALSE); - g_signal_connect_after(window->priv->side_panel, "show", G_CALLBACK (side_panel_visibility_changed), window); - g_signal_connect_after(window->priv->side_panel, "hide", G_CALLBACK (side_panel_visibility_changed), window); + g_signal_connect_after (window->priv->side_panel, "show", G_CALLBACK (side_panel_visibility_changed), window); + g_signal_connect_after (window->priv->side_panel, "hide", G_CALLBACK (side_panel_visibility_changed), window); documents_panel = xed_documents_panel_new (window); - xed_panel_add_item_with_stock_icon (XED_PANEL(window->priv->side_panel), documents_panel, _("Documents"), - GTK_STOCK_FILE); + xed_panel_add_item (XED_PANEL (window->priv->side_panel), documents_panel, _("Documents"), "text-x-generic"); } static void @@ -3097,12 +3272,9 @@ bottom_panel_visibility_changed (XedPanel *bottom_panel, gboolean visible; GtkAction *action; - visible = gtk_widget_get_visible (GTK_WIDGET(bottom_panel)); + visible = gtk_widget_get_visible (GTK_WIDGET (bottom_panel)); - if (xed_prefs_manager_bottom_panel_visible_can_set ()) - { - xed_prefs_manager_set_bottom_panel_visible (visible); - } + g_settings_set_boolean (window->priv->ui_settings, XED_SETTINGS_BOTTOM_PANEL_VISIBLE, visible); action = gtk_action_group_get_action (window->priv->panes_action_group, "ViewBottomPane"); @@ -3119,21 +3291,23 @@ bottom_panel_visibility_changed (XedPanel *bottom_panel, } static void -bottom_panel_item_removed (XedPanel *panel, +bottom_panel_item_removed (XedPanel *panel, GtkWidget *item, XedWindow *window) { if (xed_panel_get_n_items (panel) == 0) { GtkAction *action; - gtk_widget_hide (GTK_WIDGET(panel)); + + gtk_widget_hide (GTK_WIDGET (panel)); + gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->bottom_pane_button_revealer), FALSE); action = gtk_action_group_get_action (window->priv->panes_action_group, "ViewBottomPane"); gtk_action_set_sensitive (action, FALSE); } } static void -bottom_panel_item_added (XedPanel *panel, +bottom_panel_item_added (XedPanel *panel, GtkWidget *item, XedWindow *window) { @@ -3143,9 +3317,12 @@ bottom_panel_item_added (XedPanel *panel, { GtkAction *action; gboolean show; + + gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->bottom_pane_button_revealer), TRUE); + action = gtk_action_group_get_action (window->priv->panes_action_group, "ViewBottomPane"); gtk_action_set_sensitive (action, TRUE); - show = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action)); + show = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); if (show) { gtk_widget_show (GTK_WIDGET(panel)); @@ -3158,9 +3335,7 @@ create_bottom_panel (XedWindow *window) { xed_debug (DEBUG_WINDOW); window->priv->bottom_panel = xed_panel_new (GTK_ORIENTATION_HORIZONTAL); - gtk_paned_pack2 (GTK_PANED(window->priv->vpaned), window->priv->bottom_panel, - FALSE, - FALSE); + gtk_paned_pack2 (GTK_PANED (window->priv->vpaned), window->priv->bottom_panel, FALSE, FALSE); g_signal_connect_after(window->priv->bottom_panel, "show", G_CALLBACK (bottom_panel_visibility_changed), window); g_signal_connect_after(window->priv->bottom_panel, "hide", G_CALLBACK (bottom_panel_visibility_changed), window); } @@ -3169,38 +3344,49 @@ static void init_panels_visibility (XedWindow *window) { gint active_page; + gboolean side_panel_visible; + gboolean bottom_panel_visible; + xed_debug (DEBUG_WINDOW); /* side pane */ - active_page = xed_prefs_manager_get_side_panel_active_page (); - _xed_panel_set_active_item_by_id (XED_PANEL(window->priv->side_panel), active_page); + active_page = g_settings_get_int (window->priv->window_settings, XED_SETTINGS_SIDE_PANEL_ACTIVE_PAGE); + _xed_panel_set_active_item_by_id (XED_PANEL (window->priv->side_panel), active_page); - if (xed_prefs_manager_get_side_pane_visible ()) + side_panel_visible = g_settings_get_boolean (window->priv->ui_settings, XED_SETTINGS_SIDE_PANEL_VISIBLE); + bottom_panel_visible = g_settings_get_boolean (window->priv->ui_settings, XED_SETTINGS_BOTTOM_PANEL_VISIBLE); + + if (side_panel_visible) { gtk_widget_show (window->priv->side_panel); } /* bottom pane, it can be empty */ - if (xed_panel_get_n_items (XED_PANEL(window->priv->bottom_panel)) > 0) + if (xed_panel_get_n_items (XED_PANEL (window->priv->bottom_panel)) > 0) { - active_page = xed_prefs_manager_get_bottom_panel_active_page (); + active_page = g_settings_get_int (window->priv->window_settings, XED_SETTINGS_BOTTOM_PANEL_ACTIVE_PAGE); _xed_panel_set_active_item_by_id (XED_PANEL(window->priv->bottom_panel), active_page); - if (xed_prefs_manager_get_bottom_panel_visible ()) + if (bottom_panel_visible) { gtk_widget_show (window->priv->bottom_panel); } + + gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->bottom_pane_button_revealer), TRUE); } else { GtkAction *action; + action = gtk_action_group_get_action (window->priv->panes_action_group, "ViewBottomPane"); gtk_action_set_sensitive (action, FALSE); + gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->bottom_pane_button_revealer), FALSE); } /* start track sensitivity after the initial state is set */ - window->priv->bottom_panel_item_removed_handler_id = g_signal_connect(window->priv->bottom_panel, "item_removed", - G_CALLBACK (bottom_panel_item_removed), window); + window->priv->bottom_panel_item_removed_handler_id = + g_signal_connect (window->priv->bottom_panel, "item_removed", + G_CALLBACK (bottom_panel_item_removed), window); g_signal_connect(window->priv->bottom_panel, "item_added", G_CALLBACK (bottom_panel_item_added), window); } @@ -3269,9 +3455,34 @@ add_notebook (XedWindow *window, { gtk_paned_pack1 (GTK_PANED(window->priv->vpaned), notebook, TRUE, TRUE); gtk_widget_show (notebook); + + // xed_notebook_set_tab_scrolling_enabled (XED_NOTEBOOK (notebook), xed_prefs_manager_get_enable_tab_scrolling ()); + connect_notebook_signals (window, notebook); } + static void +extension_added (PeasExtensionSet *extensions, + PeasPluginInfo *info, + PeasExtension *exten, + XedWindow *window) +{ + peas_extension_call (exten, "activate"); +} + +static void +extension_removed (PeasExtensionSet *extensions, + PeasPluginInfo *info, + PeasExtension *exten, + XedWindow *window) +{ + peas_extension_call (exten, "deactivate"); + + /* Ensure update of the ui manager, because we suspect it does something with expected static strings in the + * type module (when unloaded the strings don't exist anymore, and the ui manager update in a idle func) */ + gtk_ui_manager_ensure_update (window->priv->manager); +} + static void xed_window_init (XedWindow *window) { @@ -3280,7 +3491,7 @@ xed_window_init (XedWindow *window) xed_debug (DEBUG_WINDOW); - window->priv = XED_WINDOW_GET_PRIVATE(window); + window->priv = XED_WINDOW_GET_PRIVATE (window); window->priv->active_tab = NULL; window->priv->num_tabs = 0; window->priv->removing_tabs = FALSE; @@ -3288,14 +3499,23 @@ xed_window_init (XedWindow *window) window->priv->dispose_has_run = FALSE; window->priv->fullscreen_controls = NULL; window->priv->fullscreen_animation_timeout_id = 0; + window->priv->editor_settings = g_settings_new ("org.x.editor.preferences.editor"); + window->priv->ui_settings = g_settings_new ("org.x.editor.preferences.ui"); + + /* Window settings are applied only once the window is closed. We do not want + to keep writing to disk when the window is dragged around */ + window->priv->window_settings = g_settings_new ("org.x.editor.state.window"); + g_settings_delay (window->priv->window_settings); window->priv->message_bus = xed_message_bus_new (); window->priv->window_group = gtk_window_group_new (); - gtk_window_group_add_window (window->priv->window_group, GTK_WINDOW(window)); + gtk_window_group_add_window (window->priv->window_group, GTK_WINDOW (window)); + + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), "xed-window"); main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add (GTK_CONTAINER(window), main_box); + gtk_container_add (GTK_CONTAINER (window), main_box); gtk_widget_show (main_box); /* Add menu bar and toolbar bar */ @@ -3305,12 +3525,12 @@ xed_window_init (XedWindow *window) if (geteuid () == 0) { GtkWidget *root_bar = gtk_info_bar_new (); - gtk_info_bar_set_message_type (GTK_INFO_BAR(root_bar), GTK_MESSAGE_ERROR); - GtkWidget *content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR(root_bar)); + gtk_info_bar_set_message_type (GTK_INFO_BAR (root_bar), GTK_MESSAGE_ERROR); + GtkWidget *content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (root_bar)); GtkWidget *label = gtk_label_new (_("Elevated Privileges")); gtk_widget_show (label); - gtk_container_add (GTK_CONTAINER(content_area), label); - gtk_box_pack_start (GTK_BOX(main_box), root_bar, FALSE, FALSE, 0); + gtk_container_add (GTK_CONTAINER (content_area), label); + gtk_box_pack_start (GTK_BOX (main_box), root_bar, FALSE, FALSE, 0); gtk_widget_set_visible (root_bar, TRUE); } @@ -3319,12 +3539,11 @@ xed_window_init (XedWindow *window) /* Add the main area */ xed_debug_message (DEBUG_WINDOW, "Add main area"); - window->priv->hpaned = gtk_hpaned_new (); - gtk_box_pack_start (GTK_BOX(main_box), window->priv->hpaned, TRUE, TRUE, 0); + window->priv->hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); + gtk_box_pack_start (GTK_BOX (main_box), window->priv->hpaned, TRUE, TRUE, 0); - window->priv->vpaned = gtk_vpaned_new (); - gtk_paned_pack2 (GTK_PANED(window->priv->hpaned), window->priv->vpaned, TRUE, - FALSE); + window->priv->vpaned = gtk_paned_new (GTK_ORIENTATION_VERTICAL); + gtk_paned_pack2 (GTK_PANED (window->priv->hpaned), window->priv->vpaned, TRUE, FALSE); xed_debug_message (DEBUG_WINDOW, "Create xed notebook"); window->priv->notebook = xed_notebook_new (); @@ -3336,8 +3555,8 @@ xed_window_init (XedWindow *window) /* panes' state must be restored after panels have been mapped, * since the bottom pane position depends on the size of the vpaned. */ - window->priv->side_panel_size = xed_prefs_manager_get_side_panel_size (); - window->priv->bottom_panel_size = xed_prefs_manager_get_bottom_panel_size (); + window->priv->side_panel_size = g_settings_get_int (window->priv->window_settings, XED_SETTINGS_SIDE_PANEL_SIZE); + window->priv->bottom_panel_size = g_settings_get_int (window->priv->window_settings, XED_SETTINGS_BOTTOM_PANEL_SIZE); g_signal_connect_after(window->priv->hpaned, "map", G_CALLBACK (hpaned_restore_position), window); g_signal_connect_after(window->priv->vpaned, "map", G_CALLBACK (vpaned_restore_position), window); @@ -3351,34 +3570,38 @@ xed_window_init (XedWindow *window) NULL, 0, GDK_ACTION_COPY); /* Add uri targets */ - tl = gtk_drag_dest_get_target_list (GTK_WIDGET(window)); + tl = gtk_drag_dest_get_target_list (GTK_WIDGET (window)); if (tl == NULL) { tl = gtk_target_list_new (NULL, 0); - gtk_drag_dest_set_target_list (GTK_WIDGET(window), tl); + gtk_drag_dest_set_target_list (GTK_WIDGET (window), tl); gtk_target_list_unref (tl); } gtk_target_list_add_uri_targets (tl, TARGET_URI_LIST); - /* connect instead of override, so that we can - * share the cb code with the view */ - g_signal_connect(window, "drag_data_received", G_CALLBACK (drag_data_received_cb), NULL); + /* connect instead of override, so that we can share the cb code with the view */ + g_signal_connect (window, "drag_data_received", G_CALLBACK (drag_data_received_cb), NULL); - /* we can get the clipboard only after the widget - * is realized */ - g_signal_connect(window, "realize", G_CALLBACK (window_realized), NULL); - g_signal_connect(window, "unrealize", G_CALLBACK (window_unrealized), NULL); + /* we can get the clipboard only after the widget is realized */ + g_signal_connect (window, "realize", G_CALLBACK (window_realized), NULL); + g_signal_connect (window, "unrealize", G_CALLBACK (window_unrealized), NULL); /* Check if the window is active for fullscreen */ - g_signal_connect(window, "notify::is-active", G_CALLBACK (check_window_is_active), NULL); + g_signal_connect (window, "notify::is-active", G_CALLBACK (check_window_is_active), NULL); - g_signal_connect(GTK_WIDGET (window), "key-press-event", G_CALLBACK (on_key_pressed), window); + g_signal_connect (GTK_WIDGET (window), "key-press-event", G_CALLBACK (on_key_pressed), window); xed_debug_message (DEBUG_WINDOW, "Update plugins ui"); - xed_plugins_engine_activate_plugins (xed_plugins_engine_get_default (), window); + window->priv->extensions = peas_extension_set_new (PEAS_ENGINE (xed_plugins_engine_get_default ()), + XED_TYPE_WINDOW_ACTIVATABLE, "window", window, NULL); + + g_signal_connect (window->priv->extensions, "extension-added", G_CALLBACK (extension_added), window); + g_signal_connect (window->priv->extensions, "extension-removed", G_CALLBACK (extension_removed), window); + + peas_extension_set_call (window->priv->extensions, "activate"); /* set visibility of panes. * This needs to be done after plugins activatation */ @@ -3395,7 +3618,7 @@ xed_window_init (XedWindow *window) * * Gets the active #XedView. * - * Returns: the active #XedView + * Returns: (transfer none): the active #XedView */ XedView * xed_window_get_active_view (XedWindow *window) @@ -3412,7 +3635,7 @@ xed_window_get_active_view (XedWindow *window) return NULL; } - view = xed_tab_get_view (XED_TAB(window->priv->active_tab)); + view = xed_tab_get_view (XED_TAB (window->priv->active_tab)); return view; } @@ -3423,7 +3646,7 @@ xed_window_get_active_view (XedWindow *window) * * Gets the active #XedDocument. * - * Returns: the active #XedDocument + * Returns: (transfer none): the active #XedDocument */ XedDocument * xed_window_get_active_document (XedWindow *window) @@ -3441,7 +3664,7 @@ xed_window_get_active_document (XedWindow *window) return NULL; } - return XED_DOCUMENT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + return XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); } GtkWidget * @@ -3460,7 +3683,7 @@ _xed_window_get_notebook (XedWindow *window) * Creates a new #XedTab and adds the new tab to the #XedNotebook. * In case @jump_to is %TRUE the #XedNotebook switches to that new #XedTab. * - * Returns: a new #XedTab + * Returns: (transfer none): a new #XedTab */ XedTab * xed_window_create_tab (XedWindow *window, @@ -3471,23 +3694,45 @@ xed_window_create_tab (XedWindow *window, g_return_val_if_fail(XED_IS_WINDOW (window), NULL); tab = XED_TAB(_xed_tab_new ()); - gtk_widget_show (GTK_WIDGET(tab)); + gtk_widget_show (GTK_WIDGET (tab)); - xed_notebook_add_tab (XED_NOTEBOOK(window->priv->notebook), tab, -1, jump_to); + xed_notebook_add_tab (XED_NOTEBOOK (window->priv->notebook), tab, -1, jump_to); - if (!gtk_widget_get_visible (GTK_WIDGET(window))) + if (!gtk_widget_get_visible (GTK_WIDGET (window))) { - gtk_window_present (GTK_WINDOW(window)); + gtk_window_present (GTK_WINDOW (window)); + } + + return tab; +} + +static XedTab * +process_create_tab (XedWindow *window, + XedTab *tab, + gboolean jump_to) +{ + if (tab == NULL) + { + return NULL; + } + + gtk_widget_show (GTK_WIDGET (tab)); + + xed_notebook_add_tab (XED_NOTEBOOK (window->priv->notebook), tab, -1, jump_to); + + if (!gtk_widget_get_visible (GTK_WIDGET (window))) + { + gtk_window_present (GTK_WINDOW (window)); } return tab; } /** - * xed_window_create_tab_from_uri: + * xed_window_create_tab_from_location: * @window: a #XedWindow - * @uri: the uri of the document - * @encoding: a #XedEncoding + * @location: the location of the document + * @encoding: (allow-none): a #GtkSourceEncoding * @line_pos: the line position to visualize * @create: %TRUE to create a new document in case @uri does exist * @jump_to: %TRUE to set the new #XedTab as active @@ -3497,37 +3742,41 @@ xed_window_create_tab (XedWindow *window, * Whether @create is %TRUE, creates a new empty document if location does * not refer to an existing file * - * Returns: a new #XedTab + * Returns: (transfer none): a new #XedTab */ XedTab * -xed_window_create_tab_from_uri (XedWindow *window, - const gchar *uri, - const XedEncoding *encoding, - gint line_pos, - gboolean create, - gboolean jump_to) +xed_window_create_tab_from_location (XedWindow *window, + GFile *location, + const GtkSourceEncoding *encoding, + gint line_pos, + gboolean create, + gboolean jump_to) { GtkWidget *tab; g_return_val_if_fail(XED_IS_WINDOW (window), NULL); - g_return_val_if_fail(uri != NULL, NULL); + g_return_val_if_fail(G_IS_FILE (location), NULL); - tab = _xed_tab_new_from_uri (uri, encoding, line_pos, create); - if (tab == NULL) - { - return NULL; - } + tab = _xed_tab_new_from_location (location, encoding, line_pos, create); - gtk_widget_show (tab); + return process_create_tab (window, XED_TAB (tab), jump_to); +} - xed_notebook_add_tab (XED_NOTEBOOK(window->priv->notebook), XED_TAB(tab), -1, jump_to); +XedTab * +xed_window_create_tab_from_stream (XedWindow *window, + GInputStream *stream, + const GtkSourceEncoding *encoding, + gint line_pos, + gboolean jump_to) +{ + GtkWidget *tab; - if (!gtk_widget_get_visible (GTK_WIDGET(window))) - { - gtk_window_present (GTK_WINDOW(window)); - } + g_return_val_if_fail (XED_IS_WINDOW (window), NULL); + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL); - return XED_TAB(tab); + tab = _xed_tab_new_from_stream (stream, encoding, line_pos); + + return process_create_tab (window, XED_TAB (tab), jump_to); } /** @@ -3536,7 +3785,7 @@ xed_window_create_tab_from_uri (XedWindow *window, * * Gets the active #XedTab in the @window. * - * Returns: the active #XedTab in the @window. + * Returns: (transfer none): the active #XedTab in the @window. */ XedTab * xed_window_get_active_tab (XedWindow *window) @@ -3623,12 +3872,12 @@ void xed_window_close_tab (XedWindow *window, XedTab *tab) { - g_return_if_fail(XED_IS_WINDOW (window)); - g_return_if_fail(XED_IS_TAB (tab)); - g_return_if_fail((xed_tab_get_state (tab) != XED_TAB_STATE_SAVING) + g_return_if_fail (XED_IS_WINDOW (window)); + g_return_if_fail (XED_IS_TAB (tab)); + g_return_if_fail ((xed_tab_get_state (tab) != XED_TAB_STATE_SAVING) && (xed_tab_get_state (tab) != XED_TAB_STATE_SHOWING_PRINT_PREVIEW)); - xed_notebook_remove_tab (XED_NOTEBOOK(window->priv->notebook), tab); + xed_notebook_remove_tab (XED_NOTEBOOK (window->priv->notebook), tab); } /** @@ -3691,13 +3940,13 @@ _xed_window_move_tab_to_new_window (XedWindow *window, { XedWindow *new_window; - g_return_val_if_fail(XED_IS_WINDOW (window), NULL); - g_return_val_if_fail(XED_IS_TAB (tab), NULL); - g_return_val_if_fail(gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook)) > 1, NULL); + g_return_val_if_fail (XED_IS_WINDOW (window), NULL); + g_return_val_if_fail (XED_IS_TAB (tab), NULL); + g_return_val_if_fail (gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook)) > 1, NULL); new_window = clone_window (window); - xed_notebook_move_tab (XED_NOTEBOOK(window->priv->notebook), XED_NOTEBOOK(new_window->priv->notebook), tab, -1); - gtk_widget_show (GTK_WIDGET(new_window)); + xed_notebook_move_tab (XED_NOTEBOOK (window->priv->notebook), XED_NOTEBOOK (new_window->priv->notebook), tab, -1); + gtk_widget_show (GTK_WIDGET (new_window)); return new_window; } @@ -3729,7 +3978,7 @@ xed_window_set_active_tab (XedWindow *window, * * Gets the #GtkWindowGroup in which @window resides. * - * Returns: the #GtkWindowGroup + * Returns: (transfer none): the #GtkWindowGroup */ GtkWindowGroup * xed_window_get_group (XedWindow *window) @@ -3751,7 +4000,7 @@ _xed_window_is_removing_tabs (XedWindow *window) * * Gets the #GtkUIManager associated with the @window. * - * Returns: the #GtkUIManager of the @window. + * Returns: (transfer none): the #GtkUIManager of the @window. */ GtkUIManager * xed_window_get_ui_manager (XedWindow *window) @@ -3766,7 +4015,7 @@ xed_window_get_ui_manager (XedWindow *window) * * Gets the side #XedPanel of the @window. * - * Returns: the side #XedPanel. + * Returns: (transfer none): the side #XedPanel. */ XedPanel * xed_window_get_side_panel (XedWindow *window) @@ -3781,7 +4030,7 @@ xed_window_get_side_panel (XedWindow *window) * * Gets the bottom #XedPanel of the @window. * - * Returns: the bottom #XedPanel. + * Returns: (transfer none): the bottom #XedPanel. */ XedPanel * xed_window_get_bottom_panel (XedWindow *window) @@ -3796,7 +4045,7 @@ xed_window_get_bottom_panel (XedWindow *window) * * Gets the #XedStatusbar of the @window. * - * Returns: the #XedStatusbar of the @window. + * Returns: (transfer none): the #XedStatusbar of the @window. */ GtkWidget * xed_window_get_statusbar (XedWindow *window) @@ -3809,9 +4058,9 @@ xed_window_get_statusbar (XedWindow *window) * xed_window_get_searchbar: * @window: a #XedWindow * - * Gets the #XedSearchDialog of the @window. + * Gets the #XedSearchbar of the @window. * - * Returns: the #XedSearchDialog of the @window. + * Returns: (transfer none): the #XedSearchbar of the @window. */ GtkWidget * xed_window_get_searchbar (XedWindow *window) @@ -3953,7 +4202,7 @@ _xed_window_fullscreen (XedWindow *window) } /* Go to fullscreen mode and hide bars */ - gtk_window_fullscreen (&window->window); + gtk_window_fullscreen (GTK_WINDOW (&window->window)); gtk_widget_hide (window->priv->menubar); @@ -3981,7 +4230,7 @@ _xed_window_unfullscreen (XedWindow *window) } /* Unfullscreen and show bars */ - gtk_window_unfullscreen (&window->window); + gtk_window_unfullscreen (GTK_WINDOW (&window->window)); g_signal_handlers_disconnect_by_func (window->priv->notebook, hide_notebook_tabs_on_fullscreen, window); gtk_widget_show (window->priv->menubar); @@ -4035,22 +4284,23 @@ xed_window_get_tab_from_location (XedWindow *window, for (l = tabs; l != NULL; l = g_list_next(l)) { - XedDocument *d; - XedTab *t; - GFile *f; + XedDocument *doc; + GtkSourceFile *file; + XedTab *tab; + GFile *cur_location; - t = XED_TAB(l->data); - d = xed_tab_get_document (t); + tab = XED_TAB (l->data); + doc = xed_tab_get_document (tab); + file = xed_document_get_file (doc); + cur_location = gtk_source_file_get_location (file); - f = xed_document_get_location (d); - - if ((f != NULL)) + if (cur_location != NULL) { - gboolean found = g_file_equal (location, f); - g_object_unref (f); + gboolean found = g_file_equal (location, cur_location); + if (found) { - ret = t; + ret = tab; break; } } @@ -4077,30 +4327,12 @@ xed_window_get_message_bus (XedWindow *window) return window->priv->message_bus; } -/** - * xed_window_get_tab_from_uri: - * @window: a #XedWindow - * @uri: the uri to get the #XedTab - * - * Gets the #XedTab that matches @uri. - * - * Returns: the #XedTab associated with @uri. - * - * Deprecated: 2.24: Use xed_window_get_tab_from_location() instead. - */ -XedTab * -xed_window_get_tab_from_uri (XedWindow *window, - const gchar *uri) +void +_xed_window_get_default_size (gint *width, + gint *height) { - GFile *f; - XedTab *tab; + g_return_if_fail (width != NULL && height != NULL); - g_return_val_if_fail(XED_IS_WINDOW (window), NULL); - g_return_val_if_fail(uri != NULL, NULL); - - f = g_file_new_for_uri (uri); - tab = xed_window_get_tab_from_location (window, f); - g_object_unref (f); - - return tab; + *width = XED_WINDOW_DEFAULT_WIDTH; + *height = XED_WINDOW_DEFAULT_HEIGHT; } diff --git a/xed/xed-window.h b/xed/xed-window.h index 5909d2f..ae7ad72 100644 --- a/xed/xed-window.h +++ b/xed/xed-window.h @@ -1,8 +1,7 @@ #ifndef __XED_WINDOW_H__ #define __XED_WINDOW_H__ -#include -#include +#include #include #include @@ -20,40 +19,28 @@ typedef enum XED_WINDOW_STATE_SAVING_SESSION = 1 << 5 } XedWindowState; -/* - * Type checking and casting macros - */ -#define XED_TYPE_WINDOW (xed_window_get_type()) -#define XED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_WINDOW, XedWindow)) -#define XED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_WINDOW, XedWindowClass)) -#define XED_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_WINDOW)) -#define XED_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_WINDOW)) -#define XED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_WINDOW, XedWindowClass)) +#define XED_TYPE_WINDOW (xed_window_get_type()) +#define XED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_WINDOW, XedWindow)) +#define XED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_WINDOW, XedWindowClass)) +#define XED_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_WINDOW)) +#define XED_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_WINDOW)) +#define XED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_WINDOW, XedWindowClass)) -/* Private structure type */ -typedef struct _XedWindowPrivate XedWindowPrivate; - -/* - * Main object structure - */ -typedef struct _XedWindow XedWindow; +typedef struct _XedWindow XedWindow; +typedef struct _XedWindowPrivate XedWindowPrivate; +typedef struct _XedWindowClass XedWindowClass; struct _XedWindow { - GtkWindow window; + GtkApplicationWindow window; /*< private > */ XedWindowPrivate *priv; }; -/* - * Class definition - */ -typedef struct _XedWindowClass XedWindowClass; - struct _XedWindowClass { - GtkWindowClass parent_class; + GtkApplicationWindowClass parent_class; /* Signals */ void (* tab_added) (XedWindow *window, XedTab *tab); @@ -63,13 +50,13 @@ struct _XedWindowClass void (* active_tab_state_changed) (XedWindow *window); }; -/* - * Public methods - */ +/* Public methods */ GType xed_window_get_type (void) G_GNUC_CONST; XedTab *xed_window_create_tab (XedWindow *window, gboolean jump_to); -XedTab *xed_window_create_tab_from_uri (XedWindow *window, const gchar *uri, const XedEncoding *encoding, - gint line_pos, gboolean create, gboolean jump_to); +XedTab *xed_window_create_tab_from_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding, + gint line_pos, gboolean create, gboolean jump_to); +XedTab *xed_window_create_tab_from_stream (XedWindow *window, GInputStream *stream, const GtkSourceEncoding *encoding, + gint line_pos, gboolean jump_to); void xed_window_close_tab (XedWindow *window, XedTab *tab); void xed_window_close_all_tabs (XedWindow *window); void xed_window_close_tabs (XedWindow *window, const GList *tabs); @@ -97,7 +84,6 @@ GtkWidget *xed_window_get_searchbar (XedWindow *window); GtkUIManager *xed_window_get_ui_manager (XedWindow *window); XedWindowState xed_window_get_state (XedWindow *window); XedTab *xed_window_get_tab_from_location (XedWindow *window, GFile *location); -XedTab *xed_window_get_tab_from_uri (XedWindow *window, const gchar *uri); /* Message bus */ XedMessageBus *xed_window_get_message_bus (XedWindow *window); @@ -116,8 +102,10 @@ void _xed_window_unfullscreen (XedWindow *window); gboolean _xed_window_is_fullscreen (XedWindow *window); /* these are in xed-window because of screen safety */ -void _xed_recent_add (XedWindow *window, const gchar *uri, const gchar *mime); -void _xed_recent_remove (XedWindow *window, const gchar *uri); +void _xed_recent_add (XedWindow *window, GFile *location, const gchar *mime); +void _xed_recent_remove (XedWindow *window, GFile *location); + +void _xed_window_get_default_size (gint *width, gint *height); G_END_DECLS diff --git a/xed/xed.c b/xed/xed.c index dc99eac..7dc2d6c 100644 --- a/xed/xed.c +++ b/xed/xed.c @@ -32,630 +32,40 @@ #include #endif -#include -#include -#include -#include - #include -#include -#include -#include +#include +#include -#include "xed-app.h" -#include "xed-commands.h" -#include "xed-debug.h" #include "xed-dirs.h" -#include "xed-encodings.h" -#include "xed-plugins-engine.h" -#include "xed-prefs-manager-app.h" -#include "xed-session.h" -#include "xed-utils.h" -#include "xed-window.h" - -#include "eggsmclient.h" -#include "eggdesktopfile.h" - -#ifndef ENABLE_GVFS_METADATA -#include "xed-metadata-manager.h" -#endif - -#include "bacon-message-connection.h" - -static guint32 startup_timestamp = 0; - -static BaconMessageConnection *connection; - -/* command line */ -static gint line_position = 0; -static gchar *encoding_charset = NULL; -static gboolean new_window_option = FALSE; -static gboolean new_document_option = FALSE; -static gchar **remaining_args = NULL; -static GSList *file_list = NULL; - -static void -show_version_and_quit (void) -{ - g_print ("%s - Version %s\n", g_get_application_name (), VERSION); - - exit (0); -} - -static void -list_encodings_and_quit (void) -{ - gint i = 0; - const XedEncoding *enc; - - while ((enc = xed_encoding_get_from_index (i)) != NULL) - { - g_print ("%s\n", xed_encoding_get_charset (enc)); - - ++i; - } - - exit (0); -} - -static const GOptionEntry options [] = -{ - { "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, - show_version_and_quit, N_("Show the application's version"), NULL }, - - { "encoding", '\0', 0, G_OPTION_ARG_STRING, &encoding_charset, - N_("Set the character encoding to be used to open the files listed on the command line"), N_("ENCODING")}, - - { "list-encodings", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, - list_encodings_and_quit, N_("Display list of possible values for the encoding option"), NULL}, - - { "new-window", '\0', 0, G_OPTION_ARG_NONE, &new_window_option, - N_("Create a new top-level window in an existing instance of xed"), NULL }, - - { "new-document", '\0', 0, G_OPTION_ARG_NONE, &new_document_option, - N_("Create a new document in an existing instance of xed"), NULL }, - - { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &remaining_args, - NULL, N_("[FILE...]") }, /* collects file arguments */ - - {NULL} -}; - -static void -free_command_line_data (void) -{ - g_slist_foreach (file_list, (GFunc) g_object_unref, NULL); - g_slist_free (file_list); - file_list = NULL; - - g_strfreev (remaining_args); - remaining_args = NULL; - - g_free (encoding_charset); - encoding_charset = NULL; - - new_window_option = FALSE; - new_document_option = FALSE; - line_position = 0; -} - -static void -xed_get_command_line_data (void) -{ - if (remaining_args) - { - gint i; - - for (i = 0; remaining_args[i]; i++) - { - if (*remaining_args[i] == '+') - { - if (*(remaining_args[i] + 1) == '\0') - /* goto the last line of the document */ - line_position = G_MAXINT; - else - line_position = atoi (remaining_args[i] + 1); - } - else - { - GFile *file; - - file = g_file_new_for_commandline_arg (remaining_args[i]); - file_list = g_slist_prepend (file_list, file); - } - } - - file_list = g_slist_reverse (file_list); - } - - if (encoding_charset && - (xed_encoding_get_from_charset (encoding_charset) == NULL)) - { - g_print (_("%s: invalid encoding.\n"), - encoding_charset); - } -} - -static guint32 -get_startup_timestamp (void) -{ - const gchar *startup_id_env; - gchar *startup_id = NULL; - gchar *time_str; - gchar *end; - gulong retval = 0; - - /* we don't unset the env, since startup-notification - * may still need it */ - startup_id_env = g_getenv ("DESKTOP_STARTUP_ID"); - if (startup_id_env == NULL) - goto out; - - startup_id = g_strdup (startup_id_env); - - time_str = g_strrstr (startup_id, "_TIME"); - if (time_str == NULL) - goto out; - - errno = 0; - - /* Skip past the "_TIME" part */ - time_str += 5; - - retval = strtoul (time_str, &end, 0); - if (end == time_str || errno != 0) - retval = 0; - - out: - g_free (startup_id); - - return (retval > 0) ? retval : 0; -} - -static GdkDisplay * -display_open_if_needed (const gchar *name) -{ - GSList *displays; - GSList *l; - GdkDisplay *display = NULL; - - displays = gdk_display_manager_list_displays (gdk_display_manager_get ()); - - for (l = displays; l != NULL; l = l->next) - { - if (strcmp (gdk_display_get_name ((GdkDisplay *) l->data), name) == 0) - { - display = l->data; - break; - } - } - - g_slist_free (displays); - - return display != NULL ? display : gdk_display_open (name); -} - -/* serverside */ -static void -on_message_received (const char *message, - gpointer data) -{ - const XedEncoding *encoding = NULL; - gchar **commands; - gchar **params; - gint workspace; - gint viewport_x; - gint viewport_y; - gchar *display_name; - gint screen_number; - gint i; - XedApp *app; - XedWindow *window; - GdkDisplay *display; - GdkScreen *screen; - - g_return_if_fail (message != NULL); - - xed_debug_message (DEBUG_APP, "Received message:\n%s\n", message); - - commands = g_strsplit (message, "\v", -1); - - /* header */ - params = g_strsplit (commands[0], "\t", 6); - startup_timestamp = atoi (params[0]); - display_name = params[1]; - screen_number = atoi (params[2]); - workspace = atoi (params[3]); - viewport_x = atoi (params[4]); - viewport_y = atoi (params[5]); - - display = display_open_if_needed (display_name); - if (display == NULL) - { - g_warning ("Could not open display %s\n", display_name); - g_strfreev (params); - goto out; - } - - screen = gdk_display_get_screen (display, screen_number); - - g_strfreev (params); - - /* body */ - for (i = 1; commands[i] != NULL; i++) - { - params = g_strsplit (commands[i], "\t", -1); - - if (strcmp (params[0], "NEW-WINDOW") == 0) - { - new_window_option = TRUE; - } - else if (strcmp (params[0], "NEW-DOCUMENT") == 0) - { - new_document_option = TRUE; - } - else if (strcmp (params[0], "OPEN-URIS") == 0) - { - gint n_uris, j; - gchar **uris; - - line_position = atoi (params[1]); - - if (params[2] != '\0') - encoding = xed_encoding_get_from_charset (params[2]); - - n_uris = atoi (params[3]); - uris = g_strsplit (params[4], " ", n_uris); - - for (j = 0; j < n_uris; j++) - { - GFile *file; - - file = g_file_new_for_uri (uris[j]); - file_list = g_slist_prepend (file_list, file); - } - - file_list = g_slist_reverse (file_list); - - /* the list takes ownerhip of the strings, - * only free the array */ - g_free (uris); - } - else - { - g_warning ("Unexpected bacon command"); - } - - g_strfreev (params); - } - - /* execute the commands */ - - app = xed_app_get_default (); - - if (new_window_option) - { - window = xed_app_create_window (app, screen); - } - else - { - /* get a window in the current workspace (if exists) and raise it */ - window = _xed_app_get_window_in_viewport (app, - screen, - workspace, - viewport_x, - viewport_y); - } - - if (file_list != NULL) - { - _xed_cmd_load_files_from_prompt (window, - file_list, - encoding, - line_position); - - if (new_document_option) - xed_window_create_tab (window, TRUE); - } - else - { - XedDocument *doc; - doc = xed_window_get_active_document (window); - - if (doc == NULL || - !xed_document_is_untouched (doc) || - new_document_option) - xed_window_create_tab (window, TRUE); - } - - /* set the proper interaction time on the window. - * Fall back to roundtripping to the X server when we - * don't have the timestamp, e.g. when launched from - * terminal. We also need to make sure that the window - * has been realized otherwise it will not work. lame. - */ - if (!gtk_widget_get_realized (GTK_WIDGET (window))) - gtk_widget_realize (GTK_WIDGET (window)); - - if (startup_timestamp <= 0) - startup_timestamp = gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (window))); - - gdk_x11_window_set_user_time (gtk_widget_get_window (GTK_WIDGET (window)), - startup_timestamp); - - gtk_window_present (GTK_WINDOW (window)); - - out: - g_strfreev (commands); - - free_command_line_data (); -} - -/* clientside */ -static void -send_bacon_message (void) -{ - GdkScreen *screen; - GdkDisplay *display; - const gchar *display_name; - gint screen_number; - gint ws; - gint viewport_x; - gint viewport_y; - GString *command; - - /* the messages have the following format: - * <--- header ---> <---- body -----> - * timestamp \t display_name \t screen_number \t workspace \t viewport_x \t viewport_y \v OP1 \t arg \t arg \v OP2 \t arg \t arg|... - * - * when the arg is a list of uri, they are separated by a space. - * So the delimiters are \v for the commands, \t for the tokens in - * a command and ' ' for the uris: note that such delimiters cannot - * be part of an uri, this way parsing is easier. - */ - - xed_debug (DEBUG_APP); - - screen = gdk_screen_get_default (); - display = gdk_screen_get_display (screen); - - display_name = gdk_display_get_name (display); - screen_number = gdk_screen_get_number (screen); - - xed_debug_message (DEBUG_APP, "Display: %s", display_name); - xed_debug_message (DEBUG_APP, "Screen: %d", screen_number); - - ws = xed_utils_get_current_workspace (screen); - xed_utils_get_current_viewport (screen, &viewport_x, &viewport_y); - - command = g_string_new (NULL); - - /* header */ - g_string_append_printf (command, - "%" G_GUINT32_FORMAT "\t%s\t%d\t%d\t%d\t%d", - startup_timestamp, - display_name, - screen_number, - ws, - viewport_x, - viewport_y); - - /* NEW-WINDOW command */ - if (new_window_option) - { - command = g_string_append_c (command, '\v'); - command = g_string_append (command, "NEW-WINDOW"); - } - - /* NEW-DOCUMENT command */ - if (new_document_option) - { - command = g_string_append_c (command, '\v'); - command = g_string_append (command, "NEW-DOCUMENT"); - } - - /* OPEN_URIS command, optionally specify line_num and encoding */ - if (file_list) - { - GSList *l; - - command = g_string_append_c (command, '\v'); - command = g_string_append (command, "OPEN-URIS"); - - g_string_append_printf (command, - "\t%d\t%s\t%u\t", - line_position, - encoding_charset ? encoding_charset : "", - g_slist_length (file_list)); - - for (l = file_list; l != NULL; l = l->next) - { - gchar *uri; - - uri = g_file_get_uri (G_FILE (l->data)); - command = g_string_append (command, uri); - if (l->next != NULL) - command = g_string_append_c (command, ' '); - - g_free (uri); - } - } - - xed_debug_message (DEBUG_APP, "Bacon Message: %s", command->str); - - bacon_message_connection_send (connection, - command->str); - - g_string_free (command, TRUE); -} +#include "xed-app.h" int main (int argc, char *argv[]) { - GOptionContext *context; - XedPluginsEngine *engine; - XedWindow *window; - XedApp *app; - gboolean restored = FALSE; - GError *error = NULL; - gchar *dir; - gchar *icon_dir; + XedApp *app; + gint status; + const gchar *dir; + xed_dirs_init (); - /* Setup debugging */ - xed_debug_init (); - xed_debug_message (DEBUG_APP, "Startup"); + /* Setup locale/gettext */ + setlocale (LC_ALL, ""); - setlocale (LC_ALL, ""); + dir = xed_dirs_get_xed_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, dir); - dir = xed_dirs_get_xed_locale_dir (); - bindtextdomain (GETTEXT_PACKAGE, dir); - g_free (dir); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); - startup_timestamp = get_startup_timestamp(); + app = g_object_new (XED_TYPE_APP, + "application-id", "org.x.editor", + "flags", G_APPLICATION_HANDLES_COMMAND_LINE | G_APPLICATION_HANDLES_OPEN, + NULL); - /* Setup command line options */ - context = g_option_context_new (_("- Edit text files")); - g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); - g_option_context_add_group (context, gtk_get_option_group (FALSE)); - g_option_context_add_group (context, egg_sm_client_get_option_group ()); + status = g_application_run (G_APPLICATION (app), argc, argv); - gtk_init (&argc, &argv); + g_object_unref (app); - if (!g_option_context_parse (context, &argc, &argv, &error)) - { - g_print(_("%s\nRun '%s --help' to see a full list of available command line options.\n"), - error->message, argv[0]); - g_error_free (error); - g_option_context_free (context); - return 1; - } - - g_option_context_free (context); - - xed_debug_message (DEBUG_APP, "Create bacon connection"); - - connection = bacon_message_connection_new ("xed"); - - if (connection != NULL) - { - if (!bacon_message_connection_get_is_server (connection)) - { - xed_debug_message (DEBUG_APP, "I'm a client"); - - xed_get_command_line_data (); - - send_bacon_message (); - - free_command_line_data (); - - /* we never popup a window... tell startup-notification - * that we are done. - */ - gdk_notify_startup_complete (); - - bacon_message_connection_free (connection); - - exit (0); - } - else - { - xed_debug_message (DEBUG_APP, "I'm a server"); - - bacon_message_connection_set_callback (connection, - on_message_received, - NULL); - } - } - else - { - g_warning ("Cannot create the 'xed' connection."); - } - - xed_debug_message (DEBUG_APP, "Set icon"); - - dir = xed_dirs_get_xed_data_dir (); - icon_dir = g_build_filename (dir, - "icons", - NULL); - g_free (dir); - - gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), - icon_dir); - g_free (icon_dir); - - /* Set the associated .desktop file */ - egg_set_desktop_file (DATADIR "/applications/xed.desktop"); - - /* Load user preferences */ - xed_debug_message (DEBUG_APP, "Init prefs manager"); - xed_prefs_manager_app_init (); - - /* Init plugins engine */ - xed_debug_message (DEBUG_APP, "Init plugins"); - engine = xed_plugins_engine_get_default (); - - /* Initialize session management */ - xed_debug_message (DEBUG_APP, "Init session manager"); - xed_session_init (); - - if (xed_session_is_restored ()) - restored = xed_session_load (); - - if (!restored) - { - xed_debug_message (DEBUG_APP, "Analyze command line data"); - xed_get_command_line_data (); - - xed_debug_message (DEBUG_APP, "Get default app"); - app = xed_app_get_default (); - - xed_debug_message (DEBUG_APP, "Create main window"); - window = xed_app_create_window (app, NULL); - - if (file_list != NULL) - { - const XedEncoding *encoding = NULL; - - if (encoding_charset) - encoding = xed_encoding_get_from_charset (encoding_charset); - - xed_debug_message (DEBUG_APP, "Load files"); - _xed_cmd_load_files_from_prompt (window, - file_list, - encoding, - line_position); - } - else - { - xed_debug_message (DEBUG_APP, "Create tab"); - xed_window_create_tab (window, TRUE); - } - - xed_debug_message (DEBUG_APP, "Show window"); - gtk_widget_show (GTK_WIDGET (window)); - - free_command_line_data (); - } - - xed_debug_message (DEBUG_APP, "Start gtk-main"); - - gtk_main(); - - bacon_message_connection_free (connection); - - /* We kept the original engine reference here. So let's unref it to - * finalize it properly. - */ - g_object_unref (engine); - xed_prefs_manager_app_shutdown (); - -#ifndef ENABLE_GVFS_METADATA - xed_metadata_manager_shutdown (); -#endif - - return 0; + return status; } diff --git a/xed/xedtextregion.c b/xed/xedtextregion.c deleted file mode 100644 index 3901078..0000000 --- a/xed/xedtextregion.c +++ /dev/null @@ -1,646 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * xedtextregion.h - GtkTextMark based region utility functions - * - * This file is part of the GtkSourceView widget - * - * Copyright (C) 2002 Gustavo Giráldez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "xedtextregion.h" - - -#undef ENABLE_DEBUG -/* -#define ENABLE_DEBUG -*/ - -#ifdef ENABLE_DEBUG -#define DEBUG(x) (x) -#else -#define DEBUG(x) -#endif - -typedef struct _Subregion { - GtkTextMark *start; - GtkTextMark *end; -} Subregion; - -struct _XedTextRegion { - GtkTextBuffer *buffer; - GList *subregions; - guint32 time_stamp; -}; - -typedef struct _XedTextRegionIteratorReal XedTextRegionIteratorReal; - -struct _XedTextRegionIteratorReal { - XedTextRegion *region; - guint32 region_time_stamp; - - GList *subregions; -}; - - -/* ---------------------------------------------------------------------- - Private interface - ---------------------------------------------------------------------- */ - -/* Find and return a subregion node which contains the given text - iter. If left_side is TRUE, return the subregion which contains - the text iter or which is the leftmost; else return the rightmost - subregion */ -static GList * -find_nearest_subregion (XedTextRegion *region, - const GtkTextIter *iter, - GList *begin, - gboolean leftmost, - gboolean include_edges) -{ - GList *l, *retval; - - g_return_val_if_fail (region != NULL && iter != NULL, NULL); - - if (!begin) - begin = region->subregions; - - if (begin) - retval = begin->prev; - else - retval = NULL; - - for (l = begin; l; l = l->next) { - GtkTextIter sr_iter; - Subregion *sr = l->data; - gint cmp; - - if (!leftmost) { - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_iter, sr->end); - cmp = gtk_text_iter_compare (iter, &sr_iter); - if (cmp < 0 || (cmp == 0 && include_edges)) { - retval = l; - break; - } - - } else { - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_iter, sr->start); - cmp = gtk_text_iter_compare (iter, &sr_iter); - if (cmp > 0 || (cmp == 0 && include_edges)) - retval = l; - else - break; - } - } - return retval; -} - -/* ---------------------------------------------------------------------- - Public interface - ---------------------------------------------------------------------- */ - -XedTextRegion * -xed_text_region_new (GtkTextBuffer *buffer) -{ - XedTextRegion *region; - - g_return_val_if_fail (buffer != NULL, NULL); - - region = g_new (XedTextRegion, 1); - region->buffer = buffer; - region->subregions = NULL; - region->time_stamp = 0; - - return region; -} - -void -xed_text_region_destroy (XedTextRegion *region, gboolean delete_marks) -{ - g_return_if_fail (region != NULL); - - while (region->subregions) { - Subregion *sr = region->subregions->data; - if (delete_marks) { - gtk_text_buffer_delete_mark (region->buffer, sr->start); - gtk_text_buffer_delete_mark (region->buffer, sr->end); - } - g_free (sr); - region->subregions = g_list_delete_link (region->subregions, - region->subregions); - } - region->buffer = NULL; - region->time_stamp = 0; - - g_free (region); -} - -GtkTextBuffer * -xed_text_region_get_buffer (XedTextRegion *region) -{ - g_return_val_if_fail (region != NULL, NULL); - - return region->buffer; -} - -static void -xed_text_region_clear_zero_length_subregions (XedTextRegion *region) -{ - GtkTextIter start, end; - GList *node; - - g_return_if_fail (region != NULL); - - for (node = region->subregions; node; ) { - Subregion *sr = node->data; - gtk_text_buffer_get_iter_at_mark (region->buffer, &start, sr->start); - gtk_text_buffer_get_iter_at_mark (region->buffer, &end, sr->end); - if (gtk_text_iter_equal (&start, &end)) { - gtk_text_buffer_delete_mark (region->buffer, sr->start); - gtk_text_buffer_delete_mark (region->buffer, sr->end); - g_free (sr); - if (node == region->subregions) - region->subregions = node = g_list_delete_link (node, node); - else - node = g_list_delete_link (node, node); - - ++region->time_stamp; - - } else { - node = node->next; - } - } -} - -void -xed_text_region_add (XedTextRegion *region, - const GtkTextIter *_start, - const GtkTextIter *_end) -{ - GList *start_node, *end_node; - GtkTextIter start, end; - - g_return_if_fail (region != NULL && _start != NULL && _end != NULL); - - start = *_start; - end = *_end; - - DEBUG (g_print ("---\n")); - DEBUG (xed_text_region_debug_print (region)); - DEBUG (g_message ("region_add (%d, %d)", - gtk_text_iter_get_offset (&start), - gtk_text_iter_get_offset (&end))); - - gtk_text_iter_order (&start, &end); - - /* don't add zero-length regions */ - if (gtk_text_iter_equal (&start, &end)) - return; - - /* find bounding subregions */ - start_node = find_nearest_subregion (region, &start, NULL, FALSE, TRUE); - end_node = find_nearest_subregion (region, &end, start_node, TRUE, TRUE); - - if (start_node == NULL || end_node == NULL || end_node == start_node->prev) { - /* create the new subregion */ - Subregion *sr = g_new0 (Subregion, 1); - sr->start = gtk_text_buffer_create_mark (region->buffer, NULL, &start, TRUE); - sr->end = gtk_text_buffer_create_mark (region->buffer, NULL, &end, FALSE); - - if (start_node == NULL) { - /* append the new region */ - region->subregions = g_list_append (region->subregions, sr); - - } else if (end_node == NULL) { - /* prepend the new region */ - region->subregions = g_list_prepend (region->subregions, sr); - - } else { - /* we are in the middle of two subregions */ - region->subregions = g_list_insert_before (region->subregions, - start_node, sr); - } - } - else { - GtkTextIter iter; - Subregion *sr = start_node->data; - if (start_node != end_node) { - /* we need to merge some subregions */ - GList *l = start_node->next; - Subregion *q; - - gtk_text_buffer_delete_mark (region->buffer, sr->end); - while (l != end_node) { - q = l->data; - gtk_text_buffer_delete_mark (region->buffer, q->start); - gtk_text_buffer_delete_mark (region->buffer, q->end); - g_free (q); - l = g_list_delete_link (l, l); - } - q = l->data; - gtk_text_buffer_delete_mark (region->buffer, q->start); - sr->end = q->end; - g_free (q); - l = g_list_delete_link (l, l); - } - /* now move marks if that action expands the region */ - gtk_text_buffer_get_iter_at_mark (region->buffer, &iter, sr->start); - if (gtk_text_iter_compare (&iter, &start) > 0) - gtk_text_buffer_move_mark (region->buffer, sr->start, &start); - gtk_text_buffer_get_iter_at_mark (region->buffer, &iter, sr->end); - if (gtk_text_iter_compare (&iter, &end) < 0) - gtk_text_buffer_move_mark (region->buffer, sr->end, &end); - } - - ++region->time_stamp; - - DEBUG (xed_text_region_debug_print (region)); -} - -void -xed_text_region_subtract (XedTextRegion *region, - const GtkTextIter *_start, - const GtkTextIter *_end) -{ - GList *start_node, *end_node, *node; - GtkTextIter sr_start_iter, sr_end_iter; - gboolean done; - gboolean start_is_outside, end_is_outside; - Subregion *sr; - GtkTextIter start, end; - - g_return_if_fail (region != NULL && _start != NULL && _end != NULL); - - start = *_start; - end = *_end; - - DEBUG (g_print ("---\n")); - DEBUG (xed_text_region_debug_print (region)); - DEBUG (g_message ("region_substract (%d, %d)", - gtk_text_iter_get_offset (&start), - gtk_text_iter_get_offset (&end))); - - gtk_text_iter_order (&start, &end); - - /* find bounding subregions */ - start_node = find_nearest_subregion (region, &start, NULL, FALSE, FALSE); - end_node = find_nearest_subregion (region, &end, start_node, TRUE, FALSE); - - /* easy case first */ - if (start_node == NULL || end_node == NULL || end_node == start_node->prev) - return; - - /* deal with the start point */ - start_is_outside = end_is_outside = FALSE; - - sr = start_node->data; - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); - - if (gtk_text_iter_in_range (&start, &sr_start_iter, &sr_end_iter) && - !gtk_text_iter_equal (&start, &sr_start_iter)) { - /* the starting point is inside the first subregion */ - if (gtk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter) && - !gtk_text_iter_equal (&end, &sr_end_iter)) { - /* the ending point is also inside the first - subregion: we need to split */ - Subregion *new_sr = g_new0 (Subregion, 1); - new_sr->end = sr->end; - new_sr->start = gtk_text_buffer_create_mark (region->buffer, - NULL, &end, TRUE); - start_node = g_list_insert_before (start_node, start_node->next, new_sr); - - sr->end = gtk_text_buffer_create_mark (region->buffer, - NULL, &start, FALSE); - - /* no further processing needed */ - DEBUG (g_message ("subregion splitted")); - - return; - } else { - /* the ending point is outside, so just move - the end of the subregion to the starting point */ - gtk_text_buffer_move_mark (region->buffer, sr->end, &start); - } - } else { - /* the starting point is outside (and so to the left) - of the first subregion */ - DEBUG (g_message ("start is outside")); - - start_is_outside = TRUE; - } - - /* deal with the end point */ - if (start_node != end_node) { - sr = end_node->data; - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); - } - - if (gtk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter) && - !gtk_text_iter_equal (&end, &sr_end_iter)) { - /* ending point is inside, move the start mark */ - gtk_text_buffer_move_mark (region->buffer, sr->start, &end); - } else { - end_is_outside = TRUE; - DEBUG (g_message ("end is outside")); - - } - - /* finally remove any intermediate subregions */ - done = FALSE; - node = start_node; - - while (!done) { - if (node == end_node) - /* we are done, exit in the next iteration */ - done = TRUE; - - if ((node == start_node && !start_is_outside) || - (node == end_node && !end_is_outside)) { - /* skip starting or ending node */ - node = node->next; - } else { - GList *l = node->next; - sr = node->data; - gtk_text_buffer_delete_mark (region->buffer, sr->start); - gtk_text_buffer_delete_mark (region->buffer, sr->end); - g_free (sr); - region->subregions = g_list_delete_link (region->subregions, - node); - node = l; - } - } - - ++region->time_stamp; - - DEBUG (xed_text_region_debug_print (region)); - - /* now get rid of empty subregions */ - xed_text_region_clear_zero_length_subregions (region); - - DEBUG (xed_text_region_debug_print (region)); -} - -gint -xed_text_region_subregions (XedTextRegion *region) -{ - g_return_val_if_fail (region != NULL, 0); - - return g_list_length (region->subregions); -} - -gboolean -xed_text_region_nth_subregion (XedTextRegion *region, - guint subregion, - GtkTextIter *start, - GtkTextIter *end) -{ - Subregion *sr; - - g_return_val_if_fail (region != NULL, FALSE); - - sr = g_list_nth_data (region->subregions, subregion); - if (sr == NULL) - return FALSE; - - if (start) - gtk_text_buffer_get_iter_at_mark (region->buffer, start, sr->start); - if (end) - gtk_text_buffer_get_iter_at_mark (region->buffer, end, sr->end); - - return TRUE; -} - -XedTextRegion * -xed_text_region_intersect (XedTextRegion *region, - const GtkTextIter *_start, - const GtkTextIter *_end) -{ - GList *start_node, *end_node, *node; - GtkTextIter sr_start_iter, sr_end_iter; - Subregion *sr, *new_sr; - gboolean done; - XedTextRegion *new_region; - GtkTextIter start, end; - - g_return_val_if_fail (region != NULL && _start != NULL && _end != NULL, NULL); - - start = *_start; - end = *_end; - - gtk_text_iter_order (&start, &end); - - /* find bounding subregions */ - start_node = find_nearest_subregion (region, &start, NULL, FALSE, FALSE); - end_node = find_nearest_subregion (region, &end, start_node, TRUE, FALSE); - - /* easy case first */ - if (start_node == NULL || end_node == NULL || end_node == start_node->prev) - return NULL; - - new_region = xed_text_region_new (region->buffer); - done = FALSE; - - sr = start_node->data; - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); - - /* starting node */ - if (gtk_text_iter_in_range (&start, &sr_start_iter, &sr_end_iter)) { - new_sr = g_new0 (Subregion, 1); - new_region->subregions = g_list_prepend (new_region->subregions, new_sr); - - new_sr->start = gtk_text_buffer_create_mark (new_region->buffer, NULL, - &start, TRUE); - if (start_node == end_node) { - /* things will finish shortly */ - done = TRUE; - if (gtk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter)) - new_sr->end = gtk_text_buffer_create_mark (new_region->buffer, - NULL, &end, FALSE); - else - new_sr->end = gtk_text_buffer_create_mark (new_region->buffer, - NULL, &sr_end_iter, - FALSE); - } else { - new_sr->end = gtk_text_buffer_create_mark (new_region->buffer, NULL, - &sr_end_iter, FALSE); - } - node = start_node->next; - } else { - /* start should be the same as the subregion, so copy it in the loop */ - node = start_node; - } - - if (!done) { - while (node != end_node) { - /* copy intermediate subregions verbatim */ - sr = node->data; - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, - sr->start); - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); - - new_sr = g_new0 (Subregion, 1); - new_region->subregions = g_list_prepend (new_region->subregions, new_sr); - new_sr->start = gtk_text_buffer_create_mark (new_region->buffer, NULL, - &sr_start_iter, TRUE); - new_sr->end = gtk_text_buffer_create_mark (new_region->buffer, NULL, - &sr_end_iter, FALSE); - /* next node */ - node = node->next; - } - - /* ending node */ - sr = node->data; - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); - gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); - - new_sr = g_new0 (Subregion, 1); - new_region->subregions = g_list_prepend (new_region->subregions, new_sr); - - new_sr->start = gtk_text_buffer_create_mark (new_region->buffer, NULL, - &sr_start_iter, TRUE); - - if (gtk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter)) - new_sr->end = gtk_text_buffer_create_mark (new_region->buffer, NULL, - &end, FALSE); - else - new_sr->end = gtk_text_buffer_create_mark (new_region->buffer, NULL, - &sr_end_iter, FALSE); - } - - new_region->subregions = g_list_reverse (new_region->subregions); - return new_region; -} - -static gboolean -check_iterator (XedTextRegionIteratorReal *real) -{ - if ((real->region == NULL) || - (real->region_time_stamp != real->region->time_stamp)) - { - g_warning("Invalid iterator: either the iterator " - "is uninitialized, or the region " - "has been modified since the iterator " - "was created."); - - return FALSE; - } - - return TRUE; -} - -void -xed_text_region_get_iterator (XedTextRegion *region, - XedTextRegionIterator *iter, - guint start) -{ - XedTextRegionIteratorReal *real; - - g_return_if_fail (region != NULL); - g_return_if_fail (iter != NULL); - - real = (XedTextRegionIteratorReal *)iter; - - /* region->subregions may be NULL, -> end iter */ - - real->region = region; - real->subregions = g_list_nth (region->subregions, start); - real->region_time_stamp = region->time_stamp; -} - -gboolean -xed_text_region_iterator_is_end (XedTextRegionIterator *iter) -{ - XedTextRegionIteratorReal *real; - - g_return_val_if_fail (iter != NULL, FALSE); - - real = (XedTextRegionIteratorReal *)iter; - g_return_val_if_fail (check_iterator (real), FALSE); - - return (real->subregions == NULL); -} - -gboolean -xed_text_region_iterator_next (XedTextRegionIterator *iter) -{ - XedTextRegionIteratorReal *real; - - g_return_val_if_fail (iter != NULL, FALSE); - - real = (XedTextRegionIteratorReal *)iter; - g_return_val_if_fail (check_iterator (real), FALSE); - - if (real->subregions != NULL) { - real->subregions = g_list_next (real->subregions); - return TRUE; - } - else - return FALSE; -} - -void -xed_text_region_iterator_get_subregion (XedTextRegionIterator *iter, - GtkTextIter *start, - GtkTextIter *end) -{ - XedTextRegionIteratorReal *real; - Subregion *sr; - - g_return_if_fail (iter != NULL); - - real = (XedTextRegionIteratorReal *)iter; - g_return_if_fail (check_iterator (real)); - g_return_if_fail (real->subregions != NULL); - - sr = (Subregion*)real->subregions->data; - g_return_if_fail (sr != NULL); - - if (start) - gtk_text_buffer_get_iter_at_mark (real->region->buffer, start, sr->start); - if (end) - gtk_text_buffer_get_iter_at_mark (real->region->buffer, end, sr->end); -} - -void -xed_text_region_debug_print (XedTextRegion *region) -{ - GList *l; - - g_return_if_fail (region != NULL); - - g_print ("Subregions: "); - l = region->subregions; - while (l) { - Subregion *sr = l->data; - GtkTextIter iter1, iter2; - gtk_text_buffer_get_iter_at_mark (region->buffer, &iter1, sr->start); - gtk_text_buffer_get_iter_at_mark (region->buffer, &iter2, sr->end); - g_print ("%d-%d ", gtk_text_iter_get_offset (&iter1), - gtk_text_iter_get_offset (&iter2)); - l = l->next; - } - g_print ("\n"); -} diff --git a/xed/xedtextregion.h b/xed/xedtextregion.h deleted file mode 100644 index 01f3e56..0000000 --- a/xed/xedtextregion.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * xedtextregion.h - GtkTextMark based region utility functions - * - * This file is part of the GtkSourceView widget - * - * Copyright (C) 2002 Gustavo Giráldez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XED_TEXT_REGION_H__ -#define __XED_TEXT_REGION_H__ - -#include - -G_BEGIN_DECLS - -typedef struct _XedTextRegion XedTextRegion; -typedef struct _XedTextRegionIterator XedTextRegionIterator; - -struct _XedTextRegionIterator { - /* XedTextRegionIterator is an opaque datatype; ignore all these fields. - * Initialize the iter with xed_text_region_get_iterator - * function - */ - /*< private >*/ - gpointer dummy1; - guint32 dummy2; - gpointer dummy3; -}; - -XedTextRegion *xed_text_region_new (GtkTextBuffer *buffer); -void xed_text_region_destroy (XedTextRegion *region, - gboolean delete_marks); - -GtkTextBuffer *xed_text_region_get_buffer (XedTextRegion *region); - -void xed_text_region_add (XedTextRegion *region, - const GtkTextIter *_start, - const GtkTextIter *_end); - -void xed_text_region_subtract (XedTextRegion *region, - const GtkTextIter *_start, - const GtkTextIter *_end); - -gint xed_text_region_subregions (XedTextRegion *region); - -gboolean xed_text_region_nth_subregion (XedTextRegion *region, - guint subregion, - GtkTextIter *start, - GtkTextIter *end); - -XedTextRegion *xed_text_region_intersect (XedTextRegion *region, - const GtkTextIter *_start, - const GtkTextIter *_end); - -void xed_text_region_get_iterator (XedTextRegion *region, - XedTextRegionIterator *iter, - guint start); - -gboolean xed_text_region_iterator_is_end (XedTextRegionIterator *iter); - -/* Returns FALSE if iterator is the end iterator */ -gboolean xed_text_region_iterator_next (XedTextRegionIterator *iter); - -void xed_text_region_iterator_get_subregion (XedTextRegionIterator *iter, - GtkTextIter *start, - GtkTextIter *end); - -void xed_text_region_debug_print (XedTextRegion *region); - -G_END_DECLS - -#endif /* __XED_TEXT_REGION_H__ */