# gEDA Developer Tips, tricks and hints

## How to branch correctly using CVS

Here’s a summary of what should happen with development on a branch that is intended to later be merged to the trunk. Suppose the branch is called “mine”.

1) tag the repository (trunk) to create a branch point tag:

     cvs tag mine-base

2) branch

     cvs tag -b -r mine-base mine

What step #1 does is to keep track of where the “mine” branch started
from. The "-r mine-base” in step #2 says to create the branch starting
from the tag “mine-base”. It is important to do this because you need
to be able to know where each file is rooted (i.e., what version in the
trunk it is derived from).

Usually, it is a good idea to periodically merge changes which have taken
place on the trunk to the branch. This will reduce the amount of work when
the work on the branch is ready to go back to the trunk.

# go to where the trunk is checked out and update it

     cd /to/my/trunk/sources
     cvs update -PdA

# create a temporary tag in case someone commits stuff while you’re
# in the middle of this procedure. This keeps you from losing anything.

     cvs tag merge-mine

# go to your branch source tree

     cd /to/my/branch/sources
     cvs update -Pd

# the following says to apply the changes that have taken place on
# the trunk between the version tagged with “mine-base” and “merge-mine”
# to your branch source tree

     cvs update -j mine-base -j merge-mine -dP

# if all goes well, you’ll have no conflicts. It is not uncommon
# for there to be some cases where you have to resolve conflicts by
# hand. In this case the affected files will have a special comment
# showing what your file on the branch had and what the file tagged as
# merge-mine had. You, as the programmer, have to figure out what is
# correct. Once this is all done, proceed.

# checkin with a message like “sync with trunk” or
# “pull up revs #### from the trunk” (if you were pulling up
# a specific change).

     cvs ci

# Now we move the branch point tag to the temporary merge tag
# This is because we have changed what rev each file in the branch
# is based on in the trunk. This is known as re-rooting.

     cvs tag -F -r merge-mine mine-base

# now we don’t need the temporary merge tag anymore so remove it

     cvs tag -d merge-mine

When it is time to merge changes that have taken place on a branch back
to the trunk (usually marking the end of that branch), first do a final
trunk → branch merge as mentioned above. Then do a branch → trunk merge.

Now for a branch to trunk merge you’d do

     cd /to/my/trunk/sources
     cvs update -PdA
     cvs update -j mine-base -j mine -dP

# resolve conflicts

     cvs ci
     cvs tag -F mine-base

This takes any changes between “mine-base” and “mine” and tries to apply
it to the trunk. If it all goes cleanly, you just check it in otherwise you
have to resolve conflicts. Then you move the branch point tag because the trunk
now reflects the lastest in the branch.

The above was contributed by Dan McMahill

## Doxygen Comments and styles

Any volunteer for writing some notes?

- which keywords to use
- a template for a function
- a template for structs?
- bug, todo and fixme tags

## Dialogs: Design and Behaviour

### Dialog Design

There’s a nice document from the gnome guys called Gnome HIG. There are several suggestions on how to design dialogs and how they should behave.

The dialog design is mostly a matter of taste:

- alignment of elements. See Window Layout
- right alignment of dialog buttons
- some spacing around the dialog (but how much?)
- some spacing between the elements (vertical and horizontal)
- option groups with frames or indentation?
- frame labels or bold headlines?

Misc:

- with a libsexy widget it would be possible to place an icon inside the text entry this would be usefull for some dialogs:
  - the filter entry in the component select dialog
  - the file select in the print dialog
  - the file select in the export png dialog

### Modal or Nonmodal dialogs

A modal dialog is required whenever the main application provides data for the dialog.

    Example:
      The dialog is called with a selection list and the dialog only should operate on this selection.

A modal dialog is OK too, if the dialog is only called very seldom. The file open dialog could be nonmodal because it does not require any input from the application.

A modal dialog is not OK if there is a lot of user interaction with the dialog. The component selection is a good example.

### Where to place the dialog

A dialog can be put on different places in on the screen. A list of possible places can be found in the GtkReference

The current dialogs are placed either on the mouse position (GTK_WIN_POS_MOUSE) or at no preset position (GTK_WIN_POS_NONE). The Gnome HID does not say anything about that topic.

The default setting is GTK_WIN_POS_NONE for GtkWindow see GtkWindow. The default for GtkDialog is GTK_WIN_POS_CENTER_ON_PARENT ( taken from the GtkDialog source).

### Placing dialogs in front of their parent window

Most of the dialogs are placed in front of their parent window using the transient_for property (see. GtkReference). This property should be set for all modal dialogs.

For nonmodal dialogs the setting of transient_for property is not obvious. While in gschem for example the coord dialog should stay above the parent window, the log window does not need to stay in front of it.

