libgeda

scheme_attrib.c

Go to the documentation of this file.
00001 /* gEDA - GPL Electronic Design Automation
00002  * libgeda - gEDA's library - Scheme API
00003  * Copyright (C) 2010-2011 Peter Brett <peter@peter-b.co.uk>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
00018  */
00019 
00025 #include <config.h>
00026 
00027 #include "libgeda_priv.h"
00028 #include "libgedaguile_priv.h"
00029 
00030 SCM_SYMBOL (attribute_format_sym, "attribute-format");
00031 
00045 SCM_DEFINE (parse_attrib, "%parse-attrib", 1, 0, 0,
00046             (SCM text_s), "Parse attribute name and value from text object.")
00047 {
00048   gchar *name = NULL;
00049   gchar *value = NULL;
00050   SCM result = SCM_BOOL_F;
00051 
00052   SCM_ASSERT (edascm_is_object_type (text_s, OBJ_TEXT), text_s,
00053               SCM_ARG1, s_parse_attrib);
00054 
00055   TOPLEVEL *toplevel = edascm_c_current_toplevel ();
00056   OBJECT *text = edascm_to_object (text_s);
00057 
00058   scm_dynwind_begin (0);
00059   scm_dynwind_unwind_handler (g_free, name, SCM_F_WIND_EXPLICITLY);
00060   scm_dynwind_unwind_handler (g_free, value, SCM_F_WIND_EXPLICITLY);
00061 
00062   if (o_attrib_get_name_value (text, &name, &value)) {
00063     result = scm_cons (scm_from_utf8_string (name),
00064                        scm_from_utf8_string (value));
00065   } else {
00066     scm_error (attribute_format_sym, s_parse_attrib,
00067                _("~A is not a valid attribute: invalid string '~A'."),
00068                scm_list_2 (text_s,
00069                            scm_from_utf8_string (o_text_get_string (toplevel, text))),
00070                SCM_EOL);
00071   }
00072   scm_dynwind_end ();
00073 
00074   return result;
00075 }
00076 
00088 SCM_DEFINE (object_attribs, "%object-attribs", 1, 0, 0,
00089             (SCM obj_s), "Get an object's attributes.")
00090 {
00091   /* Ensure that the argument is an object */
00092   SCM_ASSERT (EDASCM_OBJECTP (obj_s), obj_s,
00093               SCM_ARG1, s_object_attribs);
00094 
00095   OBJECT *obj = edascm_to_object (obj_s);
00096 
00097   return edascm_from_object_glist (obj->attribs);
00098 }
00099 
00111 SCM_DEFINE (attrib_attachment, "%attrib-attachment", 1, 0, 0,
00112             (SCM attrib_s), "Get the object that an attribute is attached to.")
00113 {
00114   /* Ensure that the argument is an object */
00115   SCM_ASSERT (EDASCM_OBJECTP (attrib_s), attrib_s,
00116               SCM_ARG1, s_attrib_attachment);
00117 
00118   OBJECT *obj = edascm_to_object (attrib_s);
00119 
00120   if (obj->attached_to == NULL) {
00121     return SCM_BOOL_F;
00122   } else {
00123     return edascm_from_object (obj->attached_to);
00124   }
00125 }
00126 
00152 SCM_DEFINE (attach_attrib_x, "%attach-attrib!", 2, 0, 0,
00153             (SCM obj_s, SCM attrib_s), "Attach an attribute to an object.")
00154 {
00155   SCM_ASSERT (EDASCM_OBJECTP (obj_s), obj_s,
00156               SCM_ARG1, s_attach_attrib_x);
00157   SCM_ASSERT (edascm_is_object_type (attrib_s, OBJ_TEXT), attrib_s,
00158               SCM_ARG2, s_attach_attrib_x);
00159 
00160   TOPLEVEL *toplevel = edascm_c_current_toplevel ();
00161   OBJECT *obj = edascm_to_object (obj_s);
00162   OBJECT *attrib = edascm_to_object (attrib_s);
00163 
00164   /* Check that attachment doesn't already exist */
00165   if (attrib->attached_to == obj) return obj_s;
00166 
00167   /* Check that both are in the same page and/or complex object */
00168   if ((obj->parent != attrib->parent)
00169       || (o_get_page (toplevel, obj) != o_get_page (toplevel, attrib))
00170       || ((obj->parent == NULL) && (o_get_page (toplevel, obj) == NULL))) {
00171     scm_error (edascm_object_state_sym, s_attach_attrib_x,
00172                _("Objects ~A and ~A are not part of the same page and/or complex object"),
00173                scm_list_2 (obj_s, attrib_s), SCM_EOL);
00174   }
00175 
00176   /* Check that neither is already an attached attribute */
00177   if (obj->attached_to != NULL) {
00178     scm_error (edascm_object_state_sym, s_attach_attrib_x,
00179                _("Object ~A is already attached as an attribute"),
00180                scm_list_1 (obj_s), SCM_EOL);
00181   }
00182   if (attrib->attached_to != NULL) {
00183     scm_error (edascm_object_state_sym, s_attach_attrib_x,
00184                _("Object ~A is already attached as an attribute"),
00185                scm_list_1 (attrib_s), SCM_EOL);
00186   }
00187 
00188   /* Carry out the attachment */
00189   o_emit_pre_change_notify (toplevel, attrib);
00190   o_attrib_attach (toplevel, attrib, obj, TRUE);
00191   o_emit_change_notify (toplevel, attrib);
00192 
00193   o_page_changed (toplevel, obj);
00194 
00195   scm_remember_upto_here_1 (attrib_s);
00196   return obj_s;
00197 }
00198 
00213 SCM_DEFINE (detach_attrib_x, "%detach-attrib!", 2, 0, 0,
00214             (SCM obj_s, SCM attrib_s), "Detach an attribute to an object.")
00215 {
00216   SCM_ASSERT (EDASCM_OBJECTP (obj_s), obj_s,
00217               SCM_ARG1, s_detach_attrib_x);
00218   SCM_ASSERT (edascm_is_object_type (attrib_s, OBJ_TEXT), attrib_s,
00219               SCM_ARG2, s_detach_attrib_x);
00220 
00221   TOPLEVEL *toplevel = edascm_c_current_toplevel ();
00222   OBJECT *obj = edascm_to_object (obj_s);
00223   OBJECT *attrib = edascm_to_object (attrib_s);
00224 
00225   /* If attrib isn't attached, do nothing */
00226   if (attrib->attached_to == NULL) {
00227     return obj_s;
00228   }
00229 
00230   /* Check that attrib isn't attached elsewhere */
00231   if (attrib->attached_to != obj) {
00232     scm_error (edascm_object_state_sym, s_detach_attrib_x,
00233                _("Object ~A is attribute of wrong object"),
00234                scm_list_1 (attrib_s), SCM_EOL);
00235   }
00236 
00237   /* Detach object */
00238   o_emit_pre_change_notify (toplevel, attrib);
00239   o_attrib_remove (toplevel, &obj->attribs, attrib);
00240   o_set_color (toplevel, attrib, DETACHED_ATTRIBUTE_COLOR);
00241   o_emit_change_notify (toplevel, attrib);
00242 
00243   o_page_changed (toplevel, obj);
00244 
00245   scm_remember_upto_here_1 (attrib_s);
00246   return obj_s;
00247 }
00248 
00258 SCM_DEFINE (promotable_attribs, "%promotable-attribs", 1, 0, 0,
00259             (SCM complex_s), "Get a component's promotable attributes")
00260 {
00261   SCM_ASSERT (edascm_is_object_type (complex_s, OBJ_COMPLEX), complex_s,
00262               SCM_ARG1, s_promotable_attribs);
00263 
00264   TOPLEVEL *toplevel = edascm_c_current_toplevel ();
00265   OBJECT *obj = edascm_to_object (complex_s);
00266 
00267   GList *lst = o_complex_get_promotable (toplevel, obj, FALSE);
00268 
00269   return edascm_from_object_glist (lst);
00270 }
00271 
00272 
00279 static void
00280 init_module_geda_core_attrib ()
00281 {
00282   /* Register the functions */
00283   #include "scheme_attrib.x"
00284 
00285   /* Add them to the module's public definitions. */
00286   scm_c_export (s_parse_attrib, s_object_attribs, s_attrib_attachment,
00287                 s_attach_attrib_x, s_detach_attrib_x,
00288                 s_promotable_attribs,
00289                 NULL);
00290 }
00291 
00298 void
00299 edascm_init_attrib ()
00300 {
00301   /* Define the (geda core attrib) module */
00302   scm_c_define_module ("geda core attrib",
00303                        init_module_geda_core_attrib,
00304                        NULL);
00305 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines