Commit 0ceb0096 authored by Andreas J. Guelzow 's avatar Andreas J. Guelzow

Redesign autofilter Top10 dialog. [#646641]

2011-04-10  Andreas J. Guelzow <aguelzow@pyrshep.ca>

	* autofilter-top10.ui: redesign
	* dialog-autofilter.c (type_group): new
	(autofilter_get_type): new
	(cb_autofilter_ok): access radio buttons
	(cb_top10_count_changed): new
	(cb_autofilter_ok): access radio buttons
	(cb_top10_type_changed): use autofilter_get_type
	(dialog_auto_filter_get_col_name): new
	(dialog_auto_filter): split into dialog_auto_filter and
	(dialog_auto_filter_expression): extracted from dialog_auto_filter
parent 4a82482d
......@@ -3,6 +3,7 @@ Gnumeric 1.10.15
Andreas:
* Fix shift-arrow movement for sheet objects. [#645805]
* Expand the description of SSMEDIAN. [#647247]
* Redesign autofilter Top10 dialog. [#646641]
Morten:
* Fix problems with localized function docs.
......
2011-04-10 Andreas J. Guelzow <aguelzow@pyrshep.ca>
* autofilter-top10.ui: redesign
* dialog-autofilter.c (type_group): new
(autofilter_get_type): new
(cb_autofilter_ok): access radio buttons
(cb_top10_count_changed): new
(cb_autofilter_ok): access radio buttons
(cb_top10_type_changed): use autofilter_get_type
(dialog_auto_filter_get_col_name): new
(dialog_auto_filter): split into dialog_auto_filter and
(dialog_auto_filter_expression): extracted from dialog_auto_filter
2011-04-04 Andreas J. Guelzow <aguelzow@pyrshep.ca>
* dialog-define-names.c (name_guru_init): use the correct key
......
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
......@@ -41,11 +41,9 @@
<property name="title" translatable="yes">Gnumeric : AutoFilter</property>
<property name="window_position">mouse</property>
<property name="type_hint">normal</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="col-label">
......@@ -65,12 +63,7 @@
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Show:</property>
<accessibility>
<relation type="label-for" target="top_vs_bottom_option_menu"/>
<relation type="label-for" target="item_vs_percentage_option_menu"/>
<relation type="label-for" target="item_count"/>
</accessibility>
<property name="label" translatable="yes">Count or percentage:</property>
</object>
<packing>
<property name="expand">False</property>
......@@ -78,76 +71,15 @@
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="yscale">0</property>
<child>
<object class="GtkComboBox" id="top_vs_bottom_option_menu">
<property name="visible">True</property>
<property name="model">model1</property>
<accessibility>
<relation type="labelled-by" target="label1"/>
<relation type="label-for" target="item_vs_percentage_option_menu"/>
<relation type="label-for" target="item_count"/>
</accessibility>
<child>
<object class="GtkCellRendererText" id="renderer1"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="item_count">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">adjustment1</property>
<property name="climb_rate">1</property>
<accessibility>
<relation type="labelled-by" target="top_vs_bottom_option_menu"/>
<relation type="labelled-by" target="label1"/>
<relation type="label-for" target="item_vs_percentage_option_menu"/>
</accessibility>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="yscale">0</property>
<child>
<object class="GtkComboBox" id="item_vs_percentage_option_menu">
<property name="visible">True</property>
<property name="model">model2</property>
<accessibility>
<relation type="labelled-by" target="top_vs_bottom_option_menu"/>
<relation type="labelled-by" target="label1"/>
<relation type="labelled-by" target="item_count"/>
</accessibility>
<child>
<object class="GtkCellRendererText" id="renderer2"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
<property name="position">1</property>
</packing>
</child>
</object>
......@@ -157,6 +89,65 @@
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="items-largest">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="items-smallest">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">items-largest</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="percentage-largest">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">items-largest</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="percentage-smallest">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">items-largest</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">6</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
......
......@@ -53,6 +53,22 @@ typedef struct {
#define DIALOG_KEY_EXPRESSION "autofilter-expression"
#define UNICODE_ELLIPSIS "\xe2\x80\xa6"
static char const * const type_group[] = {
"items-largest",
"items-smallest",
"percentage-largest",
"percentage-smallest",
NULL
};
static GnmFilterOp
autofilter_get_type (AutoFilterState *state)
{
return (GNM_FILTER_OP_TYPE_BUCKETS |
gnm_gui_group_value (state->gui, type_group));
}
static void
cb_autofilter_destroy (AutoFilterState *state)
{
......@@ -133,27 +149,28 @@ cb_autofilter_ok (G_GNUC_UNUSED GtkWidget *button,
GnmFilterOp op1;
GnmValue *v1 = map_op (state, &op1, "op1", "value1");
if (op1 != GNM_FILTER_UNUSED) {
w = go_gtk_builder_get_widget (state->gui, "and_button");
cond = gnm_filter_condition_new_double (op0, v0,
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)),
op1, v1);
w = go_gtk_builder_get_widget (state->gui,
"and_button");
cond = gnm_filter_condition_new_double
(op0, v0,
gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (w)),
op1, v1);
} else
cond = gnm_filter_condition_new_single (op0, v0);
cond = gnm_filter_condition_new_single
(op0, v0);
}
} else {
int bottom, percentage, count;
w = go_gtk_builder_get_widget (state->gui, "top_vs_bottom_option_menu");
bottom = gtk_combo_box_get_active (GTK_COMBO_BOX (w));
w = go_gtk_builder_get_widget (state->gui, "item_vs_percentage_option_menu");
percentage = gtk_combo_box_get_active (GTK_COMBO_BOX (w));
int count;
GnmFilterOp op = autofilter_get_type (state);
w = go_gtk_builder_get_widget (state->gui, "item_count");
count = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w));
if (bottom >= 0 && percentage >= 0)
cond = gnm_filter_condition_new_bucket (
!bottom, !percentage, count);
cond = gnm_filter_condition_new_bucket
(!(op & GNM_FILTER_OP_BOTTOM_MASK),
!(op & GNM_FILTER_OP_PERCENT_MASK),
count);
}
if (cond != NULL)
cmd_autofilter_set_condition (WORKBOOK_CONTROL (state->wbcg),
......@@ -171,13 +188,68 @@ cb_autofilter_cancel (G_GNUC_UNUSED GtkWidget *button,
}
static void
cb_top10_type_changed (GtkComboBox *menu,
cb_top10_count_changed (GtkSpinButton *button,
AutoFilterState *state)
{
int val = 0.5 + gtk_spin_button_get_value (button);
GtkWidget *w;
gchar *label;
w = go_gtk_builder_get_widget (state->gui, type_group[0]);
/* xgettext : %d gives the number of items in the autofilter. */
/* This is input to ngettext. */
label = g_strdup_printf (ngettext ("Show the largest item",
"Show the %3d largest items", val),
val);
gtk_button_set_label (GTK_BUTTON (w),label);
g_free(label);
w = go_gtk_builder_get_widget (state->gui, type_group[1]);
/* xgettext : %d gives the number of items in the autofilter. */
/* This is input to ngettext. */
label = g_strdup_printf (ngettext ("Show the smallest item",
"Show the %3d smallest items", val),
val);
gtk_button_set_label (GTK_BUTTON (w),label);
g_free(label);
if (val > 100)
val = 100;
w = go_gtk_builder_get_widget (state->gui, type_group[2]);
/* xgettext : %d gives the percentage of items in the autofilter. */
/* This is input to ngettext. */
label = g_strdup_printf
(ngettext ("Show the largest %3d%% of the items",
"Show the largest %3d%% of the items", val),
val);
gtk_button_set_label (GTK_BUTTON (w),label);
g_free(label);
w = go_gtk_builder_get_widget (state->gui, type_group[3]);
/* xgettext : %d gives the percentage of items in the autofilter. */
/* This is input to ngettext. */
label = g_strdup_printf
(ngettext ("Show the smallest %3d%% of the items",
"Show the smallest %3d%% of the items", val),
val);
gtk_button_set_label (GTK_BUTTON (w),label);
g_free(label);
}
static void
cb_top10_type_changed (G_GNUC_UNUSED GtkToggleButton *button,
AutoFilterState *state)
{
GnmFilterOp op = autofilter_get_type (state);
GtkWidget *spin = go_gtk_builder_get_widget (state->gui, "item_count");
gtk_spin_button_set_range (GTK_SPIN_BUTTON (spin), 1.,
(gtk_combo_box_get_active (menu) > 0) ? 100. : 500.);
(op == GNM_FILTER_OP_TOP_N_PERCENT ||
op == GNM_FILTER_OP_BOTTOM_N_PERCENT) ? 100.
: 500.);
}
static void
......@@ -225,10 +297,25 @@ init_operator (AutoFilterState *state, GnmFilterOp op, GnmValue const *v,
g_free (content);
}
void
dialog_auto_filter (WBCGtk *wbcg,
GnmFilter *filter, int field,
gboolean is_expr, GnmFilterCondition *cond)
static gchar *
dialog_auto_filter_get_col_name (GnmCell *cell, int col, int len)
{
gchar *label;
char *content = gnm_cell_get_rendered_text (cell);
if (g_utf8_strlen (content, -1) > len) {
char *end = g_utf8_find_prev_char
(content, content + len + 1 - strlen (UNICODE_ELLIPSIS));
strcpy (end, UNICODE_ELLIPSIS);
}
label = g_strdup_printf (_("Column %s (\"%s\")"),
col_name (col), content);
g_free (content);
return label;
}
static void
dialog_auto_filter_expression (WBCGtk *wbcg,
GnmFilter *filter, int field,
GnmFilterCondition *cond)
{
AutoFilterState *state;
GtkWidget *w;
......@@ -236,14 +323,14 @@ dialog_auto_filter (WBCGtk *wbcg,
int col;
gchar *label;
GnmCell *cell;
int len = is_expr ? 15 : 30;
int const len = 15;
g_return_if_fail (wbcg != NULL);
if (gnumeric_dialog_raise_if_exists
(wbcg, is_expr ? DIALOG_KEY_EXPRESSION : DIALOG_KEY))
(wbcg, DIALOG_KEY_EXPRESSION))
return;
gui = gnm_gtk_builder_new ((is_expr ? "autofilter-expression.ui" : "autofilter-top10.ui"),
gui = gnm_gtk_builder_new ("autofilter-expression.ui",
NULL, GO_CMD_CONTEXT (wbcg));
if (gui == NULL)
return;
......@@ -252,7 +339,7 @@ dialog_auto_filter (WBCGtk *wbcg,
state->wbcg = wbcg;
state->filter = filter;
state->field = field;
state->is_expr = is_expr;
state->is_expr = TRUE;
state->gui = gui;
g_return_if_fail (state->gui != NULL);
......@@ -263,36 +350,19 @@ dialog_auto_filter (WBCGtk *wbcg,
if (cell == NULL || gnm_cell_is_blank (cell))
label = g_strdup_printf (_("Column %s"), col_name (col));
else {
char *content = gnm_cell_get_rendered_text (cell);
if (g_utf8_strlen (content, -1) > len) {
char *end = g_utf8_find_prev_char (content, content + len + 1 - strlen (UNICODE_ELLIPSIS));
strcpy (end, UNICODE_ELLIPSIS);
}
label = g_strdup_printf (_("Column %s (\"%s\")"),
col_name (col), content);
g_free (content);
}
else
label = dialog_auto_filter_get_col_name (cell, col, len);
if (is_expr) {
gtk_label_set_text
(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label1")), label);
gtk_label_set_text
(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label2")), label);
} else {
gtk_label_set_text
(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label")), label);
w = go_gtk_builder_get_widget (state->gui, "item_vs_percentage_option_menu");
g_signal_connect (G_OBJECT (w),
"changed",
G_CALLBACK (cb_top10_type_changed), state);
}
gtk_label_set_text
(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label1")), label);
gtk_label_set_text
(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label2")), label);
g_free (label);
state->dialog = go_gtk_builder_get_widget (state->gui, "dialog");
if (cond != NULL) {
GnmFilterOp const op = cond->op[0];
if (is_expr && 0 == (op & GNM_FILTER_OP_TYPE_MASK)) {
if (0 == (op & GNM_FILTER_OP_TYPE_MASK)) {
init_operator (state, cond->op[0],
cond->value[0], "op0", "value0");
if (cond->op[1] != GNM_FILTER_UNUSED)
......@@ -301,30 +371,136 @@ dialog_auto_filter (WBCGtk *wbcg,
w = go_gtk_builder_get_widget (state->gui,
cond->is_and ? "and_button" : "or_button");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
} else if (!is_expr &&
GNM_FILTER_OP_TOP_N == (op & GNM_FILTER_OP_TYPE_MASK)) {
w = go_gtk_builder_get_widget (state->gui, "top_vs_bottom_option_menu");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), (op & 1) ? 1 : 0);
w = go_gtk_builder_get_widget (state->gui, "item_vs_percentage_option_menu");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), (op & 2) ? 1 : 0);
w = go_gtk_builder_get_widget (state->gui, "item_count");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (w),
cond->count);
}
} else {
/* initialize the combo boxes (not done by li.ui) */
if (is_expr) {
w = go_gtk_builder_get_widget (state->gui, "op0");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
w = go_gtk_builder_get_widget (state->gui, "op1");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
} else {
w = go_gtk_builder_get_widget (state->gui, "top_vs_bottom_option_menu");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
w = go_gtk_builder_get_widget (state->gui, "item_vs_percentage_option_menu");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
w = go_gtk_builder_get_widget (state->gui, "op0");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
w = go_gtk_builder_get_widget (state->gui, "op1");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
}
w = go_gtk_builder_get_widget (state->gui, "ok_button");
g_signal_connect (G_OBJECT (w),
"clicked",
G_CALLBACK (cb_autofilter_ok), state);
w = go_gtk_builder_get_widget (state->gui, "cancel_button");
g_signal_connect (G_OBJECT (w),
"clicked",
G_CALLBACK (cb_autofilter_cancel), state);
/* a candidate for merging into attach guru */
gnumeric_init_help_button (
go_gtk_builder_get_widget (state->gui, "help_button"),
GNUMERIC_HELP_LINK_AUTOFILTER_CUSTOM);
gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
state->wbcg,
GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED);
wbc_gtk_attach_guru (state->wbcg, state->dialog);
g_object_set_data_full (G_OBJECT (state->dialog),
"state", state, (GDestroyNotify)cb_autofilter_destroy);
gnumeric_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
DIALOG_KEY_EXPRESSION);
gtk_widget_show (state->dialog);
}
void
dialog_auto_filter (WBCGtk *wbcg,
GnmFilter *filter, int field,
gboolean is_expr, GnmFilterCondition *cond)
{
AutoFilterState *state;
GtkWidget *w;
GtkBuilder *gui;
int col;
gchar *label;
GnmCell *cell;
int len = is_expr ? 15 : 30;
char const * const *rb;
if (is_expr) {
dialog_auto_filter_expression (wbcg, filter, field, cond);
return;
}
g_return_if_fail (wbcg != NULL);
if (gnumeric_dialog_raise_if_exists (wbcg, DIALOG_KEY))
return;
gui = gnm_gtk_builder_new ("autofilter-top10.ui",
NULL, GO_CMD_CONTEXT (wbcg));
if (gui == NULL)
return;
state = g_new (AutoFilterState, 1);
state->wbcg = wbcg;
state->filter = filter;
state->field = field;
state->is_expr = FALSE;
state->gui = gui;
g_return_if_fail (state->gui != NULL);
col = filter->r.start.col + field;
cell = sheet_cell_get (filter->sheet, col, filter->r.start.row);
if (cell == NULL || gnm_cell_is_blank (cell))
label = g_strdup_printf (_("Column %s"), col_name (col));
else
label = dialog_auto_filter_get_col_name (cell, col, len);
gtk_label_set_text
(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label")), label);
g_free (label);
state->dialog = go_gtk_builder_get_widget (state->gui, "dialog");
if (cond != NULL && GNM_FILTER_OP_TOP_N == (cond->op[0] & GNM_FILTER_OP_TYPE_MASK)) {
gchar const *radio = NULL;
switch (cond->op[0]) {
case GNM_FILTER_OP_TOP_N:
default:
radio = type_group[0];
break;
case GNM_FILTER_OP_BOTTOM_N:
radio = type_group[1];
break;
case GNM_FILTER_OP_TOP_N_PERCENT:
radio = type_group[2];
break;
case GNM_FILTER_OP_BOTTOM_N_PERCENT:
radio = type_group[3];
break;
}
w = go_gtk_builder_get_widget (state->gui, radio);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
w = go_gtk_builder_get_widget (state->gui, "item_count");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), cond->count);
} else {
w = go_gtk_builder_get_widget (state->gui, "items-largest");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
w = go_gtk_builder_get_widget (state->gui, "item_count");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), 1);
}
g_signal_connect (G_OBJECT (w),
"value-changed",
G_CALLBACK (cb_top10_count_changed), state);
cb_top10_count_changed (GTK_SPIN_BUTTON (w), state);
rb = type_group;
while (*rb != NULL) {
w = go_gtk_builder_get_widget (state->gui, *rb);
g_signal_connect (G_OBJECT (w),
"toggled",
G_CALLBACK (cb_top10_type_changed), state);
rb++;
}
cb_top10_type_changed (NULL, state);
w = go_gtk_builder_get_widget (state->gui, "ok_button");
g_signal_connect (G_OBJECT (w),
......@@ -338,7 +514,6 @@ dialog_auto_filter (WBCGtk *wbcg,
/* a candidate for merging into attach guru */
gnumeric_init_help_button (
go_gtk_builder_get_widget (state->gui, "help_button"),
is_expr ? GNUMERIC_HELP_LINK_AUTOFILTER_CUSTOM :
GNUMERIC_HELP_LINK_AUTOFILTER_TOP_TEN);
gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
......@@ -350,6 +525,6 @@ dialog_auto_filter (WBCGtk *wbcg,
"state", state, (GDestroyNotify)cb_autofilter_destroy);
gnumeric_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
is_expr ? DIALOG_KEY_EXPRESSION : DIALOG_KEY);
DIALOG_KEY);
gtk_widget_show (state->dialog);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment