[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA: Text attributes
- To: geda-dev <geda-dev@xxxxxxxx>
- Subject: gEDA: Text attributes
- From: Carlos Nieves Ónega <cnieves.mail@xxxxxxxxx>
- Date: Sun, 19 Feb 2006 23:29:51 +0100
- Delivered-to: archiver@seul.org
- Delivered-to: geda-dev-outgoing@seul.org
- Delivered-to: geda-dev@seul.org
- Delivery-date: Sun, 19 Feb 2006 17:30:12 -0500
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:subject:from:to:content-type:date:message-id:mime-version:x-mailer; b=fbh74/YgAycCasj76Nqjtqnma4QS78Ty8iiJjf9K1auLv27Y3nyoIWz2MRpMfxQkrala9fJwY48l3rOMuLBVFQTdV9D1aVQbdzNRfz22bhUVSZRA/RkQaYz3PQ3zmUBhmj67BuG4JRRuMSDcPpi87HSH05JAt7XD6xqgNbtk6Ns=
- Reply-to: geda-dev@xxxxxxxx
- Sender: owner-geda-dev@xxxxxxxx
Hi all,
some time ago, I was trying to define some way in gschem so when the
user adds a pin, some defaults attributes are added to it automatically.
I got it working and polished with some help from Patrick (thanks
again!). These attributes are configurable in the gschemrc file. By now,
I configured it to add the pinlabel, pintype and pinnumber attributes.
Then, I didn't like it at all, because the attributes added had the same
position and all overlapped each other. That's why I spent some time
trying to get them automatically placed at the best position. This was
also configurable in the gschemrc file.
After that, I thought: why don't do the same to some of the other
component attributes? So I spent some more time, and now I got some
results. All is configurable in the gschemrc file, and therefore user
configurable.
What I did is to define some default positions for the refdes and value
attributes, even depending on the angle of the component, so they are
now autoplaced each time a new component is added, rotated, mirrored, or
even when a new attribute is added.
The result is not perfect, but I think it's a good aproach. It can have
some problems with small symbols, or IC symbols, but I think it's worth
to have it because the time to draw the schematic is reduced drastically
(no need to place the attributes by hand!).
Attached is the patch for all these features. Anyone who wants to test
it and report some comments? Try it out of the box (place a new pin,
rotate or mirror it, place a new component, add the value attribute,
rotate or mirror the component..., and see what happens to the
attributes), and read the gschemrc file if you want to know how it is
configured.
Regards,
Carlos
Index: docs/ChangeLog
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/docs/ChangeLog,v
retrieving revision 1.71
diff -u -r1.71 ChangeLog
--- docs/ChangeLog 22 Jan 2006 13:55:25 -0000 1.71
+++ docs/ChangeLog 19 Feb 2006 21:44:35 -0000
@@ -1,3 +1,7 @@
+2006-02-19 Carlos Nieves Onega <cnieves@xxxxxxxxxx>
+ * hooks/hooks_and_scheme.txt: Added documentation for some new
+ hooks, and the new add-attribute-to-object function.
+
2006-01-16 Ales Hvezda <ahvezda@xxxxxxxxxxxxx>
* configure.ac: Bumped package version to 20060123
Index: docs/hooks/hooks_and_scheme.txt
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/docs/hooks/hooks_and_scheme.txt,v
retrieving revision 1.2
diff -u -r1.2 hooks_and_scheme.txt
--- docs/hooks/hooks_and_scheme.txt 15 Sep 2002 04:09:57 -0000 1.2
+++ docs/hooks/hooks_and_scheme.txt 19 Feb 2006 21:44:36 -0000
@@ -4,6 +4,7 @@
====================================
Copyright (C) 2000 Stefan Petersen
+Copyright (C) 2006 Carlos Nieves Onega
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,7 +37,7 @@
Scheme functions
----------------
-There are two function available for handling attributes in the schematic.
+There are several functions available for handling attributes in the schematic.
* get-attribute-name-value
Inparameter : an attribute
@@ -55,15 +56,40 @@
Defined both in gschem and libgeda, mainly because
where different variables and information are available.
+* add-attribute-to-object
+Inparameters :
+ - Object: passed as a hook argument from gschem.
+ - Attribute name.
+ - Value of the attribute.
+ - Visibility: #t (visible) or #f (hidden).
+ - Show_list: a list containing what to show, using
+ elements like 'name' or 'value', or an empty list.
+Outparameter : undefined.
+Description : Adds a new attribute to an object.
+
+Examples:
+ (add-attribute-to-object object "pinlabel" "unknown" #t '(value))
+ (add-attribute-to-object object "pinnumber" "0" #t '(value name))
+ (add-attribute-to-object object "pinseq" "0" #f '(name))
Hooks
-----
Hooks are a way to define functions that will be called during different
-part of a programs execution. In gschem there are (currently) three
+part of a programs execution. In gschem there are (currently) several
different hooks available:
-* add-component-hook
+* add-component-hook: The parameter to the handling function is a list
+ of attributes.
+* add-component-object-hook: The parameter to the handling function is
+ the object added.
* copy-component-hook
+* mirror-component-object-hook
* move-component-hook
+* rotate-component-hook
+* add-pin-hook
+* mirror-pin-hook
+* rotate-pin-hook
+* add-attribute-hook
+
As their name indicate, they are called at different occasions. When
you add a component add-component-hook is called, etc.
@@ -110,5 +136,10 @@
simply add the following line:
(add-hook! copy-component-hook auto-uref)
+If you want to automatically add default attributes to each newly placed pin,
+just add the following line to your gschemrc file:
+(add-hook! add-pin-hook add-default-pin-attributes)
+Note: This is enabled by default in the system wide gschemrc file!.
+
Good luck!
Index: gschem/ChangeLog
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/ChangeLog,v
retrieving revision 1.432
diff -u -r1.432 ChangeLog
--- gschem/ChangeLog 24 Jan 2006 03:34:02 -0000 1.432
+++ gschem/ChangeLog 19 Feb 2006 21:44:53 -0000
@@ -1,3 +1,28 @@
+2006-02-18 Carlos Nieves Onega <cnieves@xxxxxxxxxx>
+ * include/globals.h, include/prototype.h, noweb/g_hook.nw,
+ noweb/g_register.nw, noweb/globals.nw, noweb/o_pin.nw,
+ noweb/o_misc.nw, noweb/o_attrib.nw, noweb/o_complex.nw:
+ Added new hooks.
+ Added new scheme subroutines:
+ - g_add_attrib, which adds an attribute to an object from scheme.
+ - g_get_pin_ends, which returns the ends' coords of a pin.
+ - g_set_attrib_text_properties, which sets all text properties
+ of an attribute.
+ - g_get_object_bounds, which returns a list with the object bounds.
+ - g_get_object_pins, which returns a list with the pins.
+
+ * scheme/Makefile.am, scheme/auto-place-attribs.scm:
+ Added new functions to autoplace the attributes.
+
+ * lib/system-gschemrc.in:
+ Modified the system-gschemrc file so gschem adds automatically
+ the default pin attributes when placing a new pin, and also
+ to automatically place the text attributes.
+
+ * noweb/i_vars.h: Fixed compiler warning.
+
+ * po/es_ES.po: fixed some strings.
+
2006-01-23 Ales Hvezda <ahvezda@xxxxxxxxxxxxx>
* po/*: auto* tools update all po files for distribution.
Index: gschem/include/globals.h
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/include/globals.h,v
retrieving revision 1.12
diff -u -r1.12 globals.h
--- gschem/include/globals.h 11 Jan 2006 14:44:08 -0000 1.12
+++ gschem/include/globals.h 19 Feb 2006 21:44:54 -0000
@@ -70,8 +70,15 @@
/* Hooks */
extern SCM add_component_hook;
+extern SCM add_component_object_hook;
+extern SCM mirror_component_object_hook;
+extern SCM rotate_component_object_hook;
extern SCM copy_component_hook;
extern SCM move_component_hook;
+extern SCM add_pin_hook;
+extern SCM mirror_pin_hook;
+extern SCM rotate_pin_hook;
+extern SCM add_attribute_hook;
#include "gettext.h"
#ifdef ENABLE_NLS
Index: gschem/include/prototype.h
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/include/prototype.h,v
retrieving revision 1.124
diff -u -r1.124 prototype.h
--- gschem/include/prototype.h 17 Dec 2005 13:59:13 -0000 1.124
+++ gschem/include/prototype.h 19 Feb 2006 21:44:58 -0000
@@ -24,6 +24,15 @@
/* g_hook.c */
SCM g_make_attrib_smob_list(TOPLEVEL *curr_w, OBJECT *curr_object);
SCM g_set_attrib_value_x(SCM attrib_smob, SCM scm_value);
+SCM g_add_attrib(SCM object, SCM attrib_name,
+ SCM attrib_value, SCM scm_vis, SCM scm_show);
+SCM g_get_pin_ends(SCM object);
+SCM
+g_set_attrib_text_properties(SCM attrib_smob, SCM scm_colorname, SCM scm_size,
+ SCM scm_alignment, SCM scm_rotation, SCM scm_x,
+ SCM scm_y);
+SCM g_get_object_bounds (SCM object_smob, SCM scm_inc_attribs);
+SCM g_get_object_pins (SCM object_smob);
/* g_keys.c */
void set_window_current_key(TOPLEVEL *w_current);
void g_keys_execute(int state, int keyval);
Index: gschem/lib/system-gschemrc.in
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/lib/system-gschemrc.in,v
retrieving revision 1.87
diff -u -r1.87 system-gschemrc.in
--- gschem/lib/system-gschemrc.in 18 Nov 2005 20:31:48 -0000 1.87
+++ gschem/lib/system-gschemrc.in 19 Feb 2006 21:45:02 -0000
@@ -768,6 +768,121 @@
;(add-hook! add-component-hook auto-uref)
;(add-hook! copy-component-hook auto-uref)
+; Define default pin attributes
+; Attributes:
+; - Attribute name.
+; - Value of the attribute.
+; - Visibility: #t (visible) or #f (hidden).
+; - Show_list: a list containing what to show, using
+; elements like 'name' or 'value', or an empty list.
+(define default-pin-attributes
+ '(("pintype" "unknown" #f ())
+ ("pinlabel" "unknown" #t (value))
+ ("pinnumber" "0" #t (value))
+ ("pinseq" "0" #f ())))
+
+(define default-position-of-text-attributes
+ ; Specifies the default position of pin attributes.
+ ; An attribute whose name is "attrib_name" in a pin with direction
+ ; "pin_direction" will be placed at the offset specified (x_offset and
+ ; y_offset) from the reference "ref".
+ ; The reference string is the reference used when placing the attribute.
+ ; It has the format:
+ ; "horizontal vertical", where:
+ ; - "horizontal" is one of the following: "Left", "Middle", "Right".
+ ; - "vertical" is one of the following: "Lower", "Middle", "Upper".
+ ; Example: "Lower Right".
+ ; The alignment and angle will be also set.
+ ; Attrib_name Direct. X_offset Y_offset Reference Alignment Angle
+ '( ("pinlabel" ">" 50 0 "Lower Right" "Lower Left" 0)
+ ("pinlabel" "<" -50 0 "Lower Left" "Lower Right" 0)
+ ("pinlabel" "^" 0 50 "Upper Middle" "Lower Left" 90)
+ ("pinlabel" "v" 0 -50 "Lower Middle" "Lower Right" 90)
+ ("pinnumber" ">" -100 50 "Lower Right" "Lower Right" 0)
+ ("pinnumber" "<" 100 50 "Lower Left" "Lower Left" 0)
+ ("pinnumber" "^" -50 -100 "Upper Middle" "Lower Right" 90)
+ ("pinnumber" "v" -50 100 "Lower Middle" "Lower Left" 90)
+
+ ; Component attributes
+ ; One direction
+ ("refdes" "<" -50 50 "Upper Middle" "Lower Right" 0)
+ ("value" "<" 50 50 "Upper Middle" "Lower Left" 0)
+ ("refdes" ">" -50 50 "Upper Middle" "Lower Right" 0)
+ ("value" ">" 50 50 "Upper Middle" "Lower Left" 0)
+ ("refdes" "^" 50 100 "Middle Left" "Lower Right" 0)
+ ("value" "^" 50 -100 "Middle Left" "Lower Right" 0)
+ ("refdes" "v" 50 100 "Middle Left" "Lower Right" 0)
+ ("value" "v" 50 -100 "Middle Left" "Lower Right" 0)
+ ; Two directions
+ ("refdes" "<>" -50 50 "Upper Middle" "Lower Right" 0)
+ ("value" "<>" 50 50 "Upper Middle" "Lower Left" 0)
+ ("refdes" "^v" -50 100 "Middle Left" "Lower Right" 0)
+ ("value" "^v" -50 -100 "Middle Left" "Lower Right" 0)
+ ; Three directions
+ ("refdes" "<^v" -50 100 "Middle Left" "Lower Right" 0)
+ ("value" "<^v" -50 -100 "Middle Left" "Lower Right" 0)
+ ("refdes" ">^v" 50 100 "Middle Right" "Lower Left" 0)
+ ("value" ">^v" 50 -100 "Middle Right" "Lower Left" 0)
+ ("refdes" "<>v" -50 -50 "Lower Middle" "Upper Right" 0)
+ ("value" "<>v" 50 -50 "Lower Middle" "Upper Left" 0)
+ ("refdes" "<>^" -50 50 "Upper Middle" "Lower Right" 0)
+ ("value" "<>^" 50 50 "Upper Middle" "Lower Left" 0)
+ ; Four directions
+ ("refdes" "<>^v" 300 50 "Upper Left" "Lower Left" 0)
+ ("value" "<>^v" -300 50 "Upper Right" "Lower Right" 0)
+ ))
+
+; Position of parameters inside default-position-of-text-attributes
+(define def-attrib-name-pos 0)
+(define def-direction-pos 1)
+(define def-x-offset-pos 2)
+(define def-y-offset-pos 3)
+(define def-reference-pos 4)
+(define def-alignment-pos 5)
+(define def-angle-pos 6)
+
+; Adds the default pin attributes to each newly placed pin.
+(define (add-default-pin-attributes object)
+ (for-each
+ (lambda (a)
+ (apply add-attribute-to-object object a)) default-pin-attributes))
+
+; Comment in this hook to automatically add the default attributes to
+; each newly placed pin
+(add-hook! add-pin-hook add-default-pin-attributes)
+
+
+; Comment in this to load the functions to place the attributes automatically.
+(load (string-append gedadatarc "/scheme/auto-place-attribs.scm"))
+
+; Autoplace pin text attributes hook.
+; Comment in these if you want the pin attributes to be automatically placed.
+; There are different hooks for situations like adding a new pin and rotating
+; or mirroring an existing one.
+; The #t at the end means that function is appended to the end of the hook.
+(add-hook! add-pin-hook (lambda (pin)
+ (autoplace-pin-attributes pin )) #t)
+(add-hook! rotate-pin-hook (lambda (pin)
+ (autoplace-pin-attributes pin )) #t)
+(add-hook! mirror-pin-hook (lambda (pin)
+ (autoplace-pin-attributes pin )) #t)
+
+; Autoplace component text attributes hook.
+; Comment in these if you want the component attributes to be
+; automatically placed.
+; There are different hooks for situations like adding a new pin, rotating
+; or mirroring an existing one, or adding a new attribute.
+; The #t at the end means that function is appended to the end of the hook.
+(add-hook! add-component-object-hook (lambda (object)
+ (autoplace-object-attributes object)) #t)
+(add-hook! rotate-component-object-hook (lambda (object)
+ (autoplace-object-attributes object)) #t)
+(add-hook! mirror-component-object-hook (lambda (object)
+ (autoplace-object-attributes object)) #t)
+(add-hook! add-attribute-hook (lambda (object)
+ (autoplace-object-attributes object)) #t)
+
+
;
; End of hooks
;
Index: gschem/noweb/g_hook.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/g_hook.nw,v
retrieving revision 1.6
diff -u -r1.6 g_hook.nw
--- gschem/noweb/g_hook.nw 4 Feb 2005 04:39:29 -0000 1.6
+++ gschem/noweb/g_hook.nw 19 Feb 2006 21:45:03 -0000
@@ -13,6 +13,11 @@
<<g_hook.c : include directives>>
<<g_hook.c : g_make_attrib_smob_list()>>
<<g_hook.c : g_set_attrib_value_x()>>
+<<g_hook.c : g_add_attrib()>>
+<<g_hook.c : g_get_pin_ends()>>
+<<g_hook.c : g_set_attrib_text_properties()>>
+<<g_hook.c : g_get_object_bounds>>
+<<g_hook.c : g_get_object_pins>>
@
@@ -145,3 +150,370 @@
@ %def g_set_attrib_value_x
+@defun g_add_attrib
+Adds an attribute [[scm_attrib_name]] with value [[scm_attrib_value]] to the given [[object]].
+The attribute has the visibility [[scm_vis]] and show [[scm_show]] flags.
+The possible values are:
+ - [[scm_vis]]: scheme boolean. Visible (TRUE) or hidden (FALSE).
+ - [[scm_show]]: a list containing what to show: "name", "value", or both.
+The return value is always TRUE.
+@end defun
+
+<<g_hook.c : g_add_attrib()>>=
+SCM
+g_add_attrib(SCM object, SCM scm_attrib_name,
+ SCM scm_attrib_value, SCM scm_vis, SCM scm_show)
+{
+ TOPLEVEL *w_current=NULL;
+ OBJECT *o_current=NULL;
+ gboolean vis;
+ int show=0;
+ gchar *attrib_name=NULL;
+ gchar *attrib_value=NULL;
+ gchar *value=NULL;
+ int i;
+ gchar *newtext=NULL;
+
+ SCM_ASSERT (SCM_STRINGP(scm_attrib_name), scm_attrib_name,
+ SCM_ARG2, "add-attribute-to-object");
+ SCM_ASSERT (SCM_STRINGP(scm_attrib_value), scm_attrib_value,
+ SCM_ARG3, "add-attribute-to-object");
+ SCM_ASSERT (scm_boolean_p(scm_vis), scm_vis,
+ SCM_ARG4, "add-attribute-to-object");
+ SCM_ASSERT (scm_list_p(scm_show), scm_show,
+ SCM_ARG5, "add-attribute-to-object");
+
+ /* Get w_current and o_current */
+ SCM_ASSERT (g_get_data_from_object_smob (object, &w_current, &o_current),
+ object, SCM_ARG1, "add-attribute-to-object");
+
+ /* Get parameters */
+ attrib_name = SCM_STRING_CHARS(scm_attrib_name);
+ attrib_value = SCM_STRING_CHARS(scm_attrib_value);
+ vis = SCM_NFALSEP(scm_vis);
+
+ for (i=0; i<=SCM_INUM(scm_length(scm_show))-1; i++) {
+ value = SCM_STRING_CHARS(scm_list_ref(scm_show, SCM_MAKINUM(i)));
+ SCM_ASSERT(!((strcasecmp(value, "name") != 0) &&
+ (strcasecmp(value, "value") != 0) ), scm_show,
+ SCM_ARG5, "add-attribute-to-object");
+ /* show = 1 => show value;
+ show = 2 => show name;
+ show = 3 => show both */
+ if (strcasecmp(value, "value") == 0) {
+ show |= 1;
+ }
+ else if (strcasecmp(value, "name") == 0) {
+ show |= 2;
+ }
+ }
+ /* Show name and value (show = 3) => show=0 for gschem */
+ if (show == 3) {
+ show = 0;
+ }
+
+ newtext = g_strdup_printf("%s=%s", attrib_name, attrib_value);
+ o_attrib_add_attrib (w_current, newtext, vis, show, o_current);
+ g_free(newtext);
+
+ return SCM_BOOL_T;
+
+}
+@ %def g_add_attrib
+
+@defun g_get_pin_ends
+Returns a list with coords of the ends of the given pin [[object]].
+The list is ( (x0 y0) (x1 y1) ), where the beginning is at (x0,y0) and the end at (x1,y1).
+The active connection end of the pin is the beginning, so this function cares about the whichend property of the pin object. If whichend is 1, then it has to reverse the ends.
+@end defun
+
+<<g_hook.c : g_get_pin_ends()>>=
+SCM
+g_get_pin_ends(SCM object)
+{
+ TOPLEVEL *w_current;
+ OBJECT *o_current;
+ SCM coord1 = SCM_EOL;
+ SCM coord2 = SCM_EOL;
+ SCM coords = SCM_EOL;
+
+ /* Get w_current and o_current */
+ SCM_ASSERT (g_get_data_from_object_smob (object, &w_current, &o_current),
+ object, SCM_ARG1, "get-pin-ends");
+
+ /* Check that it is a pin object */
+ SCM_ASSERT (o_current != NULL,
+ object, SCM_ARG1, "get-pin-ends");
+ SCM_ASSERT (o_current->type == OBJ_PIN,
+ object, SCM_ARG1, "get-pin-ends");
+ SCM_ASSERT (o_current->line != NULL,
+ object, SCM_ARG1, "get-pin-ends");
+
+ coord1 = scm_cons(SCM_MAKINUM(o_current->line->x[0]),
+ SCM_MAKINUM(o_current->line->y[0]));
+ coord2 = scm_cons(SCM_MAKINUM(o_current->line->x[1]),
+ SCM_MAKINUM(o_current->line->y[1]));
+ if (o_current->whichend == 0) {
+ coords = scm_cons(coord1, scm_list(coord2));
+ } else {
+ coords = scm_cons(coord2, scm_list(coord1));
+ }
+
+ return coords;
+}
+@ %def g_get_pin_ends
+
+@defun g_set_attrib_text_properties
+Sets several text properties of the given [[attribute smob]]:
+ - [[colorname]]: The colorname of the text, or "" to keep previous color.
+ - [[size]]: Size (numeric) of the text, or -1 to keep the previous size.
+ - [[alignment]]: String with the alignment of the text. Possible values are:
+ * "" : Keep the previous alignment.
+ * "Lower Left"
+ * "Middle Left"
+ * "Upper Left"
+ * "Lower Middle"
+ * "Middle Middle"
+ * "Upper Middle"
+ * "Lower Right"
+ * "Middle Right"
+ * "Upper Right"
+ - [[rotation]]: Angle of the text, or -1 to keep previous angle.
+ - [[x]], [[y]]: Coords of the text.
+@end defun
+
+<<g_hook.c : g_set_attrib_text_properties()>>=
+SCM
+g_set_attrib_text_properties(SCM attrib_smob, SCM scm_colorname, SCM scm_size,
+ SCM scm_alignment, SCM scm_rotation, SCM scm_x,
+ SCM scm_y)
+{
+ struct st_attrib_smob *attribute =
+ (struct st_attrib_smob *)SCM_CDR(attrib_smob);
+ OBJECT *object;
+ TOPLEVEL *w_current = (TOPLEVEL *) attribute->world;
+
+ char *colorname=NULL;
+ int color=0;
+ int size = -1;
+ char *alignment_string;
+ int alignment = -2;
+ int rotation = 0;
+ int x = -1, y = -1;
+ gboolean changed = FALSE;
+
+ SCM_ASSERT (SCM_STRINGP(scm_colorname), scm_colorname,
+ SCM_ARG2, "set-attribute-text-properties!");
+ SCM_ASSERT ( SCM_INUMP(scm_size),
+ scm_size, SCM_ARG3, "set-attribute-text-properties!");
+ SCM_ASSERT (SCM_STRINGP(scm_alignment), scm_alignment,
+ SCM_ARG4, "set-attribute-text-properties!");
+ SCM_ASSERT ( SCM_INUMP(scm_rotation),
+ scm_rotation, SCM_ARG5, "set-attribute-text-properties!");
+ SCM_ASSERT ( SCM_INUMP(scm_x),
+ scm_x, SCM_ARG6, "set-attribute-text-properties!");
+ SCM_ASSERT ( SCM_INUMP(scm_y),
+ scm_y, SCM_ARG7, "set-attribute-text-properties!");
+
+ colorname = SCM_STRING_CHARS(scm_colorname);
+
+ if (colorname && strlen(colorname) != 0) {
+ SCM_ASSERT ( (color = s_color_get_index(colorname)) != -1,
+ scm_colorname, SCM_ARG2, "set-attribute-text-properties!");
+ }
+ else {
+ color = -1;
+ }
+
+ size = SCM_INUM(scm_size);
+ rotation = SCM_INUM(scm_rotation);
+ x = SCM_INUM(scm_x);
+ y = SCM_INUM(scm_y);
+
+ alignment_string = SCM_STRING_CHARS(scm_alignment);
+
+ if (strlen(alignment_string) == 0) {
+ alignment = -1;
+ }
+ if (strcmp(alignment_string, "Lower Left") == 0) {
+ alignment = 0;
+ }
+ if (strcmp(alignment_string, "Middle Left") == 0) {
+ alignment = 1;
+ }
+ if (strcmp(alignment_string, "Upper Left") == 0) {
+ alignment = 2;
+ }
+ if (strcmp(alignment_string, "Lower Middle") == 0) {
+ alignment = 3;
+ }
+ if (strcmp(alignment_string, "Middle Middle") == 0) {
+ alignment = 4;
+ }
+ if (strcmp(alignment_string, "Upper Middle") == 0) {
+ alignment = 5;
+ }
+ if (strcmp(alignment_string, "Lower Right") == 0) {
+ alignment = 6;
+ }
+ if (strcmp(alignment_string, "Middle Right") == 0) {
+ alignment = 7;
+ }
+ if (strcmp(alignment_string, "Upper Right") == 0) {
+ alignment = 8;
+ }
+ if (alignment == -2) {
+ /* Bad specified */
+ SCM_ASSERT (SCM_STRINGP(scm_alignment), scm_alignment,
+ SCM_ARG4, "set-attribute-text-properties!");
+ }
+
+ if (attribute &&
+ attribute->attribute &&
+ attribute->attribute->object) {
+ object = (OBJECT *) attribute->attribute->object;
+ if (object &&
+ object->text) {
+ if (x != -1) {
+ object->text->x = x;
+ changed = TRUE;
+ }
+ if (y != -1) {
+ object->text->y = y;
+ changed = TRUE;
+ }
+ if (changed) {
+ WORLDtoSCREEN(w_current, x, y, &object->text->screen_x, &object->text->screen_y);
+ }
+ if (size != -1) {
+ object->text->size = size;
+ changed = TRUE;
+ }
+ if (alignment != -1) {
+ object->text->alignment = alignment;
+ changed = TRUE;
+ }
+ if (rotation != -1) {
+ object->text->angle = rotation;
+ changed = TRUE;
+ }
+ if (changed) {
+ o_text_erase(w_current, object);
+ o_text_recreate(w_current, object);
+ o_text_draw(w_current, object);
+ }
+ }
+ }
+ return SCM_BOOL_T;
+}
+@ %def g_set_attrib_text_properties
+
+
+@defun g_get_object_bounds
+Returns a list of the bounds of the [[object smob]].
+The list has the format: ( (left right) (top bottom) )
+I got top and bottom values reversed from world_get_complex_bounds, so don\'t rely on the position in the list. /* FIXME */
+@end defun
+
+<<g_hook.c : g_get_object_bounds>>=
+SCM
+g_get_object_bounds (SCM object_smob, SCM scm_inc_attribs)
+{
+ TOPLEVEL *w_current=NULL;
+ OBJECT *object=NULL;
+ int left=0, right=0, bottom=0, top=0;
+ SCM returned = SCM_EOL;
+ SCM vertical = SCM_EOL;
+ SCM horizontal = SCM_EOL;
+ OBJECT *new_object = NULL;
+ OBJECT *new_node = NULL;
+ OBJECT *aux, *last_added=NULL;
+ gboolean include_attribs;
+
+ SCM_ASSERT (scm_boolean_p(scm_inc_attribs), scm_inc_attribs,
+ SCM_ARG2, "get-object-bounds");
+ include_attribs = SCM_NFALSEP(scm_inc_attribs);
+
+ /* Get w_current and o_current */
+ SCM_ASSERT (g_get_data_from_object_smob (object_smob, &w_current, &object),
+ object_smob, SCM_ARG1, "get-object-bounds");
+
+ if (!include_attribs) {
+ /* Don't include the attributes when computing the bounds.
+ So make a new object list without the attributes (those which
+ have the attached_to != NULL) */
+ aux = object;
+ while (aux != NULL) {
+ if (aux->attached_to == NULL) {
+ new_node = (OBJECT *) malloc(sizeof(OBJECT));
+ memcpy (new_node, aux, sizeof(OBJECT));
+ new_node->next = NULL;
+ new_node->prev = last_added;
+ if (new_object) {
+ last_added->next = new_node;
+ last_added = new_node;
+ }
+ else {
+ new_object = new_node;
+ last_added = new_object;
+ }
+ }
+ aux = aux->next;
+ }
+ }
+ else {
+ new_object = object;
+ }
+
+ world_get_complex_bounds (w_current, new_object,
+ &left, &top, &right, &bottom);
+
+ if (!include_attribs) {
+ /* Free the newly created list */
+ aux = new_object;
+ while (aux != NULL) {
+ new_object = aux->next;
+ g_free(aux);
+ aux = new_object;
+ }
+ }
+
+ horizontal = scm_cons (SCM_MAKINUM(left), SCM_MAKINUM(right));
+ vertical = scm_cons (SCM_MAKINUM(top), SCM_MAKINUM(bottom));
+ returned = scm_cons (horizontal, vertical);
+ return (returned);
+}
+@ %def g_get_object_bounds
+
+
+
+@defun g_get_object_pins
+Returns a list of the pins of the [[object smob]].
+@end defun
+
+<<g_hook.c : g_get_object_pins>>=
+SCM
+g_get_object_pins (SCM object_smob)
+{
+ TOPLEVEL *w_current=NULL;
+ OBJECT *object=NULL;
+ OBJECT *prim_obj;
+ SCM returned=SCM_EOL;
+
+ /* Get w_current and o_current */
+ SCM_ASSERT (g_get_data_from_object_smob (object_smob, &w_current, &object),
+ object_smob, SCM_ARG1, "get-object-pins");
+
+ if (object->complex && object->complex->prim_objs) {
+ prim_obj = object->complex->prim_objs;
+ while (prim_obj != NULL) {
+ if (prim_obj->type == OBJ_PIN) {
+ returned = scm_cons (g_make_object_smob(w_current, prim_obj),returned);
+ }
+ prim_obj = prim_obj->next;
+ }
+ }
+
+ return (returned);
+}
+@ %def g_get_object_pins
Index: gschem/noweb/g_register.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/g_register.nw,v
retrieving revision 1.28
diff -u -r1.28 g_register.nw
--- gschem/noweb/g_register.nw 28 Oct 2005 22:26:32 -0000 1.28
+++ gschem/noweb/g_register.nw 19 Feb 2006 21:45:04 -0000
@@ -345,13 +345,32 @@
}
g_init_attrib_smob ();
+ g_init_object_smob ();
/* Hook stuff */
+ scm_c_define_gsubr ("add-attribute-to-object", 5, 0, 0, g_add_attrib);
+ scm_c_define_gsubr ("get-object-attributes", 1, 0, 0, g_get_object_attributes);
+ scm_c_define_gsubr ("get-object-bounds", 2, 0, 0, g_get_object_bounds);
+ scm_c_define_gsubr ("get-object-pins", 1, 0, 0, g_get_object_pins);
+ scm_c_define_gsubr ("get-pin-ends", 1, 0, 0, g_get_pin_ends);
+ scm_c_define_gsubr ("set-attribute-text-properties!", 7, 0, 0, g_set_attrib_text_properties);
scm_c_define_gsubr ("set-attribute-value!", 2, 0, 0, g_set_attrib_value_x);
+
add_component_hook = scm_create_hook ("add-component-hook", 1);
+ add_component_object_hook = scm_create_hook ("add-component-object-hook",
+ 1);
+ rotate_component_object_hook = scm_create_hook ("rotate-component-object-hook",
+ 1);
+ mirror_component_object_hook = scm_create_hook ("mirror-component-object-hook",
+ 1);
copy_component_hook = scm_create_hook ("copy-component-hook", 1);
move_component_hook = scm_create_hook ("move-component-hook", 1);
+ add_pin_hook = scm_create_hook ("add-pin-hook", 1);
+ mirror_pin_hook = scm_create_hook ("mirror-pin-hook", 1);
+ rotate_pin_hook = scm_create_hook ("rotate-pin-hook", 1);
+ add_attribute_hook = scm_create_hook ("add-attribute-hook", 1);
+
}
Index: gschem/noweb/globals.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/globals.nw,v
retrieving revision 1.9
diff -u -r1.9 globals.nw
--- gschem/noweb/globals.nw 27 Nov 2005 00:15:01 -0000 1.9
+++ gschem/noweb/globals.nw 19 Feb 2006 21:45:04 -0000
@@ -107,9 +107,16 @@
OBJECT *object_buffer[MAX_BUFFERS];
/* Hooks */
+SCM add_attribute_hook;
SCM add_component_hook;
+SCM add_component_object_hook;
+SCM mirror_component_object_hook;
+SCM rotate_component_object_hook;
SCM copy_component_hook;
SCM move_component_hook;
+SCM add_pin_hook;
+SCM rotate_pin_hook;
+SCM mirror_pin_hook;
-@ %def global_window_current rc_filename script_filename output_filename colormap visual white black do_logging logging_dest arc_draw_func box_draw_func circle_draw_func complex_draw_func line_draw_func net_draw_func bus_draw_func text_draw_func pin_draw_func select_func x_log_update_func quiet_mode verbose_mode stroke_info_mode object_buffer add_component_hook copy_component_hook move_component_hook
+@ %def global_window_current rc_filename script_filename output_filename colormap visual white black do_logging logging_dest arc_draw_func box_draw_func circle_draw_func complex_draw_func line_draw_func net_draw_func bus_draw_func text_draw_func pin_draw_func select_func x_log_update_func quiet_mode verbose_mode stroke_info_mode object_buffer add_component_hook add_component_object_hook copy_component_hook move_component_hook add_pin_hook rotate_pin_hook mirror_pin_hook mirror_component_object_hook add_attrib_hook
Index: gschem/noweb/i_vars.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/i_vars.nw,v
retrieving revision 1.19
diff -u -r1.19 i_vars.nw
--- gschem/noweb/i_vars.nw 28 Oct 2005 22:26:32 -0000 1.19
+++ gschem/noweb/i_vars.nw 19 Feb 2006 21:45:05 -0000
@@ -271,7 +271,8 @@
w_current->auto_save_interval = default_auto_save_interval;
if (w_current->auto_save_interval != 0) {
w_current->auto_save_timeout = g_timeout_add(w_current->auto_save_interval*1000,
- s_page_autosave, w_current);
+ (GSourceFunc) s_page_autosave,
+ w_current);
}
}
Index: gschem/noweb/o_attrib.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_attrib.nw,v
retrieving revision 1.11
diff -u -r1.11 o_attrib.nw
--- gschem/noweb/o_attrib.nw 17 Dec 2005 16:14:43 -0000 1.11
+++ gschem/noweb/o_attrib.nw 19 Feb 2006 21:45:07 -0000
@@ -551,6 +551,15 @@
if (g_ascii_strncasecmp (text_string, "slot=", 5) == 0) {
o_slot_end (w_current, text_string, strlen (text_string));
}
+
+ /* Run the add attribute hook */
+ if (scm_hook_empty_p(add_attribute_hook) == SCM_BOOL_F &&
+ object != NULL) {
+ scm_run_hook(add_attribute_hook,
+ scm_cons(g_make_object_smob(w_current,
+ o_current),
+ SCM_EOL));
+ }
w_current->page_current->CHANGED = 1;
Index: gschem/noweb/o_complex.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_complex.nw,v
retrieving revision 1.17
diff -u -r1.17 o_complex.nw
--- gschem/noweb/o_complex.nw 19 Feb 2005 23:27:07 -0000 1.17
+++ gschem/noweb/o_complex.nw 19 Feb 2006 21:45:09 -0000
@@ -445,6 +445,13 @@
SCM_EOL));
}
+ if (scm_hook_empty_p(add_component_object_hook) == SCM_BOOL_F &&
+ o_current != NULL) {
+ scm_run_hook(add_component_object_hook,
+ scm_cons(g_make_object_smob(w_current, o_current),
+ SCM_EOL));
+ }
+
/* put code here to deal with emebedded stuff */
if (w_current->embed_complex) {
char* new_basename;
Index: gschem/noweb/o_misc.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_misc.nw,v
retrieving revision 1.40
diff -u -r1.40 o_misc.nw
--- gschem/noweb/o_misc.nw 11 Jan 2006 14:48:06 -0000 1.40
+++ gschem/noweb/o_misc.nw 19 Feb 2006 21:45:13 -0000
@@ -299,6 +299,9 @@
@section Function @code{o_rotate_90()}
@defun o_rotate_90 w_current list centerx centery
+Given the selection [[list]], and the center of rotation ([[centerx]],[[centery]], this function traverses all the selection list, rotating each object.
+The selection list contains a given object and all its attributes (refdes, pinname, pinlabel, ...).
+There is a second pass to run the rotate hooks of non-simple objects, like pin or complex objects, for example.
@end defun
<<o_misc.c : o_rotate_90()>>=
@@ -310,7 +313,7 @@
int new_angle;
GList *other_objects=NULL;
GList *connected_objects=NULL;
- OBJECT *o_current;
+ OBJECT *o_current=NULL;
/* this is okay if you just hit rotate and have nothing selected */
if (list == NULL) {
@@ -411,7 +414,7 @@
o_cue_draw_list(w_current, connected_objects);
/* finally redraw the cues on the current object */
- o_cue_draw_single(w_current, object);
+ o_cue_draw_single(w_current, object);
break;
case(OBJ_COMPLEX):
@@ -518,6 +521,46 @@
s_current = s_current->next;
}
+ /* All objects were rotated. Do a 2nd pass to run the rotate hooks */
+ /* Do not run any hooks for simple objects here, like text, since they
+ were rotated in the previous pass, and the selection list can contain
+ an object and all its attributes (text) */
+ s_current = list;
+ while (s_current != NULL) {
+ object = s_current->selected_object;
+
+ if (!object) {
+ fprintf(stderr, _("ERROR: NULL object in o_rotate_90!\n"));
+ return;
+ }
+
+ switch(object->type) {
+ case(OBJ_PIN):
+ /* Run the rotate pin hook */
+ if (scm_hook_empty_p(rotate_pin_hook) == SCM_BOOL_F &&
+ object != NULL) {
+ scm_run_hook(rotate_pin_hook,
+ scm_cons(g_make_object_smob(w_current, object),
+ SCM_EOL));
+ }
+ break;
+
+ case (OBJ_COMPLEX):
+ /* Run the rotate pin hook */
+ if (scm_hook_empty_p(rotate_component_object_hook) == SCM_BOOL_F &&
+ object != NULL) {
+ scm_run_hook(rotate_component_object_hook,
+ scm_cons(g_make_object_smob(w_current, object),
+ SCM_EOL));
+ }
+ break;
+ default:
+ break;
+ }
+
+ s_current = s_current->next;
+ }
+
w_current->page_current->CHANGED = 1;
o_undo_savestate(w_current, UNDO_ALL);
}
@@ -852,6 +895,47 @@
}
+ /* All objects were rotated. Do a 2nd pass to run the rotate hooks */
+ /* Do not run any hooks for simple objects here, like text, since they
+ were rotated in the previous pass, and the selection list can contain
+ an object and all its attributes (text) */
+ s_current = list;
+ while (s_current != NULL) {
+ object = s_current->selected_object;
+
+ if (!object) {
+ fprintf(stderr, _("ERROR: NULL object in o_rotate_90!\n"));
+ return;
+ }
+
+ switch(object->type) {
+ case(OBJ_PIN):
+ /* Run the rotate pin hook */
+ if (scm_hook_empty_p(mirror_pin_hook) == SCM_BOOL_F &&
+ object != NULL) {
+ scm_run_hook(rotate_pin_hook,
+ scm_cons(g_make_object_smob(w_current, object),
+ SCM_EOL));
+ }
+ break;
+
+ case (OBJ_COMPLEX):
+ /* Run the rotate pin hook */
+ if (scm_hook_empty_p(rotate_component_object_hook) == SCM_BOOL_F &&
+ object != NULL) {
+ scm_run_hook(mirror_component_object_hook,
+ scm_cons(g_make_object_smob(w_current, object),
+ SCM_EOL));
+ }
+ break;
+ default:
+ break;
+ }
+
+ s_current = s_current->next;
+ }
+
+
w_current->page_current->CHANGED=1;
o_undo_savestate(w_current, UNDO_ALL);
}
Index: gschem/noweb/o_pin.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_pin.nw,v
retrieving revision 1.9
diff -u -r1.9 o_pin.nw
--- gschem/noweb/o_pin.nw 7 Nov 2005 02:43:10 -0000 1.9
+++ gschem/noweb/o_pin.nw 19 Feb 2006 21:45:14 -0000
@@ -53,6 +53,7 @@
#include <libgeda/libgeda.h>
+#include "../include/globals.h"
#include "../include/x_states.h"
#include "../include/prototype.h"
@@ -266,6 +267,7 @@
int color;
int size;
GList *other_objects = NULL;
+ OBJECT *o_current;
if (w_current->inside_action == 0) {
o_redraw(w_current, w_current->page_current->object_head);
@@ -343,6 +345,14 @@
x1, y1, x2, y2,
PIN_TYPE_NET, 0);
+ o_current = w_current->page_current->object_tail;
+ if (scm_hook_empty_p(add_pin_hook) == SCM_BOOL_F &&
+ o_current != NULL) {
+ scm_run_hook(add_pin_hook,
+ scm_cons(g_make_object_smob(w_current, o_current),
+ SCM_EOL));
+ }
+
other_objects = s_conn_return_others(other_objects,
w_current->page_current->
object_tail);
@@ -356,6 +366,7 @@
w_current->last_x = (-1);
w_current->last_y = (-1);
w_current->page_current->CHANGED=1;
+
o_undo_savestate(w_current, UNDO_ALL);
}
Index: gschem/po/es_ES.po
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/po/es_ES.po,v
retrieving revision 1.10
diff -u -r1.10 es_ES.po
--- gschem/po/es_ES.po 24 Jan 2006 03:04:52 -0000 1.10
+++ gschem/po/es_ES.po 19 Feb 2006 21:45:29 -0000
@@ -9,12 +9,12 @@
"Project-Id-Version: gschem VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-01-12 19:33+0100\n"
-"PO-Revision-Date: 2006-01-13 17:54+0100\n"
+"PO-Revision-Date: 2006-02-12 22:18+0100\n"
"Last-Translator: Carlos Nieves Ãnega <cnieves@xxxxxxxxxx>\n"
"Language-Team: Spanish/Spain\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
+"Content-Transfer-Encoding: 8bit"
#: noweb/a_zoom.nw:298
msgid "Zoom too small! Cannot zoom further.\n"
@@ -249,7 +249,7 @@
#: noweb/i_basic.nw:175
msgid "Pan Mode"
-msgstr "Modo Abarcar"
+msgstr "Modo Centrar"
#: noweb/i_basic.nw:179
#, c-format
@@ -485,7 +485,7 @@
#: noweb/i_callbacks.nw:1988 noweb/i_callbacks.nw:2008 noweb/rcstrings.nw:60
msgid "Pan"
-msgstr "Abarcar"
+msgstr "Centrar respecto al cursor"
#: noweb/i_callbacks.nw:2046
msgid "Update Cues"
@@ -1541,7 +1541,7 @@
#: noweb/x_dialog.nw:680
msgid "Middle Left"
-msgstr "Abajo en el centro"
+msgstr "Centrado a la izquierda"
#: noweb/x_dialog.nw:691
msgid "Upper Left"
@@ -1549,15 +1549,15 @@
#: noweb/x_dialog.nw:702
msgid "Lower Middle"
-msgstr "Centro inferior"
+msgstr "Abajo centrado"
#: noweb/x_dialog.nw:713
msgid "Middle Middle"
-msgstr "Centro Centro"
+msgstr "Centrado Centrado"
#: noweb/x_dialog.nw:724
msgid "Upper Middle"
-msgstr "Centro superior"
+msgstr "Arriba centrado"
#: noweb/x_dialog.nw:735
msgid "Lower Right"
@@ -1565,7 +1565,7 @@
#: noweb/x_dialog.nw:746
msgid "Middle Right"
-msgstr "Abajo en el centro"
+msgstr "Centrado a la derecha"
#: noweb/x_dialog.nw:757
msgid "Upper Right"
@@ -2409,3 +2409,4 @@
#: noweb/x_window.nw:951
msgid "Pan/Cancel"
msgstr "PanorÃmica/Cancelar"
+
Index: gschem/scheme/Makefile.am
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/scheme/Makefile.am,v
retrieving revision 1.8
diff -u -r1.8 Makefile.am
--- gschem/scheme/Makefile.am 23 Jul 2001 02:40:10 -0000 1.8
+++ gschem/scheme/Makefile.am 19 Feb 2006 21:45:29 -0000
@@ -1,7 +1,7 @@
scmdatadir = @GEDADATADIR@/scheme
scmdata_DATA = auto-uref.scm generate_netlist.scm gschem.scm list-keys.scm \
- print-NB-attribs.scm
+ print-NB-attribs.scm auto-place-attribs.scm
EXTRA_DIST = $(scmdata_DATA)
Index: gschem/scheme/auto-place-attribs.scm
===================================================================
RCS file: gschem/scheme/auto-place-attribs.scm
diff -N gschem/scheme/auto-place-attribs.scm
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gschem/scheme/auto-place-attribs.scm 19 Feb 2006 21:45:30 -0000
@@ -0,0 +1,197 @@
+;;; gEDA - GNU Electronic Design Automation
+;;; gschem - gEDA Schematic Capture
+;;; Copyright (C) 1998-2005 Ales V. Hvezda
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;; --------------------------------------------------------------------------
+;;
+;; Code to place new text attributes automatically
+;; written by Carlos Nieves Onega starts here.
+;;
+
+; Copyright (C) 2006 Carlos Nieves Onega
+; This function returns the pin direction of the pin object parameter.
+; It returns a one character string: "^", "v", "<" or ">". The arrow
+; points the pin's end, which is NOT the active connection end.
+; This function takes care of the pin's whichend property: if it's 1,
+; then the pin ends should be reversed.
+(define get-pin-direction
+ (lambda (pin)
+ (let* ( (pin-ends (get-pin-ends pin))
+ (pin-beginning (car pin-ends))
+ (pin-end (cdr pin-ends)) )
+ (begin
+ (if (eq? (car pin-beginning) (car pin-end) )
+ (if (<= (cdr pin-beginning) (cdr pin-end))
+ ; The x coords are equal. The pin is vertical.
+ "^"
+ "v")
+ (if (<= (car pin-beginning) (car pin-end))
+ ; The x coords are not equal. The pin is horizontal.
+ ">"
+ "<"))))))
+
+; This function gets the reference point of an object.
+; The position string is the reference to return. It has the format:
+; "horizontal vertical", where:
+; - "horizontal" is one of the following: "Left", "Middle", "Right".
+; - "vertical" is one of the following: "Lower", "Middle", "Upper".
+; Example: "Lower Right".
+(define (get-reference object position-string)
+ (if (not (string-index position-string #\ ))
+ (error "get-reference : Wrong reference format"))
+ (let* ( (bounds (get-object-bounds object #f))
+ (horiz-bounds (car bounds))
+ (vertical-bounds (cdr bounds))
+ (space-pos (string-index position-string #\ ))
+ (vertical-string (substring position-string 0 space-pos))
+ (horiz-string (substring position-string (+ space-pos 1)))
+ (horiz-pos (if (string=? horiz-string "Left")
+ (min (car horiz-bounds) (cdr horiz-bounds))
+ (if (string=? horiz-string "Middle")
+ (/ (+ (car horiz-bounds)
+ (cdr horiz-bounds)) 2)
+ (if (string=? horiz-string "Right")
+ (max (car horiz-bounds) (cdr horiz-bounds))
+ (error (string-append
+ "get-reference : Unknown reference (horizontal): "
+ horiz-string))))))
+ (vertical-pos (if (string=? vertical-string "Lower")
+ (min (car vertical-bounds) (cdr vertical-bounds))
+ (if (string=? vertical-string "Middle")
+ (/ (+ (car vertical-bounds)
+ (cdr vertical-bounds)) 2)
+ (if (string=? vertical-string "Upper")
+ (max (car vertical-bounds)
+ (cdr vertical-bounds))
+ (error (string-append
+ "get-reference : Unknown reference (vertical): "
+ vertical-string)))))) )
+ (cons horiz-pos vertical-pos)))
+
+
+
+; This function sets the default parameters of each attribute,
+; provided it is specified in the default-position-of-text-attributes.
+; It gets the attrib name from the attribute and sets
+; the text properties as specified in default-position-of-text-attributes.
+(define (set-default-position object attribute direction defaults)
+ (if (null? defaults)
+ 0
+ (let* ( (attrib-name-value (get-attribute-name-value attribute))
+ (attrib-name (car attrib-name-value)) ; Attribute name
+ (default-def (car defaults)) ; Default definition
+ (def-attrib-name (list-ref default-def ; Default attrib name
+ def-attrib-name-pos))
+ (def-direction (list-ref default-def ; Default direction
+ def-direction-pos)) )
+ ; Check if the attribute's name and direction matches.
+ (if (and (string=? attrib-name def-attrib-name)
+ (string=? def-direction
+ direction))
+ (begin
+ ; It maches, so change the text parameters
+ (let* ( (ref (get-reference object (list-ref default-def
+ def-reference-pos)))
+ (new-alignment (list-ref default-def
+ def-alignment-pos))
+ (new-angle (list-ref default-def
+ def-angle-pos))
+ (new-x (+ (list-ref default-def
+ def-x-offset-pos)
+ (car ref)))
+ (new-y (+ (list-ref default-def
+ def-y-offset-pos)
+ (cdr ref)))
+ )
+ (set-attribute-text-properties! attribute
+ "" ; keep previous color
+ -1 ; keep previous size
+ new-alignment
+ new-angle
+ new-x
+ new-y)
+ )
+ )
+
+ )
+ (set-default-position object attribute direction
+ (cdr defaults)) ; process the rest
+ ))
+ ) ; End of definition of set-default-position
+
+; This function processes the attribute list and calls
+; set-default-position for each attribute
+(define autoplace-text
+ (lambda (object direction attrib-list)
+ (if (not (eq? (length attrib-list) 0))
+ (begin
+ (set-default-position object (car attrib-list) direction
+ default-position-of-text-attributes)
+ (autoplace-text object direction (cdr attrib-list))
+ )))) ; End of definition of autoplace-pin-text
+
+
+; Autoplace the attributes of the given pin object.
+(define (autoplace-pin-attributes pin)
+ (let ((pin-direction (get-pin-direction pin))
+ (attribute-list (get-object-attributes pin)) )
+ (autoplace-text pin pin-direction attribute-list)))
+
+
+; Get the pin directions of the given list of pins.
+; It returns a list with all the pin directions of the pins.
+(define get-pin-directions
+ (lambda (pins)
+ (if (eq? (length pins) 0)
+ (list)
+ (cons (get-pin-direction (car pins))
+ (get-pin-directions (cdr pins))))))
+
+; Get the connection sides where there are pins.
+; The parameter pin-directions is a list with the directions of
+; all the pins. (As given by get-pin-directions).
+; It returns a string with the sides where there are pins.
+; It is needed that the return value doesn't depend on the order of the pins.
+; (Notice the arrow always points to the inside of the symbol).
+; Examples of return values: "<>^v", "<>", "^v".
+(define get-connection-sides
+ (lambda (pin-directions)
+ (define (check-side side-list pin-directions)
+ (if (eq? (length side-list) 0)
+ ""
+ (if (member (car side-list) pin-directions)
+ (string-append (car side-list)
+ (check-side (cdr side-list) pin-directions))
+ (check-side (cdr side-list) pin-directions))))
+ (check-side (list "<" ">" "^" "v") pin-directions)))
+
+; Autoplace the attributes of the given object.
+; This function gets some info of the object and calls autoplace-text.
+(define (autoplace-object-attributes object)
+ (let* ((pin-list (get-object-pins object))
+ (pin-directions (get-pin-directions pin-list))
+ (connection-sides (get-connection-sides pin-directions))
+ (attribute-list (get-object-attributes object)) )
+ (autoplace-text object connection-sides attribute-list)))
+
+
+;;
+;; Code to place new text attributes automatically
+;; written by Carlos Nieves Onega ends here.
+;;
+;; --------------------------------------------------------------------------
+
Index: libgeda/ChangeLog
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/ChangeLog,v
retrieving revision 1.287
diff -u -r1.287 ChangeLog
--- libgeda/ChangeLog 22 Jan 2006 13:55:33 -0000 1.287
+++ libgeda/ChangeLog 19 Feb 2006 21:45:40 -0000
@@ -1,3 +1,11 @@
+2006-02-19 Carlos Nieves Onega <cnieves@xxxxxxxxxx>
+
+ * include/prototype.h, include/struct.h, noweb/g_smob.nw:
+ Added new smob functions for OBJECT type.
+
+ * include/prototype.h, noweb/s_color.nw:
+ Added a new function returning the index of a given color name.
+
2006-01-22 Ales Hvezda <ahvezda@xxxxxxxxxxxxx>
* autogen.sh, m4/gettext.m4: Removed m4 files since they are
Index: libgeda/include/prototype.h
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/include/prototype.h,v
retrieving revision 1.99
diff -u -r1.99 prototype.h
--- libgeda/include/prototype.h 7 Nov 2005 02:43:28 -0000 1.99
+++ libgeda/include/prototype.h 19 Feb 2006 21:45:43 -0000
@@ -66,6 +66,12 @@
SCM g_set_attrib_value_internal(SCM attrib_smob, SCM scm_value, TOPLEVEL **world, OBJECT **o_attrib, char *new_string[]);
void g_init_attrib_smob(void);
+SCM g_make_object_smob(TOPLEVEL *curr_w, OBJECT *object);
+SCM g_get_object_attributes(SCM object_smob);
+void g_init_object_smob(void);
+gboolean g_get_data_from_object_smob(SCM object_smob, TOPLEVEL **toplevel,
+ OBJECT **object);
+
/* i_vars.c */
void i_vars_libgeda_set(TOPLEVEL *w_current);
void i_vars_setnames(TOPLEVEL *w_current);
@@ -497,6 +503,7 @@
int s_color_image_int(int color);
void s_color_gdcolor_init(void);
int s_color_get_name(int index, char *string);
+int s_color_get_index(char *string);
/* s_conn.c */
CONN *s_conn_return_new(OBJECT *other_object, int type, int x, int y, int whichone, int other_whichone);
Index: libgeda/include/struct.h
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/include/struct.h,v
retrieving revision 1.79
diff -u -r1.79 struct.h
--- libgeda/include/struct.h 27 Nov 2005 00:15:05 -0000 1.79
+++ libgeda/include/struct.h 19 Feb 2006 21:45:45 -0000
@@ -990,4 +990,9 @@
ATTRIB *attribute;
};
+struct st_object_smob {
+ TOPLEVEL *world; /* We need this when updating schematic */
+ OBJECT *object;
+};
+
#endif
Index: libgeda/noweb/g_smob.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/noweb/g_smob.nw,v
retrieving revision 1.9
diff -u -r1.9 g_smob.nw
--- libgeda/noweb/g_smob.nw 14 Feb 2005 02:17:36 -0000 1.9
+++ libgeda/noweb/g_smob.nw 19 Feb 2006 21:45:46 -0000
@@ -19,6 +19,16 @@
<<g_smob.c : g_set_attrib_value_internal()>>
<<g_smob.c : g_init_attrib_smob()>>
+<<g_smob.c : g_free_object_smob()>>
+<<g_smob.c : g_print_object_smob()>>
+<<g_smob.c : g_make_object_smob()>>
+<<g_smob.c : g_get_object_attributes()>>
+<<g_smob.c : g_init_object_smob()>>
+/*
+<<g_smob.c : g_get_object_from_object_smob()>>
+<<g_smob.c : g_get_toplevel_from_object_smob()>>
+*/
+<<g_smob.c : g_get_data_from_object_smob()>>
@
@@ -73,6 +83,7 @@
<<g_smob.c : global variables>>=
static long attrib_smob_tag;
+static long object_smob_tag;
@ %def attrib_smob_tag
@@ -80,6 +91,7 @@
@section Function @code{g_free_attrib_smob()}
@defun g_free_attrib_smob attrib_smob
+Free the memory allocated by the [[attribute smob]] and returns its size.
@end defun
<<g_smob.c : g_free_attrib_smob()>>=
@@ -100,6 +112,7 @@
@section Function @code{g_print_attrib_smob()}
@defun g_print_attrib_smob attrib_smob port pstate
+This function prints the given [[attribute smob]] to the [[port]]. It just prints a string showing it is an attribute and its string.
@end defun
<<g_smob.c : g_print_attrib_smob()>>=
@@ -109,9 +122,6 @@
struct st_attrib_smob *attribute =
(struct st_attrib_smob *)SCM_CDR(attrib_smob);
- /* I don't think this is valid, because C does not support this sort
- * of evaluation, it will eval ALL the statements unlike pascal which
- * will stop after the first FALSE -Ales */
if (attribute &&
attribute->attribute &&
attribute->attribute->object &&
@@ -133,6 +143,7 @@
@section Function @code{g_make_attrib_smob()}
@defun g_make_attrib_smob curr_w curr_attr
+Creates and returns a new attribute smob, based on the given TOPLEVEL [[curr_w]] and attribute [[curr_attr]].
@end defun
<<g_smob.c : g_make_attrib_smob()>>=
@@ -158,6 +169,7 @@
@section Function @code{g_get_attrib_name_value()}
@defun g_get_attrib_name_value attrib_smob
+Returns a list with the name and value of the given [[attribute smob]].
@end defun
<<g_smob.c : g_get_attrib_name_value()>>=
@@ -169,9 +181,8 @@
char *value = NULL;
SCM returned = SCM_EOL;
-
SCM_ASSERT ( SCM_NIMP(attrib_smob) &&
- (SCM_CAR(attrib_smob) == attrib_smob_tag),
+ ((long) SCM_CAR(attrib_smob) == attrib_smob_tag),
attrib_smob, SCM_ARG1, "get-attribute-name-value");
attribute = (struct st_attrib_smob *)SCM_CDR(attrib_smob);
@@ -197,6 +208,8 @@
@section Function @code{g_set_attrib_value_internal()}
@defun g_set_attrib_value_internal attrib_smob scm_value world o_attrib new_string
+The return value is always SCM_UNDEFINED.
+This function puts into a [[new string]] the [[attrib smob]] name and the new [[scm_value]] (attribute=value format). It also returns the [[TOPLEVEL]] and [[OBJECT]] pointers.
@end defun
<<g_smob.c : g_set_attrib_value_internal()>>=
@@ -210,7 +223,7 @@
char *old_value = NULL;
SCM_ASSERT ( SCM_NIMP(attrib_smob) &&
- (SCM_CAR(attrib_smob) == attrib_smob_tag),
+ ((long) SCM_CAR(attrib_smob) == attrib_smob_tag),
attrib_smob, SCM_ARG1, "set-attribute-value!");
SCM_ASSERT ( SCM_NIMP(scm_value) && SCM_STRINGP(scm_value),
scm_value, SCM_ARG2, "set-attribute-value!");
@@ -245,6 +258,7 @@
@section Function @code{g_init_attrib_smob()}
@defun g_init_attrib_smob
+Initialize the framework to support an attrib smob.
@end defun
<<g_smob.c : g_init_attrib_smob()>>=
@@ -263,3 +277,207 @@
}
@ %def g_init_attrib_smob
+
+
+
+@section Function @code{g_free_attrib_smob()}
+
+@defun g_free_object_smob object_smob
+Free the memory allocated by the [[object smob]] and returns its size.
+@end defun
+
+<<g_smob.c : g_free_object_smob()>>=
+static scm_sizet
+g_free_object_smob(SCM object_smob)
+{
+ struct st_object_smob *object =
+ (struct st_object_smob *)SCM_CDR(object_smob);
+ scm_sizet size = sizeof(struct st_object_smob);
+
+ free(object);
+ return size;
+}
+
+@ %def g_free_object_smob
+
+@section Function @code{g_print_object_smob()}
+
+@defun g_print_object_smob object_smob port pstate
+This function prints the given [[object smob]] to the [[port]]. It just prints a string showing it is an object and the object name.
+@end defun
+
+<<g_smob.c : g_print_object_smob()>>=
+static int
+g_print_object_smob(SCM object_smob, SCM port, scm_print_state *pstate)
+{
+ struct st_object_smob *object =
+ (struct st_object_smob *)SCM_CDR(object_smob);
+
+ if (object &&
+ object->object &&
+ object->object->name) {
+ scm_puts("#<object ", port);
+ scm_display (scm_makfrom0str (object->object->name),
+ port);
+ scm_puts(">", port);
+ }
+
+ /* non-zero means success */
+ return 1;
+}
+
+@ %def g_print_object_smob
+
+@section Function @code{g_make_object_smob()}
+
+@defun g_make_object_smob curr_w curr_attr
+Creates and returns an [[object smob]] from the given TOPLEVEL\'s [[curr_w]] and [[object]] pointers.
+@end defun
+
+<<g_smob.c : g_make_object_smob()>>=
+/* Creates an object smob */
+SCM
+g_make_object_smob(TOPLEVEL *curr_w, OBJECT *object)
+{
+ struct st_object_smob *smob_object;
+
+ smob_object = (struct st_object_smob *)
+ scm_must_malloc(sizeof(struct st_object_smob), "object");
+
+ smob_object->world = curr_w;
+ smob_object->object = object;
+
+ /* Assumes Guile version >= 1.3.2 */
+ SCM_RETURN_NEWSMOB(object_smob_tag, smob_object);
+}
+
+@ %def g_make_object_smob
+
+
+@section Function @code{g_get_object_attributes()}
+
+@defun g_get_object_attributes object_smob
+This function returns a list with all the attributes of the given [[object smob]].
+@end defun
+
+<<g_smob.c : g_get_object_attributes()>>=
+SCM
+g_get_object_attributes(SCM object_smob)
+{
+ TOPLEVEL *w_current;
+ struct st_object_smob *object;
+ SCM returned = SCM_EOL;
+
+ SCM_ASSERT ( SCM_NIMP(object_smob) &&
+ ((long) SCM_CAR(object_smob) == object_smob_tag),
+ object_smob, SCM_ARG1, "get-object-attributes");
+
+ object = (struct st_object_smob *)SCM_CDR(object_smob);
+
+ if (object &&
+ object->object) {
+ ATTRIB *pointer;
+
+ pointer = object->object->attribs;
+ w_current = object->world;
+ while (pointer != NULL) {
+ if (pointer->object &&
+ pointer->object->text) {
+ returned = scm_cons (g_make_attrib_smob (w_current, pointer), returned);
+ }
+ pointer = pointer->next;
+ }
+ }
+
+ return returned;
+}
+
+@ %def g_get_object_attributes
+
+
+@section Function @code{g_init_object_smob()}
+
+@defun g_init_object_smob
+Initialize the framework to support an object smob.
+@end defun
+
+<<g_smob.c : g_init_object_smob()>>=
+void
+g_init_object_smob(void)
+{
+
+ object_smob_tag = scm_make_smob_type("object", sizeof (struct st_object_smob));
+ scm_set_smob_mark(object_smob_tag, 0);
+ scm_set_smob_free(object_smob_tag, g_free_object_smob);
+ scm_set_smob_print(object_smob_tag, g_print_object_smob);
+
+ scm_c_define_gsubr("get-object-attributes", 1, 0, 0, g_get_object_attributes);
+
+ return;
+}
+
+@ %def g_init_object_smob
+
+@section Function @code{g_free_attrib_smob()}
+
+@defun g_get_object_from_object_smob object_smob
+Gets the [[object]] data from the [[object smob]].
+@end defun
+
+<<g_smob.c : g_get_object_from_object_smob()>>=
+OBJECT *
+g_get_object_from_object_smob(SCM object_smob)
+{
+
+ SCM_ASSERT ( SCM_NIMP(object_smob) &&
+ (SCM_CAR(object_smob) == object_smob_tag),
+ object_smob, SCM_ARG1, "get_object_from_object_smob");
+ return ((OBJECT *) (((struct st_object_smob *)SCM_CDR(object_smob))->object));
+}
+
+@ %def g_get_object_from_object_smob
+
+@defun g_get_object_from_object_smob object_smob
+@end defun
+
+<<g_smob.c : g_get_toplevel_from_object_smob()>>=
+TOPLEVEL *
+g_get_toplevel_from_object_smob(SCM object_smob)
+{
+
+ SCM_ASSERT ( SCM_NIMP(object_smob) &&
+ (SCM_CAR(object_smob) == object_smob_tag),
+ object_smob, SCM_ARG1, "get_toplevel_from_object_smob");
+ return ((TOPLEVEL *) (((struct st_object_smob *)SCM_CDR(object_smob))->world));
+}
+
+@ %def g_get_toplevel_from_object_smob
+
+@defun g_get_data_from_object_smob object_smob
+This function gets the [[toplevel]] and [[object]] data stored in an [[object_smob]].
+It returns FALSE if the smob is not an object smob, and TRUE otherwise.
+The pointers [[toplevel]] and [[object]] are used to return the data. If any of them is NULL, then it is just ignored.
+@end defun
+
+<<g_smob.c : g_get_data_from_object_smob()>>=
+gboolean
+g_get_data_from_object_smob(SCM object_smob, TOPLEVEL **toplevel,
+ OBJECT **object)
+{
+
+ if ( (!SCM_NIMP(object_smob)) ||
+ ((long) SCM_CAR(object_smob) != object_smob_tag) ) {
+ return(FALSE);
+ }
+ if (toplevel != NULL) {
+ *toplevel = (TOPLEVEL *)
+ (((struct st_object_smob *)SCM_CDR(object_smob))->world);
+ }
+ if (object != NULL) {
+ *object = (OBJECT *)
+ (((struct st_object_smob *)SCM_CDR(object_smob))->object);
+ }
+ return (TRUE);
+}
+
+@ %def g_get_data_from_object_smob
Index: libgeda/noweb/s_color.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/noweb/s_color.nw,v
retrieving revision 1.6
diff -u -r1.6 s_color.nw
--- libgeda/noweb/s_color.nw 4 Feb 2005 22:37:06 -0000 1.6
+++ libgeda/noweb/s_color.nw 19 Feb 2006 21:45:46 -0000
@@ -19,7 +19,7 @@
<<s_color.c : s_color_image_int()>>
<<s_color.c : s_color_gdcolor_init()>>
<<s_color.c : s_color_get_name()>>
-
+<<s_color.c : s_color_get_index()>>
@
@@ -300,3 +300,34 @@
@ %def s_color_get_name
+
+@section Function @code{s_color_get_index()}
+
+@defun s_color_get_index string
+Returns the index of the given color name.
+Returns -1 if not found.
+@end defun
+
+<<s_color.c : s_color_get_index()>>=
+int
+s_color_get_index(char *string)
+{
+ int index;
+
+ if (string == NULL) {
+ return(-1);
+ }
+
+ for (index = 0; index < MAX_COLORS; index++) {
+ if (strcasecmp(string, colors[index].color_name) == 0) {
+ return (index);
+ }
+ }
+
+ /* If the color was not found, return -1 */
+ return (-1);
+
+}
+
+
+@ %def s_color_get_int