gtranslator r3448 - in branches/GOBJECT_WORK: . data src src/dialogs src/plugin-system
- From: sdeburca svn gnome org
- To: svn-commits-list gnome org
- Subject: gtranslator r3448 - in branches/GOBJECT_WORK: . data src src/dialogs src/plugin-system
- Date: Sun, 13 Jan 2008 08:12:01 +0000 (GMT)
Author: sdeburca
Date: Sun Jan 13 08:12:00 2008
New Revision: 3448
URL: http://svn.gnome.org/viewvc/gtranslator?rev=3448&view=rev
Log:
2008-01-13 SeÃn de BÃrca <sdeburca svn gnome org>
* data/Makefile.am:
* data/gtranslator.pc.in:
* src/dialogs/Makefile.am:
* src/dialogs/preferences-dialog.{c,glade}:
* src/plugin-system/:
* src/Makefile.am:
* src/application.{c,h}:
* src/main.c:
* src/utils_gui.{c,h}:
* INSTALL:
* configure.ac:
Add plugin functionality, by Ignacio Casal Quinteiro with some help
from myself.
Added:
branches/GOBJECT_WORK/data/gtranslator.pc.in
branches/GOBJECT_WORK/src/plugin-system/
branches/GOBJECT_WORK/src/plugin-system/Makefile.am
branches/GOBJECT_WORK/src/plugin-system/module.c
branches/GOBJECT_WORK/src/plugin-system/module.h
branches/GOBJECT_WORK/src/plugin-system/plugin-info-priv.h
branches/GOBJECT_WORK/src/plugin-system/plugin-info.c
branches/GOBJECT_WORK/src/plugin-system/plugin-info.h
branches/GOBJECT_WORK/src/plugin-system/plugin-manager.c
branches/GOBJECT_WORK/src/plugin-system/plugin-manager.h
branches/GOBJECT_WORK/src/plugin-system/plugin.c
branches/GOBJECT_WORK/src/plugin-system/plugin.h
branches/GOBJECT_WORK/src/plugin-system/plugins-engine.c
branches/GOBJECT_WORK/src/plugin-system/plugins-engine.h
branches/GOBJECT_WORK/src/plugin-system/update-from-gedit.sh
Modified:
branches/GOBJECT_WORK/ChangeLog
branches/GOBJECT_WORK/INSTALL
branches/GOBJECT_WORK/configure.ac
branches/GOBJECT_WORK/data/Makefile.am
branches/GOBJECT_WORK/src/Makefile.am
branches/GOBJECT_WORK/src/application.c
branches/GOBJECT_WORK/src/application.h
branches/GOBJECT_WORK/src/dialogs/Makefile.am
branches/GOBJECT_WORK/src/dialogs/preferences-dialog.c
branches/GOBJECT_WORK/src/dialogs/preferences-dialog.glade
branches/GOBJECT_WORK/src/main.c
branches/GOBJECT_WORK/src/utils_gui.c
branches/GOBJECT_WORK/src/utils_gui.h
Modified: branches/GOBJECT_WORK/INSTALL
==============================================================================
--- branches/GOBJECT_WORK/INSTALL (original)
+++ branches/GOBJECT_WORK/INSTALL Sun Jan 13 08:12:00 2008
@@ -1,38 +1,54 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
Basic Installation
==================
- These are generic installation instructions.
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, a file
-`config.cache' that saves the results of its tests to speed up
-reconfiguring, and a file `config.log' containing compiler output
-(useful mainly for debugging `configure').
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If at some point `config.cache'
-contains results you don't want to keep, you may remove or edit it.
-
- The file `configure.in' is used to create `configure' by a program
-called `autoconf'. You only need `configure.in' if you want to change
-it or regenerate `configure' using a newer version of `autoconf'.
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system. If you're
- using `csh' on an old version of System V, you might need to type
- `sh ./configure' instead to prevent `csh' from trying to execute
- `configure' itself.
+ `./configure' to configure the package for your system.
- Running `configure' takes awhile. While running, it prints some
- messages telling which features it is checking for.
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
2. Type `make' to compile the package.
@@ -54,49 +70,49 @@
Compilers and Options
=====================
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. You can give `configure'
-initial values for variables by setting them in the environment. Using
-a Bourne-compatible shell, you can do that on the command line like
-this:
- CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-Or on systems that have the `env' program, you can do it like this:
- env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+ *Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
- You can compile the package for more than one kind of computer at the
+You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
-own directory. To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'. `cd' to the
+own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
- If you have to use a `make' that does not supports the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory. After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
Installation Names
==================
- By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc. You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
+options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
@@ -107,7 +123,7 @@
Optional Features
=================
- Some packages pay attention to `--enable-FEATURE' options to
+Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
@@ -122,48 +138,86 @@
Specifying the System Type
==========================
- There may be some features `configure' can not figure out
-automatically, but needs to determine by the type of host the package
-will run on. Usually `configure' can figure that out, but if it prints
-a message saying it can not guess the host type, give it the
-`--host=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name with three fields:
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
CPU-COMPANY-SYSTEM
-See the file `config.sub' for the possible values of each field. If
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
+need to know the machine type.
- If you are building compiler tools for cross-compiling, you can also
-use the `--target=TYPE' option to select the type of system they will
-produce code for and the `--build=TYPE' option to select the type of
-system on which you are compiling the package.
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
Sharing Defaults
================
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
-Operation Controls
+Defining Variables
==================
- `configure' recognizes the following options to control how it
-operates.
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
-`--cache-file=FILE'
- Use and save the results of the tests in FILE instead of
- `./config.cache'. Set FILE to `/dev/null' to disable caching, for
- debugging `configure'.
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
`--help'
+`-h'
Print a summary of the options to `configure', and exit.
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
`--quiet'
`--silent'
`-q'
@@ -175,8 +229,6 @@
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
-`--version'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
-`configure' also accepts some other, not widely useful, options.
Modified: branches/GOBJECT_WORK/configure.ac
==============================================================================
--- branches/GOBJECT_WORK/configure.ac (original)
+++ branches/GOBJECT_WORK/configure.ac Sun Jan 13 08:12:00 2008
@@ -10,6 +10,9 @@
AC_CONFIG_SRCDIR(src/main.c)
AM_CONFIG_HEADER(config.h)
+GTR_API_VERSION=2.0
+AC_SUBST(GTR_API_VERSION)
+
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
AM_MAINTAINER_MODE
@@ -183,6 +186,7 @@
Makefile
gtranslator.spec
data/Makefile
+data/gtranslator.pc
data/desktop/Makefile
data/desktop/gtranslator.desktop.in
data/mime/Makefile
@@ -200,6 +204,7 @@
src/toolbareditor/Makefile
src/charmap/Makefile
src/alternatelanguage/Makefile
+src/plugin-system/Makefile
])
dnl ------------------------------------------------------------------
Modified: branches/GOBJECT_WORK/data/Makefile.am
==============================================================================
--- branches/GOBJECT_WORK/data/Makefile.am (original)
+++ branches/GOBJECT_WORK/data/Makefile.am Sun Jan 13 08:12:00 2008
@@ -5,6 +5,12 @@
mime \
scripts
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gtranslator- GTR_API_VERSION@.pc
+
+gtranslator- GTR_API_VERSION@.pc: gtranslator.pc
+ cp gtranslator.pc gtranslator- GTR_API_VERSION@.pc
+
uidir = $(pkgdatadir)
ui_DATA = \
gtranslator-ui.xml \
@@ -12,4 +18,8 @@
po.lang
EXTRA_DIST = \
- $(ui_DATA)
+ $(ui_DATA) \
+ gtranslator.pc.in
+
+CLEANFILES = \
+ $(pkgconfig_DATA)
Added: branches/GOBJECT_WORK/data/gtranslator.pc.in
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/data/gtranslator.pc.in Sun Jan 13 08:12:00 2008
@@ -0,0 +1,20 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: gtranslator
+Description: gtranslator
+Requires: libgnomeui-2.0 libglade-2.0 gtksourceview-2.0
+Version: @VERSION@
+Cflags: -I${includedir}/gtranslator- GTR_API_VERSION@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: gtranslator
+Description: gtranslator
+Requires: libgnomeui-2.0 libglade-2.0 gtksourceview-2.0
+Version: @VERSION@
+Cflags: -I${includedir}/gtranslator- GTR_API_VERSION@
Modified: branches/GOBJECT_WORK/src/Makefile.am
==============================================================================
--- branches/GOBJECT_WORK/src/Makefile.am (original)
+++ branches/GOBJECT_WORK/src/Makefile.am Sun Jan 13 08:12:00 2008
@@ -5,7 +5,10 @@
SUBDIRS = toolbareditor \
dialogs \
charmap \
- alternatelanguage
+ alternatelanguage \
+ plugin-system
+
+noinst_LTLIBRARIES = libgtranslator.la
INCLUDES = \
-I$(top_srcdir) \
@@ -14,6 +17,7 @@
-I$(top_srcdir)/src/toolbareditor \
-I$(top_srcdir)/src/charmap \
-I$(top_srcdir)/src/alternatelanguage \
+ -I$(top_srcdir)/src/plugin-system \
-DGNOMELOCALEDIR=\""$(prefix)/${DATADIRNAME}/locale"\" \
-DPREFIX=\""$(prefix)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
@@ -33,6 +37,14 @@
# gtranslator-auto-learn \
# gtranslator-export-learn-buffer
+gtranslator_SOURCES = main.c
+
+gtranslator_LDADD = libgtranslator.la $(GTRANSLATOR_LIBS) $(GTKSPELL_LIBS) $(INTLLIBS)
+
+gtranslator_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
+
+libgtranslator_la_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
+
BUILT_SOURCES = \
gtranslator-marshal.h \
gtranslator-marshal.c \
@@ -56,13 +68,17 @@
view.h \
window.h
-gtranslator_SOURCES = \
+headerdir = $(prefix)/include/gtranslator- GTR_API_VERSION@/gtranslator
+
+header_DATA = \
+ $(INST_H_FILES)
+
+libgtranslator_la_SOURCES = \
$(BUILT_SOURCES) \
application.c \
compile.h \
draw-spaces.c draw-spaces.h \
languages.c languages.h \
- main.c \
message-area.c \
message-table.c \
nautilus-string.c \
@@ -99,18 +115,14 @@
comment.c \
$(INST_H_FILES)
-gtranslator_LDADD = \
- $(top_srcdir)/src/dialogs/libdialogs.la \
- $(top_srcdir)/src/toolbareditor/libtoolbareditor.la \
- $(top_srcdir)/src/charmap/libcharmap.la \
- $(top_srcdir)/src/alternatelanguage/libalternatelang.la \
- $(INTLLIBS) \
+libgtranslator_la_LIBADD = \
$(GTRANSLATOR_LIBS) \
- $(GTKSPELL_LIBS)
+ dialogs/libdialogs.la \
+ toolbareditor/libtoolbareditor.la \
+ charmap/libcharmap.la \
+ alternatelanguage/libalternatelang.la \
+ plugin-system/libpluginsystem.la
-gtranslator_LDFLAGS = \
- -Wall
-
#gtranslator_auto_learn_SOURCES = \
# auto-learn.c
#
Modified: branches/GOBJECT_WORK/src/application.c
==============================================================================
--- branches/GOBJECT_WORK/src/application.c (original)
+++ branches/GOBJECT_WORK/src/application.c Sun Jan 13 08:12:00 2008
@@ -41,6 +41,7 @@
struct _GtranslatorApplicationPrivate
{
+ GList *windows;
GtranslatorWindow *active_window;
gchar *toolbars_file;
@@ -163,6 +164,8 @@
application->priv = GTR_APPLICATION_GET_PRIVATE (application);
priv = application->priv;
+ priv->windows = NULL;
+
gtranslator_init_session(application);
priv->toolbars_model = egg_toolbars_model_new ();
@@ -208,7 +211,7 @@
}
GtranslatorApplication *
-gtranslator_application_get_instance (void)
+gtranslator_application_get_default (void)
{
static GtranslatorApplication *instance = NULL;
@@ -318,3 +321,15 @@
{
return GTR_WINDOW(app->priv->active_window);
}
+
+const GList *
+gtranslator_application_get_windows (GtranslatorApplication *app)
+{
+ g_return_val_if_fail (GTR_IS_APPLICATION (app), NULL);
+
+ if(!app->priv->windows)
+ app->priv->windows = g_list_prepend(app->priv->windows, app->priv->active_window);
+
+ return app->priv->windows;
+}
+
Modified: branches/GOBJECT_WORK/src/application.h
==============================================================================
--- branches/GOBJECT_WORK/src/application.h (original)
+++ branches/GOBJECT_WORK/src/application.h Sun Jan 13 08:12:00 2008
@@ -38,7 +38,7 @@
#define GTR_IS_APPLICATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_APPLICATION))
#define GTR_APPLICATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_APPLIAPPLICATION, GtranslatorApplicationClass))
-#define GTR_APP (gtranslator_application_get_instance())
+#define GTR_APP (gtranslator_application_get_default())
/* Private structure type */
typedef struct _GtranslatorApplicationPrivate GtranslatorApplicationPrivate;
@@ -70,7 +70,7 @@
* Public methods
*/
GType gtranslator_application_get_type (void) G_GNUC_CONST;
-GtranslatorApplication *gtranslator_application_get_instance (void);
+GtranslatorApplication *gtranslator_application_get_default (void);
EggToolbarsModel *gtranslator_application_get_toolbars_model (GtranslatorApplication *application);
@@ -85,6 +85,9 @@
GtranslatorWindow *gtranslator_application_get_active_window (GtranslatorApplication * app);
+const GList *
+gtranslator_application_get_windows (GtranslatorApplication *app);
+
G_END_DECLS
#endif /* __APPLICATION_H__ */
Modified: branches/GOBJECT_WORK/src/dialogs/Makefile.am
==============================================================================
--- branches/GOBJECT_WORK/src/dialogs/Makefile.am (original)
+++ branches/GOBJECT_WORK/src/dialogs/Makefile.am Sun Jan 13 08:12:00 2008
@@ -3,6 +3,7 @@
-I$(top_builddir) \
-I$(top_srcdir)/src \
-I$(top_builddir)/src \
+ -I$(top_srcdir)/src/plugin-system \
-DDATADIR=\""$(pkgdatadir)"\" \
-DPIXMAPSDIR=\""$(datadir)"/pixmaps/gtranslator\" \
$(GTRANSLATOR_CFLAGS) \
Modified: branches/GOBJECT_WORK/src/dialogs/preferences-dialog.c
==============================================================================
--- branches/GOBJECT_WORK/src/dialogs/preferences-dialog.c (original)
+++ branches/GOBJECT_WORK/src/dialogs/preferences-dialog.c Sun Jan 13 08:12:00 2008
@@ -23,6 +23,7 @@
#include "preferences-dialog.h"
#include "prefs-manager.h"
#include "utils_gui.h"
+#include "plugin-manager.h"
#include <glib.h>
#include <glib/gi18n.h>
@@ -82,6 +83,9 @@
/*Inteface*/
GtkWidget *left_radiobutton;
GtkWidget *right_radiobutton;
+
+ /*Plugins*/
+ GtkWidget *plugins_box;
};
/***************Files pages****************/
@@ -499,6 +503,23 @@
dlg);
}
+static void
+setup_plugin_pages(GtranslatorPreferencesDialog *dlg)
+{
+ GtkWidget *page_content;
+
+ page_content = gtranslator_plugin_manager_new ();
+ g_return_if_fail (page_content != NULL);
+
+ gtk_box_pack_start (GTK_BOX (dlg->priv->plugins_box),
+ page_content,
+ TRUE,
+ TRUE,
+ 0);
+
+ gtk_widget_show_all (page_content);
+}
+
static void
dialog_response_handler (GtkDialog *dlg,
@@ -583,6 +604,8 @@
"left_radiobutton", &dlg->priv->left_radiobutton,
"right_radiobutton", &dlg->priv->right_radiobutton,
+
+ "plugins_box", &dlg->priv->plugins_box,
NULL);
if(!ret)
@@ -605,6 +628,7 @@
setup_editor_pages(dlg);
setup_po_header_pages(dlg);
setup_interface_pages(dlg);
+ setup_plugin_pages(dlg);
}
static void
Modified: branches/GOBJECT_WORK/src/dialogs/preferences-dialog.glade
==============================================================================
--- branches/GOBJECT_WORK/src/dialogs/preferences-dialog.glade (original)
+++ branches/GOBJECT_WORK/src/dialogs/preferences-dialog.glade Sun Jan 13 08:12:00 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.0 on Fri Dec 21 21:48:57 2007 -->
+<!--Generated with glade3 3.4.0 on Sat Jan 12 17:11:29 2008 -->
<glade-interface>
<widget class="GtkDialog" id="preferences_dialog">
<property name="border_width">5</property>
@@ -534,29 +534,15 @@
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
- <widget class="GtkLabel" id="label28">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Name:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">name_entry</property>
- </widget>
- <packing>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label29">
+ <widget class="GtkEntry" id="email_entry">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Email:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">email_entry</property>
+ <property name="can_focus">True</property>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
@@ -570,15 +556,29 @@
</packing>
</child>
<child>
- <widget class="GtkEntry" id="email_entry">
+ <widget class="GtkLabel" id="label29">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Email:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">email_entry</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label28">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">name_entry</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
</widget>
@@ -638,69 +638,99 @@
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
- <widget class="GtkSpinButton" id="number_plurals_spinbutton">
+ <widget class="GtkComboBoxEntry" id="encoding_combobox">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="adjustment">2 1 10 1 10 10</property>
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="encoding_comboentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="number_plurals_label">
+ <widget class="GtkComboBoxEntry" id="team_email_combobox">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Number of pl_urals:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">number_plurals_spinbutton</property>
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="team_email_comboentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
</widget>
<packing>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">GTK_FILL</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label34">
+ <widget class="GtkComboBoxEntry" id="charset_combobox">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Language:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">language_combobox</property>
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="charset_comboentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
</widget>
<packing>
- <property name="x_options">GTK_FILL</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label35">
+ <widget class="GtkComboBoxEntry" id="langcode_combobox">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Language _code:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">langcode_combobox</property>
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="langcode_comboentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label37">
+ <widget class="GtkComboBoxEntry" id="language_combobox">
+ <property name="visible">True</property>
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="language_comboentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label39">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Character _set:</property>
+ <property name="label" translatable="yes">_Team email:</property>
<property name="use_underline">True</property>
- <property name="mnemonic_widget">charset_combobox</property>
+ <property name="mnemonic_widget">team_email_combobox</property>
</widget>
<packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
@@ -719,100 +749,70 @@
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label39">
+ <widget class="GtkLabel" id="label37">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">_Team email:</property>
+ <property name="label" translatable="yes">Character _set:</property>
<property name="use_underline">True</property>
- <property name="mnemonic_widget">team_email_combobox</property>
+ <property name="mnemonic_widget">charset_combobox</property>
</widget>
<packing>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkComboBoxEntry" id="language_combobox">
- <property name="visible">True</property>
- <child internal-child="entry">
- <widget class="GtkEntry" id="language_comboentry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkComboBoxEntry" id="langcode_combobox">
+ <widget class="GtkLabel" id="label35">
<property name="visible">True</property>
- <child internal-child="entry">
- <widget class="GtkEntry" id="langcode_comboentry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Language _code:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">langcode_combobox</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkComboBoxEntry" id="charset_combobox">
+ <widget class="GtkLabel" id="label34">
<property name="visible">True</property>
- <child internal-child="entry">
- <widget class="GtkEntry" id="charset_comboentry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Language:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">language_combobox</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkComboBoxEntry" id="team_email_combobox">
+ <widget class="GtkLabel" id="number_plurals_label">
<property name="visible">True</property>
- <child internal-child="entry">
- <widget class="GtkEntry" id="team_email_comboentry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Number of pl_urals:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">number_plurals_spinbutton</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <widget class="GtkComboBoxEntry" id="encoding_combobox">
+ <widget class="GtkSpinButton" id="number_plurals_spinbutton">
<property name="visible">True</property>
- <child internal-child="entry">
- <widget class="GtkEntry" id="encoding_comboentry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
+ <property name="can_focus">True</property>
+ <property name="adjustment">2 1 10 1 10 10</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
</packing>
</child>
</widget>
@@ -964,6 +964,29 @@
<property name="tab_fill">False</property>
</packing>
</child>
+ <child>
+ <widget class="GtkVBox" id="plugins_box">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Plugins</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="position">1</property>
Modified: branches/GOBJECT_WORK/src/main.c
==============================================================================
--- branches/GOBJECT_WORK/src/main.c (original)
+++ branches/GOBJECT_WORK/src/main.c Sun Jan 13 08:12:00 2008
@@ -28,6 +28,7 @@
#include "application.h"
#include "prefs-manager-app.h"
+#include "plugins-engine.h"
#include <locale.h>
#include <glib.h>
@@ -45,6 +46,7 @@
{
GError *error = NULL;
GnomeProgram *program;
+ GtranslatorPluginsEngine *engine;
/*
* Initialize gettext.
@@ -90,7 +92,15 @@
g_clear_error(&error);
}
+ /*
+ * Init preferences manager
+ */
gtranslator_prefs_manager_app_init();
+
+ /*
+ * Init plugin engine
+ */
+ engine = gtranslator_plugins_engine_get_default ();
/*
* Create the main app-window.
Added: branches/GOBJECT_WORK/src/plugin-system/Makefile.am
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/Makefile.am Sun Jan 13 08:12:00 2008
@@ -0,0 +1,49 @@
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ -I$(top_srcdir)/src/toolbareditor \
+ -I$(headerdir) \
+ -DPIXMAPSDIR=\""$(datadir)"/pixmaps/gtranslator\" \
+ -DGTR_PLUGINDIR=\""$(libdir)/gtranslator/plugins"\" \
+ $(GTRANSLATOR_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED_CFLAGS)
+
+noinst_LTLIBRARIES = \
+ libpluginsystem.la
+
+INST_H_FILES = \
+ plugin.h
+
+headerdir = $(prefix)/include/gtranslator- GTR_API_VERSION@/gtranslator
+
+header_DATA = \
+ $(INST_H_FILES)
+
+libpluginsystem_la_SOURCES = \
+ $(INST_H_FILES) \
+ module.h \
+ module.c \
+ plugin-info-priv.h \
+ plugin-info.c \
+ plugin-info.h \
+ plugin.c \
+ plugin-manager.c \
+ plugin-manager.h \
+ plugins-engine.c \
+ plugins-engine.h
+
+libpluginsystem_la_CFLAGS = \
+ $(GTRANSLATOR_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED) \
+ -DCURSOR_DIR=\"$(pkgdatadir)\" \
+ $(AM_CFLAGS)
+
+libpluginsystem_la_LDFLAGS = \
+ -export-dynamic
+
+EXTRA_DIST = $(pixmaps__DATA)
+
Added: branches/GOBJECT_WORK/src/plugin-system/module.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/module.c Sun Jan 13 08:12:00 2008
@@ -0,0 +1,228 @@
+/*
+ * module.c
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, 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 gtranslator Team, 2005. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: module.c 5367 2006-12-17 14:29:49Z pborelli $
+ */
+
+#include "config.h"
+
+#include "module.h"
+//#include "gtranslator-debug.h"
+
+#include <gmodule.h>
+
+typedef struct _GtranslatorModuleClass GtranslatorModuleClass;
+
+struct _GtranslatorModuleClass
+{
+ GTypeModuleClass parent_class;
+};
+
+struct _GtranslatorModule
+{
+ GTypeModule parent_instance;
+
+ GModule *library;
+
+ gchar *path;
+ GType type;
+};
+
+typedef GType (*GtranslatorModuleRegisterFunc) (GTypeModule *);
+
+static void gtranslator_module_init (GtranslatorModule *action);
+static void gtranslator_module_class_init (GtranslatorModuleClass *class);
+
+static GObjectClass *parent_class = NULL;
+
+GType
+gtranslator_module_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (GtranslatorModuleClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gtranslator_module_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GtranslatorModule),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtranslator_module_init,
+ };
+
+ type = g_type_register_static (G_TYPE_TYPE_MODULE,
+ "GtranslatorModule",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+gtranslator_module_load (GTypeModule *gmodule)
+{
+ GtranslatorModule *module = GTR_MODULE (gmodule);
+ GtranslatorModuleRegisterFunc register_func;
+
+ g_warning( "Loading %s", module->path);
+
+ module->library = g_module_open (module->path, 0);
+
+ if (module->library == NULL)
+ {
+ g_warning (g_module_error());
+
+ return FALSE;
+ }
+
+ /* extract symbols from the lib */
+ if (!g_module_symbol (module->library, "register_gtranslator_plugin",
+ (void *) ®ister_func))
+ {
+ g_warning (g_module_error());
+ g_module_close (module->library);
+
+ return FALSE;
+ }
+
+ /* symbol can still be NULL even though g_module_symbol
+ * returned TRUE */
+ if (register_func == NULL)
+ {
+ g_warning ("Symbol 'register_gtranslator_plugin' should not be NULL");
+ g_module_close (module->library);
+
+ return FALSE;
+ }
+
+ module->type = register_func (gmodule);
+
+ if (module->type == 0)
+ {
+ g_warning ("Invalid gtranslator plugin contained by module %s", module->path);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+gtranslator_module_unload (GTypeModule *gmodule)
+{
+ GtranslatorModule *module = GTR_MODULE (gmodule);
+
+ g_warning( "Unloading %s", module->path);
+
+ g_module_close (module->library);
+
+ module->library = NULL;
+ module->type = 0;
+}
+
+const gchar *
+gtranslator_module_get_path (GtranslatorModule *module)
+{
+ g_return_val_if_fail (GTR_IS_MODULE (module), NULL);
+
+ return module->path;
+}
+
+GObject *
+gtranslator_module_new_object (GtranslatorModule *module)
+{
+ g_warning( "Creating object of type %s", g_type_name (module->type));
+
+ if (module->type == 0)
+ {
+ return NULL;
+ }
+
+ return g_object_new (module->type, NULL);
+}
+
+static void
+gtranslator_module_init (GtranslatorModule *module)
+{
+ g_warning( "GtranslatorModule %p initialising", module);
+}
+
+static void
+gtranslator_module_finalize (GObject *object)
+{
+ GtranslatorModule *module = GTR_MODULE (object);
+
+ g_warning( "GtranslatorModule %p finalising", module);
+
+ g_free (module->path);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gtranslator_module_class_init (GtranslatorModuleClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
+
+ parent_class = (GObjectClass *) g_type_class_peek_parent (class);
+
+ object_class->finalize = gtranslator_module_finalize;
+
+ module_class->load = gtranslator_module_load;
+ module_class->unload = gtranslator_module_unload;
+}
+
+GtranslatorModule *
+gtranslator_module_new (const gchar *path)
+{
+ GtranslatorModule *result;
+
+ if (path == NULL || path[0] == '\0')
+ {
+ return NULL;
+ }
+
+ result = g_object_new (GTR_TYPE_MODULE, NULL);
+
+ g_type_module_set_name (G_TYPE_MODULE (result), path);
+ result->path = g_strdup (path);
+
+ return result;
+}
Added: branches/GOBJECT_WORK/src/plugin-system/module.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/module.h Sun Jan 13 08:12:00 2008
@@ -0,0 +1,65 @@
+/*
+ * module.h
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* This is a modified version of 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 gtranslator Team, 2005. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: module.h 5263 2006-10-08 14:26:02Z pborelli $
+ */
+
+#ifndef GTR_MODULE_H
+#define GTR_MODULE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_MODULE (gtranslator_module_get_type ())
+#define GTR_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTR_TYPE_MODULE, GtranslatorModule))
+#define GTR_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTR_TYPE_MODULE, GtranslatorModuleClass))
+#define GTR_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTR_TYPE_MODULE))
+#define GTR_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTR_TYPE_MODULE))
+#define GTR_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_MODULE, GtranslatorModuleClass))
+
+typedef struct _GtranslatorModule GtranslatorModule;
+
+GType gtranslator_module_get_type (void) G_GNUC_CONST;
+
+GtranslatorModule *gtranslator_module_new (const gchar *path);
+
+const gchar *gtranslator_module_get_path (GtranslatorModule *module);
+
+GObject *gtranslator_module_new_object (GtranslatorModule *module);
+
+G_END_DECLS
+
+#endif
Added: branches/GOBJECT_WORK/src/plugin-system/plugin-info-priv.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-info-priv.h Sun Jan 13 08:12:00 2008
@@ -0,0 +1,77 @@
+/*
+ * plugin-info-priv.h
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2007. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id$
+ */
+
+#ifndef __GTR_PLUGIN_INFO_PRIV_H__
+#define __GTR_PLUGIN_INFO_PRIV_H__
+
+#include "plugin-info.h"
+#include "plugin.h"
+
+typedef enum
+{
+ GTR_PLUGIN_LOADER_C,
+ GTR_PLUGIN_LOADER_PY,
+} GtranslatorPluginLoader;
+
+struct _GtranslatorPluginInfo
+{
+ gint refcount;
+
+ gchar *file;
+
+ gchar *module_name;
+ GtranslatorPluginLoader loader;
+ GTypeModule *module;
+ gchar **dependencies;
+
+ gchar *name;
+ gchar *desc;
+ gchar *icon_name;
+ gchar **authors;
+ gchar *copyright;
+ gchar *website;
+
+ GtranslatorPlugin *plugin;
+
+ gint active : 1;
+
+ /* 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;
+};
+
+GtranslatorPluginInfo *_gtranslator_plugin_info_new (const gchar *file);
+void _gtranslator_plugin_info_ref (GtranslatorPluginInfo *info);
+void _gtranslator_plugin_info_unref (GtranslatorPluginInfo *info);
+
+
+#endif /* __GTR_PLUGIN_INFO_PRIV_H__ */
Added: branches/GOBJECT_WORK/src/plugin-system/plugin-info.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-info.c Sun Jan 13 08:12:00 2008
@@ -0,0 +1,372 @@
+/*
+ * plugin-info.c
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2007. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <glib/gkeyfile.h>
+
+#include "plugin-info.h"
+#include "plugin-info-priv.h"
+//#include "gtranslator-debug.h"
+#include "plugin.h"
+
+void
+_gtranslator_plugin_info_ref (GtranslatorPluginInfo *info)
+{
+ g_atomic_int_inc (&info->refcount);
+}
+
+static GtranslatorPluginInfo *
+gtranslator_plugin_info_copy (GtranslatorPluginInfo *info)
+{
+ _gtranslator_plugin_info_ref (info);
+ return info;
+}
+
+void
+_gtranslator_plugin_info_unref (GtranslatorPluginInfo *info)
+{
+ if (!g_atomic_int_dec_and_test (&info->refcount))
+ return;
+
+ if (info->plugin != NULL)
+ {
+ g_warning( "Unref plugin %s", info->name);
+
+ g_object_unref (info->plugin);
+
+ /* info->module must not be unref since it is not possible to finalize
+ * a type module */
+ }
+
+ 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_strfreev (info->authors);
+
+ g_free (info);
+}
+
+/**
+ * gtranslator_plugin_info_get_type:
+ *
+ * Retrieves the #GType object which is associated with the #GtranslatorPluginInfo
+ * class.
+ *
+ * Return value: the GType associated with #GtranslatorPluginInfo.
+ **/
+GType
+gtranslator_plugin_info_get_type (void)
+{
+ static GType the_type = 0;
+
+ if (G_UNLIKELY (!the_type))
+ the_type = g_boxed_type_register_static (
+ "GtranslatorPluginInfo",
+ (GBoxedCopyFunc) gtranslator_plugin_info_copy,
+ (GBoxedFreeFunc) _gtranslator_plugin_info_unref);
+
+ return the_type;
+}
+
+/**
+ * gtranslator_plugin_info_new:
+ * @filename: the filename where to read the plugin information
+ *
+ * Creates a new #GtranslatorPluginInfo from a file on the disk.
+ *
+ * Return value: a newly created #GtranslatorPluginInfo.
+ */
+GtranslatorPluginInfo *
+_gtranslator_plugin_info_new (const gchar *file)
+{
+ GtranslatorPluginInfo *info;
+ GKeyFile *plugin_file = NULL;
+ gchar *str;
+
+ g_return_val_if_fail (file != NULL, NULL);
+
+ g_warning( "Loading plugin: %s", file);
+
+ info = g_new0 (GtranslatorPluginInfo, 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,
+ "Gtranslator Plugin",
+ "IAge",
+ NULL))
+ {
+ g_warning(
+ "IAge key does not exist in file: %s", file);
+ goto error;
+ }
+
+ /* Check IAge=2 */
+ if (g_key_file_get_integer (plugin_file,
+ "Gtranslator Plugin",
+ "IAge",
+ NULL) != 2)
+ {
+ g_warning(
+ "Wrong IAge in file: %s", file);
+ goto error;
+ }
+
+ /* Get module name */
+ str = g_key_file_get_string (plugin_file,
+ "Gtranslator Plugin",
+ "Module",
+ NULL);
+
+ if ((str != NULL) && (*str != '\0'))
+ {
+ info->module_name = str;
+ }
+ else
+ {
+ g_warning ("Could not find 'Module' in %s", file);
+ goto error;
+ }
+
+ /* Get the dependency list */
+ info->dependencies = g_key_file_get_string_list (plugin_file,
+ "Gtranslator Plugin",
+ "Depends",
+ NULL,
+ NULL);
+ if (info->dependencies == NULL)
+ {
+ g_warning( "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,
+ "Gtranslator Plugin",
+ "Loader",
+ NULL);
+ if (str && strcmp(str, "python") == 0)
+ {
+ info->loader = GTR_PLUGIN_LOADER_PY;
+#ifndef ENABLE_PYTHON
+ g_warning ("Cannot load Python plugin '%s' since gtranslator was not "
+ "compiled with Python support.", file);
+ goto error;
+#endif
+ }
+ else
+ {
+ info->loader = GTR_PLUGIN_LOADER_C;
+ }
+ g_free (str);
+
+ /* Get Name */
+ str = g_key_file_get_locale_string (plugin_file,
+ "Gtranslator 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,
+ "Gtranslator Plugin",
+ "Description",
+ NULL, NULL);
+ if (str)
+ info->desc = str;
+ else
+ g_warning( "Could not find 'Description' in %s", file);
+
+ /* Get Icon */
+ str = g_key_file_get_locale_string (plugin_file,
+ "Gtranslator Plugin",
+ "Icon",
+ NULL, NULL);
+ if (str)
+ info->icon_name = str;
+ else
+ g_warning( "Could not find 'Icon' in %s, using 'plugin'", file);
+
+
+ /* Get Authors */
+ info->authors = g_key_file_get_string_list (plugin_file,
+ "Gtranslator Plugin",
+ "Authors",
+ NULL,
+ NULL);
+ if (info->authors == NULL)
+ g_warning( "Could not find 'Authors' in %s", file);
+
+
+ /* Get Copyright */
+ str = g_key_file_get_string (plugin_file,
+ "Gtranslator Plugin",
+ "Copyright",
+ NULL);
+ if (str)
+ info->copyright = str;
+ else
+ g_warning( "Could not find 'Copyright' in %s", file);
+
+ /* Get Website */
+ str = g_key_file_get_string (plugin_file,
+ "Gtranslator Plugin",
+ "Website",
+ NULL);
+ if (str)
+ info->website = str;
+ else
+ g_warning( "Could not find 'Website' 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);
+ g_key_file_free (plugin_file);
+
+ return NULL;
+}
+
+gboolean
+gtranslator_plugin_info_is_active (GtranslatorPluginInfo *info)
+{
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ return info->available && info->active;
+}
+
+gboolean
+gtranslator_plugin_info_is_available (GtranslatorPluginInfo *info)
+{
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ return info->available != FALSE;
+}
+
+gboolean
+gtranslator_plugin_info_is_configurable (GtranslatorPluginInfo *info)
+{
+ g_warning( "Is '%s' configurable?", info->name);
+
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ if (info->plugin == NULL || !info->active || !info->available)
+ return FALSE;
+
+ return gtranslator_plugin_is_configurable (info->plugin);
+}
+
+const gchar *
+gtranslator_plugin_info_get_name (GtranslatorPluginInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->name;
+}
+
+const gchar *
+gtranslator_plugin_info_get_description (GtranslatorPluginInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->desc;
+}
+
+const gchar *
+gtranslator_plugin_info_get_icon_name (GtranslatorPluginInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ /* use the 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 "plugin";
+}
+
+const gchar **
+gtranslator_plugin_info_get_authors (GtranslatorPluginInfo *info)
+{
+ g_return_val_if_fail (info != NULL, (const gchar **)NULL);
+
+ return (const gchar **) info->authors;
+}
+
+const gchar *
+gtranslator_plugin_info_get_website (GtranslatorPluginInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->website;
+}
+
+const gchar *
+gtranslator_plugin_info_get_copyright (GtranslatorPluginInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->copyright;
+}
Added: branches/GOBJECT_WORK/src/plugin-system/plugin-info.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-info.h Sun Jan 13 08:12:00 2008
@@ -0,0 +1,60 @@
+/*
+ * plugin-info.h
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2007. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id$
+ */
+
+#ifndef __GTR_PLUGIN_INFO_H__
+#define __GTR_PLUGIN_INFO_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_PLUGIN_INFO (gtranslator_plugin_info_get_type ())
+#define GTR_PLUGIN_INFO(obj) ((GtranslatorPluginInfo *) (obj))
+
+typedef struct _GtranslatorPluginInfo GtranslatorPluginInfo;
+
+GType gtranslator_plugin_info_get_type (void) G_GNUC_CONST;
+
+gboolean gtranslator_plugin_info_is_active (GtranslatorPluginInfo *info);
+gboolean gtranslator_plugin_info_is_available (GtranslatorPluginInfo *info);
+gboolean gtranslator_plugin_info_is_configurable (GtranslatorPluginInfo *info);
+
+const gchar *gtranslator_plugin_info_get_name (GtranslatorPluginInfo *info);
+const gchar *gtranslator_plugin_info_get_description (GtranslatorPluginInfo *info);
+const gchar *gtranslator_plugin_info_get_icon_name (GtranslatorPluginInfo *info);
+const gchar **gtranslator_plugin_info_get_authors (GtranslatorPluginInfo *info);
+const gchar *gtranslator_plugin_info_get_website (GtranslatorPluginInfo *info);
+const gchar *gtranslator_plugin_info_get_copyright (GtranslatorPluginInfo *info);
+
+G_END_DECLS
+
+#endif /* __GTR_PLUGIN_INFO_H__ */
+
Added: branches/GOBJECT_WORK/src/plugin-system/plugin-manager.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-manager.c Sun Jan 13 08:12:00 2008
@@ -0,0 +1,889 @@
+/*
+ * plugin-manager.c
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 1998-2006. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: plugin-manager.c 6079 2008-01-12 20:18:55Z sdeburca $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <glade/glade-xml.h>
+
+#include "plugin-manager.h"
+#include "utils_gui.h"
+#include "plugins-engine.h"
+#include "plugin.h"
+//#include "gtranslator-debug.h"
+
+enum
+{
+ ACTIVE_COLUMN,
+ AVAILABLE_COLUMN,
+ INFO_COLUMN,
+ N_COLUMNS
+};
+
+#define PLUGIN_MANAGER_NAME_TITLE _("Plugin")
+#define PLUGIN_MANAGER_ACTIVE_TITLE _("Enabled")
+
+#define GTR_PLUGIN_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GTR_TYPE_PLUGIN_MANAGER, GtranslatorPluginManagerPrivate))
+
+struct _GtranslatorPluginManagerPrivate
+{
+ GtkWidget *tree;
+
+ GtkWidget *about_button;
+ GtkWidget *configure_button;
+
+ GtranslatorPluginsEngine *engine;
+
+ GtkWidget *about;
+
+ GtkWidget *popup_menu;
+};
+
+G_DEFINE_TYPE(GtranslatorPluginManager, gtranslator_plugin_manager, GTK_TYPE_VBOX)
+
+static GtranslatorPluginInfo *plugin_manager_get_selected_plugin (GtranslatorPluginManager *pm);
+static void plugin_manager_toggle_active (GtranslatorPluginManager *pm, GtkTreeIter *iter, GtkTreeModel *model);
+static void gtranslator_plugin_manager_finalize (GObject *object);
+
+static void
+gtranslator_plugin_manager_class_init (GtranslatorPluginManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gtranslator_plugin_manager_finalize;
+
+ g_type_class_add_private (object_class, sizeof (GtranslatorPluginManagerPrivate));
+}
+
+static void
+about_button_cb (GtkWidget *button,
+ GtranslatorPluginManager *pm)
+{
+ GtranslatorPluginInfo *info;
+
+ //gtranslator_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,
+ "name", gtranslator_plugin_info_get_name (info),
+ "copyright", gtranslator_plugin_info_get_copyright (info),
+ "authors", gtranslator_plugin_info_get_authors (info),
+ "comments", gtranslator_plugin_info_get_description (info),
+ "website", gtranslator_plugin_info_get_website (info),
+ "logo-icon-name", gtranslator_plugin_info_get_icon_name (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,
+ GtranslatorPluginManager *pm)
+{
+ GtranslatorPluginInfo *info;
+ GtkWindow *toplevel;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ info = plugin_manager_get_selected_plugin (pm);
+
+ g_return_if_fail (info != NULL);
+
+ g_warning( "Configuring: %s\n",
+ gtranslator_plugin_info_get_name (info));
+
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(pm)));
+
+ gtranslator_plugins_engine_configure_plugin (pm->priv->engine,
+ info, toplevel);
+
+ g_warning( "Done");
+}
+
+static void
+plugin_manager_view_info_cell_cb (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GtranslatorPluginInfo *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 ("<b>%s</b>\n%s",
+ gtranslator_plugin_info_get_name (info),
+ gtranslator_plugin_info_get_description (info));
+ g_object_set (G_OBJECT (cell),
+ "markup", text,
+ "sensitive", gtranslator_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)
+{
+ GtranslatorPluginInfo *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", gtranslator_plugin_info_get_icon_name (info),
+ "sensitive", gtranslator_plugin_info_is_available (info),
+ NULL);
+}
+
+
+static void
+active_toggled_cb (GtkCellRendererToggle *cell,
+ gchar *path_str,
+ GtranslatorPluginManager *pm)
+{
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkTreeModel *model;
+
+ //gtranslator_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)
+{
+ GtranslatorPluginManager *pm = data;
+ GtranslatorPluginInfo *info;
+
+ //gtranslator_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) &&
+ gtranslator_plugin_info_is_configurable (info));
+}
+
+static void
+row_activated_cb (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ gpointer data)
+{
+ GtranslatorPluginManager *pm = data;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ //gtranslator_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 (GtranslatorPluginManager *pm)
+{
+ const GList *plugins;
+ GtkListStore *model;
+ GtkTreeIter iter;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ plugins = gtranslator_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)
+ {
+ GtranslatorPluginInfo *info;
+ info = (GtranslatorPluginInfo *)plugins->data;
+
+ gtk_list_store_append (model, &iter);
+ gtk_list_store_set (model, &iter,
+ ACTIVE_COLUMN, gtranslator_plugin_info_is_active (info),
+ AVAILABLE_COLUMN, gtranslator_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;
+ GtranslatorPluginInfo* 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),
+ gtranslator_plugin_info_is_configurable (info));
+ }
+}
+
+static gboolean
+plugin_manager_set_active (GtranslatorPluginManager *pm,
+ GtkTreeIter *iter,
+ GtkTreeModel *model,
+ gboolean active)
+{
+ GtranslatorPluginInfo *info;
+ gboolean res = TRUE;
+
+ //gtranslator_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 (!gtranslator_plugins_engine_activate_plugin (pm->priv->engine, info)) {
+ g_warning( "Could not activate %s.\n",
+ gtranslator_plugin_info_get_name (info));
+
+ res = FALSE;
+ }
+ }
+ else
+ {
+ /* deactivate the plugin */
+ if (!gtranslator_plugins_engine_deactivate_plugin (pm->priv->engine, info)) {
+ g_warning( "Could not deactivate %s.\n",
+ gtranslator_plugin_info_get_name (info));
+
+ res = FALSE;
+ }
+ }
+
+ return res;
+}
+
+static void
+plugin_manager_toggle_active (GtranslatorPluginManager *pm,
+ GtkTreeIter *iter,
+ GtkTreeModel *model)
+{
+ gboolean active;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ gtk_tree_model_get (model, iter, ACTIVE_COLUMN, &active, -1);
+
+ active ^= 1;
+
+ plugin_manager_set_active (pm, iter, model, active);
+}
+
+static GtranslatorPluginInfo *
+plugin_manager_get_selected_plugin (GtranslatorPluginManager *pm)
+{
+ GtranslatorPluginInfo *info = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+
+ //gtranslator_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 (GtranslatorPluginManager *pm,
+ gboolean active)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ //gtranslator_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)
+{
+ GtranslatorPluginInfo *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 (gtranslator_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,
+ GtranslatorPluginManager *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,
+ GtranslatorPluginManager *pm)
+{
+ plugin_manager_set_active_all (pm, TRUE);
+}
+
+static void
+disable_all_menu_cb (GtkMenu *menu,
+ GtranslatorPluginManager *pm)
+{
+ plugin_manager_set_active_all (pm, FALSE);
+}
+
+static GtkWidget *
+create_tree_popup_menu (GtranslatorPluginManager *pm)
+{
+ GtkWidget *menu;
+ GtkWidget *item;
+ GtkWidget *image;
+ GtranslatorPluginInfo *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, gtranslator_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, gtranslator_plugin_info_is_available (info));
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
+ gtranslator_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 (GtranslatorPluginManager *pm,
+ GtkMenu *menu)
+{
+ pm->priv->popup_menu = NULL;
+}
+
+static void
+show_tree_popup_menu (GtkTreeView *tree,
+ GtranslatorPluginManager *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,
+ gtranslator_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,
+ GtranslatorPluginManager *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,
+ GtranslatorPluginManager *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)
+{
+ GtranslatorPluginInfo *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 (gtranslator_plugin_info_get_name (info1),
+ gtranslator_plugin_info_get_name (info2));
+}
+
+static void
+plugin_manager_construct_tree (GtranslatorPluginManager *pm)
+{
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell;
+ GtkListStore *model;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ model = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, GTR_TYPE_PLUGIN_INFO);
+
+ 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 (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info,
+ GtranslatorPluginManager *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! */
+ GtranslatorPluginInfo *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
+ {
+ GtranslatorPluginInfo *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 ("GtranslatorPluginManager: plugin '%s' not found in the tree model",
+ gtranslator_plugin_info_get_name (info));
+ return;
+ }
+
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, ACTIVE_COLUMN, gtranslator_plugin_info_is_active (info), -1);
+}
+
+static void
+gtranslator_plugin_manager_init (GtranslatorPluginManager *pm)
+{
+ GtkWidget *label;
+ GtkWidget *alignment;
+ GtkWidget *viewport;
+ GtkWidget *hbuttonbox;
+ gchar *markup;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ pm->priv = GTR_PLUGIN_MANAGER_GET_PRIVATE (pm);
+
+ gtk_box_set_spacing (GTK_BOX (pm), 6);
+
+ label = gtk_label_new (NULL);
+ markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
+ _("Active plugins"));
+ gtk_label_set_markup (GTK_LABEL (label), markup);
+ g_free (markup);
+ 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);
+
+ alignment = gtk_alignment_new (0., 0., 1., 1.);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+ gtk_box_pack_start (GTK_BOX (pm), alignment, TRUE, 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_container_add (GTK_CONTAINER (alignment), viewport);
+
+ pm->priv->tree = gtk_tree_view_new ();
+ gtk_container_add (GTK_CONTAINER (viewport), pm->priv->tree);
+
+ hbuttonbox = gtk_hbutton_box_new ();
+ 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 = gtranslator_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 = gtranslator_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 = gtranslator_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 (gtranslator_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
+gtranslator_plugin_manager_finalize (GObject *object)
+{
+ GtranslatorPluginManager *pm = GTR_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 (gtranslator_plugin_manager_parent_class)->finalize (object);
+
+}
+
+GtkWidget *gtranslator_plugin_manager_new (void)
+{
+ return g_object_new (GTR_TYPE_PLUGIN_MANAGER,0);
+}
Added: branches/GOBJECT_WORK/src/plugin-system/plugin-manager.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin-manager.h Sun Jan 13 08:12:00 2008
@@ -0,0 +1,83 @@
+/*
+ * plugin-manager.h
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: plugin-manager.h 5666 2007-06-29 19:52:25Z sfre $
+ */
+
+#ifndef __GTR_PLUGIN_MANAGER_H__
+#define __GTR_PLUGIN_MANAGER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_PLUGIN_MANAGER (gtranslator_plugin_manager_get_type())
+#define GTR_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTR_TYPE_PLUGIN_MANAGER, GtranslatorPluginManager))
+#define GTR_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTR_TYPE_PLUGIN_MANAGER, GtranslatorPluginManagerClass))
+#define GTR_IS_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTR_TYPE_PLUGIN_MANAGER))
+#define GTR_IS_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_PLUGIN_MANAGER))
+#define GTR_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_PLUGIN_MANAGER, GtranslatorPluginManagerClass))
+
+/* Private structure type */
+typedef struct _GtranslatorPluginManagerPrivate GtranslatorPluginManagerPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorPluginManager GtranslatorPluginManager;
+
+struct _GtranslatorPluginManager
+{
+ GtkVBox vbox;
+
+ /*< private > */
+ GtranslatorPluginManagerPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorPluginManagerClass GtranslatorPluginManagerClass;
+
+struct _GtranslatorPluginManagerClass
+{
+ GtkVBoxClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType gtranslator_plugin_manager_get_type (void) G_GNUC_CONST;
+
+GtkWidget *gtranslator_plugin_manager_new (void);
+
+G_END_DECLS
+
+#endif /* __GTR_PLUGIN_MANAGER_H__ */
Added: branches/GOBJECT_WORK/src/plugin-system/plugin.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin.c Sun Jan 13 08:12:00 2008
@@ -0,0 +1,119 @@
+/*
+ * plugin.h
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: plugin.c 4509 2006-01-06 16:45:20Z pborelli $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "plugin.h"
+
+G_DEFINE_TYPE(GtranslatorPlugin, gtranslator_plugin, G_TYPE_OBJECT)
+
+static void
+dummy (GtranslatorPlugin *plugin, GtranslatorWindow *window)
+{
+ /* Empty */
+}
+
+static GtkWidget *
+create_configure_dialog (GtranslatorPlugin *plugin)
+{
+ return NULL;
+}
+
+static gboolean
+is_configurable (GtranslatorPlugin *plugin)
+{
+ return (GTR_PLUGIN_GET_CLASS (plugin)->create_configure_dialog !=
+ create_configure_dialog);
+}
+
+static void
+gtranslator_plugin_class_init (GtranslatorPluginClass *klass)
+{
+ klass->activate = dummy;
+ klass->deactivate = dummy;
+ klass->update_ui = dummy;
+
+ klass->create_configure_dialog = create_configure_dialog;
+ klass->is_configurable = is_configurable;
+}
+
+static void
+gtranslator_plugin_init (GtranslatorPlugin *plugin)
+{
+ /* Empty */
+}
+
+void
+gtranslator_plugin_activate (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window)
+{
+ g_return_if_fail (GTR_IS_PLUGIN (plugin));
+ g_return_if_fail (GTR_IS_WINDOW (window));
+
+ GTR_PLUGIN_GET_CLASS (plugin)->activate (plugin, window);
+}
+
+void
+gtranslator_plugin_deactivate (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window)
+{
+ g_return_if_fail (GTR_IS_PLUGIN (plugin));
+ g_return_if_fail (GTR_IS_WINDOW (window));
+
+ GTR_PLUGIN_GET_CLASS (plugin)->deactivate (plugin, window);
+}
+
+void
+gtranslator_plugin_update_ui (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window)
+{
+ g_return_if_fail (GTR_IS_PLUGIN (plugin));
+ g_return_if_fail (GTR_IS_WINDOW (window));
+
+ GTR_PLUGIN_GET_CLASS (plugin)->update_ui (plugin, window);
+}
+
+gboolean
+gtranslator_plugin_is_configurable (GtranslatorPlugin *plugin)
+{
+ g_return_val_if_fail (GTR_IS_PLUGIN (plugin), FALSE);
+
+ return GTR_PLUGIN_GET_CLASS (plugin)->is_configurable (plugin);
+}
+
+GtkWidget *
+gtranslator_plugin_create_configure_dialog (GtranslatorPlugin *plugin)
+{
+ g_return_val_if_fail (GTR_IS_PLUGIN (plugin), NULL);
+
+ return GTR_PLUGIN_GET_CLASS (plugin)->create_configure_dialog (plugin);
+}
Added: branches/GOBJECT_WORK/src/plugin-system/plugin.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugin.h Sun Jan 13 08:12:00 2008
@@ -0,0 +1,245 @@
+/*
+ * plugin.h
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: plugin.h 5666 2007-06-29 19:52:25Z sfre $
+ */
+
+#ifndef __GTR_PLUGIN_H__
+#define __GTR_PLUGIN_H__
+
+#include <glib-object.h>
+
+#include "window.h"
+//#include <gtranslator/gtranslator-debug.h>
+
+/* 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 GTR_TYPE_PLUGIN (gtranslator_plugin_get_type())
+#define GTR_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTR_TYPE_PLUGIN, GtranslatorPlugin))
+#define GTR_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTR_TYPE_PLUGIN, GtranslatorPluginClass))
+#define GTR_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTR_TYPE_PLUGIN))
+#define GTR_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_PLUGIN))
+#define GTR_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_PLUGIN, GtranslatorPluginClass))
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorPlugin GtranslatorPlugin;
+
+struct _GtranslatorPlugin
+{
+ GObject parent;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorPluginClass GtranslatorPluginClass;
+
+struct _GtranslatorPluginClass
+{
+ GObjectClass parent_class;
+
+ /* Virtual public methods */
+
+ void (*activate) (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window);
+ void (*deactivate) (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window);
+
+ void (*update_ui) (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window);
+
+ GtkWidget *(*create_configure_dialog)
+ (GtranslatorPlugin *plugin);
+
+ /* Plugins should not override this, it's handled automatically by
+ the GtranslatorPluginClass */
+ gboolean (*is_configurable)
+ (GtranslatorPlugin *plugin);
+
+ /* Padding for future expansion */
+ void (*_gtranslator_reserved1) (void);
+ void (*_gtranslator_reserved2) (void);
+ void (*_gtranslator_reserved3) (void);
+ void (*_gtranslator_reserved4) (void);
+};
+
+/*
+ * Public methods
+ */
+GType gtranslator_plugin_get_type (void) G_GNUC_CONST;
+
+void gtranslator_plugin_activate (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window);
+void gtranslator_plugin_deactivate (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window);
+
+void gtranslator_plugin_update_ui (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window);
+
+gboolean gtranslator_plugin_is_configurable (GtranslatorPlugin *plugin);
+GtkWidget *gtranslator_plugin_create_configure_dialog
+ (GtranslatorPlugin *plugin);
+
+/*
+ * Utility macro used to register plugins
+ *
+ * use: GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE)
+ */
+#define GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE) \
+ \
+static GType plugin_name##_type = 0; \
+ \
+GType \
+plugin_name##_get_type (void) \
+{ \
+ return plugin_name##_type; \
+} \
+ \
+static void plugin_name##_init (PluginName *self); \
+static void plugin_name##_class_init (PluginName##Class *klass); \
+static gpointer plugin_name##_parent_class = NULL; \
+static void plugin_name##_class_intern_init (gpointer klass) \
+{ \
+ plugin_name##_parent_class = g_type_class_peek_parent (klass); \
+ plugin_name##_class_init ((PluginName##Class *) klass); \
+} \
+ \
+G_MODULE_EXPORT GType \
+register_gtranslator_plugin (GTypeModule *module) \
+{ \
+ static const GTypeInfo our_info = \
+ { \
+ sizeof (PluginName##Class), \
+ NULL, /* base_init */ \
+ NULL, /* base_finalize */ \
+ (GClassInitFunc) plugin_name##_class_intern_init, \
+ NULL, \
+ NULL, /* class_data */ \
+ sizeof (PluginName), \
+ 0, /* n_preallocs */ \
+ (GInstanceInitFunc) plugin_name##_init \
+ }; \
+ \
+ g_warning( "Registering " #PluginName); \
+ \
+ /* Initialise the i18n stuff */ \
+ bindtextdomain (GETTEXT_PACKAGE, GTR_LOCALEDIR); \
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); \
+ \
+ plugin_name##_type = g_type_module_register_type (module, \
+ GTR_TYPE_PLUGIN, \
+ #PluginName, \
+ &our_info, \
+ 0); \
+ \
+ CODE \
+ \
+ return plugin_name##_type; \
+}
+
+/*
+ * Utility macro used to register plugins
+ *
+ * use: GTR_PLUGIN_REGISTER_TYPE(PluginName, plugin_name)
+ */
+#define GTR_PLUGIN_REGISTER_TYPE(PluginName, plugin_name) \
+ GTR_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, ;)
+
+/*
+ * Utility macro used to register gobject types in plugins with additional code
+ *
+ * use: GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, CODE)
+ */
+#define GTR_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 *module) \
+{ \
+ 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_warning( "Registering " #ObjectName); \
+ \
+ g_define_type_id = g_type_module_register_type (module, \
+ PARENT_TYPE, \
+ #ObjectName, \
+ &our_info, \
+ 0); \
+ \
+ CODE \
+ \
+ return g_define_type_id; \
+}
+
+/*
+ * Utility macro used to register gobject types in plugins
+ *
+ * use: GTR_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE)
+ */
+#define GTR_PLUGIN_DEFINE_TYPE(ObjectName, object_name, PARENT_TYPE) \
+ GTR_PLUGIN_DEFINE_TYPE_WITH_CODE(ObjectName, object_name, PARENT_TYPE, ;)
+
+G_END_DECLS
+
+#endif /* __GTR_PLUGIN_H__ */
+
+
Added: branches/GOBJECT_WORK/src/plugin-system/plugins-engine.c
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugins-engine.c Sun Jan 13 08:12:00 2008
@@ -0,0 +1,693 @@
+/*
+ * plugins-engine.c
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: plugins-engine.c 6052 2008-01-04 17:32:52Z sfre $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <gconf/gconf-client.h>
+
+#include "plugins-engine.h"
+#include "plugin-info-priv.h"
+#include "plugin.h"
+//#include "gtranslator-debug.h"
+#include "application.h"
+
+#include "module.h"
+#ifdef ENABLE_PYTHON
+#include "gtranslator-python-module.h"
+#endif
+
+#define USER_GTR_PLUGINS_LOCATION ".gtranslator/plugins/"
+
+#define GTR_PLUGINS_ENGINE_BASE_KEY "/apps/gtranslator/plugins"
+#define GTR_PLUGINS_ENGINE_KEY GTR_PLUGINS_ENGINE_BASE_KEY "/active-plugins"
+
+#define PLUGIN_EXT ".plugin"
+
+/* Signals */
+enum
+{
+ ACTIVATE_PLUGIN,
+ DEACTIVATE_PLUGIN,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE(GtranslatorPluginsEngine, gtranslator_plugins_engine, G_TYPE_OBJECT)
+
+struct _GtranslatorPluginsEnginePrivate
+{
+ GList *plugin_list;
+ GConfClient *gconf_client;
+};
+
+GtranslatorPluginsEngine *default_engine = NULL;
+
+static void gtranslator_plugins_engine_active_plugins_changed (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data);
+static void gtranslator_plugins_engine_activate_plugin_real (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info);
+static void gtranslator_plugins_engine_deactivate_plugin_real (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info);
+
+static gint
+compare_plugin_info (GtranslatorPluginInfo *info1,
+ GtranslatorPluginInfo *info2)
+{
+ return strcmp (info1->module_name, info2->module_name);
+}
+
+static void
+gtranslator_plugins_engine_load_dir (GtranslatorPluginsEngine *engine,
+ const gchar *dir,
+ GSList *active_plugins)
+{
+ GError *error = NULL;
+ GDir *d;
+ const gchar *dirent;
+
+ g_return_if_fail (engine->priv->gconf_client != NULL);
+ g_return_if_fail (dir != NULL);
+
+ g_warning( "DIR: %s", dir);
+
+ d = g_dir_open (dir, 0, &error);
+ if (!d)
+ {
+ g_warning (error->message);
+ g_error_free (error);
+ return;
+ }
+
+ while ((dirent = g_dir_read_name (d)))
+ {
+ if (g_str_has_suffix (dirent, PLUGIN_EXT))
+ {
+ gchar *plugin_file;
+ GtranslatorPluginInfo *info;
+
+ plugin_file = g_build_filename (dir, dirent, NULL);
+ info = _gtranslator_plugin_info_new (plugin_file);
+ g_free (plugin_file);
+
+ if (info == NULL)
+ continue;
+
+ /* If a plugin with this name has already been loaded
+ * drop this one (user plugins override system plugins) */
+ if (g_list_find_custom (engine->priv->plugin_list,
+ info,
+ (GCompareFunc)compare_plugin_info) != NULL)
+ {
+ g_warning ("Two or more plugins named '%s'. "
+ "Only the first will be considered.\n",
+ info->module_name);
+
+ _gtranslator_plugin_info_unref (info);
+
+ continue;
+ }
+
+ /* Actually, the plugin will be activated when reactivate_all
+ * will be called for the first time. */
+ info->active = g_slist_find_custom (active_plugins,
+ info->module_name,
+ (GCompareFunc)strcmp) != NULL;
+
+ engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info);
+
+ g_warning( "Plugin %s loaded", info->name);
+ }
+ }
+
+ g_dir_close (d);
+}
+
+static void
+gtranslator_plugins_engine_load_all (GtranslatorPluginsEngine *engine)
+{
+ GSList *active_plugins;
+ const gchar *home;
+ const gchar *pdirs_env;
+ gchar **pdirs;
+ int i;
+
+ active_plugins = gconf_client_get_list (engine->priv->gconf_client,
+ GTR_PLUGINS_ENGINE_KEY,
+ GCONF_VALUE_STRING,
+ NULL);
+
+ /* load user's plugins */
+ home = g_get_home_dir ();
+ if (home == NULL)
+ {
+ g_warning ("Could not get HOME directory\n");
+ }
+ else
+ {
+ gchar *pdir;
+
+ pdir = g_build_filename (home,
+ USER_GTR_PLUGINS_LOCATION,
+ NULL);
+
+ if (g_file_test (pdir, G_FILE_TEST_IS_DIR))
+ gtranslator_plugins_engine_load_dir (engine, pdir, active_plugins);
+
+ g_free (pdir);
+ }
+
+ pdirs_env = g_getenv ("GTR_PLUGINS_PATH");
+ /* What if no env var is set? We use the default location(s)! */
+ if (pdirs_env == NULL)
+ pdirs_env = GTR_PLUGINDIR;
+
+ g_warning( "GTR_PLUGINS_PATH=%s", pdirs_env);
+ pdirs = g_strsplit (pdirs_env, G_SEARCHPATH_SEPARATOR_S, 0);
+
+ for (i = 0; pdirs[i] != NULL; i++)
+ gtranslator_plugins_engine_load_dir (engine, pdirs[i], active_plugins);
+
+ g_strfreev (pdirs);
+}
+
+static void
+gtranslator_plugins_engine_init (GtranslatorPluginsEngine *engine)
+{
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ if (!g_module_supported ())
+ {
+ g_warning ("gtranslator is not able to initialize the plugins engine.");
+ return;
+ }
+
+ engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine,
+ GTR_TYPE_PLUGINS_ENGINE,
+ GtranslatorPluginsEnginePrivate);
+
+ engine->priv->gconf_client = gconf_client_get_default ();
+ g_return_if_fail (engine->priv->gconf_client != NULL);
+
+ gconf_client_add_dir (engine->priv->gconf_client,
+ GTR_PLUGINS_ENGINE_BASE_KEY,
+ GCONF_CLIENT_PRELOAD_ONELEVEL,
+ NULL);
+
+ gconf_client_notify_add (engine->priv->gconf_client,
+ GTR_PLUGINS_ENGINE_KEY,
+ gtranslator_plugins_engine_active_plugins_changed,
+ engine, NULL, NULL);
+
+ gtranslator_plugins_engine_load_all (engine);
+}
+
+void
+gtranslator_plugins_engine_garbage_collect (GtranslatorPluginsEngine *engine)
+{
+#ifdef ENABLE_PYTHON
+ gtranslator_python_garbage_collect ();
+#endif
+}
+
+static void
+gtranslator_plugins_engine_finalize (GObject *object)
+{
+ GtranslatorPluginsEngine *engine = GTR_PLUGINS_ENGINE (object);
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+#ifdef ENABLE_PYTHON
+ /* Note: that this may cause finalization of objects (typically
+ * the GtranslatorWindow) by running the garbage collector. Since some
+ * of the plugin may have installed callbacks upon object
+ * finalization (typically they need to free the WindowData)
+ * it must run before we get rid of the plugins.
+ */
+ gtranslator_python_shutdown ();
+#endif
+
+ g_return_if_fail (engine->priv->gconf_client != NULL);
+
+ g_list_foreach (engine->priv->plugin_list,
+ (GFunc) _gtranslator_plugin_info_unref, NULL);
+ g_list_free (engine->priv->plugin_list);
+
+ g_object_unref (engine->priv->gconf_client);
+}
+
+static void
+gtranslator_plugins_engine_class_init (GtranslatorPluginsEngineClass *klass)
+{
+ GType the_type = G_TYPE_FROM_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gtranslator_plugins_engine_finalize;
+ klass->activate_plugin = gtranslator_plugins_engine_activate_plugin_real;
+ klass->deactivate_plugin = gtranslator_plugins_engine_deactivate_plugin_real;
+
+ signals[ACTIVATE_PLUGIN] =
+ g_signal_new ("activate-plugin",
+ the_type,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtranslatorPluginsEngineClass, activate_plugin),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ GTR_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 (GtranslatorPluginsEngineClass, deactivate_plugin),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ GTR_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ g_type_class_add_private (klass, sizeof (GtranslatorPluginsEnginePrivate));
+}
+
+GtranslatorPluginsEngine *
+gtranslator_plugins_engine_get_default (void)
+{
+ if (default_engine != NULL)
+ return default_engine;
+
+ default_engine = GTR_PLUGINS_ENGINE (g_object_new (GTR_TYPE_PLUGINS_ENGINE, NULL));
+ g_object_add_weak_pointer (G_OBJECT (default_engine),
+ (gpointer) &default_engine);
+ return default_engine;
+}
+
+const GList *
+gtranslator_plugins_engine_get_plugin_list (GtranslatorPluginsEngine *engine)
+{
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ return engine->priv->plugin_list;
+}
+
+static gboolean
+load_plugin_module (GtranslatorPluginInfo *info)
+{
+ gchar *path;
+ gchar *dirname;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ g_return_val_if_fail (info != NULL, FALSE);
+ g_return_val_if_fail (info->file != NULL, FALSE);
+ g_return_val_if_fail (info->module_name != NULL, FALSE);
+ g_return_val_if_fail (info->plugin == NULL, FALSE);
+ g_return_val_if_fail (info->available, FALSE);
+
+ switch (info->loader)
+ {
+ case GTR_PLUGIN_LOADER_C:
+ dirname = g_path_get_dirname (info->file);
+ g_return_val_if_fail (dirname != NULL, FALSE);
+
+ path = g_module_build_path (dirname, info->module_name);
+ g_free (dirname);
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ info->module = G_TYPE_MODULE (gtranslator_module_new (path));
+ g_free (path);
+
+ break;
+
+#ifdef ENABLE_PYTHON
+ case GTR_PLUGIN_LOADER_PY:
+ {
+ gchar *dir;
+
+ if (!gtranslator_python_init ())
+ {
+ /* Mark plugin as unavailable and fails */
+ info->available = FALSE;
+
+ g_warning ("Cannot load Python plugin '%s' since gtranslator "
+ "was not able to initialize the Python interpreter.",
+ info->name);
+
+ return FALSE;
+ }
+
+ dir = g_path_get_dirname (info->file);
+
+ g_return_val_if_fail ((info->module_name != NULL) &&
+ (info->module_name[0] != '\0'),
+ FALSE);
+
+ info->module = G_TYPE_MODULE (
+ gtranslator_python_module_new (dir, info->module_name));
+
+ g_free (dir);
+ break;
+ }
+#endif
+ default:
+ g_return_val_if_reached (FALSE);
+ }
+
+ if (!g_type_module_use (info->module))
+ {
+ switch (info->loader)
+ {
+ case GTR_PLUGIN_LOADER_C:
+ g_warning ("Cannot load plugin '%s' since file '%s' cannot be read.",
+ info->name,
+ gtranslator_module_get_path (GTR_MODULE (info->module)));
+ break;
+
+ case GTR_PLUGIN_LOADER_PY:
+ g_warning ("Cannot load Python plugin '%s' since file '%s' cannot be read.",
+ info->name,
+ info->module_name);
+ break;
+
+ default:
+ g_return_val_if_reached (FALSE);
+ }
+
+ g_object_unref (G_OBJECT (info->module));
+ info->module = NULL;
+
+ /* Mark plugin as unavailable and fails */
+ info->available = FALSE;
+
+ return FALSE;
+ }
+
+ switch (info->loader)
+ {
+ case GTR_PLUGIN_LOADER_C:
+ info->plugin =
+ GTR_PLUGIN (gtranslator_module_new_object (GTR_MODULE (info->module)));
+ break;
+
+#ifdef ENABLE_PYTHON
+ case GTR_PLUGIN_LOADER_PY:
+ info->plugin =
+ GTR_PLUGIN (gtranslator_python_module_new_object (GTR_PYTHON_MODULE (info->module)));
+ break;
+#endif
+
+ default:
+ g_return_val_if_reached (FALSE);
+ }
+
+ g_type_module_unuse (info->module);
+
+ g_warning( "End");
+
+ return TRUE;
+}
+
+static void
+save_active_plugin_list (GtranslatorPluginsEngine *engine)
+{
+ GSList *active_plugins = NULL;
+ GList *l;
+ gboolean res;
+
+ for (l = engine->priv->plugin_list; l != NULL; l = l->next)
+ {
+ const GtranslatorPluginInfo *info = (const GtranslatorPluginInfo *) l->data;
+ if (info->active)
+ {
+ active_plugins = g_slist_prepend (active_plugins,
+ info->module_name);
+ }
+ }
+
+ res = gconf_client_set_list (engine->priv->gconf_client,
+ GTR_PLUGINS_ENGINE_KEY,
+ GCONF_VALUE_STRING,
+ active_plugins,
+ NULL);
+
+ if (!res)
+ g_warning ("Error saving the list of active plugins.");
+
+ g_slist_free (active_plugins);
+}
+
+static void
+gtranslator_plugins_engine_activate_plugin_real (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info)
+{
+ gboolean res = TRUE;
+
+ if (info->active || !info->available)
+ return;
+
+ if (info->plugin == NULL)
+ res = load_plugin_module (info);
+
+ if (res)
+ {
+ const GList *wins = gtranslator_application_get_windows (gtranslator_application_get_default ());
+ for (; wins != NULL; wins = wins->next)
+ gtranslator_plugin_activate (info->plugin, GTR_WINDOW (wins->data));
+
+ info->active = TRUE;
+ }
+ else
+ g_warning ("Error activating plugin '%s'", info->name);
+}
+
+gboolean
+gtranslator_plugins_engine_activate_plugin (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info)
+{
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ if (!info->available)
+ return FALSE;
+
+ if (info->active)
+ return TRUE;
+
+ g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
+ if (info->active)
+ save_active_plugin_list (engine);
+
+ return info->active;
+}
+
+static void
+gtranslator_plugins_engine_deactivate_plugin_real (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info)
+{
+ const GList *wins;
+
+ if (!info->active || !info->available)
+ return;
+
+ wins = gtranslator_application_get_windows (gtranslator_application_get_default ());
+ for (; wins != NULL; wins = wins->next)
+ gtranslator_plugin_deactivate (info->plugin, GTR_WINDOW (wins->data));
+
+ info->active = FALSE;
+}
+
+gboolean
+gtranslator_plugins_engine_deactivate_plugin (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info)
+{
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ if (!info->active || !info->available)
+ return TRUE;
+
+ g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info);
+ if (!info->active)
+ save_active_plugin_list (engine);
+
+ return !info->active;
+}
+
+static void
+reactivate_all (GtranslatorPluginsEngine *engine,
+ GtranslatorWindow *window)
+{
+ GList *pl;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ for (pl = engine->priv->plugin_list; pl; pl = pl->next)
+ {
+ gboolean res = TRUE;
+
+ GtranslatorPluginInfo *info = (GtranslatorPluginInfo*)pl->data;
+
+ /* If plugin is not available, don't try to activate/load it */
+ if (info->available && info->active)
+ {
+ if (info->plugin == NULL)
+ res = load_plugin_module (info);
+
+ if (res)
+ gtranslator_plugin_activate (info->plugin,
+ window);
+ }
+ }
+
+ g_warning( "End");
+}
+
+void
+gtranslator_plugins_engine_update_plugins_ui (GtranslatorPluginsEngine *engine,
+ GtranslatorWindow *window,
+ gboolean new_window)
+{
+ GList *pl;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ g_return_if_fail (GTR_IS_WINDOW (window));
+
+ if (new_window)
+ reactivate_all (engine, window);
+
+ /* updated ui of all the plugins that implement update_ui */
+ for (pl = engine->priv->plugin_list; pl; pl = pl->next)
+ {
+ GtranslatorPluginInfo *info = (GtranslatorPluginInfo*)pl->data;
+
+ if (!info->available || !info->active)
+ continue;
+
+ g_warning( "Updating UI of %s", info->name);
+
+ gtranslator_plugin_update_ui (info->plugin, window);
+ }
+}
+
+void
+gtranslator_plugins_engine_configure_plugin (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info,
+ GtkWindow *parent)
+{
+ GtkWidget *conf_dlg;
+
+ GtkWindowGroup *wg;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ g_return_if_fail (info != NULL);
+
+ conf_dlg = gtranslator_plugin_create_configure_dialog (info->plugin);
+ g_return_if_fail (conf_dlg != NULL);
+ gtk_window_set_transient_for (GTK_WINDOW (conf_dlg),
+ parent);
+
+ wg = parent->group;
+ 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);
+}
+
+static void
+gtranslator_plugins_engine_active_plugins_changed (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data)
+{
+ GtranslatorPluginsEngine *engine;
+ GList *pl;
+ gboolean to_activate;
+ GSList *active_plugins;
+
+ //gtranslator_debug (DEBUG_PLUGINS);
+
+ g_return_if_fail (entry->key != NULL);
+ g_return_if_fail (entry->value != NULL);
+
+ engine = GTR_PLUGINS_ENGINE (user_data);
+
+ if (!((entry->value->type == GCONF_VALUE_LIST) &&
+ (gconf_value_get_list_type (entry->value) == GCONF_VALUE_STRING)))
+ {
+ g_warning ("The gconf key '%s' may be corrupted.", GTR_PLUGINS_ENGINE_KEY);
+ return;
+ }
+
+ active_plugins = gconf_client_get_list (engine->priv->gconf_client,
+ GTR_PLUGINS_ENGINE_KEY,
+ GCONF_VALUE_STRING,
+ NULL);
+
+ for (pl = engine->priv->plugin_list; pl; pl = pl->next)
+ {
+ GtranslatorPluginInfo *info = (GtranslatorPluginInfo*)pl->data;
+
+ if (!info->available)
+ continue;
+
+ to_activate = (g_slist_find_custom (active_plugins,
+ info->module_name,
+ (GCompareFunc)strcmp) != NULL);
+
+ if (!info->active && to_activate)
+ g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info);
+ else if (info->active && !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);
+}
+
+
Added: branches/GOBJECT_WORK/src/plugin-system/plugins-engine.h
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/plugins-engine.h Sun Jan 13 08:12:00 2008
@@ -0,0 +1,97 @@
+/*
+ * plugins-engine.h
+ * This file is part of gtranslator
+ *
+ * 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gtranslator Team, 2002-2005. See the AUTHORS file for a
+ * list of people on the gtranslator Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: plugins-engine.h 6045 2007-12-28 20:45:22Z sfre $
+ */
+
+#ifndef __GTR_PLUGINS_ENGINE_H__
+#define __GTR_PLUGINS_ENGINE_H__
+
+#include <glib.h>
+#include "window.h"
+#include "plugin-info.h"
+#include "plugin.h"
+
+G_BEGIN_DECLS
+
+#define GTR_TYPE_PLUGINS_ENGINE (gtranslator_plugins_engine_get_type ())
+#define GTR_PLUGINS_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTR_TYPE_PLUGINS_ENGINE, GtranslatorPluginsEngine))
+#define GTR_PLUGINS_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTR_TYPE_PLUGINS_ENGINE, GtranslatorPluginsEngineClass))
+#define GTR_IS_PLUGINS_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTR_TYPE_PLUGINS_ENGINE))
+#define GTR_IS_PLUGINS_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTR_TYPE_PLUGINS_ENGINE))
+#define GTR_PLUGINS_ENGINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTR_TYPE_PLUGINS_ENGINE, GtranslatorPluginsEngineClass))
+
+typedef struct _GtranslatorPluginsEngine GtranslatorPluginsEngine;
+typedef struct _GtranslatorPluginsEnginePrivate GtranslatorPluginsEnginePrivate;
+
+struct _GtranslatorPluginsEngine
+{
+ GObject parent;
+ GtranslatorPluginsEnginePrivate *priv;
+};
+
+typedef struct _GtranslatorPluginsEngineClass GtranslatorPluginsEngineClass;
+
+struct _GtranslatorPluginsEngineClass
+{
+ GObjectClass parent_class;
+
+ void (* activate_plugin) (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info);
+
+ void (* deactivate_plugin) (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info);
+};
+
+GType gtranslator_plugins_engine_get_type (void) G_GNUC_CONST;
+
+GtranslatorPluginsEngine *gtranslator_plugins_engine_get_default (void);
+
+void gtranslator_plugins_engine_garbage_collect (GtranslatorPluginsEngine *engine);
+
+const GList *gtranslator_plugins_engine_get_plugin_list (GtranslatorPluginsEngine *engine);
+
+gboolean gtranslator_plugins_engine_activate_plugin (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info);
+gboolean gtranslator_plugins_engine_deactivate_plugin (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info);
+
+void gtranslator_plugins_engine_configure_plugin (GtranslatorPluginsEngine *engine,
+ GtranslatorPluginInfo *info,
+ GtkWindow *parent);
+
+/*
+ * new_window == TRUE if this function is called because a new top window
+ * has been created
+ */
+void gtranslator_plugins_engine_update_plugins_ui (GtranslatorPluginsEngine *engine,
+ GtranslatorWindow *window,
+ gboolean new_window);
+
+G_END_DECLS
+
+#endif /* __GTR_PLUGINS_ENGINE_H__ */
Added: branches/GOBJECT_WORK/src/plugin-system/update-from-gedit.sh
==============================================================================
--- (empty file)
+++ branches/GOBJECT_WORK/src/plugin-system/update-from-gedit.sh Sun Jan 13 08:12:00 2008
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+SVN_URI=http://svn.gnome.org/svn/gedit/trunk/gedit
+FILES="gedit-module.h \
+ gedit-module.c \
+ gedit-plugin-info-priv.h \
+ gedit-plugin-info.c \
+ gedit-plugin-info.h \
+ gedit-plugin.h \
+ gedit-plugin.c \
+ gedit-plugin-manager.c \
+ gedit-plugin-manager.h \
+ gedit-plugins-engine.c \
+ gedit-plugins-engine.h"
+
+echo "Obtaining latest version of the sources"
+for FILE in $FILES
+do
+ svn export $SVN_URI/$FILE
+done
+
+sed_it () {
+ sed \
+ -e 's/gedit-module/module/g' \
+ -e 's/gedit-plugin-info/plugin-info/g' \
+ -e 's/gedit-plugin/plugin/g' \
+ -e 's/gedit-panel.h/panel.h/g' \
+ -e 's/gedit-window.h/window.h/g' \
+ -e 's/gedit-utils.h/utils_gui.h/g' \
+ -e 's/#include <gedit\/gedit-debug.h>/\/\/#include <gedit\/gedit-debug.h>/g' \
+ -e 's/#include "gedit-debug.h"/\/\/#include "gedit-debug.h"/g' \
+ -e 's/#include "gedit-app.h"/#include "application.h"/g' \
+ -e 's/gedit_debug_message (DEBUG_PLUGINS,/g_warning(/g' \
+ -e 's/gedit_debug/\/\/gedit_debug/g' \
+ -e 's/gedit_app/gtranslator_application/g' \
+ -e 's/.gnome2\/gedit\/plugins\//.gtranslator\/plugins\//g' \
+ -e 's/\/apps\/gedit-2\/plugins/\/apps\/gtranslator\/plugins/g' \
+ -e 's/gedit/gtranslator/g' \
+ -e 's/Gedit/Gtranslator/g' \
+ -e 's/GEDIT/GTR/g' \
+ $1
+}
+
+sed_it gedit-module.h > module.h
+sed_it gedit-module.c > module.c
+sed_it gedit-plugin-info-priv.h > plugin-info-priv.h
+sed_it gedit-plugin-info.h > plugin-info.h
+sed_it gedit-plugin-info.c > plugin-info.c
+sed_it gedit-plugin.c > plugin.c
+sed_it gedit-plugin.h > plugin.h
+sed_it gedit-plugin-manager.h > plugin-manager.h
+sed_it gedit-plugin-manager.c > plugin-manager.c
+sed_it gedit-plugins-engine.c > plugins-engine.c
+sed_it gedit-plugins-engine.h > plugins-engine.h
+
+rm gedit-module.h
+rm gedit-module.c
+rm gedit-plugin-info-priv.h
+rm gedit-plugin-info.h
+rm gedit-plugin-info.c
+rm gedit-plugin.c
+rm gedit-plugin.h
+rm gedit-plugin-manager.c
+rm gedit-plugin-manager.h
+rm gedit-plugins-engine.c
+rm gedit-plugins-engine.h
+
Modified: branches/GOBJECT_WORK/src/utils_gui.c
==============================================================================
--- branches/GOBJECT_WORK/src/utils_gui.c (original)
+++ branches/GOBJECT_WORK/src/utils_gui.c Sun Jan 13 08:12:00 2008
@@ -32,6 +32,98 @@
#include <gtk/gtk.h>
+GtkWidget *
+gtranslator_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;
+}
+
+void
+gtranslator_utils_menu_position_under_widget (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data)
+{
+ GtkWidget *w = GTK_WIDGET (user_data);
+ GtkRequisition requisition;
+
+ gdk_window_get_origin (w->window, x, y);
+ gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
+
+ if (gtk_widget_get_direction (w) == GTK_TEXT_DIR_RTL)
+ {
+ *x += w->allocation.x + w->allocation.width - requisition.width;
+ }
+ else
+ {
+ *x += w->allocation.x;
+ }
+
+ *y += w->allocation.y + w->allocation.height;
+
+ *push_in = TRUE;
+}
+
+void
+gtranslator_utils_menu_position_under_tree_view (GtkMenu *menu,
+ 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);
+
+ selection = gtk_tree_view_get_selection (tree);
+ g_return_if_fail (selection != NULL);
+
+ if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+ {
+ GtkTreePath *path;
+ GdkRectangle rect;
+
+ gdk_window_get_origin (GTK_WIDGET (tree)->window, 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_size_request (GTK_WIDGET (menu), &requisition);
+ *x += rect.width - requisition.width;
+ }
+ }
+ else
+ {
+ /* no selection -> regular "under widget" positioning */
+ gtranslator_utils_menu_position_under_widget (menu,
+ x, y, push_in,
+ tree);
+ }
+}
+
+
/**
* gtranslator_utils_get_glade_widgets:
* @filename: the path to the glade file
Modified: branches/GOBJECT_WORK/src/utils_gui.h
==============================================================================
--- branches/GOBJECT_WORK/src/utils_gui.h (original)
+++ branches/GOBJECT_WORK/src/utils_gui.h Sun Jan 13 08:12:00 2008
@@ -21,6 +21,22 @@
#define GTR_UTILS_GUI_H 1
#include <gtk/gtkwidget.h>
+#include <gtk/gtkmenu.h>
+
+GtkWidget *gtranslator_gtk_button_new_with_stock_icon (const gchar *label,
+ const gchar *stock_id);
+
+void gtranslator_utils_menu_position_under_widget (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data);
+
+void gtranslator_utils_menu_position_under_tree_view (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data);
gboolean gtranslator_utils_get_glade_widgets (const gchar *filename,
const gchar *root_node,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]