anjuta r4066 - in trunk: . libanjuta libanjuta/vapi-gen libanjuta/vapi-gen/libanjuta libanjuta/vapi-gen/libanjuta-interfaces manuals/reference/libanjuta plugins/project-wizard/templates plugins/project-wizard/templates/anjuta-plugin-vala plugins/project-wizard/templates/anjuta-plugin-vala/po plugins/project-wizard/templates/anjuta-plugin-vala/src plugins/symbol-db
- From: jhs svn gnome org
- To: svn-commits-list gnome org
- Subject: anjuta r4066 - in trunk: . libanjuta libanjuta/vapi-gen libanjuta/vapi-gen/libanjuta libanjuta/vapi-gen/libanjuta-interfaces manuals/reference/libanjuta plugins/project-wizard/templates plugins/project-wizard/templates/anjuta-plugin-vala plugins/project-wizard/templates/anjuta-plugin-vala/po plugins/project-wizard/templates/anjuta-plugin-vala/src plugins/symbol-db
- Date: Sun, 6 Jul 2008 23:03:38 +0000 (UTC)
Author: jhs
Date: Sun Jul 6 23:03:38 2008
New Revision: 4066
URL: http://svn.gnome.org/viewvc/anjuta?rev=4066&view=rev
Log:
2008-07-07 Johannes Schmid <jhs gnome org>
* libanjuta/libanjuta-1.0.deps:
* libanjuta/vapi-gen/README:
* libanjuta/vapi-gen/anjuta-gen-vapi.sh:
* libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.deps:
* libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.excludes:
* libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.files:
* libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.metadata:
* libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.namespace:
* libanjuta/vapi-gen/libanjuta/libanjuta-1.0.deps:
* libanjuta/vapi-gen/libanjuta/libanjuta-1.0.excludes:
* libanjuta/vapi-gen/libanjuta/libanjuta-1.0.files:
* libanjuta/vapi-gen/libanjuta/libanjuta-1.0.metadata:
* libanjuta/vapi-gen/libanjuta/libanjuta-1.0.namespace:
* manuals/reference/libanjuta/writing-plugins-vala.sgml:
* plugins/project-wizard/templates/anjuta-plugin-vala.wiz:
* plugins/project-wizard/templates/anjuta-plugin-vala/Makefile.am:
* plugins/project-wizard/templates/anjuta-plugin-vala/configure.ac.
tpl:
* plugins/project-wizard/templates/anjuta-plugin-vala/po/Makefile.a
m:
* plugins/project-wizard/templates/anjuta-plugin-vala/po/POTFILES.i
n:
* plugins/project-wizard/templates/anjuta-plugin-vala/src/Makefile.
am:
* plugins/project-wizard/templates/anjuta-plugin-vala/src/Makefile.
am.tpl:
* plugins/project-wizard/templates/anjuta-plugin-vala/src/config.va
pi:
* plugins/project-wizard/templates/anjuta-plugin-vala/src/plugin.va
la:
* plugins/symbol-db/symbol-db-system.c (destroy_single_scan_data),
(destroy_engine_scan_data), (sdb_system_init),
(sdb_system_finalize), (sdb_system_class_init),
(sdb_system_get_normalized_cflags),
(on_engine_package_single_file_scan_end), (symbol_db_system_new),
(symbol_db_system_is_package_parsed), (on_pkg_config_output),
(sdb_system_files_visit_dir), (prepare_files_to_be_scanned),
(on_engine_package_scan_end), (sdb_system_do_scan_package_1),
(sdb_system_do_scan_next_package),
(sdb_system_do_scan_new_package), (on_pkg_config_exit),
(symbol_db_system_scan_package),
(symbol_db_system_is_package_parseable):
* plugins/symbol-db/symbol-db-system.h:
Added various missing files to svn
Added:
trunk/libanjuta/libanjuta-1.0.deps
trunk/libanjuta/vapi-gen/
trunk/libanjuta/vapi-gen/README
trunk/libanjuta/vapi-gen/anjuta-gen-vapi.sh
trunk/libanjuta/vapi-gen/libanjuta/
trunk/libanjuta/vapi-gen/libanjuta-interfaces/
trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.deps
trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.excludes
trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.files
trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.metadata
trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.namespace
trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.deps
trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.excludes
trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.files
trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.metadata
trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.namespace
trunk/manuals/reference/libanjuta/writing-plugins-vala.sgml
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/
trunk/plugins/project-wizard/templates/anjuta-plugin-vala.wiz
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/Makefile.am
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/configure.ac.tpl
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/po/
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/po/Makefile.am
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/po/POTFILES.in
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/Makefile.am
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/Makefile.am.tpl
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/config.vapi
trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/plugin.vala
trunk/plugins/symbol-db/symbol-db-system.c
trunk/plugins/symbol-db/symbol-db-system.h
Modified:
trunk/ChangeLog
Added: trunk/libanjuta/libanjuta-1.0.deps
==============================================================================
--- (empty file)
+++ trunk/libanjuta/libanjuta-1.0.deps Sun Jul 6 23:03:38 2008
@@ -0,0 +1,11 @@
+gtk+-2.0
+gdk-pixbuf-2.0
+gdk-2.0
+gconf-2.0
+libglade-2.0
+libgnome-2.0
+libgnomeui-2.0
+gnome-vfs-2.0
+atk
+pango
+cairo
Added: trunk/libanjuta/vapi-gen/README
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/README Sun Jul 6 23:03:38 2008
@@ -0,0 +1,2 @@
+run the anjuta-gen-vapi.sh script in this directory after installing
+anjuta to regenerate the Vala bindings.
Added: trunk/libanjuta/vapi-gen/anjuta-gen-vapi.sh
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/anjuta-gen-vapi.sh Sun Jul 6 23:03:38 2008
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# for Anjuta namespace
+vala-gen-introspect libanjuta-1.0 libanjuta/
+vapigen --library libanjuta libanjuta/libanjuta-1.0.gi
+
+# for IAnjuta namespace
+vala-gen-introspect libanjuta-1.0 libanjuta-interfaces/
+vapigen --vapidir . --library libanjuta-interfaces libanjuta-interfaces/libanjuta-1.0.gi
+
+cat libanjuta.vapi libanjuta-interfaces.vapi > ../libanjuta-1.0.vapi
Added: trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.deps
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.deps Sun Jul 6 23:03:38 2008
@@ -0,0 +1,12 @@
+gtk+-2.0
+gdk-pixbuf-2.0
+gdk-2.0
+gconf-2.0
+libglade-2.0
+libgnome-2.0
+libgnomeui-2.0
+gnome-vfs-2.0
+atk
+pango
+cairo
+libanjuta
Added: trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.excludes
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.excludes Sun Jul 6 23:03:38 2008
@@ -0,0 +1,2 @@
+include/libanjuta-1.0/libanjuta/interfaces/libanjuta-interfaces.h
+include/libanjuta-1.0/libanjuta/interfaces/libanjuta-iface-marshallers.h
Added: trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.files
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.files Sun Jul 6 23:03:38 2008
@@ -0,0 +1,2 @@
+lib/libanjuta.so
+include/libanjuta-1.0/libanjuta/interfaces/
Added: trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.metadata
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.metadata Sun Jul 6 23:03:38 2008
@@ -0,0 +1 @@
+IAnjuta cheader_filename="libanjuta/interfaces/libanjuta-interfaces.h"
Added: trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.namespace
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta-interfaces/libanjuta-1.0.namespace Sun Jul 6 23:03:38 2008
@@ -0,0 +1 @@
+IAnjuta
Added: trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.deps
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.deps Sun Jul 6 23:03:38 2008
@@ -0,0 +1,11 @@
+gtk+-2.0
+gdk-pixbuf-2.0
+gdk-2.0
+gconf-2.0
+libglade-2.0
+libgnome-2.0
+libgnomeui-2.0
+gnome-vfs-2.0
+atk
+pango
+cairo
Added: trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.excludes
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.excludes Sun Jul 6 23:03:38 2008
@@ -0,0 +1,3 @@
+include/libanjuta-1.0/libanjuta/libanjuta.h
+include/libanjuta-1.0/libanjuta/anjuta-marshal.h
+include/libanjuta-1.0/libanjuta/interfaces/
Added: trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.files
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.files Sun Jul 6 23:03:38 2008
@@ -0,0 +1,2 @@
+lib/libanjuta.so
+include/libanjuta-1.0/libanjuta/
Added: trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.metadata
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.metadata Sun Jul 6 23:03:38 2008
@@ -0,0 +1,23 @@
+Anjuta cheader_filename="libanjuta/libanjuta.h"
+
+AnjutaShell::save_prompt has_emitter="1"
+
+anjuta_plugin_add_watch.added delegate_target_pos="3.1"
+
+anjuta_ui_add_action_group_entries.entries is_array="1"
+anjuta_ui_add_action_group_entries.num_entries hidden="1"
+anjuta_ui_add_action_group_entries.user_data hidden="0"
+
+AnjutaAsyncCommandPriv hidden="1"
+AnjutaCommandPriv hidden="1"
+AnjutaGluePlugin hidden="1"
+AnjutaLauncherPriv hidden="1"
+AnjutaPluginHandlePriv hidden="1"
+AnjutaPluginManagerPriv hidden="1"
+AnjutaPreferencesPriv hidden="1"
+AnjutaProfileManagerPriv hidden="1"
+AnjutaProfilePriv hidden="1"
+AnjutaSessionPriv hidden="1"
+AnjutaStatusPriv hidden="1"
+AnjutaVcsStatusTreeViewPriv hidden="1"
+GError hidden="1"
Added: trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.namespace
==============================================================================
--- (empty file)
+++ trunk/libanjuta/vapi-gen/libanjuta/libanjuta-1.0.namespace Sun Jul 6 23:03:38 2008
@@ -0,0 +1 @@
+Anjuta
Added: trunk/manuals/reference/libanjuta/writing-plugins-vala.sgml
==============================================================================
--- (empty file)
+++ trunk/manuals/reference/libanjuta/writing-plugins-vala.sgml Sun Jul 6 23:03:38 2008
@@ -0,0 +1,134 @@
+<chapter id="writing-plugins-vala">
+ <title>Writing plugins in Vala</title>
+ <para>
+ Before writing an Anjuta plugin, please read
+ <xref linkend="anjuta-architecture"/> for general concepts about how Anjuta
+ plugins interact with Anjuta Shell and other plugins.
+ </para>
+ <para>
+ Anjuta API is divided in two namespaces : Anjuta and IAnjuta. Anjuta
+ contains API to interact with the IDE, and IAnjuta contains interfaces that
+ plugins implement to be able to interact with each other.
+ Writing a plugin for Anjuta is as simple as subclassing Anjuta.Plugin,
+ overriding activate and deactivate, and writing a .plugin file to let Anjuta
+ know about your plugin.
+ </para>
+ <para>
+ This tutorial is still uncomplete. However most of the documentation
+ regarding C plugins is still applicable, so you can always refer to
+ <xref linkend="writing-plugins">it</xref>.
+ </para>
+ <para>
+ In this tutorial, we will write a basic <emphasis>Hello world</emphasis>
+ plugin that does nothing but adding a "Hello World" label to Anjuta.
+ </para>
+ <sect1 id="writing-code">
+ <title> Writing the plugin code </title>
+ <para>
+ As said earlier, we will need to subclass Anjuta.Plugin and override some
+ methods, so here is Anjuta.Plugin :
+ <programlisting>
+public class Anjuta.Plugin : GLib.Object {
+ public uint add_watch (string name, Anjuta.PluginValueAdded added, Anjuta.PluginValueRemoved removed);
+ public bool is_active ();
+ public void remove_watch (uint id, bool send_remove);
+ public virtual bool activate ();
+ public virtual bool deactivate ();
+ public weak Anjuta.Shell shell { get; set; }
+ public signal void activated ();
+ public signal void deactivated ();
+}
+ </programlisting>
+ The methods we'll need to override are activate and deactivate, the shell
+ property is what we'll use to interact with Anjuta. <methodname>add_watch</methodname>
+ and <methodname>remove_watch</methodname> are used to interface with the
+ <emphasis>Values System</emphasis> see <xref linkend="anjuta-architecture"/>
+ for more information. The rest is pretty self explanatory, and we generally won't need it.
+ </para>
+ <para>
+ We will only use the <methodname>add_widget</methodname> method of
+ <type>Anjuta.Shell</type> in this tutorial. For more informations, you can see
+ the <link linkend="AnjutaShell">C API documentation</link>.
+ </para>
+ <para>
+ This plugin does nothing more than showing a "Hello World" widget in
+ Anjuta
+ </para>
+ <programlisting>
+using Gtk;
+using Anjuta;
+
+public class HelloWorldPlugin: Plugin {
+ /* The hello world widget */
+ Widget widget;
+
+ /* We use the "override" keyword to override the virtual methods activate and deactivate */
+ public override bool activate () {
+ widget = new Label("Hello World");
+
+ /* adding the widget */
+ shell.add_widget(widget, /* the widget to add */
+ "AnjutaHelloWorldPlugin", /* name of the widget*/
+ "HelloWorldPlugin", /* title, should be translated */
+ Gtk.STOCK_ABOUT, /* icon stock id */
+ ShellPlacement.CENTER); /* placement in in the shell */
+ return true; /* false if activation failed */
+ }
+
+ public override bool deactivate () {
+ /* remove the widget we've added */
+ shell.remove_widget(widget);
+
+ return true; /* false if plugin doesn't want to deactivate */
+ }
+}
+
+/* Initialization function, in C this would be automatically generated by the
+ ANJUTA_SIMPLE_PLUGIN macro */
+[ModuleInit]
+public GLib.Type anjuta_glue_register_components (GLib.TypeModule module) {
+ return typeof (HelloWorldPlugin);
+}
+ </programlisting>
+ </sect1>
+ <sect1>
+ <title>Writing a plugin description</title>
+ Anjuta needs a file with a plugin extension to know about our plugin, its name
+ and description, where it is located, when to load it. Here is an example for our
+ basic plugin :
+ <programlisting>
+[Anjuta Plugin]
+Name=Hello World
+Description=An example hello world plugin.
+Location=anjuta-hello-world:HelloWorldPlugin
+Icon=anjuta-sample-plugin-48.png
+ </programlisting>
+ Generally, Name and Description should be translated. Using intltool, you can
+ do this by prefixing them with _.
+ Location is of the form libraryname:ClassName : libraryname is the name of the
+ library file (without the lib prefix and .so suffix), and ClassName is the full
+ class name including the namespace (and not separated by a period as you would
+ write it in Vala).
+ Icon is the icon to be used by the plugin, here we put sample plugin icon which
+ is distributed along with Anjuta, but you could put your own icon instead.
+ <para>
+ For more information about plugin description files, refer to
+ <xref linkend="plugin-description-file"/>.
+ </para>
+ </sect1>
+ <sect1>
+ <title>Compiling and installing the plugin</title>
+ <sect2>
+ <title>Manual compilation</title>
+ Assuming you saved the plugin as hello-plugin.vala, you can compile it with :
+ <userinput>
+valac --ccode --pkg libanjuta-1.0 hello-plugin.vala
+gcc -shared -o libanjuta-hello-world.so
+ </userinput>
+ </sect2>
+ <sect2>
+ <title>Using autotools</title>
+ Coming soon.
+ </sect2>
+ </sect1>
+</chapter>
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala.wiz
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala.wiz Sun Jul 6 23:03:38 2008
@@ -0,0 +1,117 @@
+<project-wizard>
+ <name>Anjuta Plugin</name>
+ <description>Anjuta plugin project that uses libanjuta framework</description>
+ <icon>anjuta-plugin-logo.png</icon>
+ <category>Vala</category>
+ <required-program>automake</required-program>
+ <required-program>autoconf</required-program>
+ <required-program>make</required-program>
+ <required-package>libanjuta-1.0</required-package>
+</project-wizard>
+
+<page name="basic" _label="Basic information" _description="General Project Information">
+ <property type="string" name="Name" _label="Project Name:" _description="Project name must not contain spaces, because it will be the name of the project build target (executable, library etc.)" default="anjuta-plugin-foobar" summary="yes" restriction="filename" mandatory="yes"/>
+ <property type="string" name="Author" _label="Author:" _description="" default="[+UserName+]" mandatory="yes"/>
+ <property type="string" name="Email" _label="Email address:" _description="" default="[+EmailAddress+]" mandatory="no"/>
+ <property type="string" name="Version" _label="Version:" default="0.1" mandatory="yes"/>
+</page>
+
+<page name="options" _label="Project options" _description="Options for project build system">
+ <property type="directory" name="Destination" _label="Destination:" _description="" default="[+AnjutaProjectDirectory+]/[+(string-downcase (get "Name"))+]" mandatory="yes" exist="no" summary="yes"/>
+ <property type="list" name="License" _label="License" _description="Select code license" default="GPL" editable="no">
+ <item name="GPL" _label="General Public License (GPL)"/>
+ <item name="LGPL" _label="Lesser General Public License (LGPL)"/>
+ <item name="BSD" _label="Berkeley Software Distribution License (BSD)"/>
+ <item name="None" _label="No license"/>
+ </property>
+ <property type="hidden" name="NameUpper" default="[+(string-upcase (get "Name"))+]"/>
+ <property type="hidden" name="NameLower" default="[+(string-downcase (get "Name"))+]"/>
+ <property type="hidden" name="NameCUpper" default="[+(string->c-name! (string-substitute (string-upcase (get "Name")) " " "_"))+]"/>
+ <property type="hidden" name="NameCLower" default="[+(string->c-name! (string-substitute (string-downcase (get "Name")) " " "_"))+]"/>
+ <property type="hidden" name="NameHLower" default="[+(string-substitute (string->c-name! (string-downcase (get "Name"))) " " "-")+]"/>
+ <property type="string" name="PluginTitle" _label="Plugin Title:" _description="Display title of the plugin" default="Anjuta Foobar Sample Plugin" summary="yes" mandatory="yes"/>
+ <property type="string" name="PluginDescription" _label="Plugin Description:" _description="Display description of the plugin" default="A sample demonstration plugin for Anjuta" summary="yes" mandatory="yes"/>
+ <property type="string" name="PluginClass" _label="Plugin Class Name:" _description="Plugin class name" default="AnjutaFoobarPlugin" summary="yes" mandatory="yes"/>
+ <property type="string" name="PluginDependencies" _label="Plugin Dependencies:" _description="Comma separated, other plugins that this plugin depends on. It could be either primary interface name or plugin location (library:class)" default="" summary="yes"/>
+ <property type="icon" name="Icon" _label="Icon File:" _description="Icon file for the plugin" summary="yes" mandatory="yes"/>
+ <property type="boolean" name="HasGladeFile" _label="Create glade interface file" _description="Create a template glade interface file" default="1"/>
+ <property type="boolean" name="HasUI" _label="Plugin has menus or/and toolbars" _description="Whether the plugin has menus or toolbars" default="1"/>
+ <property type="hidden" name="HaveI18n" default="1"/>
+ <property type="hidden" name="HaveSharedlib" default="1"/>
+ <property type="boolean" name="HavePackage" _label="Configure external packages:" _description="Use pkg-config to add library support from other packages" default="0"/>
+</page>
+
+[+IF (=(get "HavePackage") "1")+]
+<page name="packages" _label="Configure external packages" _description="Configure external packages">
+ <property type="string" name="PackageModule1" _label="Require Package:" _description="Give a package name that your project require. You may also mention what is the required version of the package. For example, 'libgnomeui-2.0' or 'libgnomeui-2.0 >= 2.2.0'" mandatory="yes"/>
+ <property type="string" name="PackageModule2" _label="Require Package:" _description="Give a package name that your project require. You may also mention what is the required version of the package. For example, 'libgnomeui-2.0' or 'libgnomeui-2.0 >= 2.2.0'"/>
+ <property type="string" name="PackageModule3" _label="Require Package:" _description="Give a package name that your project require. You may also mention what is the required version of the package. For example, 'libgnomeui-2.0' or 'libgnomeui-2.0 >= 2.2.0'"/>
+ <property type="string" name="PackageModule4" _label="Require Package:" _description="Give a package name that your project require. You may also mention what is the required version of the package. For example, 'libgnomeui-2.0' or 'libgnomeui-2.0 >= 2.2.0'"/>
+ <property type="string" name="PackageModule5" _label="Require Package:" _description="Give a package name that your project require. You may also mention what is the required version of the package. For example, 'libgnomeui-2.0' or 'libgnomeui-2.0 >= 2.2.0'"/>
+</page>
+[+ENDIF+]
+
+<page name="watches" _label="Values to watch" _description="Shell values to watch">
+ <property type="string" name="value1" _label="Value Name:" _description="Name of the value to watch" default="" summary="yes"/>
+ <property type="string" name="value2" _label="Value Name:" _description="Name of the value to watch" default="" summary="yes"/>
+ <property type="string" name="value3" _label="Value Name:" _description="Name of the value to watch" default="" summary="yes"/>
+</page>
+
+<page name="compoments" _label="Implement plugin interfaces" _description="Plugin interfaces to implement">
+ <property type="string" name="interface1" _label="Interface:" _description="Interface implemented by the plugin"/>
+ <property type="string" name="interface2" _label="Interface:" _description="Interface implemented by the plugin"/>
+ <property type="string" name="interface3" _label="Interface:" _description="Interface implemented by the plugin"/>
+</page>
+
+<content>
+ <directory source="terminal" destination="[+Destination+]">
+ <file source="AUTHORS"/>
+ <file source="ChangeLog"/>
+ <file source="Makefile.am.tpl" destination="Makefile.am"/>
+ <file source="NEWS"/>
+ <file source="README"/>
+ <file source="autogen.sh" executable="yes"/>
+ <file destination="[+NameHLower+].anjuta" source="project.anjuta"/>
+ <file source="cvsignore" destination=".cvsignore"/>
+ <directory source="src">
+ <file source="cvsignore" destination=".cvsignore"/>
+ </directory>
+ [+IF (=(get "HaveI18n") "1")+]
+ <directory source="po">
+ <file source="ChangeLog"/>
+ <file source="LINGUAS" />
+ <file source="cvsignore" destination=".cvsignore"/>
+ </directory>
+ [+ENDIF+]
+ </directory>
+ <directory source="anjuta-plugin" destination="[+Destination+]">
+ <directory source="src">
+ <file source="[+Icon+]" destination="[+NameHLower+].png"/>
+ <file source="plugin.plugin.in" destination="[+NameHLower+].plugin.in"/>
+ [+IF (=(get "HasUI") "1")+]
+ <file source="plugin.ui" destination="[+NameHLower+].ui"/>
+ [+ENDIF+]
+ [+IF (=(get "HasGladeFile") "1")+]
+ <file source="plugin.glade" destination="[+NameHLower+].glade"/>
+ [+ENDIF+]
+ </directory>
+ </directory>
+ <directory source="anjuta-plugin-vala" destination="[+Destination+]">
+ <file source="configure.ac.tpl" destination="configure.ac"/>
+ <directory source="src">
+ <file source="Makefile.am.tpl" destination="Makefile.am"/>
+ <file source="plugin.vala"/>
+ <file source="config.vapi"/>
+ </directory>
+ [+IF (=(get "HaveI18n") "1")+]
+ <directory source="po">
+ <file source="POTFILES.in"/>
+ </directory>
+ [+ENDIF+]
+ </directory>
+</content>
+
+<action>
+ <run command="sh -c "cd [+(raw-shell-str (get "Destination"))+] && ./autogen.sh""/>
+ <open file="[+Destination+]/[+NameHLower+].anjuta"/>
+</action>
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala/Makefile.am Sun Jul 6 23:03:38 2008
@@ -0,0 +1,9 @@
+
+SUBDIRS = src po
+
+wizard_filesdir = $(anjuta_data_dir)/project/anjuta-plugin-vala
+wizard_files_DATA = \
+ configure.ac.tpl
+
+EXTRA_DIST = $(wizard_files_DATA)
+
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala/configure.ac.tpl
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala/configure.ac.tpl Sun Jul 6 23:03:38 2008
@@ -0,0 +1,100 @@
+[+ autogen5 template +]
+dnl Process this file with autoconf to produce a configure script.
+dnl Created by Anjuta application wizard.
+
+AC_INIT([+NameHLower+], [+Version+])
+
+AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
+AM_CONFIG_HEADER(config.h)
+AM_MAINTAINER_MODE
+
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+
+AC_PATH_PROG(VALAC, valac)
+AC_SUBST(VALAC)
+
+[+IF (=(get "HaveI18n") "1")+]
+dnl ***************************************************************************
+dnl Internationalization
+dnl ***************************************************************************
+GETTEXT_PACKAGE=[+NameHLower+]
+AC_SUBST(GETTEXT_PACKAGE)
+AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name])
+AM_GLIB_GNU_GETTEXT
+IT_PROG_INTLTOOL([0.35.0])
+[+ENDIF+]
+
+[+IF (=(get "HaveSharedlib") "1")+]
+AM_PROG_LIBTOOL
+[+ENDIF+]
+
+PKG_CHECK_MODULES(LIBANJUTA, [libanjuta-1.0])
+AC_SUBST(LIBANJUTA_CFLAGS)
+AC_SUBST(LIBANJUTA_LIBS)
+
+[+IF (=(get "HavePackage") "1")+]
+PKG_CHECK_MODULES([+NameCUpper+], [[+PackageModule1+] [+PackageModule2+] [+PackageModule3+] [+PackageModule4+] [+PackageModule5+]])
+AC_SUBST([+NameCUpper+]_CFLAGS)
+AC_SUBST([+NameCUpper+]_LIBS)
+[+ENDIF+]
+
+dnl Setup Plugin directories
+dnl ------------------------
+anjutalibdir=`pkg-config --variable=libdir libanjuta-1.0`
+anjutadatadir=`pkg-config --variable=datadir libanjuta-1.0`
+AC_SUBST(anjutalibdir)
+AC_SUBST(anjutadatadir)
+anjuta_plugin_dir='$(anjutalibdir)/anjuta'
+anjuta_data_dir='$(anjutadatadir)/anjuta'
+anjuta_ui_dir='$(anjutadatadir)/anjuta/ui'
+anjuta_glade_dir='$(anjutadatadir)/anjuta/glade'
+anjuta_image_dir='$(anjutadatadir)/pixmaps/anjuta'
+AC_SUBST(anjuta_plugin_dir)
+AC_SUBST(anjuta_data_dir)
+AC_SUBST(anjuta_ui_dir)
+AC_SUBST(anjuta_glade_dir)
+AC_SUBST(anjuta_image_dir)
+
+[+IF (=(get "HaveGtkDoc") "1")+]
+##################################################
+# Check for gtk-doc.
+##################################################
+AC_ARG_WITH(html-dir, [ --with-html-dir=PATH path to installed docs ])
+if test "x$with_html_dir" = "x" ; then
+ HTML_DIR='${datadir}/gtk-doc/html'
+else
+ HTML_DIR=$with_html_dir
+fi
+AC_SUBST(HTML_DIR)
+
+gtk_doc_min_version=1.0
+AC_MSG_CHECKING([gtk-doc version >= $gtk_doc_min_version])
+if pkg-config --atleast-version=$gtk_doc_min_version gtk-doc; then
+ AC_MSG_RESULT(yes)
+ GTKDOC=true
+else
+ AC_MSG_RESULT(no)
+ GTKDOC=false
+fi
+dnl Let people disable the gtk-doc stuff.
+AC_ARG_ENABLE(gtk-doc,
+ [ --enable-gtk-doc Use gtk-doc to build documentation [default=auto]],
+ enable_gtk_doc="$enableval", enable_gtk_doc=auto)
+if test x$enable_gtk_doc = xauto ; then
+ if test x$GTKDOC = xtrue ; then
+ enable_gtk_doc=yes
+ else
+ enable_gtk_doc=no
+ fi
+fi
+AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes)
+[+ENDIF+]
+
+AC_OUTPUT([
+Makefile
+src/Makefile
+[+IF (=(get "HaveI18n") "1")+]po/Makefile.in[+ENDIF+]
+])
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala/po/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala/po/Makefile.am Sun Jul 6 23:03:38 2008
@@ -0,0 +1,3 @@
+wizard_filesdir = $(anjuta_data_dir)/project/anjuta-plugin-vala/po
+wizard_files_DATA = POTFILES.in
+EXTRA_DIST = $(wizard_files_DATA)
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala/po/POTFILES.in
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala/po/POTFILES.in Sun Jul 6 23:03:38 2008
@@ -0,0 +1,5 @@
+[+ autogen5 template +]
+# List of source files containing translatable strings.
+
+src/plugin.vala
+src/[+NameHLower+].plugin.in
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/Makefile.am Sun Jul 6 23:03:38 2008
@@ -0,0 +1,7 @@
+wizard_filesdir = $(anjuta_data_dir)/project/anjuta-plugin-vala/src
+wizard_files_DATA = \
+ Makefile.am.tpl \
+ plugin.vala \
+ config.vapi
+
+EXTRA_DIST = $(wizard_files_DATA)
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/Makefile.am.tpl
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/Makefile.am.tpl Sun Jul 6 23:03:38 2008
@@ -0,0 +1,74 @@
+[+ autogen5 template +]
+# Sample Makefile for a anjuta plugin.
+[+IF (=(get "HasUI") "1")+]
+# Plugin UI file
+[+NameCLower+]_uidir = $(anjuta_ui_dir)
+[+NameCLower+]_ui_DATA = [+NameHLower+].ui
+[+ENDIF+]
+[+IF (=(get "HasGladeFile") "1")+]
+# Plugin Glade file
+[+NameCLower+]_gladedir = $(anjuta_glade_dir)
+[+NameCLower+]_glade_DATA = [+NameHLower+].glade
+[+ENDIF+]
+# Plugin Icon file
+[+NameCLower+]_pixmapsdir = $(anjuta_image_dir)
+[+NameCLower+]_pixmaps_DATA = [+NameHLower+].png
+
+# Plugin description file
+plugin_in_files = [+NameHLower+].plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+[+NameCLower+]_plugindir = $(anjuta_plugin_dir)
+[+NameCLower+]_plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
+
+# NOTE :
+# The naming convention is very intentional
+# We are forced to use the prefix 'lib' by automake and libtool
+# There is probably a way to avoid it but it is not worth to effort
+# to find out.
+# The 'anjuta_' prfix is a safety measure to avoid conflicts where the
+# plugin 'libpython.so' needs to link with the real 'libpython.so'
+
+# Include paths
+AM_CPPFLAGS = \
+ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+ -DANJUTA_DATA_DIR=\"$(anjuta_data_dir)\" \
+ -DANJUTA_PLUGIN_DIR=\"$(anjuta_plugin_dir)\" \
+ -DANJUTA_IMAGE_DIR=\"$(anjuta_image_dir)\" \
+ -DANJUTA_GLADE_DIR=\"$(anjuta_glade_dir)\" \
+ -DANJUTA_UI_DIR=\"$(anjuta_ui_dir)\" \
+ -DPACKAGE_DATA_DIR=\"$(datadir)\" \
+ -DPACKAGE_SRC_DIR=\"$(srcdir)\" \
+ $(LIBANJUTA_CFLAGS) [+IF (=(get "HavePackage") "1")+]$([+NameCUpper+]_CFLAGS)[+ENDIF+]\
+ -include config.h # so it gets included before glib-i18n.h
+
+# Where to install the plugin
+plugindir = $(anjuta_plugin_dir)
+
+# The plugin
+plugin_LTLIBRARIES = lib[+NameHLower+].la
+
+# Plugin sources
+lib[+NameCLower+]_la_VALASOURCES = plugin.vala config.vapi
+[+NameCLower+]_PACKAGES = --pkg libanjuta-1.0 [+ IF PackageModule1 +][+ % PackageModule1 "--pkg %s" +][+ ENDIF +] [+ IF PackageModule2 +][+ % PackageModule2 "--pkg %s" +][+ ENDIF +] [+ IF PackageModule3 +][+ % PackageModule3 "--pkg %s" +][+ ENDIF +] [+ IF PackageModule4 +][+ % PackageModule4 "--pkg %s" +][+ ENDIF +] [+ IF PackageModule5 +][+ % PackageModule5 "--pkg %s" +][+ ENDIF +]
+
+BUILT_SOURCES = [+NameCLower+].vala.stamp
+
+lib[+NameCLower+]_la_SOURCES = [+NameCLower+].vala.stamp \
+ $(lib[+NameCLower+]_la_VALASOURCES:.vala=.c) \
+ $(lib[+NameCLower+]_la_VALASOURCES:.vala=.h)
+
+[+NameCLower+].vala.stamp : $(lib[+NameCLower+]_la_VALASOURCES)
+ $(VALAC) -C $([+NameCLower+]_PACKAGES) $^
+ touch $@
+
+# Plugin dependencies
+lib[+NameCLower+]_la_LIBADD = \
+ $(LIBANJUTA_LIBS) [+IF (=(get "HavePackage") "1")+]$([+NameCUpper+]_LIBS)[+ENDIF+]
+
+EXTRA_DIST = \
+ $(plugin_in_files) \
+ $([+NameCLower+]_plugin_DATA) \
+ [+IF (=(get "HasUI") "1")+]$([+NameCLower+]_ui_DATA)[+ENDIF+] \
+ [+IF (=(get "HasGladeFile") "1")+]$([+NameCLower+]_glade_DATA)[+ENDIF+] \
+ $([+NameCLower+]_pixmaps_DATA)
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/config.vapi
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/config.vapi Sun Jul 6 23:03:38 2008
@@ -0,0 +1,24 @@
+[+ autogen5 template +]
+/*
+ * plugin.h
+ * Copyright (C) [+Author+] [+(shell "date +%Y")+] <[+Email+]>
+ *
+[+CASE (get "License") +]
+[+ == "BSD" +][+(bsd "plugin.h" (get "Author") " * ")+]
+[+ == "LGPL" +][+(lgpl "plugin.h" (get "Author") " * ")+]
+[+ == "GPL" +][+(gpl "plugin.h" " * ")+]
+[+ESAC+] */
+
+[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")]
+namespace Config {
+ public const string GETTEXT_PACKAGE;
+ public const string PACKAGE_LOCALE_DIR;
+ public const string ANJUTA_DATA_DIR;
+ public const string ANJUTA_PLUGIN_DIR;
+ public const string ANJUTA_IMAGE_DIR;
+ public const string ANJUTA_GLADE_DIR;
+ public const string ANJUTA_UI_DIR;
+ public const string PACKAGE_DATA_DIR;
+ public const string PACKAGE_SRC_DIR;
+}
+
Added: trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/plugin.vala
==============================================================================
--- (empty file)
+++ trunk/plugins/project-wizard/templates/anjuta-plugin-vala/src/plugin.vala Sun Jul 6 23:03:38 2008
@@ -0,0 +1,95 @@
+[+ autogen5 template +]
+/*
+ * plugin.vala
+ * Copyright (C) [+Author+] [+(shell "date +%Y")+] <[+Email+]>
+ *
+[+CASE (get "License") +]
+[+ == "BSD" +][+(bsd "plugin.c" (get "Author") " * ")+]
+[+ == "LGPL" +][+(lgpl "plugin.c" (get "Author") " * ")+]
+[+ == "GPL" +][+(gpl "plugin.c" " * ")+]
+[+ESAC+] */
+
+using GLib;
+using Anjuta;
+
+public class [+PluginClass+] : Plugin {
+[+IF (=(get "HasUI") "1") +]
+ static string UI_FILE;
+[+ENDIF+][+IF (=(get "HasGladeFile") "1") +]
+ static string GLADE_FILE;
+[+ENDIF+][+IF (or (=(get "HasUI") "1") (=(get "HasGladeFile") "1") ) +]
+ static construct {
+ // workaround for bug 538166, should be const
+[+IF (=(get "HasUI") "1") +] UI_FILE = Config.ANJUTA_DATA_DIR + "/ui/[+NameHLower+].ui";
+[+ ENDIF +][+IF (=(get "HasGladeFile") "1") +] GLADE_FILE = Config.ANJUTA_DATA_DIR + "/glade/[+NameHLower+].glade";
+[+ ENDIF +]
+ }
+[+ ENDIF +]
+[+IF (=(get "HasUI") "1") +]
+ private int uiid = 0;
+ private Gtk.ActionGroup action_group;
+[+ENDIF+][+IF (=(get "HasGladeFile") "1") +]
+ private Gtk.Widget widget = null;
+[+ENDIF+]
+[+IF (=(get "HasUI") "1") +]
+ const Gtk.ActionEntry[] actions_file = {
+ {
+ "ActionFileSample", /* Action name */
+ Gtk.STOCK_NEW, /* Stock icon, if any */
+ N_("_Sample action"), /* Display label */
+ null, /* short-cut */
+ N_("Sample action"), /* Tooltip */
+ on_sample_action_activate /* action callback */
+ }
+ };
+
+ public void on_sample_action_activate (Gtk.Action action) {
+
+ /* Query for object implementing IAnjutaDocumentManager interface */
+ var docman = (IAnjuta.DocumentManager) shell.get_object ("IAnjutaDocumentManager");
+ var editor = (IAnjuta.Editor) docman.get_current_document ();
+
+ /* Do whatever with plugin */
+
+ }
+[+ENDIF+]
+ public override bool activate () {
+
+ //DEBUG_PRINT ("[+PluginClass+]: Activating [+PluginClass+] plugin ...");
+[+IF (=(get "HasUI") "1") +]
+ /* Add all UI actions and merge UI */
+ var ui = shell.get_ui ();
+ action_group = ui.add_action_group_entries ("ActionGroupFile[+NameHLower+]",
+ _("Sample file operations"),
+ actions_file,
+ Config.GETTEXT_PACKAGE, true,
+ this);
+ uiid = ui.merge (UI_FILE);
+[+ENDIF+][+IF (=(get "HasGladeFile") "1") +]
+ /* Add plugin widgets to Shell */
+ var gxml = new Glade.XML (GLADE_FILE, "top_widget", null);
+ widget = gxml.get_widget ("top_widget");
+ shell.add_widget (widget, "[+PluginClass+]Widget",
+ _("[+PluginClass+] widget"), null,
+ ShellPlacement.BOTTOM);
+[+ENDIF+]
+ return true;
+ }
+
+ public override bool deactivate () {
+ //DEBUG_PRINT ("[+PluginClass+]: Dectivating [+PluginClass+] plugin ...");
+[+IF (=(get "HasGladeFile") "1") +]
+ shell.remove_widget (widget);
+[+ENDIF+][+IF (=(get "HasUI") "1") +]
+ var ui = shell.get_ui ();
+ ui.remove_action_group (action_group);
+ ui.unmerge (uiid);
+[+ENDIF+]
+ return true;
+ }
+}
+
+[ModuleInit]
+public GLib.Type anjuta_glue_register_components (GLib.TypeModule module) {
+ return typeof ([+PluginClass+]);
+}
Added: trunk/plugins/symbol-db/symbol-db-system.c
==============================================================================
--- (empty file)
+++ trunk/plugins/symbol-db/symbol-db-system.c Sun Jul 6 23:03:38 2008
@@ -0,0 +1,704 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta_trunk
+ * Copyright (C) Massimo Cora' 2008 <maxcvs email it>
+ *
+ * anjuta_trunk is free software.
+ *
+ * You may 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.
+ *
+ * anjuta_trunk 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 anjuta_trunk. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#include "symbol-db-system.h"
+#include "plugin.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-launcher.h>
+#include <libanjuta/interfaces/ianjuta-language.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <string.h>
+
+struct _SymbolDBSystemPriv
+{
+ AnjutaLauncher *single_package_scan_launcher;
+ IAnjutaLanguage *lang_manager;
+ SymbolDBEngine *sdbe_globals;
+
+ GQueue *sscan_queue;
+ GQueue *engine_queue;
+};
+
+typedef struct _SingleScanData {
+ SymbolDBSystem *sdbs;
+ gchar *package_name;
+ gchar *contents;
+ gboolean engine_scan;
+
+ PackageParseableCallback parseable_cb;
+ gpointer parseable_data;
+
+} SingleScanData;
+
+typedef struct _EngineScanData {
+ SymbolDBSystem *sdbs;
+ gchar *package_name;
+ GList *cflags;
+
+} EngineScanData;
+
+enum
+{
+ SCAN_PACKAGE_START,
+ SCAN_PACKAGE_END,
+ SINGLE_FILE_SCAN_END,
+ LAST_SIGNAL
+};
+
+static unsigned int signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (SymbolDBSystem, sdb_system, G_TYPE_OBJECT);
+
+/* forward decl */
+static void
+on_pkg_config_exit (AnjutaLauncher * launcher, int child_pid,
+ int exit_status, gulong time_taken_in_seconds,
+ gpointer user_data);
+
+
+static void
+destroy_single_scan_data (SingleScanData *ss_data)
+{
+ g_return_if_fail (ss_data != NULL);
+
+ g_free (ss_data->package_name);
+ g_free (ss_data->contents);
+
+ g_free (ss_data);
+}
+
+static void
+destroy_engine_scan_data (EngineScanData *es_data)
+{
+ if (es_data->cflags)
+ {
+ g_list_foreach (es_data->cflags, (GFunc)g_free, NULL);
+ g_list_free (es_data->cflags);
+ }
+
+ g_free (es_data->package_name);
+ g_free (es_data);
+}
+
+
+static void
+sdb_system_init (SymbolDBSystem *object)
+{
+ SymbolDBSystem *sdbs;
+
+ sdbs = SYMBOL_DB_SYSTEM (object);
+ sdbs->priv = g_new0 (SymbolDBSystemPriv, 1);
+
+ /* create launcher for single global package scan */
+ sdbs->priv->single_package_scan_launcher = anjuta_launcher_new ();
+ anjuta_launcher_set_check_passwd_prompt (sdbs->priv->single_package_scan_launcher,
+ FALSE);
+
+ /* single scan launcher's queue */
+ sdbs->priv->sscan_queue = g_queue_new ();
+ sdbs->priv->engine_queue = g_queue_new ();
+
+}
+
+static void
+sdb_system_finalize (GObject *object)
+{
+ SymbolDBSystem *sdbs;
+ SymbolDBSystemPriv *priv;
+
+ sdbs = SYMBOL_DB_SYSTEM (object);
+ priv = sdbs->priv;
+ if (priv->single_package_scan_launcher)
+ {
+ anjuta_launcher_reset (priv->single_package_scan_launcher);
+ g_object_unref (priv->single_package_scan_launcher);
+ priv->single_package_scan_launcher = NULL;
+ }
+
+ /* free also the queue */
+ g_queue_foreach (priv->sscan_queue, (GFunc)g_free, NULL);
+ g_queue_free (priv->sscan_queue);
+ priv->sscan_queue = NULL;
+
+ /* FIXME: missing engine queue */
+ /* FIXME: disconnect signals */
+
+
+ G_OBJECT_CLASS (sdb_system_parent_class)->finalize (object);
+}
+
+static void
+sdb_system_class_init (SymbolDBSystemClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+ signals[SCAN_PACKAGE_START]
+ = g_signal_new ("scan-package-start",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (SymbolDBSystemClass, scan_package_start),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT_POINTER, G_TYPE_NONE,
+ 2,
+ G_TYPE_INT,
+ G_TYPE_POINTER);
+
+ signals[SCAN_PACKAGE_END]
+ = g_signal_new ("scan-package-end",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (SymbolDBSystemClass, scan_package_end),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING, G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[SINGLE_FILE_SCAN_END]
+ = g_signal_new ("single-file-scan-end",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (SymbolDBSystemClass, single_file_scan_end),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ object_class->finalize = sdb_system_finalize;
+}
+
+/**
+ * @return GList of cflags (strings) in a format like /usr/include/my_foo_lib.
+ * @return NULL on error.
+ */
+static GList *
+sdb_system_get_normalized_cflags (const gchar *chars)
+{
+ gchar **flags;
+ gint i;
+ GList *good_flags;
+ const gchar *curr_flag;
+
+ /* We should receive here something like
+ * '-I/usr/include/gimp-2.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include'.
+ * Split up the chars and take a decision if we like it or not.
+ */
+ flags = g_strsplit (chars, " ", -1);
+
+ i = 0;
+ /* if, after the while loop, good_flags is != NULL that means that we found
+ * some good flags to include for a future scan
+ */
+ good_flags = NULL;
+ while ((curr_flag = flags[i++]) != NULL)
+ {
+ /* '-I/usr/include/gimp-2.0' would be good, but '/usr/include/' wouldn't. */
+ if (g_regex_match_simple ("\\.*/usr/include/\\w+", curr_flag, 0, 0) == TRUE)
+ {
+ /* FIXME the +2. It's to skip the -I */
+ DEBUG_PRINT ("adding %s to good_flags", curr_flag +2);
+ /* FIXME the +2. It's to skip the -I */
+ good_flags = g_list_prepend (good_flags, g_strdup (curr_flag + 2));
+ }
+ }
+
+ g_strfreev (flags);
+ return good_flags;
+}
+
+static void
+on_engine_package_single_file_scan_end (SymbolDBEngine *dbe, gpointer user_data)
+{
+ SymbolDBSystem *sdbs;
+
+ sdbs = SYMBOL_DB_SYSTEM (user_data);
+
+ g_signal_emit (sdbs, signals[SINGLE_FILE_SCAN_END], 0);
+}
+
+SymbolDBSystem *
+symbol_db_system_new (SymbolDBPlugin *sdb_plugin,
+ const SymbolDBEngine *sdbe)
+{
+ SymbolDBSystem *sdbs;
+ SymbolDBSystemPriv *priv;
+
+ g_return_val_if_fail (sdbe != NULL, NULL);
+ sdbs = g_object_new (SYMBOL_TYPE_DB_SYSTEM, NULL);
+
+ priv = sdbs->priv;
+ priv->sdbe_globals = (SymbolDBEngine*)sdbe;
+
+ priv->lang_manager = anjuta_shell_get_interface (ANJUTA_PLUGIN(sdb_plugin)->shell,
+ IAnjutaLanguage, NULL);
+
+ g_signal_connect (G_OBJECT (priv->sdbe_globals), "single-file-scan-end",
+ G_CALLBACK (on_engine_package_single_file_scan_end), sdbs);
+
+ return sdbs;
+}
+
+/**
+ * Check on globals db if the project 'package_name' is present or not.
+ */
+gboolean
+symbol_db_system_is_package_parsed (SymbolDBSystem *sdbs,
+ const gchar * package_name)
+{
+ SymbolDBSystemPriv *priv;
+
+ g_return_val_if_fail (sdbs != NULL, FALSE);
+ g_return_val_if_fail (package_name != NULL, FALSE);
+
+ priv = sdbs->priv;
+
+ return symbol_db_engine_project_exists (priv->sdbe_globals,
+ package_name);
+}
+
+static void
+on_pkg_config_output (AnjutaLauncher * launcher,
+ AnjutaLauncherOutputType output_type,
+ const gchar * chars, gpointer user_data)
+{
+ SymbolDBSystem *sdbs;
+ SymbolDBSystemPriv *priv;
+ SingleScanData *ss_data;
+
+ if (output_type == ANJUTA_LAUNCHER_OUTPUT_STDERR)
+ {
+ /* no way. We don't like errors on stderr... */
+ return;
+ }
+
+ ss_data = (SingleScanData *)user_data;
+ sdbs = ss_data->sdbs;
+ priv = sdbs->priv;
+
+ if (ss_data->contents != NULL)
+ {
+ gchar *to_be_freed;
+ to_be_freed = ss_data->contents;
+
+ /* concatenate the output to the relative package's object */
+ ss_data->contents = g_strconcat (ss_data->contents, chars, NULL);
+ g_free (to_be_freed);
+ }
+ else
+ {
+ ss_data->contents = g_strdup (chars);
+ }
+}
+
+static GList **
+sdb_system_files_visit_dir (GList **files_list, const gchar* uri)
+{
+
+ GList *files_in_curr_dir = NULL;
+
+ if (gnome_vfs_directory_list_load (&files_in_curr_dir, uri,
+ GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
+ {
+ GList *node;
+ node = files_in_curr_dir;
+ do {
+ GnomeVFSFileInfo* info;
+
+ info = node->data;
+
+ if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY)
+ {
+ if (strcmp (info->name, ".") == 0 ||
+ strcmp (info->name, "..") == 0)
+ continue;
+
+ gchar *tmp = g_strdup_printf ("%s/%s", uri, info->name);
+
+ /* recurse */
+ files_list = sdb_system_files_visit_dir (files_list, tmp);
+
+ g_free (tmp);
+ }
+ else
+ {
+ gchar *local_path;
+ gchar *tmp = g_strdup_printf ("%s/%s",
+ uri, info->name);
+
+ local_path = gnome_vfs_get_local_path_from_uri (tmp);
+ *files_list = g_list_prepend (*files_list, local_path);
+ g_free (tmp);
+ }
+ } while ((node = node->next) != NULL);
+ }
+
+ return files_list;
+}
+
+static void
+prepare_files_to_be_scanned (SymbolDBSystem *sdbs,
+ GList *cflags,
+ GPtrArray *OUT_files_to_scan_array,
+ GPtrArray *OUT_languages_array)
+{
+ SymbolDBSystemPriv *priv;
+ GList *node;
+
+ priv = sdbs->priv;
+ node = cflags;
+
+ do {
+ GList *files_tmp_list = NULL;
+ gchar *uri;
+
+ uri = gnome_vfs_get_uri_from_local_path (node->data);
+
+ /* files_tmp_list needs to be freed */
+ sdb_system_files_visit_dir (&files_tmp_list, uri);
+ g_free (uri);
+
+ if (files_tmp_list != NULL)
+ {
+ /* last loop here. With files_visit_dir we'll retrieve all files nodes
+ * under the passed directory
+ */
+ GList *tmp_node;
+ tmp_node = files_tmp_list;
+ do {
+ const gchar* file_mime;
+ IAnjutaLanguageId lang_id;
+ const gchar* lang;
+ file_mime = gnome_vfs_get_mime_type_for_name (tmp_node->data);
+
+ lang_id = ianjuta_language_get_from_mime_type (priv->lang_manager, file_mime,
+ NULL);
+
+ /* No supported language... */
+ if (!lang_id)
+ {
+ continue;
+ }
+
+ lang = ianjuta_language_get_name (priv->lang_manager, lang_id, NULL);
+
+ g_ptr_array_add (OUT_languages_array, g_strdup (lang));
+ g_ptr_array_add (OUT_files_to_scan_array,
+ g_strdup (tmp_node->data));
+ } while ((tmp_node = tmp_node->next) != NULL);
+
+ /* free the tmp files list */
+ g_list_foreach (files_tmp_list, (GFunc)g_free, NULL);
+ g_list_free (files_tmp_list);
+ }
+ } while ((node = node->next) != NULL);
+}
+
+static void
+on_engine_package_scan_end (SymbolDBEngine *dbe, gpointer user_data)
+{
+ SymbolDBSystem *sdbs;
+ SymbolDBSystemPriv *priv;
+ EngineScanData *es_data;
+
+ es_data = (EngineScanData *)user_data;
+ sdbs = es_data->sdbs;
+ priv = sdbs->priv;
+
+ /* first of all disconnect the signals */
+ g_signal_handlers_disconnect_by_func (dbe, on_engine_package_scan_end,
+ user_data);
+
+ /* notify listeners that we ended the scan of the package */
+ g_signal_emit (sdbs, signals[SCAN_PACKAGE_END], 0, es_data->package_name);
+
+ /* remove the data from the queue */
+ DEBUG_PRINT ("removing on_engine_package_scan_end %s", es_data->package_name);
+ g_queue_remove (priv->engine_queue, es_data);
+ destroy_engine_scan_data (es_data);
+
+ /* have we got something left in the queue? */
+ if (g_queue_get_length (priv->engine_queue) > 0)
+ {
+ GPtrArray *files_to_scan_array;
+ GPtrArray *languages_array;
+ EngineScanData *es_data;
+
+ files_to_scan_array = g_ptr_array_new ();
+ languages_array = g_ptr_array_new();
+
+ /* peek the head */
+ es_data = g_queue_peek_head (priv->engine_queue);
+
+ DEBUG_PRINT ("gonna scanning on_engine_package_scan_end %s", es_data->package_name);
+ /* the above arrays will be populated with this function */
+ prepare_files_to_be_scanned (sdbs, es_data->cflags, files_to_scan_array,
+ languages_array);
+
+ g_signal_connect (G_OBJECT (priv->sdbe_globals), "scan-end",
+ G_CALLBACK (on_engine_package_scan_end), es_data);
+
+ symbol_db_engine_add_new_project (priv->sdbe_globals, NULL,
+ es_data->package_name);
+
+ g_signal_emit (sdbs, signals[SCAN_PACKAGE_START], 0,
+ files_to_scan_array->len,
+ es_data->package_name);
+
+ symbol_db_engine_add_new_files (priv->sdbe_globals,
+ es_data->package_name,
+ files_to_scan_array,
+ languages_array,
+ FALSE);
+ }
+}
+
+static inline void
+sdb_system_do_scan_package_1 (SymbolDBSystem *sdbs,
+ SingleScanData *ss_data)
+{
+ SymbolDBSystemPriv *priv;
+ gchar *exe_string;
+ priv = sdbs->priv;
+
+ exe_string = g_strdup_printf ("pkg-config --cflags %s",
+ ss_data->package_name);
+
+ g_signal_connect (G_OBJECT (priv->single_package_scan_launcher),
+ "child-exited", G_CALLBACK (on_pkg_config_exit), ss_data);
+
+ anjuta_launcher_execute (priv->single_package_scan_launcher,
+ exe_string, on_pkg_config_output,
+ ss_data);
+ g_free (exe_string);
+}
+
+/**
+ * Scan the next package in queue, if exists.
+ */
+static void
+sdb_system_do_scan_next_package (SymbolDBSystem *sdbs)
+{
+ SymbolDBSystemPriv *priv;
+ priv = sdbs->priv;
+
+ if (g_queue_get_length (priv->sscan_queue) > 0)
+ {
+ /* get the next one without storing it into queue */
+ SingleScanData *ss_data = g_queue_peek_head (priv->sscan_queue);
+
+ /* enjoy */
+ sdb_system_do_scan_package_1 (sdbs, ss_data);
+ }
+}
+
+/**
+ * Scan a new package storing it in queue either for later retrieval or
+ * for signaling the 'busy status'.
+ */
+static void
+sdb_system_do_scan_new_package (SymbolDBSystem *sdbs,
+ SingleScanData *ss_data)
+{
+ SymbolDBSystemPriv *priv;
+ priv = sdbs->priv;
+
+ if (g_queue_get_length (priv->sscan_queue) > 0)
+ {
+ /* there's something already working... being this function called in a
+ * single-threaded fashion we can put the the next parameter on the queue
+ */
+ DEBUG_PRINT ("pushed on queue for later scanning");
+ g_queue_push_tail (priv->sscan_queue, ss_data);
+ return;
+ }
+
+ g_queue_push_tail (priv->sscan_queue, ss_data);
+ sdb_system_do_scan_package_1 (sdbs, ss_data);
+ return;
+}
+
+static void
+on_pkg_config_exit (AnjutaLauncher * launcher, int child_pid,
+ int exit_status, gulong time_taken_in_seconds,
+ gpointer user_data)
+{
+ SymbolDBSystem *sdbs;
+ SymbolDBSystemPriv *priv;
+ SingleScanData *ss_data;
+ GList *cflags = NULL;
+
+ ss_data = (SingleScanData *)user_data;
+ sdbs = ss_data->sdbs;
+ priv = sdbs->priv;
+
+ /* first of all disconnect the signals */
+ g_signal_handlers_disconnect_by_func (launcher, on_pkg_config_exit,
+ user_data);
+
+ if (ss_data->contents != NULL && strlen (ss_data->contents) > 0)
+ {
+ cflags = sdb_system_get_normalized_cflags (ss_data->contents);
+ }
+
+ /* check our ss_data struct. If it has a != null callback then we should
+ * call it right now..
+ */
+ if (ss_data->parseable_cb != NULL)
+ {
+ DEBUG_PRINT ("on_pkg_config_exit parseable activated");
+ ss_data->parseable_cb (sdbs, cflags == NULL ? FALSE : TRUE,
+ ss_data->parseable_data);
+ }
+
+ /* no callback to call. Just parse the package on */
+ if (ss_data->engine_scan == TRUE && cflags != NULL)
+ {
+ EngineScanData *es_data;
+
+ es_data = g_new0 (EngineScanData, 1);
+ es_data->sdbs = sdbs;
+ es_data->cflags = cflags;
+ es_data->package_name = g_strdup (ss_data->package_name);
+
+ /* is the engine queue already full && working? */
+ if (g_queue_get_length (priv->engine_queue) > 0)
+ {
+ /* just push the tail waiting for a later processing [i.e. after
+ * a scan-end received
+ */
+ DEBUG_PRINT ("pushing on engine queue %s", es_data->package_name);
+ g_queue_push_tail (priv->engine_queue, es_data);
+ }
+ else
+ {
+ GPtrArray *files_to_scan_array = g_ptr_array_new ();
+ GPtrArray *languages_array = g_ptr_array_new();
+
+ /* push the tail to signal a 'working engine' */
+ g_queue_push_tail (priv->engine_queue, es_data);
+
+ /* the above arrays will be populated with this function */
+ prepare_files_to_be_scanned (sdbs, cflags, files_to_scan_array,
+ languages_array);
+
+ g_signal_connect (G_OBJECT (priv->sdbe_globals), "scan-end",
+ G_CALLBACK (on_engine_package_scan_end), es_data);
+
+ symbol_db_engine_add_new_project (priv->sdbe_globals, NULL,
+ es_data->package_name);
+
+ /* notify the listeners about our intention of adding new files
+ * to the db
+ */
+ g_signal_emit (sdbs, signals[SCAN_PACKAGE_START], 0,
+ files_to_scan_array->len,
+ es_data->package_name);
+
+ /* note the FALSE as last parameter: we don't want
+ * to re-scan an already present file. There's the possibility
+ * infact to have more references of the same files in different
+ * packages
+ */
+ symbol_db_engine_add_new_files (priv->sdbe_globals,
+ es_data->package_name,
+ files_to_scan_array,
+ languages_array,
+ FALSE);
+ }
+ }
+
+ /* destroys, after popping, the ss_data from the queue */
+ g_queue_remove (priv->sscan_queue, ss_data);
+ destroy_single_scan_data (ss_data);
+
+ /* proceed with another scan */
+ sdb_system_do_scan_next_package (sdbs);
+}
+
+gboolean
+symbol_db_system_scan_package (SymbolDBSystem *sdbs,
+ const gchar * package_name)
+{
+ SingleScanData *ss_data;
+ SymbolDBSystemPriv *priv;
+
+ g_return_val_if_fail (sdbs != NULL, FALSE);
+ g_return_val_if_fail (package_name != NULL, FALSE);
+
+ priv = sdbs->priv;
+
+ /* does is already exist on db? */
+ if (symbol_db_system_is_package_parsed (sdbs, package_name) == TRUE)
+ {
+ DEBUG_PRINT ("symbol_db_system_scan_package: no need to scan %s",
+ package_name);
+ return FALSE;
+ }
+
+ /* create the object to store in the queue */
+ ss_data = (SingleScanData*)g_new0 (SingleScanData, 1);
+
+ /* we don't have chars now. Just fill with the package_name */
+ ss_data->sdbs = sdbs;
+ ss_data->package_name = g_strdup (package_name);
+ ss_data->contents = NULL;
+ ss_data->parseable_cb = NULL;
+ ss_data->parseable_data = NULL;
+ ss_data->engine_scan = TRUE;
+
+ /* package is a new one. No worries about scan queue */
+ sdb_system_do_scan_new_package (sdbs, ss_data);
+ return TRUE;
+}
+
+void
+symbol_db_system_is_package_parseable (SymbolDBSystem *sdbs,
+ const gchar * package_name,
+ PackageParseableCallback parseable_cb,
+ gpointer user_data)
+{
+ SingleScanData *ss_data;
+ SymbolDBSystemPriv *priv;
+
+ g_return_if_fail (sdbs != NULL);
+ g_return_if_fail (package_name != NULL);
+
+ priv = sdbs->priv;
+
+ /* create the object to store in the queue */
+ ss_data = (SingleScanData*)g_new0 (SingleScanData, 1);
+
+ /* we don't have chars now. Just fill with the package_name */
+ ss_data->sdbs = sdbs;
+ ss_data->package_name = g_strdup (package_name);
+ ss_data->contents = NULL;
+ ss_data->parseable_cb = parseable_cb;
+ ss_data->parseable_data = user_data;
+ /* this is just an info single_scan_data */
+ ss_data->engine_scan = FALSE;
+
+ /* package is a new one. No worries about scan queue */
+ sdb_system_do_scan_new_package (sdbs, ss_data);
+}
Added: trunk/plugins/symbol-db/symbol-db-system.h
==============================================================================
--- (empty file)
+++ trunk/plugins/symbol-db/symbol-db-system.h Sun Jul 6 23:03:38 2008
@@ -0,0 +1,106 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta_trunk
+ * Copyright (C) Massimo Cora' 2008 <maxcvs email it>
+ *
+ * anjuta_trunk is free software.
+ *
+ * You may 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.
+ *
+ * anjuta_trunk 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 anjuta_trunk. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _SYMBOL_DB_SYSTEM_H_
+#define _SYMBOL_DB_SYSTEM_H_
+
+#include <glib-object.h>
+
+#include "symbol-db-engine.h"
+
+G_BEGIN_DECLS
+
+#define SYMBOL_TYPE_DB_SYSTEM (sdb_system_get_type ())
+#define SYMBOL_DB_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SYMBOL_TYPE_DB_SYSTEM, SymbolDBSystem))
+#define SYMBOL_DB_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SYMBOL_TYPE_DB_SYSTEM, SymbolDBSystemClass))
+#define SYMBOL_IS_DB_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SYMBOL_TYPE_DB_SYSTEM))
+#define SYMBOL_IS_DB_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SYMBOL_TYPE_DB_SYSTEM))
+#define SYMBOL_DB_SYSTEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SYMBOL_TYPE_DB_SYSTEM, SymbolDBSystemClass))
+
+typedef struct _SymbolDBSystemClass SymbolDBSystemClass;
+typedef struct _SymbolDBSystem SymbolDBSystem;
+typedef struct _SymbolDBSystemPriv SymbolDBSystemPriv;
+
+#include "plugin.h"
+
+struct _SymbolDBSystemClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (* single_file_scan_end) ();
+ void (* scan_package_start) (guint num_files, const gchar *package);
+ void (* scan_package_end) (const gchar *package);
+};
+
+struct _SymbolDBSystem
+{
+ GObject parent_instance;
+ SymbolDBSystemPriv *priv;
+};
+
+typedef void (*PackageParseableCallback) (SymbolDBSystem *sdbs,
+ gboolean is_parseable,
+ gpointer user_data);
+
+
+GType sdb_system_get_type (void) G_GNUC_CONST;
+
+SymbolDBSystem *
+symbol_db_system_new (SymbolDBPlugin *sdb_plugin,
+ const SymbolDBEngine *sdbe);
+
+/**
+ * Perform a check on db to see if the package_name is present or not.
+ */
+gboolean
+symbol_db_system_is_package_parsed (SymbolDBSystem *sdbs,
+ const gchar * package_name);
+
+/**
+ * Test whether the package has a good cflags output, i.e. it's parseable.
+ * This function does not tell us anything about the db. It could be that
+ * the package is already on db.
+ * Because this function calls AnjutaLauncher inside, the answer is asynchronous.
+ * So user should put his gui in 'waiting/busy' status before going on, and of course
+ * he should also prepare a callback to receive the status.
+ */
+void
+symbol_db_system_is_package_parseable (SymbolDBSystem *sdbs,
+ const gchar * package_name,
+ PackageParseableCallback parseable_cb,
+ gpointer user_data);
+
+/**
+ * Scan a package. We won't do a check if the package is really parseable, but only
+ * if it already exists on db. E.g. if a package has a wrong cflags string then
+ * the population won't start.
+ */
+gboolean
+symbol_db_system_scan_package (SymbolDBSystem *sdbs,
+ const gchar * package_name);
+
+G_END_DECLS
+
+#endif /* _SYMBOL_DB_SYSTEM_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]