Just resend this mail, it seems that hackers back now.




Please do not omit this mail just because size of the patch or the mail. Please
be patient, compare to the problems it resolves, I think it worths.


Then I will first describe problems in current table. Then the solution
provided in the patch.

Bugzilla link of this bug:
http://bugzilla.ximian.com/show_bug.cgi?id=35557

1. Current Problems
==================================================================
There are some serious problems found in table of composer:
I. When select the outmost bound of table resize the table will cause
hang the cpu.
II. Select the table like I, edit the table, add column undo will crash.
III.In the case table contain a subtable, select the subtable, and right
click the sub-table. Select 'Table' in the popup. There are actually
two 'Table'. One represent table, another sub-table. But if when you
click it, you found both the properties in the dialog are for one
of the 'Table'. It is, if you have table of subtable of different
size, the properties of them are of the same.

Actually I think there are very likely more problems I do not know. All
these problems caused by similiar root reasons:

a. First is the widely used function html_engine_get_table(). It return
a table. either object point to by the current cursor or grandfather of
the object. Then the table is used. Consider case III mentioned above,
if we use this function, we cannot tell which table is the one we want.

By grep and wc you find there are more than 60 of usages of it.

b. In functions that edit the table, e.g., delete_table_column().
It just assume user's focus is on table's cell and want to edit
the table contain it. In case I and II above, this is not true.



2. Solutions in the patch
===========================================================
Actually there are too many use of these functions. So I can't
fix all of them at once, just focus on table edit use the popup
menu. And also try to not affect other part.

Thus to resolve this problems, the patch attached do follow jobs:

a. First we must know whether user specified is which table. Thus
add a flag into the structure GtkHTMLEditTableProperties. And
in popup.c, when generate the pop up menu, add a case so that
we can set the new added flag into GtkHTMLEditTableProperties.

b. a new function html_engine_get_table_2(), compare to
html_engine_get_table(), one more parameter is added to specify whether
you want table point by cursor or grandfather of it. The choose that
not to rewrite html_engine_get_table() is because the wide use of it.

c. Use the html_engine_get_table_2() in table editing functions,e.g.,
delete_table_column(). Also add a flag to this function, thus to specify
which table to use. Add html_engine_delete_table_column_2() which call
delte_table_column() and specify using the object point by cursor
as table. Because html_engine_delete_table_column() will assume the
grandfather. Choose not modify html_engine_get_table() directly is
because it is used in gtkhtml.c.

Any comments are wellcome!

I will resend the mail after Jan.2, when hackers back,:-). And I
also hope copyright problem will be resolved at that time.


Best Regards
York Du

Index: components/html-editor/popup.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/components/html-editor/popup.c,v
retrieving revision 1.62
diff -u -4 -r1.62 popup.c
--- components/html-editor/popup.c      2 Oct 2002 17:11:34 -0000       1.62
+++ components/html-editor/popup.c      24 Dec 2002 07:26:46 -0000
@@ -230,8 +230,15 @@
                                                                   rule_properties,
                                                                   rule_apply_cb,
                                                                   rule_close_cb);
                        break;
+               case GTK_HTML_EDIT_PROPERTY_TABLE_SELF:
+                       gtk_html_edit_properties_dialog_add_entry 
+(cd->properties_dialog,
+                                                                  t, _("Table"),
+                                                                  table_properties_2,
+                                                                  table_apply_cb,
+                                                                  table_close_cb);
+                       break;
                case GTK_HTML_EDIT_PROPERTY_TABLE:
                        gtk_html_edit_properties_dialog_add_entry 
