Notes for Developers on contributing to Anjuta
----------------------------------------------

(TO BE EXPANDED OVER TIME - please post submissions to the Anjuta 
Development mailing list or the project maintainer)

Getting Started:
---------------
The first thing to do is to decide whether you want to work on Anjuta or
Anjuta2. Briefly, Anjuta2 has a much cleaner architecture, so if you are
a component/OOP freak, or are hear to teach yourself good GNOME
programming, anjuta2 might be the right place. OTOH, Anjuta has many
more features and is (arguably) more actively developed and maintained.
So, if you want to contribute to an IDE that works now and use it
yourself, IMO you're better off contributing to Anjuta. There are plans
for a merge of some sort in the future.

Second thing to do is to get a build working. Both anjuta and anjuta2 can be
built using jhbuild, which is the recommended way to build GNOME
2.2. and Anjuta(2). It is advisable to use '--enable-warnings
--enable-debug' with configure while building anjuta if you want to hack
on it. Anjuta can be used to hack on Anjuta, and there is a anjuta.prj
file in CVS for this purpose.

Once you have got anjuta built and loaded in itself, the most important
thing is to decide what to work on (the TODO, as you say). There are
many directions you can take. I'm listing some of the more common ones
in order of difficulty.

0. Use it, test it, report bug, request features, etc. In short, become
an active user. That is how most people become anjuta developers.

1. Documentation and translation. While this might not be a very
attractive option, it has many benefits for newbie developers. You get
to know the code and feature set better, and learn the way GNOME
projects are developed. Also, you will be helping a lot of people to use
Anjuta better. You can use the wiki or update the manuals, DAQ, etc.
that are supplied with the source.

2. Scratch your itch. This is probably the most attractive option for a
reasonably experienced developer. Find something which does not work for
you, or some feature that you want but is missing. Then report it on the
devel list saying that you'd want to work on it (this is essential to
avoid duplication). Then send us patches !

3. Fixing bugs and implementing feature requests. You can find our bug
and RFE database at the sourceforge page (http://sf.net/projects/anjuta). You
can also have a look at the reasonably up-to-date TODO file we maintain
in the source code.

4. Working on the porting anjuta features to anjuta2. This is a noble
undertaking but likely to be hard work, and probably not suitable for
newbie developers.

5. Working on porting anjuta2 architecture to anjuta. This is probably
the most difficult one. However, if you are an experienced developer,
you'll find this enormously rewarding and very challenging. Read the
ROADMAP file that comes with the source code to understand where we are
and where we want to be in the long term. Then pick up one of the action
points and try to implement it.

Resources:
----------

Homepage: http://www.anjuta.org/
Project details page: http://sourceforge.net/projects/anjuta/
CVS snapshots: http://www.anjuta.org/cvs/
Anonymous CVS Access: cvs -z3 -d:pserver:anonymous@anoncvs.gnome.org:/cvs/gnome co anjuta
Mailing Lists: http://sourceforge.net/mail/?group_id=14222
Bug database: http://sourceforge.net/tracker/?atid=114222&group_id=14222&func=browse
Feature Requests: http://sourceforge.net/tracker/?atid=364222&group_id=14222&func=browse
Forums: http://sourceforge.net/forum/?group_id=14222
IRC: irc.gnome.org (Channel: #anjuta and #devel-apps)

Tools
-----

IMPORTANT: please be careful about using Anjuta to develop Anjuta.
Any instabilities in the development version may cause problems.

Anjuta is written using a mixture of C and C++. You will require
the standard GNU tool chain and current stable GNOME libraries to 
build and work with the Anjuta sources.


Submitting patches
------------------

Patches are good, and patches are always welcome! Small, self-contained 
patches are preferred - larger patches which touch on a large number 
of areas of the source tree are more complex to apply and test. 

Patches may be submitted to the project website, to the mailing lists, 
or directly to the project maintainer.

The six-step plan to patching happiness is as follows:

1) All patches should be submitted in *unified* form, i.e. created 
with the command "diff -u" or "cvs diff -u"). 

Make your changes in all files (including the ChangeLog file) and run
"cvs diff -u > patch.diff" in the top level anjuta/ directory. This diff
file will contain patches for all of the files together.

Remember to run the cvs diff for the *top* project directory. It will
automatically recurse into the subdirectories and generate the patches.

