libgeda
|
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 }