(cd->properties_dialog,
                                                                   t, _("Table"),
                                                                   table_properties,
@@ -496,9 +503,9 @@
                        ADD_PROP (PARAGRAPH);
                        break;
                case HTML_TYPE_TABLE:
                        ADD_SEP;
-                       ADD_PROP (TABLE);
+                       ADD_PROP (TABLE_SELF);
                        ADD_ITEM (_("Table..."), prop_dialog, TABLE);
                default:
                }
                if (obj->parent && obj->parent->parent && HTML_IS_TABLE_CELL 
(obj->parent->parent)) {
Index: components/html-editor/properties.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/components/html-editor/properties.h,v
retrieving revision 1.12
diff -u -4 -r1.12 properties.h
--- components/html-editor/properties.h 2 Oct 2002 17:11:34 -0000       1.12
+++ components/html-editor/properties.h 24 Dec 2002 07:26:46 -0000
@@ -38,8 +38,9 @@
        GTK_HTML_EDIT_PROPERTY_LINK,
        GTK_HTML_EDIT_PROPERTY_BODY,
        GTK_HTML_EDIT_PROPERTY_RULE,
        GTK_HTML_EDIT_PROPERTY_TABLE,
+       GTK_HTML_EDIT_PROPERTY_TABLE_SELF, /* It is a table */
        GTK_HTML_EDIT_PROPERTY_CELL,
 };
 
 GtkHTMLEditPropertiesDialog * gtk_html_edit_properties_dialog_new          
(GtkHTMLControlData *cd,
Index: components/html-editor/table.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/components/html-editor/table.c,v
retrieving revision 1.35
diff -u -4 -r1.35 table.c
--- components/html-editor/table.c      16 Oct 2001 21:19:19 -0000      1.35
+++ components/html-editor/table.c      24 Dec 2002 07:26:48 -0000
@@ -96,8 +96,9 @@
        GtkWidget *option_template;
 
        gboolean   disable_change;
        gboolean   insert;
+       gboolean   self;
 } GtkHTMLEditTableProperties;
 
 static void set_insert_ui (GtkHTMLEditTableProperties *d);
 
@@ -711,13 +712,15 @@
        FILL;
 }
 
 static void
-get_data (GtkHTMLEditTableProperties *d)
+get_data (GtkHTMLEditTableProperties *d, gboolean self)
 {
-       d->table = html_engine_get_table (d->cd->html->engine);
+       d->table = html_engine_get_table_2 (d->cd->html->engine, self);
        g_return_if_fail (d->table);
 
+       if (self) d->self = TRUE;
+
        if (d->table->bgColor) {
                d->has_bg_color = TRUE;
                d->bg_color     = *d->table->bgColor;
        }
@@ -756,10 +759,25 @@
 table_properties (GtkHTMLControlData *cd, gpointer *set_data)
 {
        GtkHTMLEditTableProperties *data = data_new (cd);
        GtkWidget *rv;
+       gboolean flag;
+
+       get_data (data, FALSE);
+       *set_data = data;
+       rv        = table_widget (data);
+       set_ui (data);
+
+       return rv;
+}
+
+GtkWidget *
+table_properties_2 (GtkHTMLControlData *cd, gpointer *set_data)
+{
+       GtkHTMLEditTableProperties *data = data_new (cd);
+       GtkWidget *rv;
 
-       get_data (data);
+       get_data (data, TRUE);
        *set_data = data;
        rv        = table_widget (data);
        set_ui (data);
 
@@ -833,13 +851,13 @@
                                             d->has_width ? d->width : 0, d->has_width 
? d->width_percent : FALSE);
                d->changed_width = FALSE;
        }
        if (d->changed_cols) {
-               html_engine_table_set_cols (d->cd->html->engine, d->cols);
+               html_engine_table_set_cols (d->cd->html->engine, d->cols, d->self);
                d->changed_cols = FALSE;
        }
        if (d->changed_rows) {
-               html_engine_table_set_rows (d->cd->html->engine, d->rows);
+               html_engine_table_set_rows (d->cd->html->engine, d->rows, d->self);
                d->changed_rows = FALSE;
        }
 }
 