We ask for patches in this format because:
- more often then not, patches are out of sync with current CVS. This 
can happen because someone is submitting a patch taken against an old 
version of Anjuta, or against anonymous CVS (which is usually out of 
sync for 24 hours). Therefore, the maintainers have to review patches 
manually.
- if a patch file is opened in Anjuta (or editors such as Nedit) in 
"Diff" mode, *unified* formats are more readable and errors and 
mis-syncs are easily detected. Non-unified formats are hard to read.
- unified patches are more intelligent in recognizing changed lines
(because by default there is a 3-line context buffer).

2) Diffs taken against CVS should be preceded by "cvs -z3 up" in 
*all* cases.

3) If anonymous CVS is used, one way of to matching more closely with 
the actual CVS is by running "cvs -z3 up" on all three anonymous CVS 
servers (annocvs1.gnome.org, annocvs2.gnome.org and annocvs3.gnome.org). 
Run the following command in succession for the three servers:

cvs -d:pserver:annocvs[123].gnome.org:/cvs/gnome/anjuta

Details about the anonymous CVS servers can be obtained by issuing the 
command "host annocvs.gnome.org"

4) If the patch is big or is not high priority (i.e. things other than 
stability patches), then either send it to the lead developers directly 
(cc-ing them together is a nice idea), or post it on the sourceforge page. 
*Never* post big patches to the mailing lists, since they will annoy 
subscribers and are liable to be rejected by the list server. Send
a reference email to the list mentioning that you have sent a patch.

5) *Always* include a ChangeLog entry as part of the diff to ensure that
your entry is also committed directly with your name mentioned.

6) Name the patch with a useful filename. e.g. avoid calling your patch
patch.diff, anjuta.diff or something like that. It is easier to manage
a queue of patches named things like biswa-print-20020605.diff and 
bug-544912.diff as the names are more meaningful. Include the bug number
or your name and the date in the name of the file. Thanks!


General source structure
------------------------

When editing the code, adding new classes or methods, etc. please 
conform with the style already followed in the source files.

If a section of code will require further work, please add helpful
comments of the form /* FIXME: ... */

Conventions:
* _cbs suffix - callbacks
* _gui suffix - UI definitions for windows, dialogs etc.

Key elements:
* src/ - the main Anjuta sources
* scintilla/ - the editor
* widgets/ - additional widgets used
* gdl/ - Gdl Widgets (esp. the dock)
* launcher/ - launcher wrapper used by the debugger
* printing/ - gnome-print support
* tagmanager/ - the tagmanager library
* plugins/ - plugin components (see the sample for more information)


Scintilla
---------

The editing component in Anjuta is Scintilla (www.scintilla.org). 
The Scintilla sources are imported to the scintilla/ directory in the
Anjuta source tree - some reorganization is required:

Scintilla		Anjuta
---------		------
src/		->	scintilla/
gtk/		->	scintilla/
include/	->	scintilla/include

These are used to compile libscintilla.a, the library which provides
the bulk of Anjuta's editing functions.

The interface into Scintilla is in src/aneditor.cxx. This is based on
SciTE and a lot of care needs to be taken when merging code, since it
combines several different files from the SciTE source tree and is
quite flexible in the ways that they are used. Also, note that lexer
objects from Scintilla must be referenced in src/Makefile.am in order 
to get linked into Anjuta.


Messages and translations
-------------------------

There are a few rules we ask contributors to follow when adding new
message strings and labels to Anjuta.

1. BE CONSISTENT!! 
a) refer to the standard GNOME Word List in the GNOME Style Guide 
(http://developer.gnome.org/documents/style-guide/) when referencing 
different user interface features, and then use the same terminology 
throughout. Try to ensure that your use of words matches the rest of
the code.
b) make sure that mixed case is only used where it makes sense to do so.

Example: "Unable to Start Plug in Module %s".
This message is not ideal since the standard terminology is "plugin" (so 
please do not use "Plug in", "plug-in", etc.). Also, in this case there 
is no reason for the words "start" and "module" to start with an uppercase 
letter.

There are a few standard terms we use - in particular:
- plugin
- Project (always with an uppercase P)

2. Do not use contractions (don't, can't, etc.). These can make a message 
difficult to translate.

3. Do not use colloquial expressions. They may seem cool or amusing, but 
actually they can be hard to translate into all languages. Also, although as 
developers it is OK to have fun, messages with certain language in them can be 
intimidating for new or inexperienced users, and are not very professional.

Example: "You FOOL! I can not attach to myself." 
This message was originally used in the debugger code, and was removed some 
time ago. It is quite fun, but a new user might be put off. 

