HTMLPoint * html_point_max (HTMLPoint *a, HTMLPoint *b) { GSList *a_downline, *b_downline; HTMLPoint *rv = NULL; if (a->object == b->object) return a->offset < b->offset ? b : a; a_downline = get_downtree_line (a->object); b_downline = get_downtree_line (b->object); do_downtree_lines_intersection (&a_downline, &b_downline, NULL); if (a_downline == NULL) /* it means that a is parent (container) of b */ rv = a->offset ? a : b; else if (b_downline == NULL) /* it means that b is parent (container) of a */ rv = b->offset ? b : a; else rv = html_object_children_max (HTML_OBJECT (a_downline->data), HTML_OBJECT (b_downline->data)) == HTML_OBJECT (a_downline->data) ? a : b; g_slist_free (a_downline); g_slist_free (b_downline); return rv; }
void html_interval_forall (HTMLInterval *i, HTMLEngine *e, HTMLObjectForallFunc f, gpointer data) { GSList *from_downline, *to_downline; HTMLEngine *engine; g_return_if_fail (i->from.object); g_return_if_fail (i->to.object); i = html_interval_flat (i); from_downline = get_downtree_line (i->from.object); to_downline = get_downtree_line (i->to.object); engine = do_downtree_lines_intersection (&from_downline, &to_downline, e); if (from_downline) interval_forall (HTML_OBJECT (from_downline->data)->parent, from_downline, to_downline, html_object_get_engine (HTML_OBJECT (from_downline->data)->parent, engine), f, data); else { g_assert (i->from.object == i->to.object); html_object_forall (i->from.object, html_object_get_engine (i->from.object, engine), f, data); } g_slist_free (from_downline); g_slist_free (to_downline); html_interval_destroy (i); }
void html_table_insert_column (HTMLTable *t, HTMLEngine *e, gint col, HTMLTableCell **column, HTMLUndoDirection dir) { HTMLTableCell *cell; HTMLPoint pos; gint c, r; guint position_before; html_engine_freeze (e); position_before = e->cursor->position; pos.object = e->cursor->object; pos.offset = e->cursor->offset; html_engine_goto_table_0 (e, t); html_table_alloc_cell (t, 0, t->totalCols); for (c = t->totalCols - 1; c > col; c--) { for (r = 0; r < t->totalRows; r++) { HTMLTableCell *cell = t->cells[r][c - 1]; if (cell) { if (cell->col == c - 1) { html_table_cell_set_position (cell, cell->row, c); t->cells[r][c - 1] = NULL; } else if (c == col + 1 && cell->row == r) cell->cspan++; if (cell->col > c - 1) t->cells[r][c - 1] = NULL; t->cells[r][c] = cell; } } } for (r = 0; r < t->totalRows; r++) { if (!t->cells[r][col]) { guint len; cell = column ? HTML_TABLE_CELL (html_object_op_copy (HTML_OBJECT (column[r]), HTML_OBJECT (t), e, NULL, NULL, &len)) : html_engine_new_cell (e, t); html_table_set_cell (t, r, col, cell); html_table_cell_set_position (t->cells[r][col], r, col); } } html_cursor_jump_to (e->cursor, e, pos.object, pos.offset); insert_column_setup_undo (e, col, position_before, dir); html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC); html_engine_queue_draw (e, HTML_OBJECT (t)); html_engine_thaw (e); }
void html_table_delete_column (HTMLTable *t, HTMLEngine *e, gint col, HTMLUndoDirection dir) { HTMLTableCell **column; HTMLTableCell *cell; HTMLPoint pos; gint r, c; guint position_after; /* this command is valid only in table and when this table has > 1 column */ if (!t || t->totalCols < 2) return; html_engine_freeze (e); column = g_new0 (HTMLTableCell *, t->totalRows); backward_before_col (e, t, col); pos.object = e->cursor->object; pos.offset = e->cursor->offset; html_engine_goto_table_0 (e, t); for (r = 0; r < t->totalRows; r++) { cell = t->cells[r][col]; /* remove & keep old one */ if (cell && cell->col == col) { HTML_OBJECT (cell)->parent = NULL; column[r] = cell; t->cells[r][col] = NULL; } for (c = col + 1; c < t->totalCols; c++) { cell = t->cells[r][c]; if (cell && cell->col != col) { if (cell->row == r && cell->col == c) html_table_cell_set_position (cell, r, c - 1); t->cells[r][c - 1] = cell; t->cells[r][c] = NULL; } } } html_cursor_jump_to (e->cursor, e, pos.object, pos.offset); position_after = e->cursor->position; delete_column_setup_undo (e, column, t->totalRows, position_after, col, dir); t->totalCols--; html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC); html_engine_queue_draw (e, HTML_OBJECT (t)); html_engine_thaw (e); }
void html_table_insert_row (HTMLTable *t, HTMLEngine *e, gint row, HTMLTableCell **row_cells, HTMLUndoDirection dir) { HTMLTableCell *cell; HTMLPoint pos; gint r, c; guint position_before; html_engine_freeze (e); position_before = e->cursor->position; pos.object = e->cursor->object; pos.offset = e->cursor->offset; html_engine_goto_table_0 (e, t); html_table_alloc_cell (t, t->totalRows, 0); for (r = t->totalRows; r > row; r--) { for (c = 0; c < t->totalCols; c++) { HTMLTableCell *cell = t->cells[r - 1][c]; if (cell) { if (cell->row == r - 1) { html_table_cell_set_position (cell, r, cell->col); t->cells[r - 1][c] = NULL; } else if (r == row + 1 && cell->col == c) cell->rspan++; if (cell->row > r - 1) t->cells[r - 1][c] = NULL; t->cells[r][c] = cell; } } } for (c = 0; c < t->totalCols; c++) { if (!t->cells[row][c]) { guint len; cell = row_cells ? HTML_TABLE_CELL (html_object_op_copy (HTML_OBJECT (row_cells[c]), HTML_OBJECT (t), e, NULL, NULL, &len)) : html_engine_new_cell (e, t); html_table_set_cell (t, row, c, cell); html_table_cell_set_position (t->cells[row][c], row, c); } } html_cursor_jump_to (e->cursor, e, pos.object, pos.offset); insert_row_setup_undo (e, row, position_before, dir); html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC); html_engine_queue_draw (e, HTML_OBJECT (t)); html_engine_thaw (e); }
void html_cluealigned_init (HTMLClueAligned *aligned, HTMLClueAlignedClass *klass, HTMLObject *parent, gint x, gint y, gint max_width, gint percent) { HTMLClue *clue; HTMLObject *object; clue = HTML_CLUE (aligned); object = HTML_OBJECT (aligned); html_clue_init (clue, HTML_CLUE_CLASS (klass)); object->x = x; object->y = y; object->max_width = max_width; object->percent = percent; if (percent > 0) object->flags &= ~HTML_OBJECT_FLAG_FIXEDWIDTH; clue->valign = HTML_VALIGN_BOTTOM; clue->halign = HTML_HALIGN_LEFT; aligned->next_aligned = NULL; object->parent = parent; object->flags |= HTML_OBJECT_FLAG_ALIGNED; }
static gboolean html_engine_search_next_int (HTMLEngine *e) { HTMLSearch *info = e->search_info; gboolean retval = FALSE; if (!info) return FALSE; if (html_engine_get_editable (e)) { gchar *text = g_strdup (info->text); retval = html_engine_search (e, text, info->case_sensitive, info->forward, info->regular); g_free (text); } else { if (info->stack) retval = html_object_search (HTML_OBJECT (info->stack->data), info); else { html_search_push (info, e->clue); retval = e->clue ? html_object_search (e->clue, info) : FALSE; } if (retval) display_search_results (info); else { html_search_pop (info); html_engine_disable_selection (e); } } return retval; }
gboolean html_engine_search (HTMLEngine *e, const gchar *text, gboolean case_sensitive, gboolean forward, gboolean regular) { HTMLSearch *info; HTMLObject *p; HTMLObject *o; if (e->search_info) { html_search_destroy (e->search_info); } info = e->search_info = html_search_new (e, text, case_sensitive, forward, regular); p = e->search_info->stack ? HTML_OBJECT (e->search_info->stack->data)->parent : NULL; o = p ? p : e->clue; if (o && html_object_search (o, info)) { display_search_results (info); return TRUE; } else return FALSE; }
static gboolean search (HTMLObject *self, HTMLSearch *info) { HTMLEngine *e = GTK_HTML (HTML_FRAME (self)->html)->engine; /* printf ("search\n"); */ /* search_next? */ if (info->stack && HTML_OBJECT (info->stack->data) == e->clue) { /* printf ("next\n"); */ info->engine = GTK_HTML (GTK_HTML (HTML_FRAME (self)->html)->iframe_parent)->engine; html_search_pop (info); html_engine_unselect_all (e); return html_search_next_parent (info); } info->engine = e; html_search_push (info, e->clue); if (html_object_search (e->clue, info)) return TRUE; html_search_pop (info); info->engine = GTK_HTML (GTK_HTML (HTML_FRAME (self)->html)->iframe_parent)->engine; /* printf ("FALSE\n"); */ return FALSE; }
void html_embedded_init (HTMLEmbedded *element, HTMLEmbeddedClass *klass, GtkWidget *parent, const gchar *name, const gchar *value) { HTMLObject *object; d (printf ("embedded %p init\n", element)); object = HTML_OBJECT (element); html_object_init (object, HTML_OBJECT_CLASS (klass)); element->form = NULL; if (name) element->name = g_strdup (name); else element->name = g_strdup (""); if (value) element->value = g_strdup (value); else element->value = g_strdup (""); element->widget = NULL; element->parent = parent; element->width = 0; element->height = 0; element->abs_x = element->abs_y = -1; element->changed_id = 0; }
static void table_set_spacing (HTMLEngine *e, HTMLTable *t, gint spacing, gboolean relative, HTMLUndoDirection dir) { HTMLTableSetAttrUndo *undo; gint new_spacing; if (!t || !HTML_IS_TABLE (t)) return; if (relative) new_spacing = t->spacing + spacing; else new_spacing = spacing; if (new_spacing < 0) new_spacing = 0; if (new_spacing == t->spacing) return; undo = attr_undo_new (HTML_TABLE_SPACING); undo->attr.spacing = t->spacing; html_undo_add_action (e->undo, e, html_undo_action_new ("Set table spacing", table_set_spacing_undo_action, HTML_UNDO_DATA (undo), html_cursor_get_position (e->cursor), html_cursor_get_position (e->cursor)), dir); t->spacing = new_spacing; html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC); html_engine_schedule_update (e); }
static void table_set_bg_color (HTMLEngine *e, HTMLTable *t, GdkColor *c, HTMLUndoDirection dir) { HTMLTableSetAttrUndo *undo; undo = attr_undo_new (HTML_TABLE_BGCOLOR); if (t->bgColor) { undo->attr.color.color = *t->bgColor; undo->attr.color.has_bg_color = TRUE; } else undo->attr.color.has_bg_color = FALSE; html_undo_add_action (e->undo, e, html_undo_action_new ("Set table background color", table_set_bg_color_undo_action, HTML_UNDO_DATA (undo), html_cursor_get_position (e->cursor), html_cursor_get_position (e->cursor)), dir); if (c) { if (!t->bgColor) t->bgColor = gdk_color_copy (c); *t->bgColor = *c; } else { if (t->bgColor) gdk_color_free (t->bgColor); t->bgColor = NULL; } html_engine_queue_draw (e, HTML_OBJECT (t)); }
void html_cluev_init (HTMLClueV *cluev, HTMLClueVClass *klass, gint x, gint y, gint percent) { HTMLObject *object; HTMLClue *clue; object = HTML_OBJECT (cluev); clue = HTML_CLUE (cluev); html_clue_init (clue, HTML_CLUE_CLASS (klass)); object->x = x; object->y = y; object->percent = percent; clue->valign = HTML_VALIGN_BOTTOM; clue->halign = HTML_HALIGN_NONE; cluev->dir = HTML_DIRECTION_DERIVED; clue->head = clue->tail = clue->curr = NULL; cluev->align_left_list = NULL; cluev->align_right_list = NULL; cluev->padding = 0; cluev->border_style = HTML_BORDER_NONE; cluev->border_width = 0; cluev->border_color = NULL; cluev->background_color = NULL; }
/* FIXME this must be rewritten as the multiple type casts make my head spin. The types in `HTMLClueAligned' are chosen wrong. */ static void remove_aligned_by_parent ( HTMLClueV *cluev, HTMLObject *p ) { HTMLClueAligned *tmp; HTMLObject *obj; tmp = NULL; obj = cluev->align_left_list; while (obj) { if (obj->parent == p) { if (tmp) { tmp->next_aligned = HTML_CLUEALIGNED (obj)->next_aligned; tmp = HTML_CLUEALIGNED (obj); } else { cluev->align_left_list = HTML_OBJECT (HTML_CLUEALIGNED (obj)->next_aligned); tmp = NULL; } } else { tmp = HTML_CLUEALIGNED (obj); } obj = HTML_OBJECT (HTML_CLUEALIGNED (obj)->next_aligned); } tmp = NULL; obj = cluev->align_right_list; while (obj) { if (obj->parent == p) { if (tmp) { tmp->next_aligned = HTML_CLUEALIGNED (obj)->next_aligned; tmp = HTML_CLUEALIGNED (obj); } else { cluev->align_right_list = HTML_OBJECT (HTML_CLUEALIGNED (obj)->next_aligned); tmp = NULL; } } else { tmp = HTML_CLUEALIGNED (obj); } obj = HTML_OBJECT (HTML_CLUEALIGNED (obj)->next_aligned); } }
gboolean html_engine_goto_table (HTMLEngine *e, HTMLTable *table, gint row, gint col) { HTMLTableCell *cell; html_engine_goto_table_0 (e, table); do { cell = html_engine_get_table_cell (e); if (cell && HTML_OBJECT (cell)->parent && HTML_OBJECT (cell)->parent == HTML_OBJECT (table) && cell->col == col && cell->row == row) return TRUE; } while (cell && html_cursor_forward (e->cursor, e)); return FALSE; }
static void interval_forall (HTMLObject *parent, GSList *from_down, GSList *to_down, HTMLEngine *e, HTMLObjectForallFunc f, gpointer data) { HTMLObject *o, *from, *to; from = from_down ? HTML_OBJECT (from_down->data) : html_object_head (parent); to = to_down ? HTML_OBJECT (to_down->data) : NULL; for (o = from; o; o = html_object_next_not_slave (o)) { interval_forall (o, (from_down && o == HTML_OBJECT (from_down->data)) ? from_down->next : NULL, (to_down && o == HTML_OBJECT (to_down->data)) ? to_down->next : NULL, html_object_get_engine (o, e), f, data); if (o == to) break; } (*f) (parent, e, data); }
HTMLObject * html_cluev_new (gint x, gint y, gint percent) { HTMLClueV *cluev; cluev = g_new (HTMLClueV, 1); html_cluev_init (cluev, &html_cluev_class, x, y, percent); return HTML_OBJECT (cluev); }
static void display_search_results (HTMLSearch *info) { HTMLEngine *e = info->engine; if (!info->found) return; if (e->editable) { html_engine_hide_cursor (e); html_engine_disable_selection (e); html_cursor_jump_to (e->cursor, e, HTML_OBJECT (info->found->data), info->start_pos); html_engine_set_mark (e); html_cursor_jump_to (e->cursor, e, info->last, info->stop_pos); html_engine_show_cursor (e); } else { html_engine_select_interval (e, html_interval_new (HTML_OBJECT (info->found->data), info->last, info->start_pos, info->stop_pos)); move_to_found (info); } }
gboolean html_engine_table_goto_row (HTMLEngine *e, HTMLTable *table, gint row) { HTMLTableCell *cell; if (html_engine_goto_table_0 (e, table)) { html_cursor_forward (e->cursor, e); cell = html_engine_get_table_cell (e); while (cell && cell->row != row && HTML_OBJECT (cell)->parent == HTML_OBJECT (table)) { html_engine_next_cell (e, FALSE); cell = html_engine_get_table_cell (e); } return cell != NULL && HTML_OBJECT (cell)->parent == HTML_OBJECT (table); } return FALSE; }
static void delete_cells_undo_destroy (HTMLUndoData *undo_data) { DeleteCellsUndo *data = (DeleteCellsUndo *) undo_data; gint i; for (i = 0; i < data->size; i++) if (data->cells[i]) html_object_destroy (HTML_OBJECT (data->cells[i])); g_free (data->cells); }
static void table_set_padding (HTMLEngine *e, HTMLTable *t, gint padding, gboolean relative, HTMLUndoDirection dir) { HTMLTableSetAttrUndo *undo; gint r, c; gint new_padding; if (!t || !HTML_IS_TABLE (t)) return; if (relative) new_padding = t->padding + padding; else new_padding = padding; if (new_padding < 0) new_padding = 0; if (new_padding == t->padding) return; undo = attr_undo_new (HTML_TABLE_PADDING); undo->attr.padding = t->padding; html_undo_add_action (e->undo, e, html_undo_action_new ("Set table padding", table_set_padding_undo_action, HTML_UNDO_DATA (undo), html_cursor_get_position (e->cursor), html_cursor_get_position (e->cursor)), dir); t->padding = new_padding; for (r = 0; r < t->totalRows; r++) for (c = 0; c < t->totalCols; c++) if (t->cells[r][c]->col == c && t->cells[r][c]->row == r) { HTML_CLUEV (t->cells[r][c])->padding = new_padding; HTML_OBJECT (t->cells[r][c])->change |= HTML_CHANGE_ALL_CALC; } html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC); html_engine_schedule_update (e); }
/* called when some state in an embedded html object has changed ... do a redraw */ static void html_embedded_object_changed (GtkHTMLEmbedded *eb, HTMLEngine *e) { HTMLObject *object; object = HTML_OBJECT (g_object_get_data (G_OBJECT (eb), "embeddedelement")); if (object) html_object_calc_size (object, e->painter, NULL); html_engine_schedule_update (e); }
static void backward_before_row (HTMLEngine *e, HTMLTable *table, gint row) { HTMLObject *cell; do { if (!html_cursor_backward (e->cursor, e)) return; cell = html_cursor_child_of (e->cursor, HTML_OBJECT (table)); } while (cell && HTML_IS_TABLE_CELL (cell) && HTML_TABLE_CELL (cell)->row >= row); }
HTMLObject * html_cluealigned_new (HTMLObject *parent, gint x, gint y, gint max_width, gint percent) { HTMLClueAligned *aclue; aclue = g_new (HTMLClueAligned, 1); html_cluealigned_init (aclue, &html_cluealigned_class, parent, x, y, max_width, percent); return HTML_OBJECT (aclue); }
static void table_set_width (HTMLEngine *e, HTMLTable *t, gint width, gboolean percent, HTMLUndoDirection dir) { HTMLTableSetAttrUndo *undo; undo = attr_undo_new (HTML_TABLE_WIDTH); undo->attr.width.width = HTML_OBJECT (t)->percent ? HTML_OBJECT (t)->percent : (HTML_OBJECT (t)->flags & HTML_OBJECT_FLAG_FIXEDWIDTH ? t->specified_width : 0); undo->attr.width.percent = HTML_OBJECT (t)->percent != 0; html_undo_add_action (e->undo, e, html_undo_action_new ("Set table width", table_set_width_undo_action, HTML_UNDO_DATA (undo), html_cursor_get_position (e->cursor), html_cursor_get_position (e->cursor)), dir); if (percent) { HTML_OBJECT (t)->percent = width; HTML_OBJECT (t)->flags &= ~ HTML_OBJECT_FLAG_FIXEDWIDTH; t->specified_width = 0; } else { HTML_OBJECT (t)->percent = 0; t->specified_width = width; if (width) HTML_OBJECT (t)->flags |= HTML_OBJECT_FLAG_FIXEDWIDTH; else HTML_OBJECT (t)->flags &= ~ HTML_OBJECT_FLAG_FIXEDWIDTH; } html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC); html_engine_schedule_update (e); }
HTMLObject * html_text_input_new (GtkWidget *parent, gchar *name, gchar *value, gint size, gint maxlen, gboolean password) { HTMLTextInput *ti; ti = g_new0 (HTMLTextInput, 1); html_text_input_init (ti, &html_text_input_class, parent, name, value, size, maxlen, password); return HTML_OBJECT (ti); }
void html_engine_delete_table (HTMLEngine *e) { HTMLTable *table; html_engine_disable_selection (e); table = html_engine_get_table (e); if (!table) return; while (e->cursor->object != HTML_OBJECT (table) || e->cursor->offset) html_cursor_backward (e->cursor, e); html_engine_set_mark (e); html_cursor_end_of_line (e->cursor, e); html_engine_delete (e); }
void html_engine_draw_table_cursor (HTMLEngine *e) { HTMLCursorRectangle *cr; HTMLTable *table; HTMLObject *to; static gboolean enabled = TRUE; if (!enabled) return; cr = &e->cursor_table; table = html_engine_get_table (e); to = HTML_OBJECT (table); if (table) { static gint offset = 0; gboolean animate; if (to != cr->object) { if (cr->object) refresh_under_cursor (e, cr, &enabled); cr->object = to; } html_object_calc_abs_position (to, &cr->x1, &cr->y2); cr->x2 = cr->x1 + to->width - 1; cr->y2--; cr->y1 = cr->y2 - (to->ascent + to->descent - 1); animate = HTML_IS_TABLE (e->cursor->object) && !html_engine_get_table_cell (e); if (animate) { offset++; offset %= 4; } draw_cursor_rectangle (e, cr->x1, cr->y1, cr->x2, cr->y2, COLORS (table), offset); } else if (cr->object) { refresh_under_cursor (e, cr, &enabled); cr->object = NULL; } }
void html_engine_draw_cell_cursor (HTMLEngine *e) { HTMLCursorRectangle *cr; HTMLTableCell *cell; HTMLObject *co; static gboolean enabled = TRUE; if (!enabled) return; cr = &e->cursor_cell; cell = html_engine_get_table_cell (e); co = HTML_OBJECT (cell); if (cell) { static gint offset = 0; gboolean animate; if (co != cr->object) { if (cr->object) refresh_under_cursor (e, cr, &enabled); cr->object = co; } html_object_calc_abs_position (co, &cr->x1, &cr->y2); cr->x2 = cr->x1 + co->width - 1; cr->y2 -= 2; cr->y1 = cr->y2 - (co->ascent + co->descent - 2); animate = !HTML_IS_IMAGE (e->cursor->object); if (animate) { offset++; offset %= 4; } draw_cursor_rectangle (e, cr->x1, cr->y1, cr->x2, cr->y2, COLORS (cell), offset); } else if (cr->object) { refresh_under_cursor (e, cr, &enabled); cr->object = NULL; } }
static void html_embedded_allocate (GtkWidget *w, GtkAllocation *allocation, HTMLEmbedded *e) { GtkWidget *parent; parent = gtk_widget_get_parent (w); if (e->width != allocation->width || e->height != allocation->height) { if (e->width != allocation->width) { html_object_change_set (HTML_OBJECT (e), HTML_CHANGE_ALL_CALC); e->width = allocation->width; } e->height = allocation->height; if (GTK_IS_HTML (parent)) html_engine_schedule_update (GTK_HTML (parent)->engine); } }