/*! \brief create a copy of a text object * \par Function Description * This function creates a copy of the text object \a o_current. * * \param [in] toplevel The TOPLEVEL object * \param [in] object The object that is copied * \return a new text object */ GedaObject* geda_text_object_copy (TOPLEVEL *toplevel, const GedaObject *object) { GedaObject *new_obj; g_return_val_if_fail (object != NULL, NULL); g_return_val_if_fail (object->text != NULL, NULL); g_return_val_if_fail (object->type == OBJ_TEXT, NULL); new_obj = geda_text_object_new (toplevel, object->color, object->text->x, object->text->y, object->text->alignment, object->text->angle, object->text->string, object->text->size, geda_object_get_visible (object), object->show_name_value); return new_obj; }
/*! \brief Updates the preview widget. * \par Function Description * This function updates the preview: if the preview is active and a * filename has been given, it opens the file and displays * it. Otherwise it displays a blank page. * * \param [in] preview The preview widget. */ static void preview_update (GschemPreview *preview) { int left, top, right, bottom; int width, height; GError * err = NULL; GschemPageView *preview_view = GSCHEM_PAGE_VIEW (preview); g_return_if_fail (preview_view != NULL); PAGE *preview_page = gschem_page_view_get_page (preview_view); if (preview_page == NULL) { return; } TOPLEVEL *preview_toplevel = preview_page->toplevel; /* delete old preview */ s_page_delete_objects (preview_toplevel, preview_page); if (preview->active) { g_assert ((preview->filename == NULL) || (preview->buffer == NULL)); if (preview->filename != NULL) { /* open up file in current page */ f_open_flags (preview_toplevel, preview_page, preview->filename, F_OPEN_RC | F_OPEN_RESTORE_CWD, NULL); /* test value returned by f_open... - Fix me */ /* we should display something if there an error occured - Fix me */ } if (preview->buffer != NULL) { /* Load the data buffer */ GList * objects = o_read_buffer (preview_toplevel, NULL, preview->buffer, -1, _("Preview Buffer"), &err); if (err == NULL) { s_page_append_list (preview_toplevel, preview_page, objects); } else { s_page_append (preview_toplevel, preview_page, geda_text_object_new (preview_toplevel, 2, 100, 100, LOWER_MIDDLE, 0, err->message, 10, VISIBLE, SHOW_NAME_VALUE)); g_error_free(err); } } } if (world_get_object_glist_bounds (preview_toplevel, s_page_objects (preview_page), &left, &top, &right, &bottom)) { /* Clamp the canvas size to the extents of the page being previewed */ width = right - left; height = bottom - top; GschemPageGeometry *geometry = gschem_page_view_get_page_geometry (preview_view); geometry->world_left = left - ((double)width * OVER_ZOOM_FACTOR); geometry->world_right = right + ((double)width * OVER_ZOOM_FACTOR); geometry->world_top = top - ((double)height * OVER_ZOOM_FACTOR); geometry->world_bottom = bottom + ((double)height * OVER_ZOOM_FACTOR); } /* display current page (possibly empty) */ gschem_page_view_zoom_extents (preview_view, NULL); }
static void create_placeholder(TOPLEVEL * toplevel, OBJECT * new_node, int x, int y) { GedaBounds bounds; OBJECT *new_prim_obj; char *not_found_text = NULL; int x_offset, y_offset; /* Put placeholder into object list. Changed by SDB on * 1.19.2005 to fix problem that symbols were silently * deleted by gattrib when RC files were messed up. */ new_node->type = OBJ_PLACEHOLDER; /* Mark the origin of the missing component */ new_prim_obj = geda_line_object_new (toplevel, DETACHED_ATTRIBUTE_COLOR, x - 50, y, x + 50, y); new_node->complex->prim_objs = g_list_prepend (new_node->complex->prim_objs, new_prim_obj); new_prim_obj = geda_line_object_new (toplevel, DETACHED_ATTRIBUTE_COLOR, x, y + 50, x, y - 50); new_node->complex->prim_objs = g_list_prepend (new_node->complex->prim_objs, new_prim_obj); /* Add some useful text */ not_found_text = g_strdup_printf (_("Component not found:\n %s"), new_node->complex_basename); new_prim_obj = geda_text_object_new (toplevel, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X, y + NOT_FOUND_TEXT_Y, LOWER_LEFT, 0, not_found_text, 8, VISIBLE, SHOW_NAME_VALUE); new_node->complex->prim_objs = g_list_prepend (new_node->complex->prim_objs, new_prim_obj); g_free(not_found_text); /* figure out where to put the hazard triangle */ geda_text_object_calculate_bounds (toplevel, new_prim_obj, &bounds); x_offset = (bounds.max_x - bounds.min_x) / 4; y_offset = bounds.max_y - bounds.min_y + 100; /* 100 is just an additional offset */ /* add hazard triangle */ new_prim_obj = geda_line_object_new (toplevel, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X + x_offset, y + NOT_FOUND_TEXT_Y + y_offset, x + NOT_FOUND_TEXT_X + x_offset + 600, y + NOT_FOUND_TEXT_Y + y_offset); o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID, 50, -1, -1); new_node->complex->prim_objs = g_list_prepend (new_node->complex->prim_objs, new_prim_obj); new_prim_obj = geda_line_object_new (toplevel, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X + x_offset, y + NOT_FOUND_TEXT_Y + y_offset, x + NOT_FOUND_TEXT_X + x_offset + 300, y + NOT_FOUND_TEXT_Y + y_offset + 500); o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID, 50, -1, -1); new_node->complex->prim_objs = g_list_prepend (new_node->complex->prim_objs, new_prim_obj); new_prim_obj = geda_line_object_new (toplevel, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X + x_offset + 300, y + NOT_FOUND_TEXT_Y + y_offset + 500, x + NOT_FOUND_TEXT_X + x_offset + 600, y + NOT_FOUND_TEXT_Y + y_offset); o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID, 50, -1, -1); new_node->complex->prim_objs = g_list_prepend (new_node->complex->prim_objs, new_prim_obj); new_prim_obj = geda_text_object_new (toplevel, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X + x_offset + 270, y + NOT_FOUND_TEXT_Y + y_offset + 90, LOWER_LEFT, 0, "!", 18, VISIBLE, SHOW_NAME_VALUE); new_node->complex->prim_objs = g_list_prepend (new_node->complex->prim_objs, new_prim_obj); new_node->complex->prim_objs = g_list_reverse(new_node->complex->prim_objs); }
/* text item */ OBJECT *o_attrib_add_attrib(GschemToplevel *w_current, const char *text_string, int visibility, int show_name_value, OBJECT *object) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); OBJECT *new_obj; int world_x = - 1, world_y = -1; int align = LOWER_LEFT; int angle = 0; int color; int left, right, top, bottom; OBJECT *o_current; color = DETACHED_ATTRIBUTE_COLOR; o_current = object; /* creating a toplevel or unattached attribute */ if (o_current) { /* get coordinates of where to place the text object */ switch(o_current->type) { case(OBJ_COMPLEX): case(OBJ_PLACEHOLDER): world_x = o_current->complex->x; world_y = o_current->complex->y; align = LOWER_LEFT; angle = 0; color = ATTRIBUTE_COLOR; break; case(OBJ_ARC): world_x = geda_arc_object_get_center_x (o_current); world_y = geda_arc_object_get_center_y (o_current); align = LOWER_LEFT; angle = 0; color = ATTRIBUTE_COLOR; break; case(OBJ_CIRCLE): world_x = geda_circle_object_get_center_x (o_current); world_y = geda_circle_object_get_center_y (o_current); align = LOWER_LEFT; angle = 0; color = ATTRIBUTE_COLOR; break; case(OBJ_BOX): world_x = o_current->box->upper_x; world_y = o_current->box->upper_y; align = LOWER_LEFT; angle = 0; color = ATTRIBUTE_COLOR; break; case(OBJ_LINE): case(OBJ_NET): case(OBJ_PIN): case(OBJ_BUS): { int dx = o_current->line->x[1] - o_current->line->x[0]; int dy = o_current->line->y[1] - o_current->line->y[0]; if (dy == 0) { if (dx > 0) { world_x = o_current->line->x[0] + SPACING_FROM_END; world_y = o_current->line->y[0] + SPACING_PERPENDICULAR; align = LOWER_LEFT; angle = 0; } else { world_x = o_current->line->x[0] - SPACING_FROM_END; world_y = o_current->line->y[0] + SPACING_PERPENDICULAR; align = LOWER_RIGHT; angle = 0; } } else if (dx == 0) { if (dy > 0) { world_x = o_current->line->x[0] - SPACING_PERPENDICULAR; world_y = o_current->line->y[0] + SPACING_FROM_END; align = LOWER_LEFT; angle = 90; } else { world_x = o_current->line->x[0] - SPACING_PERPENDICULAR; world_y = o_current->line->y[0] - SPACING_FROM_END; align = LOWER_RIGHT; angle = 90; } } else { world_x = o_current->line->x[0]; world_y = o_current->line->y[0]; align = LOWER_LEFT; angle = 0; } color = ATTRIBUTE_COLOR; } break; case(OBJ_TEXT): world_x = o_current->text->x; world_y = o_current->text->y; color = DETACHED_ATTRIBUTE_COLOR; align = LOWER_LEFT; angle = 0; o_current = NULL; break; } } else { world_get_object_glist_bounds (toplevel, s_page_objects (toplevel->page_current), &left, &top, &right, &bottom); /* this really is the lower left hand corner */ world_x = left; world_y = top; /* printf("%d %d\n", world_x, world_y); */ align = LOWER_LEFT; angle = 0; color = DETACHED_ATTRIBUTE_COLOR; } /* first create text item */ new_obj = geda_text_object_new (toplevel, color, world_x, world_y, align, angle, text_string, w_current->text_size, /* current text size */ visibility, show_name_value); s_page_append (toplevel, toplevel->page_current, new_obj); /* now attach the attribute to the object (if o_current is not NULL) */ /* remember that o_current contains the object to get the attribute */ if (o_current) { o_attrib_attach (toplevel, new_obj, o_current, FALSE); } o_selection_add (toplevel, toplevel->page_current->selection_list, new_obj); /* handle slot= attribute, it's a special case */ if (o_current != NULL && g_ascii_strncasecmp (text_string, "slot=", 5) == 0) { o_slot_end (w_current, o_current, text_string); } /* Call add-objects-hook. */ g_run_hook_object (w_current, "%add-objects-hook", new_obj); g_run_hook_object (w_current, "%select-objects-hook", new_obj); gschem_toplevel_page_content_changed (w_current, toplevel->page_current); return new_obj; }
/*! \brief read a text object from a char buffer * \par Function Description * This function reads a text object from the textbuffer \a tb and * the text starting with the line \a firstline. * If the line object was read successfully, a new object is * create and appended to the \a object_list. * * \param [in] toplevel The TOPLEVEL object * \param [in] first_line the first line of the text * \param [in] tb a text buffer (usually a line of a schematic file) * \param [in] release_ver The release number gEDA * \param [in] fileformat_ver a integer value of the file format * \return The object list, or NULL on error. */ OBJECT* o_text_read (TOPLEVEL *toplevel, const char *first_line, TextBuffer *tb, unsigned int release_ver, unsigned int fileformat_ver, GError **err) { OBJECT *new_obj; char type; int x, y; int color; int size; int visibility; int show_name_value; int angle; int alignment; int num_lines = 0; int i; char* string = NULL; GString *textstr; if (fileformat_ver >= 1) { if (sscanf(first_line, "%c %d %d %d %d %d %d %d %d %d\n", &type, &x, &y, &color, &size, &visibility, &show_name_value, &angle, &alignment, &num_lines) != 10) { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse text object")); return NULL; } } else if (release_ver < VERSION_20000220) { /* yes, above less than (not less than and equal) is correct. The format */ /* change occurred in 20000220 */ if (sscanf(first_line, "%c %d %d %d %d %d %d %d\n", &type, &x, &y, &color, &size, &visibility, &show_name_value, &angle) != 8) { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse text object")); return NULL; } alignment = LOWER_LEFT; /* older versions didn't have this */ num_lines = 1; /* only support a single line */ } else { if (sscanf(first_line, "%c %d %d %d %d %d %d %d %d\n", &type, &x, &y, &color, &size, &visibility, &show_name_value, &angle, &alignment) != 9) { g_set_error (err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse text object")); return NULL; } num_lines = 1; /* only support a single line */ } if (size < MINIMUM_TEXT_SIZE) { s_log_message (_("Found an invalid text size [ %1$s ]"), first_line); size = DEFAULT_TEXT_SIZE; s_log_message (_("Setting text size to %1$d."), size); } if (!geda_angle_is_ortho (angle)) { s_log_message (_("Found an unsupported text angle [ %1$s ]"), first_line); angle = geda_angle_make_ortho (angle); s_log_message (_("Setting angle to %1$d."), angle); } switch(alignment) { case(LOWER_LEFT): case(MIDDLE_LEFT): case(UPPER_LEFT): case(LOWER_MIDDLE): case(MIDDLE_MIDDLE): case(UPPER_MIDDLE): case(LOWER_RIGHT): case(MIDDLE_RIGHT): case(UPPER_RIGHT): break; default: s_log_message (_("Found an unsupported text alignment [ %1$s ]"), first_line); alignment = LOWER_LEFT; s_log_message(_("Setting alignment to LOWER_LEFT.")); break; } if (color < 0 || color > MAX_COLORS) { s_log_message(_("Found an invalid color [ %1$s ]"), first_line); color = DEFAULT_COLOR; s_log_message(_("Setting color to default color.")); } g_assert(num_lines && num_lines > 0); textstr = g_string_new (""); for (i = 0; i < num_lines; i++) { const gchar *line; line = s_textbuffer_next_line (tb); if (line == NULL) { g_string_free (textstr, TRUE); g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Unexpected end-of-file after %1$d lines"), i); return NULL; } textstr = g_string_append (textstr, line); } /* retrieve the character string from the GString */ string = g_string_free (textstr, FALSE); string = geda_string_remove_ending_newline (string); /* convert the character string to UTF-8 if necessary */ if (!g_utf8_validate (string, -1, NULL)) { /* if it is not utf-8, it is ISO_8859-15 */ gchar *tmp = g_convert (string, strlen (string), "UTF-8", "ISO_8859-15", NULL, NULL, NULL); if (tmp == NULL) { fprintf (stderr, "Failed to convert text string to UTF-8: %1$s.\n", string); } else { /* successfully converted string, now use tmp as string */ g_free (string); string = tmp; } } new_obj = geda_text_object_new (toplevel, color, x, y, alignment, angle, string, size, visibility, show_name_value); g_free(string); return new_obj; }