4. Do not use the first person "I" for referring to Anjuta in messages 
(again, the previous message is an example of this). This is bad practice in 
technical writing. If you need to refer to Anjuta itself, please use the word
"Anjuta"! :-)


Documentation
-------------

The documentation is stored in the manuals/ directory, and consists 
of a set of SGML sources conforming to the GNOME Documentation Project's
Style Guide. Please ensure that all additions also follow these guidelines.

Screenshots used in the manual are processed using The Gimp. Single dialogs
and menus are converted to RGB and the Script-Fu Drop Shadow effect applied 
(with the default settings). All documentation images are in PNG format.

Translations of application messages are stored in the standard po/ 
directory structure at the top level of the source tree.



Graphics
--------

PNG format is preferred for application graphics.

The image filenames are mapped in the file src/pixmaps.h, with helper functions
for manipulating them in src/resources.c. Please use this method for including
graphics and do not use the filenames directly.



ARCHITECTURE:
-------------

The current architecture is rather monolithic and inflexible. There is a drive
undergoing to change this. Please have a look at the ROADMAP file for details.

1) Event Driven:
----------------

When Anjuta was first designed, the primary goal was to enable the use of 
external unix commands in a more productive and intuitive way. Therefore,
anjuta follows non-blocking input/output operations aggressively. This means
that anjuta UI will not freeze while it performs a lengthy task. All such
jobs are event-driven (I am not referring to the gtk-events here) and works
on asynchronous basis. The example jobs are compilation, debugging, file search,
class updates etc. While asynchronous event-driven implementation is more
complex than it's synchronous counter part, it gives a smooth and non frustrative
operation. :-)

1a) Executing external commands in non-blocking mode:
-----------------------------------------------------

launcher (launcher.[c,h]) is the class responsible for executing external commands in
non-blocking mode. launcher_execute takes 4 arguments, first is the command
to be executed, second is the stdout callback, stderr callback and the child
terminated callback. They are called when there is chars available in the
stdout and stderr and when the child terminates respectively.

/* Start a job. */
/* command_str is the command to be executed */
/* stdout_func is the callback to be called when chars are received in STDOUT from the process */
/* stderr_func is the callback to be called when chars are received in STDERR from the process */
/* commnad_terminated is the callback to be called when the job is completed or terminated */
gboolean launcher_execute(gchar* command_str,
                               void (*stdout_func)(gchar*),
                               void (*stderr_func)(gchar*),
                               void (*command_terminated)(gint status, time_t time));

The three callbacks stated above should be of the following prototype:

/* The function names are arbitary */
void stdout_func (gchar * chars);
void stderr_func (gchar * chars);
void command_terminated (int return_status, time_t total_time);

Refer to the file launcher.h for further information.

Remember to use this launcher instead of gtk/glib non-blocking IO interface.

1b) Process synchronization:
----------------------------

The rest of the processes, which are quick (less that 1/10 sec) in execution
or whose IO interfaces are not necessary, can safely be forked just like a
normal fork. For shorter execution wait() system call would suffice it's
synchronization when the process ends, but for longer jobs, asynchronous
notification is suggested.

For asynchronous notification of child termination, a few additional steps
are needed to be done just after the fork() call. Register the child pid
with the call to anjuta_register_child(). It takes two arguments, first the
child pid and second, the callback to be called when the process with that
pid terminates. The call to the callback is shipped with the child exit status.

/* Registers the child for asynchronous notification */
void anjuta_register_child_process (pid_t pid,
			       void (*callback) (int status, gpointer user_data),
			       gpointer user_data);

/* Unregisters the child. No notification will be emited thereafter. */
void anjuta_unregister_child_process (pid_t pid);

The callback should be of the following prototype:

/* function name choosen arbitarily */
void child_terminated_callback (int status, gpointer user_data);

For further information, refer to the file anjuta.c.

WARNING: Do not hook up the signal SIGCHLD, for the similar purpose. Just use
the above method to perform the same thing. SIGCHLD is used by Anjuta 
internally to manage the children.

2) How to add new menu items in the Main Menu:
----------------------------------------------
The files to look for are main_menubar_def.h, mainmenu_callbacks.[ch] and
main_menubar.[ch]. You might also need to have a peek at controls.[ch].

2a) How to add new menu items in the Edit->Insert menu:
-------------------------------------------------------
There are 6 files which need to be updated.