Index: components/html-editor/table.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/components/html-editor/table.h,v
retrieving revision 1.2
diff -u -4 -r1.2 table.h
--- components/html-editor/table.h      15 May 2001 16:53:13 -0000      1.2
+++ components/html-editor/table.h      24 Dec 2002 07:26:48 -0000
@@ -26,8 +26,9 @@
 #include <gnome.h>
 #include "control-data.h"
 
 GtkWidget             * table_properties      (GtkHTMLControlData *cd, gpointer 
*set_data);
+GtkWidget             * table_properties_2      (GtkHTMLControlData *cd, gpointer 
+*set_data);
 GtkWidget             * table_insert          (GtkHTMLControlData *cd, gpointer 
*set_data);
 void                    table_insert_cb       (GtkHTMLControlData *cd, gpointer  
get_data);
 void                    table_apply_cb        (GtkHTMLControlData *cd, gpointer  
get_data);
 void                    table_close_cb        (GtkHTMLControlData *cd, gpointer  
get_data);
Index: src/htmlengine-edit-table.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine-edit-table.c,v
retrieving revision 1.56
diff -u -4 -r1.56 htmlengine-edit-table.c
--- src/htmlengine-edit-table.c 7 Oct 2002 10:02:23 -0000       1.56
+++ src/htmlengine-edit-table.c 24 Dec 2002 07:26:55 -0000
@@ -35,12 +35,16 @@
 #include "htmltablecell.h"
 #include "htmltablepriv.h"
 #include "htmlundo.h"
 
-static void delete_table_column (HTMLEngine *e, HTMLUndoDirection dir);
-static void insert_table_column (HTMLEngine *e, gboolean after, HTMLTableCell 
**column_cells, HTMLUndoDirection dir);
-static void delete_table_row    (HTMLEngine *e, HTMLUndoDirection dir);
-static void insert_table_row    (HTMLEngine *e, gboolean after, HTMLTableCell 
**row_cells, HTMLUndoDirection dir);
+struct _DeleteCellsUndo;
+typedef struct _DeleteCellsUndo DeleteCellsUndo;
+
+static void delete_table_column (HTMLEngine *e, HTMLUndoDirection dir, int col,  
+gboolean self);
+static void insert_table_column (HTMLEngine *e, gint col, HTMLTableCell 
+**column_cells, HTMLUndoDirection dir, gboolean self);
+static void delete_table_row    (HTMLEngine *e, HTMLUndoDirection dir, int row, 
+gboolean self);
+static void insert_table_row    (HTMLEngine *e, gint row, HTMLTableCell **row_cells, 
+HTMLUndoDirection dir, gboolean self);
+static DeleteCellsUndo *  delete_cells_undo_new (HTMLTableCell **cells, gint size, 
+gint pos, gboolean self);
 
 HTMLTable *
 html_engine_get_table (HTMLEngine *e)
 {
@@ -55,8 +59,27 @@
        else
                return HTML_TABLE (e->cursor->object->parent->parent->parent);
 }
 
+HTMLTable *
+html_engine_get_table_2(HTMLEngine *e, gboolean flag)
+{
+       if (flag) {
+               if (HTML_IS_TABLE (e->cursor->object))
+                       return HTML_TABLE (e->cursor->object);
+               return NULL;
+       }
+
+       if (!e->cursor->object->parent
+                || !e->cursor->object->parent->parent
+                || !e->cursor->object->parent->parent->parent)
+               return NULL;
+       else if (!HTML_IS_TABLE (e->cursor->object->parent->parent->parent))
+               return NULL;
+       else
+               return HTML_TABLE (e->cursor->object->parent->parent->parent);
+}
+
 HTMLTableCell *
 html_engine_new_cell (HTMLEngine *e, HTMLTable *table)
 {
        HTMLObject    *cell;
@@ -84,8 +107,18 @@
  *
  * Inserts new table with one cell containing an empty flow with an empty text. 
Inserted table has 1 row and 1 column.
  **/
 
+struct _DeleteCellsUndo {
+       HTMLUndoData data;
+
+       HTMLTableCell **cells;
+       gint size;
+       gint pos;
+       gboolean self;
+};
+
+
 void
 html_engine_insert_table_1_1 (HTMLEngine *e)
 {
        HTMLObject    *table;
@@ -134,17 +167,18 @@
 
 static void
 insert_column_undo_action (HTMLEngine *e, HTMLUndoData *data, HTMLUndoDirection dir, 
guint position_after)
 {
-       delete_table_column (e, html_undo_direction_reverse (dir));
+       DeleteCellsUndo * undo_data = (DeleteCellsUndo *) data;
+        delete_table_column (e, html_undo_direction_reverse (dir), undo_data->pos, 
+undo_data->self);
 }
 
 static void
-insert_column_setup_undo (HTMLEngine *e, guint position_before, HTMLUndoDirection dir)
+insert_column_setup_undo (HTMLEngine *e, guint position_before, HTMLUndoDirection 
+dir, gint col, gboolean self)
 {
        html_undo_add_action (e->undo,
                              html_undo_action_new ("Insert table column", 
insert_column_undo_action,
-                                                   NULL, html_cursor_get_position 
(e->cursor),
+                                                   
+HTML_UNDO_DATA(delete_cells_undo_new(NULL, 0, col, self)), html_cursor_get_position 
+(e->cursor),
                                                    position_before),
                              dir);
 }
 
@@ -179,23 +213,25 @@
        } while (html_cursor_forward (e->cursor, e));
 }
 
 static void
-insert_table_column (HTMLEngine *e, gint col, HTMLTableCell **column, 
HTMLUndoDirection dir)
+insert_table_column (HTMLEngine *e, gint col, HTMLTableCell **column, 
+HTMLUndoDirection dir, gboolean self)
 {
        HTMLTable *t;
        HTMLTableCell *cell;
        gint c, r;
        guint position_before;
 
-       t = HTML_TABLE (html_object_nth_parent (e->cursor->object, 3));
+       t = html_engine_get_table_2(e, self);
+
        if (!t)
                return;
 
        html_engine_freeze (e);
 
        position_before = e->cursor->position;
-       go_table_0 (e, HTML_OBJECT (t));
+       if (!self)
+               go_table_0 (e, HTML_OBJECT (t));
 
        html_table_alloc_cell (t, 0, t->totalCols);
        for (r = 0; r < t->totalRows; r ++) {
                for (c = t->totalCols - 1; c >= col; c --) {
@@ -219,10 +255,12 @@
                        html_table_cell_set_position (t->cells [r][col], r, col);
                }
        }
 
-       go_after_col (e, HTML_OBJECT (t), col);
-       insert_column_setup_undo (e, position_before, dir);
+       /* If the table itself is selected, do not need to move cursor. */
+       if (!self)
+               go_after_col (e, HTML_OBJECT (t), col);
+       insert_column_setup_undo (e, position_before, dir, col, self);
        html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC);
        html_engine_queue_draw (e, HTML_OBJECT (t));
        html_engine_thaw (e);
 }
@@ -242,24 +280,21 @@
        HTMLObject *cell;
 
        cell = html_object_nth_parent (e->cursor->object, 2);
        if (cell && HTML_IS_TABLE_CELL (cell))
-               insert_table_column (e, HTML_TABLE_CELL (cell)->col + (after ? 1 : 0), 
NULL, HTML_UNDO_UNDO);
+               insert_table_column (e, HTML_TABLE_CELL (cell)->col + (after ? 1 : 0), 
+NULL, HTML_UNDO_UNDO, FALSE);
+}
+
+void
+html_engine_insert_table_column_2(HTMLEngine *e, int col, gboolean after)
+{
+       insert_table_column (e, col + (after ? 1 : 0), NULL, HTML_UNDO_UNDO, TRUE);
 }
 
 /*
  * Delete column
  */
 
-struct _DeleteCellsUndo {
-       HTMLUndoData data;
-
-       HTMLTableCell **cells;
-       gint size;
-       gint pos;
-};
-typedef struct _DeleteCellsUndo DeleteCellsUndo;
-
 static void
 delete_cells_undo_destroy (HTMLUndoData *undo_data)
 {
        DeleteCellsUndo *data = (DeleteCellsUndo *) undo_data;
@@ -269,9 +304,9 @@
                html_object_destroy (HTML_OBJECT (data->cells [i]));
 }
 
 static DeleteCellsUndo *
