[gnumeric] Paste: full-column paste includes column width.



commit 076965969c7e3cf6d3a8811bd1ec406ea2ad03c2
Author: Morten Welinder <terra gnome org>
Date:   Tue Apr 24 09:36:00 2018 -0400

    Paste: full-column paste includes column width.
    
    Ditto for rows.

 NEWS                |    1 +
 src/colrow.c        |   61 +++++++++++++++++++++++++++++++++++++--
 src/colrow.h        |    6 ++++
 src/xml-sax-read.c  |    6 ++++
 src/xml-sax-write.c |   80 ++++++++++++++++++++++++++++++---------------------
 5 files changed, 118 insertions(+), 36 deletions(-)
---
diff --git a/NEWS b/NEWS
index ec3f1c5..8da2148 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,7 @@ Morten:
        * Fix ssconvert --merge-to problem with names.  [#795408]
        * Fix problem with image pasting.
        * Allow pasting an image into Gnumeric.  [#366816]
+       * Full-column paste includes column width.  [#121722]
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.39
diff --git a/src/colrow.c b/src/colrow.c
index e7a0283..aa0bf5b 100644
--- a/src/colrow.c
+++ b/src/colrow.c
@@ -35,6 +35,7 @@
 #include "cellspan.h"
 #include "rendered-value.h"
 #include <goffice/goffice.h>
+#include <string.h>
 
 /* Making ColRowInfo a boxed type to make introspection happy. using no-op
  * functions for copy and free, and crossing fingers.
@@ -61,7 +62,7 @@ col_row_info_get_type (void)
 double
 colrow_compute_pixel_scale (Sheet const *sheet, gboolean horizontal)
 {
-       return sheet->last_zoom_factor_used *
+       return (sheet ? sheet->last_zoom_factor_used : 1.0) *
                gnm_app_display_dpi_get (horizontal) / 72.;
 }
 
@@ -74,7 +75,7 @@ colrow_compute_pixels_from_pts (ColRowInfo *cri, Sheet const *sheet,
        if (scale == -1)
                scale = colrow_compute_pixel_scale (sheet, horizontal);
 
-       if (horizontal && sheet->display_formulas)
+       if (horizontal && sheet && sheet->display_formulas)
                scale *= 2;
 
        cri->size_pixels = (int)(cri->size_pts * scale + 0.5);
@@ -189,7 +190,7 @@ colrow_free (ColRowInfo *cri)
  * @last:      stop column (inclusive)
  * @callback: (scope call): A callback function which should return %TRUE to stop
  *              the iteration.
- * @user_data: A bagage pointer.
+ * @user_data: A baggage pointer.
  *
  * Iterates through the existing rows or columns within the range supplied.
  * Currently only support left -> right iteration.  If a callback returns
@@ -228,6 +229,60 @@ col_row_collection_foreach (ColRowCollection const *infos, int first, int last,
        return FALSE;
 }
 
+
+/**
+ * colrow_state_list_foreach:
+ * @list: The #ColRowStateList to iterate.
+ * @sheet: (nullable): Origin #Sheet.
+ * @is_cols: %TRUE for columns, %FALSE for rows.
+ * @base: index of first column or row.
+ * @callback: (scope call): A callback function which should
+ *   return %TRUE to stop the iteration.
+ * @user_data: A baggage pointer.
+ *
+ * Iterates through the existing rows or columns within the range supplied.
+ * Currently only support left -> right iteration.  If a callback returns
+ * %TRUE iteration stops.
+ **/
+gboolean
+colrow_state_list_foreach (ColRowStateList *list,
+                          Sheet const *sheet, gboolean is_cols,
+                          int base,
+                          ColRowHandler callback,
+                          gpointer user_data)
+{
+       GnmColRowIter iter;
+       int i = base;
+       ColRowStateList *l;
+       ColRowInfo cri;
+       double scale = colrow_compute_pixel_scale (sheet, is_cols);
+
+       // This sets various fields we do not have
+       memset (&cri, 0, sizeof (cri));
+
+       iter.cri = &cri;
+       for (l = list; l; l = l->next) {
+               ColRowRLEState *rle = l->data;
+               ColRowState const *state = &rle->state;
+               int l;
+
+               cri.size_pts = state->size_pts;
+               cri.outline_level = state->outline_level;
+               cri.is_collapsed = state->is_collapsed;
+               cri.hard_size = state->hard_size;
+               cri.visible = state->visible;
+               colrow_compute_pixels_from_pts (&cri, sheet, is_cols, scale);
+
+               for (l = 0; l < rle->length; l++) {
+                       iter.pos = i++;
+                       if (iter.cri && (*callback)(&iter, user_data))
+                               return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+
 /*****************************************************************************/
 
 typedef struct _ColRowIndex {
diff --git a/src/colrow.h b/src/colrow.h
index f354345..e6fa197 100644
--- a/src/colrow.h
+++ b/src/colrow.h
@@ -110,6 +110,12 @@ ColRowStateList    *colrow_get_states           (Sheet *sheet, gboolean is_cols,
                                              int first, int last);
 void            colrow_set_states           (Sheet *sheet, gboolean is_cols,
                                              int first, ColRowStateList *states);
+gboolean colrow_state_list_foreach          (ColRowStateList *list,
+                                             Sheet const *sheet,
+                                             gboolean is_cols,
+                                             int base,
+                                             ColRowHandler callback,
+                                             gpointer user_data);
 
 ColRowStateGroup  *colrow_state_group_destroy  (ColRowStateGroup *set);
 ColRowStateGroup  *colrow_set_sizes            (Sheet *sheet, gboolean is_cols,
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index ea515d3..8ebcade 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -3468,6 +3468,12 @@ read_file_common (ReadFileWhat what, XMLSaxParseState *state,
                                           "SHEET_STYLES",
                                           "CLIPBOARDRANGE");
                gnm_xml_in_doc_add_subset (doc, gnumeric_1_0_dtd,
+                                          "SHEET_COLS",
+                                          "CLIPBOARDRANGE");
+               gnm_xml_in_doc_add_subset (doc, gnumeric_1_0_dtd,
+                                          "SHEET_ROWS",
+                                          "CLIPBOARDRANGE");
+               gnm_xml_in_doc_add_subset (doc, gnumeric_1_0_dtd,
                                           "SHEET_CELLS",
                                           "CLIPBOARDRANGE");
                gnm_xml_in_doc_add_subset (doc, gnumeric_1_0_dtd,
diff --git a/src/xml-sax-write.c b/src/xml-sax-write.c
index 92fbae2..10afd71 100644
--- a/src/xml-sax-write.c
+++ b/src/xml-sax-write.c
@@ -729,15 +729,16 @@ xml_write_styles (GnmOutputXML *state)
 
 typedef struct {
        GnmOutputXML *state;
-       gboolean        is_column;
-       ColRowInfo const *prev;
+       gboolean is_column;
+       ColRowInfo prev;
        int prev_pos, rle_count;
+       GnmCellRegion const *cr;
 } closure_write_colrow;
 
 static gboolean
 xml_write_colrow_info (GnmColRowIter const *iter, closure_write_colrow *closure)
 {
-       ColRowInfo const *prev = closure->prev;
+       ColRowInfo const *prev = &closure->prev;
        GsfXMLOut *output = closure->state->output;
        ColRowInfo const *def =
                sheet_colrow_get_default (closure->state->sheet,
@@ -747,7 +748,7 @@ xml_write_colrow_info (GnmColRowIter const *iter, closure_write_colrow *closure)
        if (NULL != iter && col_row_info_equal (prev, iter->cri))
                return FALSE;
 
-       if (prev != NULL && !col_row_info_equal (prev, def)) {
+       if (closure->prev_pos != -1 && !col_row_info_equal (prev, def)) {
                if (closure->is_column)
                        gsf_xml_out_start_element (output, GNM "ColInfo");
                else
@@ -771,7 +772,7 @@ xml_write_colrow_info (GnmColRowIter const *iter, closure_write_colrow *closure)
 
        closure->rle_count = 0;
        if (NULL != iter) {
-               closure->prev = iter->cri;
+               closure->prev = *iter->cri;
                closure->prev_pos = iter->pos;
        }
 
@@ -779,34 +780,45 @@ xml_write_colrow_info (GnmColRowIter const *iter, closure_write_colrow *closure)
 }
 
 static void
-xml_write_cols_rows (GnmOutputXML *state)
+xml_write_cols_rows (GnmOutputXML *state, GnmCellRegion const *cr)
 {
-       closure_write_colrow closure;
-       gsf_xml_out_start_element (state->output, GNM "Cols");
-       xml_out_add_points (state->output, "DefaultSizePts",
-               sheet_col_get_default_size_pts (state->sheet));
-       closure.state = state;
-       closure.is_column = TRUE;
-       closure.prev = NULL;
-       closure.prev_pos = -1;
-       closure.rle_count = 0;
-       col_row_collection_foreach (&state->sheet->cols, 0, gnm_sheet_get_last_col (state->sheet),
-               (ColRowHandler)&xml_write_colrow_info, &closure);
-       xml_write_colrow_info (NULL, &closure); /* flush */
-       gsf_xml_out_end_element (state->output); /* </gnm:Cols> */
-
-       gsf_xml_out_start_element (state->output, GNM "Rows");
-       xml_out_add_points (state->output, "DefaultSizePts",
-               sheet_row_get_default_size_pts (state->sheet));
-       closure.state = state;
-       closure.is_column = FALSE;
-       closure.prev = NULL;
-       closure.prev_pos = -1;
-       closure.rle_count = 0;
-       col_row_collection_foreach (&state->sheet->rows, 0, gnm_sheet_get_last_row (state->sheet),
-               (ColRowHandler)&xml_write_colrow_info, &closure);
-       xml_write_colrow_info (NULL, &closure); /* flush */
-       gsf_xml_out_end_element (state->output); /* </gnm:Rows> */
+       const Sheet *sheet = state->sheet;
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               closure_write_colrow closure;
+               gboolean is_cols = (i == 0);
+
+               gsf_xml_out_start_element (state->output,
+                                          is_cols ? GNM "Cols" : GNM "Rows");
+
+               if (sheet)
+                       xml_out_add_points
+                               (state->output, "DefaultSizePts",
+                                sheet_colrow_get_default (sheet, is_cols)->size_pts);
+
+               closure.state = state;
+               closure.cr = cr;
+               closure.is_column = is_cols;
+               memset (&closure.prev, 0, sizeof (closure.prev));
+               closure.prev_pos = -1;
+               closure.rle_count = 0;
+               if (cr)
+                       colrow_state_list_foreach
+                               (is_cols ? cr->col_state : cr->row_state,
+                                sheet, is_cols,
+                                is_cols ? cr->base.col : cr->base.row,
+                                (ColRowHandler)&xml_write_colrow_info,
+                                &closure);
+               else
+                       col_row_collection_foreach
+                               (is_cols ? &sheet->cols : &sheet->rows,
+                                0, colrow_max(is_cols, sheet) - 1,
+                                (ColRowHandler)&xml_write_colrow_info,
+                                &closure);
+               xml_write_colrow_info (NULL, &closure); /* flush */
+               gsf_xml_out_end_element (state->output); /* </gnm:Cols> */
+       }
 }
 
 static void
@@ -1379,7 +1391,7 @@ xml_write_sheet (GnmOutputXML *state, Sheet const *sheet)
        xml_write_named_expressions (state, sheet->names);
        xml_write_print_info (state, sheet->print_info);
        xml_write_styles (state);
-       xml_write_cols_rows (state);
+       xml_write_cols_rows (state, NULL);
        xml_write_selection_info (state);
        xml_write_objects (state, sheet->sheet_objects);
        xml_write_cells (state);
@@ -1651,6 +1663,8 @@ gnm_cellregion_to_xml (GnmCellRegion const *cr)
        if (cr->not_as_contents)
                gsf_xml_out_add_bool (state.state.output, "NotAsContent", TRUE);
 
+       xml_write_cols_rows (&state.state, cr);
+
        if (cr->styles != NULL) {
                gsf_xml_out_start_element (state.state.output, GNM "Styles");
                for (s_ptr = cr->styles ; s_ptr != NULL ; s_ptr = s_ptr->next)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]