* main_menubar_def.h - update insert_submenu_uiinfo (and others 
e.g. inserttext1_submenu_uiinfo) to add the item, help text and name of the 
callback function.
* main_menubar.h - update struct _EditSubMenu with the name of the menu widget
* main_menubar.c - update the array of items referenced around mb->edit.insert_*
* mainmenu_callbacks.h, mainmenu_callbacks.c - declare the name of the new callback 
function in the header file, and add the new function itself based on the
existing on_insert_*() functions
* controls.c - update the list of gtk_widget_set_sensitive calls with a new entry for 
the menu widget em->insert_* (as specified in main_menubar.h)


3) How to add new toolbar items in the Toolbars:
------------------------------------------------
Have a look at toolbar.[ch] and controls.[ch].


4) Dialogs and Windows:
-----------------------
When adding new dialogs or windows, please ensure...

- the WMCLASS attribute is set to a unique value

- a default icon is defined
Dialogs will take the Anjuta app icon by default, but windows (GtkWindow) will 
need the following lines added to their creation code:

#include <libgnomeui/gnome-window-icon.h>
...
    gnome_window_icon_set_from_default(GTK_WINDOW(window1));



5) Property/Config management:
------------------------------
Anjuta does not use gconf (at least, not now), and instead has its own config 
manager/properties manager. The source for this is in src/properties.cxx.
There are some advantages in using this over gconf, including the ability to
do variable substitution. Anjuta needs these advantages to operate properly.
Even though gconf have additional advantages, we are not really concerned about
them right now. In future, things may change, though.

FIXME.

When Anjuta was started, there were not many application support libraries.
To cope up with the requirements, anjuta had to implement the supports within
itself. And it is still going.

6) Global shortcut keys:
------------------------

The following callback (located in anjuta.c) :

gint
on_anjuta_window_key_press_event (GtkWidget   *widget,
				  GdkEventKey *event,
				  gpointer     user_data)

is called when some key is pressed in the whole environement, because the
event is triggered off by the main GtkWindow. It has been created for navigating
between the different buffers (Ctrl-[Shift]-Tab).

It's aim is to implement global shortcut keys. For now on, it only works in the main window.

Note : It's possible to install such an handler in the other windows if it's
really needed, so the new callback can propagate the event to app (the GnomeApp)
and we'll have a central place for those shortcuts.

6a) How to add a global shortcut:
---------------------------------

It's pretty self-explanatory, but here's the "how to" :

Just before the callback, you have some GDK modifiers "shortcuts", just because
it's a pain to write this each time, and the 'm_' stuff makes you see in an instant
which modifiers are used (Shift or Control) :

enum {
	m__ = 0,
	mS_ = GDK_SHIFT_MASK,
	m_C = GDK_CONTROL_MASK,
	mSC = GDK_SHIFT_MASK | GDK_SHIFT_MASK
};

These are to ease filling the structure (1) : 

You add an id for your shortcut in the enum : 

enum {
	ID_NEXTBUFFER = 0,
	ID_PREVBUFFER = 1
	...
};

Then, you add a line with the modifiers used, the GDK corresponding key, and the
shortcut id.

(1):

static ShortcutMapping global_keymap[] = {
	{ m_C, GDK_Tab,		 ID_NEXTBUFFER },
	{ mSC, GDK_ISO_Left_Tab, ID_PREVBUFFER },
	...
	{ 0,   0		 0 }
};

Finally, you add a case in the callback's switch :

gint
on_anjuta_window_key_press_event (GtkWidget   *widget,
	...

	switch (global_keymap[i].id) {
	case ID_xxx:
		<statements>

		break;
	}
	default:
		return FALSE;
	}

	...
	

7) How to add a new project type:
---------------------------------

It is currently a bit difficult - the code is spread around and not
very consistent. 

Things to do as a start:

- in project_type.c and add an array for your project type (this 
is well-commented). Add it to the load_project_type function.

- in project_dbase.h: Add your project type to the enum PROJECT_TYPE_*

- in wizard_gui.c: create_project_type_selection_page():
Add an icon to the list for the project type and define it in pixmaps.h
(If you are a bad artist, it might be good to ask for help with this on 
the mailing list)

- appwiz_page1.c: Add your type in on_wizard_app_icon_select()

So that was the easy part ;-)

Now search for every occurrence of PROJECT_TYPE_* and project_type_* in 
the code, and decide if you have anything to add (there are about 
10 places where it occurs).

Good luck!

8) How to correctly credit people:
----------------------------------

New contributors must always be credited. There are three files which 
must be updated:

	* THANKS
	* widgets/e-shell-about-box.c
	* manuals/C/anjuta-manual/authors.sgml

You should also ensure that you submit headed ChangeLog entries with a 
name and e-mail address when you submit a patch.