-delete_cells_undo_new (HTMLTableCell **cells, gint size, gint pos)
+delete_cells_undo_new (HTMLTableCell **cells, gint size, gint pos, gboolean self)
 {
        DeleteCellsUndo *data;
 
        data = g_new0 (DeleteCellsUndo, 1);
@@ -281,8 +316,9 @@
        data->data.destroy = delete_cells_undo_destroy;
        data->cells        = cells;
        data->pos          = pos;
        data->size         = size;
+       data->self         = self;
 
        return data;
 }
 
@@ -290,45 +326,50 @@
 delete_column_undo_action (HTMLEngine *e, HTMLUndoData *undo_data, HTMLUndoDirection 
dir, guint position_after)
 {
        DeleteCellsUndo *data = (DeleteCellsUndo *) undo_data;
 
-       g_assert (data->size == HTML_TABLE (html_object_nth_parent (e->cursor->object, 
3))->totalRows);
-       insert_table_column (e, data->pos, data->cells, html_undo_direction_reverse 
(dir));
+       insert_table_column (e, data->pos, data->cells, html_undo_direction_reverse 
+(dir), data->self);
 }
 
 static void
-delete_column_setup_undo (HTMLEngine *e, HTMLTableCell **column, gint size, guint 
position_before, gint col, HTMLUndoDirection dir)
+delete_column_setup_undo (HTMLEngine *e, HTMLTableCell **column, gint size, guint 
+position_before, gint col, HTMLUndoDirection dir, gboolean self)
 {
        html_undo_add_action (e->undo,
                              html_undo_action_new ("Delete table column", 
delete_column_undo_action,
-                                                   HTML_UNDO_DATA 
(delete_cells_undo_new (column, size, col)),
+                                                   HTML_UNDO_DATA 
+(delete_cells_undo_new (column, size, col, self)),
                                                    html_cursor_get_position 
(e->cursor),
                                                    position_before), dir);
 }
 
 static void
-delete_table_column (HTMLEngine *e, HTMLUndoDirection dir)
+delete_table_column (HTMLEngine *e, HTMLUndoDirection dir, int del_col, gboolean self)
 {
        HTMLTable *t;
        HTMLTableCell *cell;
        HTMLTableCell **column;
        gint r, c, col;
        guint position_before;
 
-       t = HTML_TABLE (html_object_nth_parent (e->cursor->object, 3));
+       t = html_engine_get_table_2(e, self);
 
        /* this command is valid only in table and when this table has > 1 column */
        if (!t || !HTML_IS_TABLE (HTML_OBJECT (t)) || t->totalCols < 2)
                return;
 
        html_engine_freeze (e);
 
        position_before = e->cursor->position;
-       cell   = HTML_TABLE_CELL (html_object_nth_parent (e->cursor->object, 2));
-       col    = cell->col;
+       if (!self) {
+               cell = HTML_TABLE_CELL (html_object_nth_parent (e->cursor->object, 2));
+               col = cell->col;
+       } else {
+               col = del_col;
+       }
+
        column = g_new0 (HTMLTableCell *, t->totalRows);
 
-       go_table_0 (e, HTML_OBJECT (t));
+       if (!self)
+               go_table_0 (e, HTML_OBJECT (t));
        for (r = 0; r < t->totalRows; r ++) {
                cell = t->cells [r][col];
 
                /* remove & keep old one */
@@ -347,10 +388,12 @@
                                t->cells [r][c]     = NULL;
                        }
                }
        }
-       go_after_col (e, HTML_OBJECT (t), MIN (col, t->totalCols - 1));
-       delete_column_setup_undo (e, column, t->totalRows, position_before, col, dir);
+       
+       if (!self)
+               go_after_col (e, HTML_OBJECT (t), MIN (col, t->totalCols - 1));
+       delete_column_setup_undo (e, column, t->totalRows, position_before, col, dir, 
+self);
        t->totalCols --;
 
        html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC);
        html_engine_queue_draw (e, HTML_OBJECT (t));
