[gnumeric] ssconvert merge: inital patch from 581616.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnumeric] ssconvert merge: inital patch from 581616.
- Date: Mon, 11 May 2009 20:58:32 -0400 (EDT)
commit e718a5d5dbd01faaf41f37699e296e238dfb9a66
Author: Morten Welinder <terra gnome org>
Date: Mon May 11 19:43:54 2009 -0400
ssconvert merge: inital patch from 581616.
---
src/ssconvert.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 187 insertions(+), 5 deletions(-)
diff --git a/src/ssconvert.c b/src/ssconvert.c
index 6205907..983ef8b 100644
--- a/src/ssconvert.c
+++ b/src/ssconvert.c
@@ -16,6 +16,11 @@
#include "position.h"
#include "parse-util.h"
#include "workbook.h"
+#include "workbook-priv.h"
+#include "sheet.h"
+#include "dependent.h"
+#include "expr-name.h"
+#include "str.h"
#include "libgnumeric.h"
#include "gutils.h"
#include "gnumeric-paths.h"
@@ -46,6 +51,7 @@ static char *ssconvert_import_encoding = NULL;
static char *ssconvert_import_id = NULL;
static char *ssconvert_export_id = NULL;
static char *ssconvert_export_options = NULL;
+static char *ssconvert_merge_target = NULL;
static char **ssconvert_goal_seek = NULL;
static const GOptionEntry ssconvert_options [] = {
@@ -82,6 +88,13 @@ static const GOptionEntry ssconvert_options [] = {
/* ---------------------------------------- */
{
+ "merge-to", 'M',
+ 0, G_OPTION_ARG_STRING, &ssconvert_merge_target,
+ N_("Merge listed files (all same format) to make this file"),
+ N_("file")
+ },
+
+ {
"export-type", 'T',
0, G_OPTION_ARG_STRING, &ssconvert_export_id,
N_("Optionally specify which exporter to use"),
@@ -225,8 +238,165 @@ list_them (get_them_f get_them,
}
}
+/* Look at a set of workbooks, and pick a sheet size that would
+ be good for sheets in a workbook merging them all. */
+static int
+suggest_size (const char *inputs[], int *csuggest, int *rsuggest,
+ GOFileOpener *fo, IOContext *io_context,
+ GOCmdContext *cc)
+{
+ int rmax = 0;
+ int cmax = 0;
+ while (*inputs!=NULL) {
+ const char *fname = *inputs;
+ char *uri = go_shell_arg_to_uri (fname);
+ WorkbookView *wbv2 =
+ wb_view_new_from_uri (uri, fo,
+ io_context,
+ ssconvert_import_encoding);
+ inputs++;
+ if (wbv2!=NULL) {
+ Workbook *wb2 = wb_view_get_workbook (wbv2);
+ int i;
+ /* Looping through sheets should be redundant
+ if all must be same size; let's do it anyway */
+ for (i=0; i<workbook_sheet_count (wb2); i++) {
+ Sheet *sheet = workbook_sheet_by_index (wb2,i);
+ int r = gnm_sheet_get_max_rows (sheet);
+ int c = gnm_sheet_get_max_cols (sheet);
+ if (r>rmax) rmax = r;
+ if (c>cmax) cmax = c;
+ }
+ g_object_unref (wb2);
+ }
+ g_free (uri);
+ }
+ gnm_sheet_suggest_size (&cmax, &rmax);
+ if (csuggest!=NULL) *csuggest = cmax;
+ if (rsuggest!=NULL) *rsuggest = rmax;
+ return 0;
+}
+
+
+/* Append the sheets of workbook wb2 to workbook wb. Resize sheets
+ if necessary. Fix workbook links in sheet if necessary.
+ Merge names in workbook scope (conflicts result in an error). */
+static int
+merge_single (Workbook *wb, Workbook *wb2, int cmax, int rmax,
+ GOCmdContext *cc) {
+
+ /* Move names with workbook scope in wb2 over to wb */
+ GSList *names = g_slist_sort (gnm_named_expr_collection_list (wb2->names),
+ (GCompareFunc)expr_name_cmp_by_name);
+ GSList *p;
+ for (p = names; p; p = p->next) {
+ GnmNamedExpr *nexpr = p->data;
+ if (nexpr!=NULL) {
+ if (nexpr->pos.wb!=NULL) {
+ /* Check for clash with existing name */
+ GnmParsePos pp;
+ parse_pos_init (&pp,wb,NULL,0,0);
+ GnmNamedExpr *nexpr2;
+ nexpr2 = expr_name_lookup (&pp,
+ nexpr->name->str);
+ if (nexpr2!=NULL) {
+ g_printerr (_("Name conflict during merge: '%s' appears twice at workbook scope.\n"),
+ nexpr->name->str);
+ g_slist_free (names);
+ return -1;
+ }
+
+ /* Move name scope to workbook wb */
+ Sheet *sheet = workbook_sheet_by_index (wb2,0);
+ expr_name_set_scope(nexpr,sheet);
+ nexpr->pos.wb = wb;
+ expr_name_set_scope(nexpr,NULL);
+ }
+ }
+ }
+
+ while (workbook_sheet_count (wb2) > 0) {
+ /* Remove sheet from incoming workbook */
+ Sheet *sheet = workbook_sheet_by_index (wb2,0);
+ int loc = workbook_sheet_count (wb);
+ int r = gnm_sheet_get_max_rows (sheet);
+ int c = gnm_sheet_get_max_cols (sheet);
+ GOUndo *undo;
+ g_object_ref (sheet);
+ workbook_sheet_delete (sheet);
+ sheet->workbook = wb;
+
+ /* Fix names that reference the old workbook */
+ GSList *names = g_slist_sort (gnm_named_expr_collection_list (sheet->names),
+ (GCompareFunc)expr_name_cmp_by_name);
+ GSList *p;
+ for (p = names; p; p = p->next) {
+ GnmNamedExpr *nexpr = p->data;
+ if (nexpr!=NULL) {
+ if (nexpr->pos.wb!=NULL) {
+ nexpr->pos.wb = wb;
+ }
+ }
+ }
+ g_slist_free (names);
+
+ /* Resize if necessary (not sure if this is needed) */
+ if (r!=rmax || c!=cmax) {
+ undo = gnm_sheet_resize (sheet,
+ cmax,
+ rmax,
+ cc);
+ if (undo!=NULL) {
+ g_object_unref (undo);
+ }
+ }
+
+ /* Pick a free sheet name */
+ char *name = workbook_sheet_get_free_name(wb,
+ sheet->name_unquoted,
+ FALSE,
+ TRUE);
+ g_object_set (sheet, "name", name, NULL);
+ g_free (name);
+
+ /* Insert and revive the sheet */
+ workbook_sheet_attach_at_pos (wb,sheet,loc);
+ dependents_revive_sheet (sheet);
+ g_object_unref (sheet);
+ }
+ return 0;
+}
+
+/* Merge a collection of workbooks into one. */
+merge (Workbook *wb, char const *inputs[],
+ GOFileOpener *fo, IOContext *io_context,
+ GOCmdContext *cc)
+{
+ int result = 0;
+ int cmax, rmax;
+ suggest_size (inputs, &cmax, &rmax, fo, io_context, cc);
+
+ while (*inputs!=NULL && result==0) {
+ const char *fname = *inputs;
+ char *uri = go_shell_arg_to_uri (fname);
+ WorkbookView *wbv2 =
+ wb_view_new_from_uri (uri, fo,
+ io_context,
+ ssconvert_import_encoding);
+ inputs++;
+ if (wbv2!=NULL) {
+ g_print ("Adding %s\n", fname);
+ Workbook *wb2 = wb_view_get_workbook (wbv2);
+ result = merge_single (wb, wb2, cmax, rmax, cc);
+ g_object_unref (wb2);
+ }
+ g_free (uri);
+ }
+ return result;
+}
+
static int
-convert (char const *inarg, char const *outarg,
+convert (char const *inarg, char const *outarg, char const *mergeargs[],
GOCmdContext *cc)
{
int res = 0;
@@ -288,8 +458,14 @@ convert (char const *inarg, char const *outarg,
if (fs != NULL) {
IOContext *io_context = gnumeric_io_context_new (cc);
- WorkbookView *wbv = wb_view_new_from_uri (infile, fo,
- io_context, ssconvert_import_encoding);
+ WorkbookView *wbv;
+ if (mergeargs==NULL) {
+ wbv = wb_view_new_from_uri (infile, fo,
+ io_context,
+ ssconvert_import_encoding);
+ } else {
+ wbv = workbook_view_new (NULL);
+ }
if (wbv == NULL || gnumeric_io_error_occurred (io_context)) {
gnumeric_io_error_display (io_context);
@@ -304,6 +480,10 @@ convert (char const *inarg, char const *outarg,
goto out;
}
+ if (mergeargs!=NULL) {
+ merge (wb, mergeargs, fo, io_context, cc);
+ }
+
if (ssconvert_goal_seek) {
int i;
@@ -399,8 +579,10 @@ main (int argc, char const **argv)
list_them (&go_get_file_openers,
(get_desc_f) &go_file_opener_get_id,
(get_desc_f) &go_file_opener_get_description);
- else if (argc == 2 || argc == 3) {
- res = convert (argv[1], argv[2], cc);
+ else if (ssconvert_merge_target!=NULL && argc>=3) {
+ res = convert (argv[1], ssconvert_merge_target, argv+1, cc);
+ } else if (argc == 2 || argc == 3) {
+ res = convert (argv[1], argv[2], NULL, cc);
} else {
g_printerr (_("Usage: %s [OPTION...] %s\n"),
g_get_prgname (),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]