Note: There is an older mechanism that keeps the the dialogs in front of gschem. If the raise-dialog-boxes-on-expose variable is set to enable in one of gschem’s configuration files, it may cause problems with some window managers. If dialogs are flickering at 100% CPU load, then disable that setting.

    ; raise-dialog-boxes-on-expose string
    ;
    ; Controls if dialog boxes are raised whenever an expose event happens
    ; Default is enabled
    ;
    ;(raise-dialog-boxes-on-expose "enabled")
    (raise-dialog-boxes-on-expose "disabled")

### Button order in dialogs

Button order at the bottom of the dialog depends on which operating system the user is using. GTK handles this automatically (require version > 2.6.0) , but requires the developers set the alternative button order. For more information, check the GTK documentation here.

The alternative button order is set with just one call to a GTK function:

    #if GTK_CHECK_VERSION (2,6,0)
      /* Set the alternative button order (ok, cancel, help) for other systems */
      gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
    					  GTK_RESPONSE_OK,
    					  GTK_RESPONSE_NO,
    					  GTK_RESPONSE_CANCEL,
    					  GTK_RESPONSE_HELP,
    					  -1);
    #endif

This should be done for every new dialog created, before running it.

### Dialog design of the current dialogs

- There is some space around the whole dialog (DIALOG_BORDER_SPACING).
- Some indentation to show the topic group (DIALOG_INDENTATION) below it’s bold headline.
- The vertikal and the horizontal separation is done with DIALOG_H_SPACING and DIALOG_V_SPACING.

### Source template for simple dialogs

This template is not intented to compile, but you can easily copy the code block that you need.

    void dialog (TOPLEVEL *w_current)
    {
      GtkWidget *vbox, *label, *alignment, *table;
      GtkWidget *dialog;

      /* only create the dialog if it is not there yet. This usually is a
         widget pointer in the w_current structure:
         dialog = w_current->tewindow */
      if (!dialog) {
        dialog = gtk_dialog_new_with_buttons(_("Dialog title"),
    					 /* the parent window or NULL */
    					 GTK_WINDOW(w_current->main_window),
    					 /* dialog properties */
    					 GTK_DIALOG_MODAL, /* 0 for nonmodal dialogs */
    					 /* dialog buttons and response signals */
    					 GTK_STOCK_CANCEL,
    					 GTK_RESPONSE_REJECT,
    					 GTK_STOCK_OK,
    					 GTK_RESPONSE_ACCEPT,
    					 NULL);

    #if GTK_CHECK_VERSION (2,6,0)
        /* Set the alternative button order (ok, cancel, help) for other systems */
        gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
    	  				    GTK_RESPONSE_OK,
    					    GTK_RESPONSE_NO,
    					    GTK_RESPONSE_CANCEL,
    					    GTK_RESPONSE_HELP,
    					    -1);
    #endif

        /* set default response signal. This is usually triggered by the
           "Return" key */
        gtk_dialog_set_default_response(GTK_DIALOG(dialog),
    				    GTK_RESPONSE_ACCEPT);

        /* set the function for handling the button responses and dialog close
           for nonmodal dialogs you can use dialog_run() too.*/
        gtk_signal_connect(GTK_OBJECT(dialog), "response",
    		       GTK_SIGNAL_FUNC(dialog_response), w_current);

        /* where to place the dialog: GTK_WIN_POS_MOUSE or GTK_WIN_POS_NONE */
        gtk_window_position(GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);

        /* set the border spacing and the vbox spacing of the dialog */
        vbox = GTK_DIALOG(dialog)->vbox;
        gtk_container_set_border_width(GTK_CONTAINER(dialog),DIALOG_BORDER_SPACING);
        gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING);

        /* create a label (with markup) and pack it into the dialog box */
        label = gtk_label_new(_("<b>Section label</b>"));
        gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
        gtk_misc_set_alignment(GTK_MISC(label),0,0);
        gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);

        /* create a alignment container with the DIALOG_INDENTATION on the left */
        alignment = gtk_alignment_new(0,0,1,1);
        gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0,
    			      DIALOG_INDENTATION, 0);
        gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);

        /* a table can store several entries. It is stored in the aligment container.
           Note: the vertical and horizontal cell spacings */
        table = gtk_table_new (3, 2, FALSE);
        gtk_table_set_row_spacings(GTK_TABLE(table), DIALOG_V_SPACING);
        gtk_table_set_col_spacings(GTK_TABLE(table), DIALOG_H_SPACING);
        gtk_container_add(GTK_CONTAINER(alignment), table);

        /* a simple text label in one table cell with left alignment.
           Note: the GTK_FILL in the third line is required */
        label = gtk_label_new(_("Text:"));
        gtk_misc_set_alignment(GTK_MISC(label),0,0);
        gtk_table_attach(GTK_TABLE(table), label, 0,1,0,1, GTK_FILL,0,0,0);

        /* a simple text entry completes the option row */
        textentry = gtk_entry_new_with_max_length (10);
        gtk_table_attach_defaults(GTK_TABLE(table), textentry, 1,2,0,1);
        gtk_entry_set_activates_default(GTK_ENTRY(textentry), TRUE);

        /* ..... more table rows with options, or new sections */

        /* create references to all widgets that you need later */
        GLADE_HOOKUP_OBJECT(dialog, sizeentry,"textentry");

        /* show all widgets recursivly */
        gtk_widget_show_all(dialog);
      }

      else {
        /* Dialog is already there. Present it to the user.
           This is only required if you have a nonmodal dialog */
        gtk_window_present(GTK_WINDOW(dialog));
      }

      /* always set the current values to the dialog
         If you're placing that part at the end of the dialog function you can
         easily create dialogs that can be called, even if they are already open */
      textentry = g_object_get_data(G_OBJECT(dialog), "textentry");
      gtk_entry_set_text(GTK_ENTRY(textentry), string);
      /* select the text region that the user usually likes to overwrite */
      gtk_entry_select_region(GTK_ENTRY(textentry), 0, strlen(string));
    }