@@ -366,9 +409,15 @@
 
 void
 html_engine_delete_table_column (HTMLEngine *e)
 {
-       delete_table_column (e, HTML_UNDO_UNDO);
+       delete_table_column (e, HTML_UNDO_UNDO, 0 , FALSE);
+}
+
+void
+html_engine_delete_table_column_2 (HTMLEngine *e, int col)
+{
+       delete_table_column (e, HTML_UNDO_UNDO, col, TRUE);
 }
 
 /*
  *  Insert Row
@@ -376,37 +425,40 @@
 
 static void
 insert_row_undo_action (HTMLEngine *e, HTMLUndoData *data, HTMLUndoDirection dir, 
guint position_after)
 {
-       delete_table_row (e, html_undo_direction_reverse (dir));
+       DeleteCellsUndo * undo_data = (DeleteCellsUndo *) data;
+       delete_table_row (e, html_undo_direction_reverse (dir), undo_data->pos , 
+undo_data->self);
 }
 
 static void
-insert_row_setup_undo (HTMLEngine *e, guint position_before, HTMLUndoDirection dir)
+insert_row_setup_undo (HTMLEngine *e, guint position_before, HTMLUndoDirection dir, 
+gint row, gboolean self)
 {
        html_undo_add_action (e->undo,
                              html_undo_action_new ("Insert table row", 
insert_row_undo_action,
-                                                   NULL,
+                                                   
+HTML_UNDO_DATA(delete_cells_undo_new(NULL, 0, row, self)),
                                                    html_cursor_get_position 
(e->cursor),
                                                    html_cursor_get_position 
(e->cursor)),
                              dir);
 }
 
 static void
-insert_table_row (HTMLEngine *e, gint row, HTMLTableCell **row_cells, 
HTMLUndoDirection dir)
+insert_table_row (HTMLEngine *e, gint row, HTMLTableCell **row_cells, 
+HTMLUndoDirection dir, gboolean self)
 {
        HTMLTable *t;
        HTMLTableCell *cell;
        gint r, c;
        guint position_before;
 
-       t = HTML_TABLE (html_object_nth_parent (e->cursor->object, 3));
+       t = html_engine_get_table_2 (e, self);
+
        if (!t)
                return;
 
        html_engine_freeze (e);
        position_before = e->cursor->position;
-       go_table_0 (e, HTML_OBJECT (t));
+       if (!self)
+               go_table_0 (e, HTML_OBJECT (t));
 
        html_table_alloc_cell (t, t->totalRows, 0);
        for (c = 0; c < t->totalCols; c ++) {
                for (r = t->totalRows; r > row; r --) {
@@ -430,10 +482,11 @@
                        html_table_cell_set_position (t->cells [row][c], row, c);
                }
        }
 
-       go_after_row (e, HTML_OBJECT (t), row);
-       insert_row_setup_undo (e, position_before, dir);
+       if (!self)
+               go_after_row (e, HTML_OBJECT (t), row);
+       insert_row_setup_undo (e, position_before, dir, row, self);
        html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC);
        html_engine_queue_draw (e, HTML_OBJECT (t));
        html_engine_thaw (e);
 }
@@ -453,9 +506,15 @@
        HTMLObject *cell;
 
        cell = html_object_nth_parent (e->cursor->object, 2);
        if (cell && HTML_IS_TABLE_CELL (cell))
-               insert_table_row (e, HTML_TABLE_CELL (cell)->row + (after ? 1 : 0), 
NULL, HTML_UNDO_UNDO);
+               insert_table_row (e, HTML_TABLE_CELL (cell)->row + (after ? 1 : 0), 
+NULL, HTML_UNDO_UNDO, FALSE);
+}
+
+void
+html_engine_insert_table_row_2 (HTMLEngine *e, int row, gboolean after)
+{
+       insert_table_row (e, row + (after ? 1 : 0), NULL, HTML_UNDO_UNDO, TRUE);
 }
 
 /*
  * Delete row
@@ -465,46 +524,49 @@
 delete_row_undo_action (HTMLEngine *e, HTMLUndoData *undo_data, HTMLUndoDirection 
dir, guint position_after)
 {
        DeleteCellsUndo *data = (DeleteCellsUndo *) undo_data;
 
-       g_assert (data->size == HTML_TABLE (html_object_nth_parent (e->cursor->object, 
3))->totalCols);
-       insert_table_row (e, data->pos, data->cells, html_undo_direction_reverse 
(dir));
+       insert_table_row (e, data->pos, data->cells, html_undo_direction_reverse 
+(dir), data->self);
 }
 
 static void
 delete_row_setup_undo (HTMLEngine *e, HTMLTableCell **row_cells, gint size, guint 
position_before,
-                      gint row, HTMLUndoDirection dir)
+                      gint row, HTMLUndoDirection dir, gboolean self)
 {
        html_undo_add_action (e->undo,
                              html_undo_action_new ("Delete table row", 
delete_row_undo_action,
-                                                   HTML_UNDO_DATA 
(delete_cells_undo_new (row_cells, size, row)),
+                                                   HTML_UNDO_DATA 
+(delete_cells_undo_new (row_cells, size, row, self)),
                                                    html_cursor_get_position 
(e->cursor),
                                                    position_before), dir);
 }
 
 static void
-delete_table_row (HTMLEngine *e, HTMLUndoDirection dir)
+delete_table_row (HTMLEngine *e, HTMLUndoDirection dir, int del_row, gboolean self)
 {
        HTMLTable *t;
        HTMLTableCell *cell;
        HTMLTableCell **row_cells;
        gint r, c, row;
        guint position_before;
 
-       t = HTML_TABLE (html_object_nth_parent (e->cursor->object, 3));
+       t = html_engine_get_table_2 (e, self);
 
        /* this command is valid only in table and when this table has > 1 row */
        if (!t || !HTML_IS_TABLE (HTML_OBJECT (t)) || t->totalRows < 2)
                return;
 
        html_engine_freeze (e);
 
        position_before = e->cursor->position;
