[gnumeric] diff: first, very rough, cut at a gui for diff
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] diff: first, very rough, cut at a gui for diff
- Date: Mon, 9 Apr 2018 01:44:08 +0000 (UTC)
commit 4261f4911493608c1f60ab0f7662a3111da78c8b
Author: Morten Welinder <terra gnome org>
Date: Sun Apr 8 21:41:43 2018 -0400
diff: first, very rough, cut at a gui for diff
po/POTFILES.in | 2 +
src/GNOME_Gnumeric-gtk.xml.in | 1 +
src/dialogs/Makefile.am | 2 +
src/dialogs/dialog-sheet-compare.c | 387 ++++++++++++++++++++++++++++++++++++
src/dialogs/dialogs.h | 1 +
src/dialogs/sheet-compare.ui | 283 ++++++++++++++++++++++++++
src/wbc-gtk-actions.c | 6 +
7 files changed, 682 insertions(+), 0 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e9d7743..c3d19bf 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -182,6 +182,7 @@ src/dialogs/dialog-row-height.c
src/dialogs/dialog-scenarios.c
src/dialogs/dialog-search-replace.c
src/dialogs/dialog-search.c
+src/dialogs/dialog-sheet-compare.c
src/dialogs/dialog-sheet-order.c
src/dialogs/dialog-sheetobject-size.c
src/dialogs/dialog-shuffle.c
@@ -265,6 +266,7 @@ src/dialogs/dialog-zoom.c
[type: gettext/glade]src/dialogs/search-replace.ui
[type: gettext/glade]src/dialogs/search.ui
[type: gettext/glade]src/dialogs/sheetobject-size.ui
+[type: gettext/glade]src/dialogs/sheet-compare.ui
[type: gettext/glade]src/dialogs/sheet-order.ui
[type: gettext/glade]src/dialogs/sheet-rename.ui
[type: gettext/glade]src/dialogs/sheet-resize.ui
diff --git a/src/GNOME_Gnumeric-gtk.xml.in b/src/GNOME_Gnumeric-gtk.xml.in
index 28a7b4e..f726625 100644
--- a/src/GNOME_Gnumeric-gtk.xml.in
+++ b/src/GNOME_Gnumeric-gtk.xml.in
@@ -208,6 +208,7 @@
<menuitem action="ToolsScenarioAdd"/>
</menu>
<menuitem action="ToolsSimulation"/>
+ <menuitem action="ToolsCompare"/>
<separator/>
<menuitem action="ToolsPlugins"/>
</menu>
diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am
index df6c68a..4a2b9de 100644
--- a/src/dialogs/Makefile.am
+++ b/src/dialogs/Makefile.am
@@ -64,6 +64,7 @@ libdialogs_la_SOURCES = \
dialog-scenarios.c \
dialog-search.c \
dialog-search-replace.c \
+ dialog-sheet-compare.c \
dialog-sheet-order.c \
dialog-sheet-rename.c \
dialog-sheet-resize.c \
@@ -160,6 +161,7 @@ embedded_uis = \
scenario-manager.ui \
search-replace.ui \
search.ui \
+ sheet-compare.ui \
sheet-order.ui \
sheet-rename.ui \
sheet-resize.ui \
diff --git a/src/dialogs/dialog-sheet-compare.c b/src/dialogs/dialog-sheet-compare.c
new file mode 100644
index 0000000..a2274de
--- /dev/null
+++ b/src/dialogs/dialog-sheet-compare.c
@@ -0,0 +1,387 @@
+/*
+ * dialog-comparet-order.c: Dialog to compare two sheets.
+ *
+ * (C) Copyright 2018 Morten Welinder (terra gnome org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <gnumeric-config.h>
+#include <glib/gi18n-lib.h>
+#include <gnumeric.h>
+#include "sheet-diff.h"
+#include "dialogs.h"
+#include "help.h"
+
+#include <gui-util.h>
+#include <wbc-gtk.h>
+#include <workbook-view.h>
+#include <workbook.h>
+#include <sheet.h>
+#include <ranges.h>
+#include <application.h>
+
+#define SHEET_COMPARE_KEY "sheet-compare-dialog"
+
+enum {
+ ITEM_DESC,
+ NUM_COLMNS
+};
+
+
+typedef struct {
+ WBCGtk *wbcg;
+
+ GtkBuilder *gui;
+ GtkWidget *dialog;
+ GtkWidget *notebook;
+
+ GtkWidget *cancel_btn;
+ GtkWidget *compare_btn;
+
+ GtkWidget *sheet_sel_A;
+ GtkWidget *sheet_sel_B;
+ GtkWidget *wb_sel_A;
+ GtkWidget *wb_sel_B;
+
+ GtkTreeView *results_view;
+ GtkTreeStore *results;
+
+ gboolean has_cell_section;
+ GtkTreeIter cell_section_iter;
+
+ gboolean has_style_section;
+ GtkTreeIter style_section_iter;
+} SheetCompare;
+
+
+static void
+cb_sheet_compare_destroy (SheetCompare *state)
+{
+ Workbook *wb = wb_control_get_workbook (GNM_WBC (state->wbcg));
+
+ g_object_unref (state->gui);
+ g_object_set_data (G_OBJECT (wb), SHEET_COMPARE_KEY, NULL);
+ state->gui = NULL;
+
+ g_free (state);
+}
+
+static void
+cb_cancel_clicked (G_GNUC_UNUSED GtkWidget *ignore,
+ SheetCompare *state)
+{
+ gtk_widget_destroy (GTK_WIDGET (state->dialog));
+}
+
+static void
+reset_sheet_menu (GtkWidget *sheet_sel, Workbook *wb, int def_sheet)
+{
+ GOOptionMenu *om = GO_OPTION_MENU (sheet_sel);
+ GtkMenu *menu;
+ GtkWidget *act = NULL;
+
+ if (wb == g_object_get_data (G_OBJECT (om), "wb"))
+ return;
+ g_object_set_data (G_OBJECT (om), "wb", wb);
+
+ menu = GTK_MENU (gtk_menu_new ());
+ WORKBOOK_FOREACH_SHEET (wb, sheet, {
+ GtkWidget *item =
+ gtk_check_menu_item_new_with_label
+ (sheet->name_unquoted);
+ gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), TRUE);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
+ g_object_set_data (G_OBJECT (item), "sheet", sheet);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ if (def_sheet-- == 0)
+ act = item;
+ });
+
+ gtk_widget_show_all (GTK_WIDGET (menu));
+ go_option_menu_set_menu (om, GTK_WIDGET (menu));
+
+ if (act)
+ go_option_menu_select_item (om, GTK_MENU_ITEM (act));
+}
+
+static GtkWidget *
+create_sheet_selector (gboolean qnew)
+{
+ GtkWidget *w = go_option_menu_new ();
+ g_object_set_data (G_OBJECT (w), "qnew", GUINT_TO_POINTER (qnew));
+ return w;
+}
+
+
+static void
+cb_wb_changed (GOOptionMenu *om, SheetCompare *state)
+{
+ GtkWidget *item = go_option_menu_get_history (om);
+ Workbook *wb = g_object_get_data (G_OBJECT (item), "wb");
+ GtkWidget *sheet_sel = g_object_get_data (G_OBJECT (om), "sheet_sel");
+
+ if (wb)
+ reset_sheet_menu (sheet_sel, wb, -1);
+}
+
+static GtkWidget *
+create_wb_selector (SheetCompare *state, GtkWidget *sheet_sel,
+ Workbook *wb0, gboolean qnew)
+{
+ GtkMenu *menu;
+ GOOptionMenu *om;
+ GList *l, *wbs;
+ GtkWidget *act = NULL;
+
+ om = GO_OPTION_MENU (go_option_menu_new ());
+ menu = GTK_MENU (gtk_menu_new ());
+
+ wbs = gnm_app_workbook_list ();
+ for (l = wbs; l; l = l->next) {
+ Workbook *wb = l->data;
+ GtkWidget *item, *child;
+ const char *uri;
+ char *markup, *shortname, *filename, *dirname, *longname, *duri;
+
+ uri = go_doc_get_uri (GO_DOC (wb));
+ filename = go_filename_from_uri (uri);
+ if (filename) {
+ shortname = g_filename_display_basename (filename);
+ } else {
+ shortname = g_filename_display_basename (uri);
+ }
+
+ dirname = g_path_get_dirname (filename);
+ duri = g_uri_unescape_string (dirname, NULL);
+ longname = duri
+ ? g_filename_display_name (duri)
+ : g_strdup (uri);
+
+ markup = g_markup_printf_escaped
+ (_("%s\n<small>%s</small>"),
+ shortname, longname);
+
+ item = gtk_menu_item_new_with_label ("");
+ child = gtk_bin_get_child (GTK_BIN (item));
+ gtk_label_set_markup (GTK_LABEL (child), markup);
+ gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_MIDDLE);
+
+ g_free (markup);
+ g_free (shortname);
+ g_free (dirname);
+ g_free (longname);
+ g_free (duri);
+ g_free (filename);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ g_object_set_data (G_OBJECT (item), "wb", wb);
+ if (wb == wb0)
+ act = item;
+ }
+
+ gtk_widget_show_all (GTK_WIDGET (menu));
+ go_option_menu_set_menu (om, GTK_WIDGET (menu));
+
+ if (act)
+ go_option_menu_select_item (om, GTK_MENU_ITEM (act));
+
+ reset_sheet_menu (sheet_sel, WORKBOOK (wbs->data),
+ qnew ? 1 : 0);
+
+ g_object_set_data (G_OBJECT (om), "sheet_sel", sheet_sel);
+
+ g_signal_connect (G_OBJECT (om), "changed",
+ G_CALLBACK (cb_wb_changed), state);
+
+ return GTK_WIDGET (om);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void
+dsc_cell_changed (gpointer user, GnmCell const *oc, GnmCell const *nc)
+{
+ SheetCompare *state = user;
+ GtkTreeIter iter;
+ char *text;
+ const char *loc;
+
+ if (!state->has_cell_section) {
+ gtk_tree_store_insert (state->results,
+ &state->cell_section_iter,
+ NULL, -1);
+ gtk_tree_store_set (state->results,
+ &state->cell_section_iter,
+ ITEM_DESC, _("Cells"),
+ -1);
+ state->has_cell_section = TRUE;
+ }
+
+ loc = cell_name (oc ? oc : nc);
+ if (oc && nc)
+ text = g_strdup_printf (_("Cell %s changed"), loc);
+ else if (oc)
+ text = g_strdup_printf (_("Cell %s removed."), loc);
+ else if (nc)
+ text = g_strdup_printf (_("Cell %s added."), loc);
+ else
+ g_assert_not_reached ();
+ gtk_tree_store_insert (state->results, &iter,
+ &state->cell_section_iter,
+ -1);
+ gtk_tree_store_set (state->results, &iter,
+ ITEM_DESC, text,
+ -1);
+ g_free (text);
+}
+
+static void
+dsc_style_changed (gpointer user, GnmRange const *r,
+ G_GNUC_UNUSED GnmStyle const *os,
+ G_GNUC_UNUSED GnmStyle const *ns)
+{
+ SheetCompare *state = user;
+ GtkTreeIter iter;
+ char *text;
+
+ if (!state->has_style_section) {
+ gtk_tree_store_insert (state->results,
+ &state->style_section_iter,
+ NULL, -1);
+ gtk_tree_store_set (state->results,
+ &state->style_section_iter,
+ ITEM_DESC, _("Formatting"),
+ -1);
+ state->has_style_section = TRUE;
+ }
+
+ text = g_strdup_printf (_("Style for range %s changed"),
+ range_as_string (r));
+ gtk_tree_store_insert (state->results, &iter,
+ &state->style_section_iter,
+ -1);
+ gtk_tree_store_set (state->results, &iter,
+ ITEM_DESC, text,
+ -1);
+ g_free (text);
+}
+
+static const GnmDiffActions dsc_actions = {
+ .cell_changed = dsc_cell_changed,
+ .style_changed = dsc_style_changed,
+};
+
+static void
+cb_compare_clicked (G_GNUC_UNUSED GtkWidget *ignore,
+ SheetCompare *state)
+{
+ GtkTreeView *tv = state->results_view;
+ GtkTreeStore *ts = gtk_tree_store_new (NUM_COLMNS, G_TYPE_STRING);
+ GtkWidget *w;
+ Sheet *sheet_A, *sheet_B;
+
+ if (gtk_tree_view_get_n_columns (tv) == 0) {
+ GtkTreeViewColumn *tvc;
+
+ tvc = gtk_tree_view_column_new_with_attributes
+ (_("Description"),
+ gtk_cell_renderer_text_new (),
+ "text", ITEM_DESC, NULL);
+ gtk_tree_view_append_column (tv, tvc);
+ }
+
+ w = go_option_menu_get_history (GO_OPTION_MENU (state->sheet_sel_A));
+ sheet_A = w ? g_object_get_data (G_OBJECT (w), "sheet") : NULL;
+ w = go_option_menu_get_history (GO_OPTION_MENU (state->sheet_sel_B));
+ sheet_B = w ? g_object_get_data (G_OBJECT (w), "sheet") : NULL;
+
+ if (sheet_A && sheet_B) {
+ state->results = ts;
+ gnm_diff_sheets (&dsc_actions, state, sheet_A, sheet_B);
+ state->results = NULL;
+ }
+
+ gtk_tree_view_set_model (tv, GTK_TREE_MODEL (ts));
+ g_object_unref (ts);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (state->notebook), 1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void
+dialog_sheet_compare (WBCGtk *wbcg)
+{
+ SheetCompare *state;
+ GtkBuilder *gui;
+ Workbook *wb;
+
+ g_return_if_fail (wbcg != NULL);
+
+ wb = wb_control_get_workbook (GNM_WBC (wbcg));
+
+ gui = gnm_gtk_builder_load ("sheet-compare.ui", NULL, GO_CMD_CONTEXT (wbcg));
+ if (gui == NULL)
+ return;
+
+ /* Only pop up one copy per workbook */
+ if (gnm_dialog_raise_if_exists (wbcg, SHEET_COMPARE_KEY))
+ return;
+
+
+ g_object_set_data (G_OBJECT (wb), SHEET_COMPARE_KEY, (gpointer) gui);
+ state = g_new0 (SheetCompare, 1);
+ state->gui = gui;
+ state->wbcg = wbcg;
+ state->dialog = go_gtk_builder_get_widget (gui, "sheet-compare-dialog");
+ state->notebook = go_gtk_builder_get_widget (gui, "notebook");
+ state->cancel_btn = go_gtk_builder_get_widget (gui, "cancel_button");
+ state->compare_btn = go_gtk_builder_get_widget (gui, "compare_button");
+ state->results_view = GTK_TREE_VIEW (go_gtk_builder_get_widget (gui, "results_treeview"));
+
+ state->sheet_sel_A = create_sheet_selector (FALSE);
+ state->wb_sel_A = create_wb_selector (state, state->sheet_sel_A,
+ wb, FALSE);
+ go_gtk_widget_replace (go_gtk_builder_get_widget (gui, "sheet_selector_A"),
+ state->sheet_sel_A);
+ go_gtk_widget_replace (go_gtk_builder_get_widget (gui, "wb_selector_A"),
+ state->wb_sel_A);
+
+ state->sheet_sel_B = create_sheet_selector (TRUE);
+ state->wb_sel_B = create_wb_selector (state, state->sheet_sel_B,
+ wb, TRUE);
+ go_gtk_widget_replace (go_gtk_builder_get_widget (gui, "sheet_selector_B"),
+ state->sheet_sel_B);
+ go_gtk_widget_replace (go_gtk_builder_get_widget (gui, "wb_selector_B"),
+ state->wb_sel_B);
+
+#define CONNECT(o,s,c) g_signal_connect(G_OBJECT(o),s,G_CALLBACK(c),state)
+ CONNECT (state->cancel_btn, "clicked", cb_cancel_clicked);
+ CONNECT (state->compare_btn, "clicked", cb_compare_clicked);
+#undef CONNECT
+
+ /* a candidate for merging into attach guru */
+ wbc_gtk_attach_guru (state->wbcg, GTK_WIDGET (state->dialog));
+ g_object_set_data_full (G_OBJECT (state->dialog),
+ "state", state,
+ (GDestroyNotify) cb_sheet_compare_destroy);
+
+ gnm_restore_window_geometry (GTK_WINDOW (state->dialog),
+ SHEET_COMPARE_KEY);
+
+ go_gtk_nonmodal_dialog (wbcg_toplevel (state->wbcg),
+ GTK_WINDOW (state->dialog));
+ gtk_widget_show_all (GTK_WIDGET (state->dialog));
+}
diff --git a/src/dialogs/dialogs.h b/src/dialogs/dialogs.h
index 6a045f9..b7c478c 100644
--- a/src/dialogs/dialogs.h
+++ b/src/dialogs/dialogs.h
@@ -57,6 +57,7 @@ void dialog_autosave (WBCGtk *wbcg);
gboolean dialog_autosave_prompt (WBCGtk *wbcg);
void dialog_autoformat (WBCGtk *wbcg);
void dialog_consolidate (WBCGtk *wbcg);
+void dialog_sheet_compare (WBCGtk *wbcg);
void dialog_sheet_order (WBCGtk *wbcg);
void dialog_sheet_resize (WBCGtk *wbcg);
void dialog_sheet_rename (WBCGtk *wbcg, Sheet *sheet);
diff --git a/src/dialogs/sheet-compare.ui b/src/dialogs/sheet-compare.ui
new file mode 100644
index 0000000..fff66ad
--- /dev/null
+++ b/src/dialogs/sheet-compare.ui
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface>
+ <requires lib="gtk+" version="3.8"/>
+ <object class="GtkAdjustment" id="results_hadjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="results_vadjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="sheet-compare-dialog">
+ <property name="can_focus">False</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="button_box1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="compare_button">
+ <property name="label" translatable="yes">Compare</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkSeparator" id="separator1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="height">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Workbook</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Workbook</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Sheet</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Sheet</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="wb_selector_A">
+ <property name="label" translatable="yes">button</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="wb_selector_B">
+ <property name="label" translatable="yes">button</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="sheet_selector_A">
+ <property name="label" translatable="yes">button</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="sheet_selector_B">
+ <property name="label" translatable="yes">button</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">First Sheet</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Second Sheet</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="separator2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="separator3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="options_tab">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Options</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolled_window1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hadjustment">results_hadjustment</property>
+ <property name="vadjustment">results_vadjustment</property>
+ <property name="vscrollbar_policy">always</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="results_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hadjustment">results_hadjustment</property>
+ <property name="vadjustment">results_vadjustment</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="tree_selection1"/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="results_tab">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Results</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/wbc-gtk-actions.c b/src/wbc-gtk-actions.c
index 8f6525d..65bab45 100644
--- a/src/wbc-gtk-actions.c
+++ b/src/wbc-gtk-actions.c
@@ -914,6 +914,7 @@ static GNM_ACTION_DEF (cb_tools_solver) { dialog_solver (wbcg, wbcg_cur_
static GNM_ACTION_DEF (cb_tools_scenario_add) { dialog_scenario_add (wbcg); }
static GNM_ACTION_DEF (cb_tools_scenarios) { dialog_scenarios (wbcg); }
static GNM_ACTION_DEF (cb_tools_simulation) { dialog_simulation (wbcg, wbcg_cur_sheet (wbcg)); }
+static GNM_ACTION_DEF (cb_tools_compare) { dialog_sheet_compare (wbcg); }
static GNM_ACTION_DEF (cb_tools_anova_one_factor) { dialog_anova_single_factor_tool (wbcg, wbcg_cur_sheet
(wbcg)); }
static GNM_ACTION_DEF (cb_tools_anova_two_factor) { dialog_anova_two_factor_tool (wbcg, wbcg_cur_sheet
(wbcg)); }
static GNM_ACTION_DEF (cb_tools_chi_square_independence) { dialog_chi_square_tool (wbcg, wbcg_cur_sheet
(wbcg), TRUE); }
@@ -2912,6 +2913,11 @@ static GnmActionEntry const actions[] = {
"simulation to find out probable outputs and risks related to them"),
.callback = G_CALLBACK (cb_tools_simulation)
},
+ { .name = "ToolsCompare",
+ .label = N_("Compare Sheets..."),
+ .tooltip = N_("Find differences between two sheets"),
+ .callback = G_CALLBACK (cb_tools_compare)
+ },
/* Tools -> Scenarios */
{ .name = "ToolsScenarios",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]