The response function for such a dialog may look like this:

    void dialog_response(GtkWidget *widget, gint response, TOPLEVEL *w_current)
    {
      switch (response) {
      case GTK_RESPONSE_ACCEPT:
        /* apply the dialog settings:
           just insert your code here if it is short
           call an extra apply function if the required code is long */
        break;
      case GTK_RESPONSE_REJECT:
      case GTK_RESPONSE_DELETE_EVENT:
        /* for modal dialogs just do nothing,
           for nonmodal dialogs, destroy the dialog and clean up */
        break;
      default:
        /* catch wrong signals signals (paranoid error checking ;-)) */
        printf("dialog_response(): strange signal %d\n", response);
      }

      /* for nonmodal dialogs just do nothing,
         for modal dialogs, always destroy the dialog and clean up */
    }

### Current Dialog Issues in Gschem

- every dialog has it’s own design
- dialog placement: mouse position or no predefined position?
- dialogs do not remember their last size, position and contents.
- missing keyboard shortcuts

Here’s a list of things that could be improved:

##### Print Dialog

- change design?

##### Write Image

- In the fileselect dialog the default filename is missing if the file does not exist
- Return key does not work in the filename entry

##### Execute Script

##### Edit Text

- some missing keyboard shortcuts
- add *unmodified* tags if there are multiple selections
- maybe add some color pixbufs for the color
- maybe replace the text alignment with nine ratio buttons, toggle buttons with icons or …

##### Color Dialog

- maybe add some color pixbufs for the color

##### Line Width and Type

- keyboard shortcuts missing
- icons for the line type

##### Fill Type

- keyboard shortcuts missing
- icons in the fill type

##### Translate Symbol

##### Page Manager

- wrong button order? Depends on whether you think the refresh button is the main action button or just an extra button.
- Maybe the “Return” key should trigger Refresh

##### Component Selector

- strange edit widget when typing and the tree is selected (It’s a search helper widget, disable it?!)

##### Single Attribut Editor

- when multiple elements are selected and you call edit (ee) there are a few problems:
  - if the first object is text, then this dialog is opened (but with the wrong list parameter
  - if the first object is complex then the multiple attribute editor is called

##### Multi Attribute Editor

##### Add Text

##### Arc Params

- add the diameter to the dialog, but select the start angle entry (increment = grid)
- let “ee” call that dialog if only a single arc is selected
- maybe add a section label

##### Insert Picture

##### Picture Replace

- the new picture uses the aspect ratio of the old picture
- the dialog has lots in common with the Insert Picture dialog. They could use some code together

##### Find Text

- manipulates the mouse pointer (maybe the zooming code is the culprit). Just press “Return” to trigger a FindNext
- if you select hierarchy and the found text is in a different schematic, then the filename in the title is not updated
- maybe add an option: “Select all matching text objects”, disable hierarchy for that feature!
- gschem hangs if you use that dialog with hierarchical schematics that have dependancy loops (e.g. the autonumber test schematics)
- add an option “search for visible text only”
- maybe use regular expressions instead of the substring for the searchtext

##### Hide Text

- use regular expressions instead of starting substring

##### Show Text

- use regular expressions instead of starting substring
- Maybe merge that dialog together with the “Hide Text” dialog

##### Autonumber Text

- Maybe disable the skip option if the renumber scope is “selection”. The other skip options (Page and Hierarchy) are really stupid.

##### Text Size

##### Snap Grid Spacing

##### Coord Dialog

- maybe move the world coordinates to the main window status bar

##### About Dialog

##### Hotkeys