-       cell      = HTML_TABLE_CELL (html_object_nth_parent (e->cursor->object, 2));
-       row       = cell->row;
+       if (!self) {
+               cell = HTML_TABLE_CELL (html_object_nth_parent (e->cursor->object, 2));
+               row = cell->row;
+       } else 
+               row = del_row;
        row_cells = g_new0 (HTMLTableCell *, t->totalCols);
 
-       go_table_0 (e, HTML_OBJECT (t));
+       if (!self)
+               go_table_0 (e, HTML_OBJECT (t));
        for (c = 0; c < t->totalCols; c ++) {
                cell = t->cells [row][c];
 
                /* remove & keep old one */
@@ -524,11 +586,12 @@
                        }
                }
        }
 
-       go_after_row (e, HTML_OBJECT (t), MIN (row, t->totalCols - 1));
+       if (!self)
+               go_after_row (e, HTML_OBJECT (t), MIN (row, t->totalCols - 1));
        t->totalRows --;
-       delete_row_setup_undo (e, row_cells, t->totalCols, position_before, row, dir);
+       delete_row_setup_undo (e, row_cells, t->totalCols, position_before, row, dir, 
+self);
        html_object_change_set (HTML_OBJECT (t), HTML_CHANGE_ALL_CALC);
        html_engine_queue_draw (e, HTML_OBJECT (t));
        html_engine_thaw (e);
 }
@@ -542,9 +605,15 @@
 
 void
 html_engine_delete_table_row (HTMLEngine *e)
 {
-       delete_table_row (e, HTML_UNDO_UNDO);
+       delete_table_row (e, HTML_UNDO_UNDO, 0, FALSE);
+}
+
+void
+html_engine_delete_table_row_2 (HTMLEngine *e, int row)
+{
+       delete_table_row (e, HTML_UNDO_UNDO, row, TRUE);
 }
 
 typedef enum {
        HTML_TABLE_BORDER,
@@ -1056,18 +1125,32 @@
  * set number of columns in current table
  */
 
 void
-html_engine_table_set_cols (HTMLEngine *e, gint cols)
+html_engine_table_set_cols (HTMLEngine *e, gint cols, gboolean self)
 {
-       HTMLTable *table = html_engine_get_table (e);
+       HTMLTable *table;
+
+       table = html_engine_get_table_2 (e, self);
 
        if (!table)
                return;
 
        if (table->totalCols == cols)
                return;
 
+       /* Orignal code actually assume table is the parent, not self. */
+       if (self) {
+               if (table->totalCols < cols) {
+                       while (table->totalCols < cols)
+                               html_engine_insert_table_column_2 (e, 
+table->totalCols-1, TRUE);
+               } else {
+                       while (table->totalCols > cols)
+                               html_engine_delete_table_column_2 (e, 
+table->totalCols-1);
+               }
+               return;
+       }
+
        if (table->totalCols < cols) {
                html_engine_table_goto_col (e, table->totalCols - 1);
                while (table->totalCols < cols)
                        html_engine_insert_table_column (e, TRUE);
@@ -1075,30 +1158,39 @@
                html_engine_table_goto_col (e, table->totalCols - 1);
                while (table->totalCols > cols)
                        html_engine_delete_table_column (e);
        }
-
-       /*
-         FIXME: jump to some well defined position (like the same position as before
-         or at beginning of 1st new column or to last position in remaining cells
-       */
 }
 
 /*
  * set number of rows in current table
  */
 
 void
-html_engine_table_set_rows (HTMLEngine *e, gint rows)
+html_engine_table_set_rows (HTMLEngine *e, gint rows, gboolean self)
 {
-       HTMLTable *table = html_engine_get_table (e);
+       HTMLTable *table;
+
+       table = html_engine_get_table_2 (e, self);
 
        if (!table)
                return;
 
        if (table->totalRows == rows)
                return;
 
+       /* Orignal code actually assume table is the parent, not self. */
+       if (self) {
+               if (table->totalRows < rows) {
+                       while (table->totalRows < rows)
+                               html_engine_insert_table_row_2 (e, table->totalRows-1, 
+ TRUE);
+               } else {
+                       while (table->totalRows > rows)
+                               html_engine_delete_table_row_2 (e, table->totalRows - 
+1);
+               }
+               return;
+       }
+
        if (table->totalRows < rows) {
                html_engine_table_goto_row (e, table->totalRows - 1);
                while (table->totalRows < rows)
                        html_engine_insert_table_row (e, TRUE);
@@ -1106,12 +1198,8 @@
                html_engine_table_goto_row (e, table->totalRows - 1);
                while (table->totalRows > rows)
                        html_engine_delete_table_row (e);
        }
-
-       /*
-         FIXME: like set_cols
-       */
 }
 
 void
 html_engine_delete_table (HTMLEngine *e)
Index: src/htmlengine-edit-table.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine-edit-table.h,v
retrieving revision 1.20
diff -u -4 -r1.20 htmlengine-edit-table.h
--- src/htmlengine-edit-table.h 16 Oct 2001 21:19:04 -0000      1.20
+++ src/htmlengine-edit-table.h 24 Dec 2002 07:26:55 -0000
@@ -67,11 +67,13 @@
                                                    HTMLTable      *t,
                                                    gint            width,
                                                    gboolean        percent);
 void           html_engine_table_set_cols          (HTMLEngine     *e,
-                                                   gint            cols);
+                                                   gint            cols,
+                                                   gboolean        self);
 void           html_engine_table_set_rows          (HTMLEngine     *e,
-                                                   gint            rows);
+                                                   gint            rows,
+                                                   gboolean        self);
 HTMLTable     *html_engine_get_table               (HTMLEngine     *e);
 gboolean       html_engine_table_goto_0_0          (HTMLEngine     *e);
 gboolean       html_engine_table_goto_col          (HTMLEngine     *e,
                                                    gint            col);

Reply via email to