1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
4 * dialog-define-name.c: Edit named regions.
7 * Jody Goldberg <jody@gnome.org>
8 * Michael Meeks <michael@ximian.com>
9 * Chema Celorio <chema@celorio.com>
10 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses/>.
25 #include <gnumeric-config.h>
26 #include <glib/gi18n-lib.h>
32 #include <expr-name.h>
33 #include <selection.h>
35 #include <sheet-view.h>
37 #include <workbook-control.h>
39 #include <workbook-view.h>
41 #include <parse-util.h>
43 #include <widgets/gnumeric-expr-entry.h>
44 #include <widgets/gnumeric-cell-renderer-expr-entry.h>
45 #include <widgets/gnumeric-cell-renderer-toggle.h>
50 #define DEFINE_NAMES_KEY "define-names-dialog"
51 #define PASTE_NAMES_KEY "paste-names-dialog"
58 GtkTreeModel
*model_f
;
60 GtkWidget
*close_button
;
61 GtkWidget
*paste_button
;
62 GtkWidget
*search_entry
;
71 GdkPixbuf
*image_delete
;
72 GdkPixbuf
*image_lock
;
74 GdkPixbuf
*image_down
;
75 GdkPixbuf
*image_paste
;
77 gboolean is_paste_dialog
;
86 ITEM_CONTENT_IS_EDITABLE
,
87 ITEM_NAME_IS_EDITABLE
,
91 ITEM_ADDDELETE_ACTIVE
,
99 item_type_workbook
= 0,
100 item_type_main_sheet
,
101 item_type_other_sheet
,
102 item_type_locked_name
,
103 item_type_available_wb_name
,
104 item_type_available_sheet_name
,
105 item_type_foreign_name
,
106 item_type_new_unsaved_wb_name
,
107 item_type_new_unsaved_sheet_name
,
112 * name_guru_translate_pathstring_to_iter:
114 * @path_string: in the filter_model
115 * @iter: in the base model
120 name_guru_translate_pathstring_to_iter (NameGuruState
*state
,
122 gchar
const *path_string
)
126 if (!gtk_tree_model_get_iter_from_string
127 (state
->model_f
, &iter_f
, path_string
))
130 gtk_tree_model_filter_convert_iter_to_child_iter
131 (GTK_TREE_MODEL_FILTER (state
->model_f
), iter
, &iter_f
);
139 * name_guru_expand_at_iter:
143 * expand the treeview at the given iter.
147 name_guru_expand_at_iter (NameGuruState
*state
, GtkTreeIter
*iter
)
151 path
= gtk_tree_model_get_path
152 (GTK_TREE_MODEL (state
->model
), iter
);
153 gtk_tree_view_expand_to_path
154 (GTK_TREE_VIEW (state
->treeview
), path
);
155 gtk_tree_path_free (path
);
160 * name_guru_warned_if_used:
162 * @nexpr: expression to be deleted
164 * If the expresion that is about to be deleted is being used,
165 * warn the user about it. Ask if we should proceed or not
167 * Return Value: TRUE if users confirms deletion, FALSE otherwise
171 name_guru_warn (NameGuruState
*state
,
174 return (!expr_name_in_use (nexpr
) ||
176 (GTK_WINDOW (state
->dialog
), FALSE
,
177 "The defined name '%s' is in use. "
178 "Do you really want to delete it?",
179 expr_name_name (nexpr
)));
183 cb_name_guru_show_all (G_GNUC_UNUSED GtkTreeModel
*model
,
184 G_GNUC_UNUSED GtkTreePath
*path
,
185 GtkTreeIter
*iter
, gpointer data
)
187 NameGuruState
*state
= data
;
188 gtk_tree_store_set (state
->model
, iter
,
195 name_guru_erase_search_entry (GtkEntry
*entry
,
196 G_GNUC_UNUSED GtkEntryIconPosition icon_pos
,
197 G_GNUC_UNUSED GdkEvent
*event
,
200 NameGuruState
*state
= data
;
201 gtk_entry_set_text (entry
, "");
202 gtk_tree_model_foreach (GTK_TREE_MODEL (state
->model
),
203 cb_name_guru_show_all
, state
);
207 cb_name_guru_search (GtkTreeModel
*model
,
208 G_GNUC_UNUSED GtkTreePath
*path
,
209 GtkTreeIter
*iter
, gpointer data
)
211 char const *text
= data
;
213 gboolean visible
= TRUE
, was_visible
;
216 gtk_tree_model_get (model
, iter
,
219 ITEM_VISIBLE
, &was_visible
,
222 if (type
!= item_type_workbook
&&
223 type
!= item_type_main_sheet
&&
224 type
!= item_type_other_sheet
) {
225 gchar
*name_n
, *name_cf
, *text_n
, *text_cf
;
227 text_n
= g_utf8_normalize (text
, -1, G_NORMALIZE_ALL
);
228 text_cf
= g_utf8_casefold(text_n
, -1);
229 name_n
= g_utf8_normalize (name
, -1, G_NORMALIZE_ALL
);
230 name_cf
= g_utf8_casefold(name_n
, -1);
231 visible
= (NULL
!= g_strstr_len (name_cf
, -1, text_cf
));
238 if (visible
!= was_visible
)
239 gtk_tree_store_set (GTK_TREE_STORE (model
), iter
,
240 ITEM_VISIBLE
, visible
,
248 name_guru_search (GtkEntry
*entry
, gpointer data
)
251 NameGuruState
*state
= data
;
253 if (0 == gtk_entry_get_text_length (entry
)){
254 name_guru_erase_search_entry
256 GTK_ENTRY_ICON_SECONDARY
, NULL
,
260 text
= gtk_entry_get_text (entry
);
261 gtk_tree_model_foreach (GTK_TREE_MODEL (state
->model
),
262 cb_name_guru_search
, (gpointer
) text
);
266 cb_get_names (G_GNUC_UNUSED gpointer key
, GnmNamedExpr
*nexpr
,
269 if (!nexpr
->is_hidden
)
270 *accum
= g_list_prepend (*accum
, nexpr
);
274 name_guru_get_available_sheet_names (Sheet
const *sheet
)
278 gnm_sheet_foreach_name (sheet
, (GHFunc
) cb_get_names
, &res
);
279 return g_list_sort (res
, (GCompareFunc
)expr_name_cmp_by_name
);
283 name_guru_get_available_wb_names (Workbook
const *wb
)
287 workbook_foreach_name (wb
, TRUE
,
288 (GHFunc
) cb_get_names
,
290 return g_list_sort (res
, (GCompareFunc
)expr_name_cmp_by_name
);
294 name_guru_set_images (NameGuruState
*state
, GtkTreeIter
*name_iter
,
295 item_type_t type
, gboolean pastable
)
297 GdkPixbuf
*button1
= NULL
, *button2
= NULL
;
300 case item_type_workbook
:
301 case item_type_main_sheet
:
302 button2
= state
->image_add
;
304 case item_type_locked_name
:
305 button2
= state
->image_lock
;
307 case item_type_available_wb_name
:
308 case item_type_new_unsaved_wb_name
:
309 button1
= state
->image_down
;
310 button2
= state
->image_delete
;
312 case item_type_available_sheet_name
:
313 case item_type_new_unsaved_sheet_name
:
314 button1
= state
->image_up
;
315 button2
= state
->image_delete
;
317 case item_type_other_sheet
:
318 case item_type_foreign_name
:
323 gtk_tree_store_set (state
->model
, name_iter
,
324 ITEM_UPDOWN_IMAGE
, button1
,
325 ITEM_ADDDELETE_IMAGE
, button2
,
327 pastable
? state
->image_paste
: NULL
,
328 ITEM_UPDOWN_ACTIVE
, button1
!= NULL
,
329 ITEM_ADDDELETE_ACTIVE
, button2
!= NULL
,
334 name_guru_store_names (GList
*list
,
336 NameGuruState
*state
,
339 GtkTreeIter name_iter
;
341 item_type_t adj_type
;
344 for (l
= list
; l
!= NULL
; l
= l
->next
) {
345 GnmNamedExpr
*nexpr
= l
->data
;
346 gboolean ciseditable
, ispastable
;
348 if (nexpr
->is_hidden
|| expr_name_is_placeholder (nexpr
))
351 ispastable
= ciseditable
=
352 type
== item_type_available_wb_name
353 || type
== item_type_available_sheet_name
;
355 if (nexpr
->is_permanent
) {
356 adj_type
= item_type_locked_name
;
361 content
= expr_name_as_string (nexpr
, &state
->pp
,
362 sheet_get_conventions (state
->sheet
));
365 gtk_tree_store_append (state
->model
, &name_iter
,
367 gtk_tree_store_set (state
->model
, &name_iter
,
368 ITEM_NAME
, expr_name_name (nexpr
),
369 ITEM_NAME_POINTER
, nexpr
,
370 ITEM_CONTENT
, content
,
372 ITEM_CONTENT_IS_EDITABLE
, ciseditable
,
373 ITEM_NAME_IS_EDITABLE
, FALSE
,
374 ITEM_PASTABLE
, ispastable
,
379 name_guru_set_images (state
, &name_iter
, adj_type
, ispastable
);
385 name_guru_populate_list (NameGuruState
*state
)
389 g_return_if_fail (state
!= NULL
);
390 g_return_if_fail (state
->treeview
!= NULL
);
392 gtk_tree_store_clear (state
->model
);
394 gtk_tree_store_append (state
->model
, &iter
, NULL
);
395 gtk_tree_store_set (state
->model
, &iter
,
396 ITEM_NAME
, _("Workbook"),
397 ITEM_NAME_POINTER
, NULL
,
398 ITEM_TYPE
, item_type_workbook
,
399 ITEM_CONTENT_IS_EDITABLE
, FALSE
,
400 ITEM_NAME_IS_EDITABLE
, FALSE
,
401 ITEM_PASTABLE
, FALSE
,
404 name_guru_set_images (state
, &iter
, item_type_workbook
, FALSE
);
405 name_guru_store_names (name_guru_get_available_wb_names (state
->wb
),
408 item_type_available_wb_name
);
409 name_guru_expand_at_iter (state
, &iter
);
411 gtk_tree_store_append (state
->model
, &iter
, NULL
);
412 gtk_tree_store_set (state
->model
, &iter
,
413 ITEM_NAME
, state
->sheet
->name_unquoted
,
414 ITEM_NAME_POINTER
, state
->sheet
,
415 ITEM_TYPE
, item_type_main_sheet
,
416 ITEM_CONTENT_IS_EDITABLE
, FALSE
,
417 ITEM_NAME_IS_EDITABLE
, FALSE
,
418 ITEM_PASTABLE
, FALSE
,
421 name_guru_set_images (state
, &iter
, item_type_main_sheet
, FALSE
);
423 name_guru_store_names (name_guru_get_available_sheet_names
427 item_type_available_sheet_name
);
428 name_guru_expand_at_iter (state
, &iter
);
430 WORKBOOK_FOREACH_SHEET
433 if (sheet
== state
->sheet
)
436 gtk_tree_store_append (state
->model
, &iter
, NULL
);
437 gtk_tree_store_set (state
->model
, &iter
,
438 ITEM_NAME
, sheet
->name_unquoted
,
439 ITEM_NAME_POINTER
, sheet
,
440 ITEM_TYPE
, item_type_other_sheet
,
441 ITEM_CONTENT_IS_EDITABLE
, FALSE
,
442 ITEM_NAME_IS_EDITABLE
, FALSE
,
444 ITEM_PASTABLE
, FALSE
,
447 name_guru_store_names
448 (name_guru_get_available_sheet_names (sheet
),
449 &iter
, state
, item_type_foreign_name
);
454 name_guru_paste (NameGuruState
*state
, GtkTreeIter
*iter
)
457 gboolean is_pastable
;
459 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
),
461 ITEM_PASTABLE
, &is_pastable
,
468 if (wbcg_edit_start (state
->wbcg
, FALSE
, FALSE
)) {
471 entry
= wbcg_get_entry (state
->wbcg
);
473 position
= gtk_entry_get_text_length (entry
);
475 gtk_editable_insert_text (GTK_EDITABLE (entry
), "=",
478 gtk_editable_delete_selection (GTK_EDITABLE (entry
));
479 position
= gtk_editable_get_position
480 (GTK_EDITABLE (entry
));
482 if (state
->has_pasted
) {
483 char sep
= go_locale_get_arg_sep ();
484 gtk_editable_insert_text (GTK_EDITABLE (entry
), &sep
,
487 gtk_editable_insert_text (GTK_EDITABLE (entry
), name
,
489 gtk_editable_set_position (GTK_EDITABLE (entry
), position
);
494 state
->has_pasted
= TRUE
;
502 cb_name_guru_clicked (GtkWidget
*button
, NameGuruState
*state
)
504 if (state
->dialog
== NULL
)
507 wbcg_set_entry (state
->wbcg
, NULL
);
509 if (button
== state
->close_button
) {
510 gtk_widget_destroy (state
->dialog
);
513 if (button
== state
->paste_button
) {
516 if (gtk_tree_selection_get_selected
517 (gtk_tree_view_get_selection
518 (GTK_TREE_VIEW (state
->treeview
)), NULL
, &iter_f
)) {
519 gtk_tree_model_filter_convert_iter_to_child_iter
520 (GTK_TREE_MODEL_FILTER (state
->model_f
),
522 if (name_guru_paste (state
, &iter
))
523 gtk_widget_destroy (state
->dialog
);
530 name_guru_init_button (NameGuruState
*state
, char const *name
)
532 GtkWidget
*tmp
= go_gtk_builder_get_widget (state
->gui
, name
);
534 g_return_val_if_fail (tmp
!= NULL
, NULL
);
536 g_signal_connect (G_OBJECT (tmp
),
538 G_CALLBACK (cb_name_guru_clicked
), state
);
543 cb_name_guru_destroy (NameGuruState
*state
)
545 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
547 wb_view_selection_desc (wb_control_view (wbc
), TRUE
, wbc
);
548 g_clear_object (&state
->gui
);
549 g_clear_object (&state
->model
);
551 if (!state
->is_paste_dialog
)
552 wbcg_edit_finish (state
->wbcg
, WBC_EDIT_REJECT
, NULL
);
554 g_clear_object (&state
->image_paste
);
555 g_clear_object (&state
->image_add
);
556 g_clear_object (&state
->image_delete
);
557 g_clear_object (&state
->image_lock
);
558 g_clear_object (&state
->image_up
);
559 g_clear_object (&state
->image_down
);
561 state
->dialog
= NULL
;
567 cb_name_guru_paste (G_GNUC_UNUSED GtkCellRendererToggle
*cell
,
571 NameGuruState
*state
= data
;
574 if (name_guru_translate_pathstring_to_iter
575 (state
, &iter
, path_string
))
576 name_guru_paste (state
, &iter
);
580 name_guru_add (NameGuruState
*state
, GtkTreeIter
*iter
, gchar
const *path_string
)
582 GtkTreeIter name_iter
;
587 path
= gtk_tree_path_new_from_string (path_string
);
589 type
= ((gtk_tree_path_get_indices (path
))[0] == 0) ?
590 item_type_new_unsaved_wb_name
:
591 item_type_new_unsaved_sheet_name
;
592 content
= selection_to_string (state
->sv
, FALSE
);
594 gtk_tree_store_insert (state
->model
, &name_iter
,
596 gtk_tree_store_set (state
->model
, &name_iter
,
597 ITEM_NAME
, _("<new name>"),
598 ITEM_NAME_POINTER
, NULL
,
600 ((content
== NULL
) ? "#REF!" : content
),
602 ITEM_CONTENT_IS_EDITABLE
, TRUE
,
603 ITEM_NAME_IS_EDITABLE
, TRUE
,
604 ITEM_PASTABLE
, FALSE
,
607 name_guru_set_images (state
, &name_iter
, type
, FALSE
);
608 name_guru_expand_at_iter (state
, iter
);
613 name_guru_delete (NameGuruState
*state
, GtkTreeIter
*iter
, item_type_t type
)
617 if (type
!= item_type_new_unsaved_wb_name
&&
618 type
!= item_type_new_unsaved_sheet_name
) {
619 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
),
621 ITEM_NAME_POINTER
, &nexpr
,
624 if (!name_guru_warn (state
, nexpr
))
627 cmd_remove_name (GNM_WBC (state
->wbcg
), nexpr
);
629 gtk_tree_store_remove (state
->model
, iter
);
634 cb_name_guru_add_delete (G_GNUC_UNUSED GtkCellRendererToggle
*cell
,
638 NameGuruState
*state
= data
;
641 if (name_guru_translate_pathstring_to_iter
642 (state
, &iter
, path_string
)) {
645 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
),
651 case item_type_workbook
:
652 case item_type_main_sheet
:
653 name_guru_add (state
, &iter
, path_string
);
655 case item_type_available_wb_name
:
656 case item_type_available_sheet_name
:
657 case item_type_new_unsaved_wb_name
:
658 case item_type_new_unsaved_sheet_name
:
659 name_guru_delete (state
, &iter
, type
);
661 case item_type_other_sheet
:
662 case item_type_locked_name
:
663 case item_type_foreign_name
:
671 name_guru_find_place (NameGuruState
*state
, GtkTreeIter
*iter
,
672 GtkTreeIter
*parent_iter
, GnmNamedExpr
*nexpr
)
674 GtkTreeIter next_iter
;
675 GnmNamedExpr
*next_nexpr
;
677 gtk_tree_model_iter_children (GTK_TREE_MODEL (state
->model
),
681 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
),
683 ITEM_NAME_POINTER
, &next_nexpr
,
685 if (next_nexpr
!= NULL
&&
686 expr_name_cmp_by_name (nexpr
, next_nexpr
) < 0) {
687 gtk_tree_store_insert_before
694 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (state
->model
),
697 gtk_tree_store_append (state
->model
, iter
,
700 gtk_tree_store_prepend (state
->model
, iter
,
707 name_guru_move_record (NameGuruState
*state
, GtkTreeIter
*from_iter
,
708 GtkTreeIter
*new_parent_iter
, item_type_t new_type
)
711 gchar
*name
, *content
;
712 gboolean ceditable
, neditable
, pastable
, visible
;
713 GtkTreeIter new_iter
;
715 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
),
718 ITEM_NAME_POINTER
, &nexpr
,
719 ITEM_CONTENT
, &content
,
720 ITEM_CONTENT_IS_EDITABLE
, &ceditable
,
721 ITEM_NAME_IS_EDITABLE
, &neditable
,
722 ITEM_PASTABLE
, &pastable
,
723 ITEM_VISIBLE
, &visible
,
726 gtk_tree_store_remove (state
->model
, from_iter
);
728 name_guru_find_place (state
, &new_iter
, new_parent_iter
, nexpr
);
730 gtk_tree_store_set (state
->model
, &new_iter
,
732 ITEM_NAME_POINTER
, nexpr
,
733 ITEM_CONTENT
, content
,
735 ITEM_CONTENT_IS_EDITABLE
, ceditable
,
736 ITEM_NAME_IS_EDITABLE
, neditable
,
737 ITEM_PASTABLE
, pastable
,
738 ITEM_VISIBLE
, visible
,
740 name_guru_set_images (state
, &new_iter
, new_type
, pastable
);
741 name_guru_expand_at_iter (state
, &new_iter
);
747 cb_name_guru_switch_scope (G_GNUC_UNUSED GtkCellRendererToggle
*cell
,
751 NameGuruState
*state
= data
;
754 if (name_guru_translate_pathstring_to_iter
755 (state
, &iter
, path_string
)) {
756 item_type_t type
, new_type
;
757 gchar
const *new_path
;
759 GtkTreeIter new_parent_iter
;
761 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
),
764 ITEM_NAME_POINTER
, &nexpr
,
768 case item_type_available_wb_name
:
770 (GNM_WBC (state
->wbcg
),
771 nexpr
, state
->sheet
))
774 new_type
= item_type_available_sheet_name
;
776 case item_type_new_unsaved_wb_name
:
778 new_type
= item_type_new_unsaved_sheet_name
;
780 case item_type_available_sheet_name
:
782 (GNM_WBC (state
->wbcg
),
786 new_type
= item_type_available_wb_name
;
788 case item_type_new_unsaved_sheet_name
:
790 new_type
= item_type_new_unsaved_wb_name
;
792 case item_type_workbook
:
793 case item_type_main_sheet
:
794 case item_type_other_sheet
:
795 case item_type_locked_name
:
796 case item_type_foreign_name
:
801 if (gtk_tree_model_get_iter_from_string
802 (GTK_TREE_MODEL (state
->model
),
803 &new_parent_iter
, new_path
)) {
804 name_guru_move_record
805 (state
, &iter
, &new_parent_iter
, new_type
);
811 name_guru_parse_pos_init (NameGuruState
*state
,
812 GnmParsePos
*pp
, item_type_t type
)
815 case item_type_available_wb_name
:
816 case item_type_new_unsaved_wb_name
:
817 parse_pos_init (pp
, state
->wb
, NULL
,
818 state
->pp
.eval
.col
, state
->pp
.eval
.row
);
820 case item_type_available_sheet_name
:
821 case item_type_new_unsaved_sheet_name
:
822 parse_pos_init (pp
, state
->wb
, state
->sheet
,
823 state
->pp
.eval
.col
, state
->pp
.eval
.row
);
825 case item_type_workbook
:
826 case item_type_main_sheet
:
827 case item_type_other_sheet
:
828 case item_type_locked_name
:
829 case item_type_foreign_name
:
836 * Return the expression if it is acceptable.
837 * The parse position will be initialized then.
840 static GnmExprTop
const*
841 name_guru_check_expression (NameGuruState
*state
, gchar
*text
,
842 GnmParsePos
*pp
, item_type_t type
)
844 GnmExprTop
const *texpr
;
847 if (!name_guru_parse_pos_init (state
, pp
, type
))
848 return NULL
; /* We should have never gotten here. */
850 if (text
== NULL
|| text
[0] == '\0') {
851 go_gtk_notice_dialog (GTK_WINDOW (state
->dialog
),
853 _("Why would you want to define a "
854 "name for the empty string?"));
858 texpr
= gnm_expr_parse_str (text
, pp
,
859 GNM_EXPR_PARSE_DEFAULT
|
860 GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_INVALID
|
861 GNM_EXPR_PARSE_PERMIT_MULTIPLE_EXPRESSIONS
,
863 parse_error_init (&perr
));
865 if (perr
.err
== NULL
)
868 go_gtk_notice_dialog (GTK_WINDOW (state
->dialog
),
870 "%s", perr
.err
->message
);
871 parse_error_free (&perr
);
874 /* don't allow user to define a nexpr that looks like a placeholder *
875 * because it will be would disappear from the lists. */
876 if (gnm_expr_top_is_err (texpr
, GNM_ERROR_NAME
)) {
877 go_gtk_notice_dialog (GTK_WINDOW (state
->dialog
), GTK_MESSAGE_ERROR
,
878 _("Why would you want to define a name to be #NAME?"));
879 parse_error_free (&perr
);
880 gnm_expr_top_unref (texpr
);
889 cb_name_guru_content_edited
890 (G_GNUC_UNUSED GnumericCellRendererExprEntry
*cell
,
893 NameGuruState
*state
)
898 GnmExprTop
const *texpr
;
901 if (!name_guru_translate_pathstring_to_iter
902 (state
, &iter
, path_string
))
905 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &iter
,
907 ITEM_NAME_POINTER
, &nexpr
,
910 /* check whether the content is valid */
913 texpr
= name_guru_check_expression (state
, new_text
, &pp
, type
);
917 /* content is valid */
919 if (type
!= item_type_new_unsaved_wb_name
920 && type
!= item_type_new_unsaved_sheet_name
) {
921 /* save the changes (if the name is already saved) */
922 cmd_define_name (GNM_WBC (state
->wbcg
),
923 expr_name_name (nexpr
),
926 gnm_expr_top_unref (texpr
);
929 gtk_tree_store_set (state
->model
, &iter
, ITEM_CONTENT
, new_text
, -1);
933 cb_name_guru_name_edited (G_GNUC_UNUSED GtkCellRendererText
*cell
,
936 NameGuruState
*state
)
939 GtkTreeIter parent_iter
;
942 GnmExprTop
const *texpr
;
946 g_return_if_fail (new_text
!= NULL
);
948 if (!name_guru_translate_pathstring_to_iter
949 (state
, &iter
, path_string
))
952 gtk_tree_model_get (GTK_TREE_MODEL (state
->model
), &iter
,
954 ITEM_CONTENT
, &content
,
957 if (type
!= item_type_new_unsaved_wb_name
&&
958 type
!= item_type_new_unsaved_sheet_name
)
961 name_guru_parse_pos_init (state
, &pp
, type
);
962 nexpr
= expr_name_lookup (&pp
, new_text
);
964 if (nexpr
!= NULL
&& !nexpr
->is_placeholder
) {
965 Sheet
*scope
= nexpr
->pos
.sheet
;
966 if ((type
== item_type_new_unsaved_wb_name
&&
968 (type
== item_type_new_unsaved_sheet_name
)) {
970 (GTK_WINDOW (state
->dialog
),
972 _("This name is already in use!"));
977 texpr
= name_guru_check_expression (state
, content
, &pp
, type
);
981 if (!cmd_define_name (GNM_WBC (state
->wbcg
),
984 nexpr
= expr_name_lookup (&pp
, new_text
);
986 type
= (type
== item_type_new_unsaved_wb_name
) ?
987 item_type_available_wb_name
:
988 item_type_available_sheet_name
;
991 (state
->model
, &iter
,
993 ITEM_NAME_POINTER
, nexpr
,
996 ITEM_NAME_IS_EDITABLE
, FALSE
,
998 name_guru_set_images (state
, &iter
, type
, TRUE
);
1000 if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (state
->model
),
1001 &parent_iter
, &iter
))
1002 name_guru_move_record (state
, &iter
, &parent_iter
, type
);
1007 name_guru_update_sensitivity (GtkTreeSelection
*treeselection
,
1010 NameGuruState
*state
= user_data
;
1011 gboolean is_pastable
= FALSE
;
1014 if (gtk_tree_selection_get_selected
1015 (treeselection
, NULL
, &iter
))
1016 gtk_tree_model_get (state
->model_f
, &iter
,
1017 ITEM_PASTABLE
, &is_pastable
,
1019 gtk_widget_set_sensitive (GTK_WIDGET (state
->paste_button
),
1025 cb_name_guru_selection_function (G_GNUC_UNUSED GtkTreeSelection
*selection
,
1026 GtkTreeModel
*model
,
1028 gboolean path_currently_selected
,
1029 G_GNUC_UNUSED gpointer data
)
1033 if (path_currently_selected
)
1035 if (gtk_tree_model_get_iter (model
, &iter
, path
)) {
1036 gboolean is_pastable
, is_editable
;
1037 gtk_tree_model_get (model
,
1039 ITEM_PASTABLE
, &is_pastable
,
1040 ITEM_CONTENT_IS_EDITABLE
, &is_editable
,
1042 return (is_pastable
|| is_editable
);
1048 name_guru_init (NameGuruState
*state
, WBCGtk
*wbcg
, gboolean is_paste_dialog
)
1050 Workbook
*wb
= wb_control_get_workbook (GNM_WBC (wbcg
));
1051 GtkTreeViewColumn
*column
;
1052 GtkCellRenderer
*renderer
;
1053 GtkTreeSelection
*selection
;
1054 GtkWidget
*widget
= GTK_WIDGET (wbcg_toplevel (wbcg
));
1056 state
->is_paste_dialog
= is_paste_dialog
;
1057 state
->has_pasted
= FALSE
;
1059 state
->gui
= gnm_gtk_builder_load ("res:ui/define-name.ui", NULL
,
1060 GO_CMD_CONTEXT (wbcg
));
1061 if (state
->gui
== NULL
)
1066 state
->sv
= wb_control_cur_sheet_view (GNM_WBC (wbcg
));
1067 state
->sheet
= sv_sheet (state
->sv
);
1068 parse_pos_init_editpos (&state
->pp
, state
->sv
);
1070 state
->dialog
= go_gtk_builder_get_widget (state
->gui
, "NameGuru");
1072 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state
->dialog
),
1074 GNM_DIALOG_DESTROY_SHEET_REMOVED
);
1075 state
->model
= gtk_tree_store_new
1077 G_TYPE_STRING
, G_TYPE_POINTER
, G_TYPE_STRING
,
1078 G_TYPE_INT
, G_TYPE_BOOLEAN
, G_TYPE_BOOLEAN
,
1079 GDK_TYPE_PIXBUF
, GDK_TYPE_PIXBUF
,
1080 G_TYPE_BOOLEAN
, G_TYPE_BOOLEAN
, G_TYPE_BOOLEAN
,
1081 GDK_TYPE_PIXBUF
, G_TYPE_BOOLEAN
);
1083 state
->treeview
= go_gtk_builder_get_widget (state
->gui
, "name_list");
1085 state
->model_f
= gtk_tree_model_filter_new
1086 (GTK_TREE_MODEL (state
->model
), NULL
);
1087 gtk_tree_model_filter_set_visible_column
1088 (GTK_TREE_MODEL_FILTER (state
->model_f
), ITEM_VISIBLE
);
1090 gtk_tree_view_set_model (GTK_TREE_VIEW (state
->treeview
),
1092 g_object_unref (state
->model_f
);
1093 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (state
->treeview
),
1095 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (state
->treeview
),
1096 GTK_TREE_VIEW_GRID_LINES_NONE
);
1097 gtk_tree_view_set_reorderable (GTK_TREE_VIEW (state
->treeview
),
1100 renderer
= gtk_cell_renderer_text_new ();
1101 g_signal_connect (G_OBJECT (renderer
), "edited",
1102 G_CALLBACK (cb_name_guru_name_edited
), state
);
1103 column
= gtk_tree_view_column_new_with_attributes
1107 "editable", ITEM_NAME_IS_EDITABLE
,
1109 gtk_tree_view_append_column (GTK_TREE_VIEW (state
->treeview
), column
);
1111 if (is_paste_dialog
) {
1112 renderer
= gnumeric_cell_renderer_toggle_new ();
1113 g_signal_connect (G_OBJECT (renderer
),
1115 G_CALLBACK (cb_name_guru_paste
), state
);
1116 column
= gtk_tree_view_column_new_with_attributes
1119 "active", ITEM_PASTABLE
,
1120 "pixbuf", ITEM_PASTE_IMAGE
,
1122 gtk_tree_view_append_column (GTK_TREE_VIEW (state
->treeview
),
1125 renderer
= gnumeric_cell_renderer_toggle_new ();
1126 g_signal_connect (G_OBJECT (renderer
),
1128 G_CALLBACK (cb_name_guru_add_delete
), state
);
1129 column
= gtk_tree_view_column_new_with_attributes
1132 "active", ITEM_ADDDELETE_ACTIVE
,
1133 "pixbuf", ITEM_ADDDELETE_IMAGE
,
1135 gtk_tree_view_append_column (GTK_TREE_VIEW (state
->treeview
),
1138 renderer
= gnumeric_cell_renderer_toggle_new ();
1139 g_signal_connect (G_OBJECT (renderer
),
1141 G_CALLBACK (cb_name_guru_switch_scope
),
1143 column
= gtk_tree_view_column_new_with_attributes
1146 "active", ITEM_UPDOWN_ACTIVE
,
1147 "pixbuf", ITEM_UPDOWN_IMAGE
,
1149 gtk_tree_view_append_column (GTK_TREE_VIEW (state
->treeview
),
1153 renderer
= gnumeric_cell_renderer_expr_entry_new (state
->wbcg
);
1154 g_signal_connect (G_OBJECT (renderer
), "edited",
1155 G_CALLBACK (cb_name_guru_content_edited
), state
);
1156 column
= gtk_tree_view_column_new_with_attributes
1159 "text", ITEM_CONTENT
,
1160 "editable", ITEM_CONTENT_IS_EDITABLE
,
1162 gtk_tree_view_append_column (GTK_TREE_VIEW (state
->treeview
), column
);
1165 selection
= gtk_tree_view_get_selection
1166 (GTK_TREE_VIEW (state
->treeview
));
1167 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_BROWSE
);
1168 gtk_tree_selection_set_select_function
1169 (selection
, cb_name_guru_selection_function
,
1172 state
->close_button
= name_guru_init_button (state
, "close_button");
1173 state
->paste_button
= name_guru_init_button (state
, "paste_button");
1175 if (is_paste_dialog
) {
1176 g_signal_connect (G_OBJECT (selection
),
1178 G_CALLBACK (name_guru_update_sensitivity
),
1180 state
->image_paste
= go_gtk_widget_render_icon_pixbuf (widget
, "edit-paste", GTK_ICON_SIZE_MENU
);
1181 state
->image_add
= NULL
;
1182 state
->image_delete
= NULL
;
1183 state
->image_lock
= NULL
;
1184 state
->image_up
= NULL
;
1185 state
->image_down
= NULL
;
1187 state
->image_paste
= NULL
;
1188 state
->image_add
= go_gtk_widget_render_icon_pixbuf (widget
, "list-add", GTK_ICON_SIZE_MENU
);
1189 state
->image_delete
= go_gtk_widget_render_icon_pixbuf (widget
, "list-remove", GTK_ICON_SIZE_MENU
);
1190 state
->image_lock
= go_gtk_widget_render_icon_pixbuf (widget
, "gnumeric-protection-yes", GTK_ICON_SIZE_MENU
);
1191 state
->image_up
= go_gtk_widget_render_icon_pixbuf (widget
, "go-up", GTK_ICON_SIZE_MENU
);
1192 state
->image_down
= go_gtk_widget_render_icon_pixbuf (widget
, "go-down", GTK_ICON_SIZE_MENU
);
1195 state
->search_entry
= go_gtk_builder_get_widget (state
->gui
, "search_entry");
1197 g_signal_connect (G_OBJECT (state
->search_entry
),
1199 G_CALLBACK (name_guru_erase_search_entry
),
1202 g_signal_connect (G_OBJECT (state
->search_entry
),
1204 G_CALLBACK (name_guru_search
),
1207 name_guru_populate_list (state
);
1208 name_guru_update_sensitivity (selection
, state
);
1210 gnm_init_help_button (
1211 go_gtk_builder_get_widget (state
->gui
, "help_button"),
1212 is_paste_dialog
? GNUMERIC_HELP_LINK_PASTE_NAMES
1213 : GNUMERIC_HELP_LINK_DEFINE_NAMES
);
1215 /* a candidate for merging into attach guru */
1216 gnm_keyed_dialog (state
->wbcg
, GTK_WINDOW (state
->dialog
),
1217 is_paste_dialog
? PASTE_NAMES_KEY
1218 : DEFINE_NAMES_KEY
);
1219 go_gtk_nonmodal_dialog (wbcg_toplevel (state
->wbcg
),
1220 GTK_WINDOW (state
->dialog
));
1222 g_object_set_data_full (G_OBJECT (state
->dialog
),
1223 "state", state
, (GDestroyNotify
)cb_name_guru_destroy
);
1225 if (is_paste_dialog
) {
1226 gtk_window_set_title (GTK_WINDOW (state
->dialog
),
1227 _("Paste Defined Names"));
1228 gtk_widget_show_all (GTK_WIDGET (state
->dialog
));
1230 wbc_gtk_attach_guru (state
->wbcg
, state
->dialog
);
1231 gtk_widget_show (GTK_WIDGET (state
->dialog
));
1238 * dialog_define_names:
1241 * Create and show the define names dialog.
1244 dialog_define_names (WBCGtk
*wbcg
)
1246 NameGuruState
*state
;
1248 g_return_if_fail (wbcg
!= NULL
);
1250 /* Only one guru per workbook. */
1251 if (wbc_gtk_get_guru (wbcg
))
1254 /* Only pop up one copy per workbook */
1255 if (gnm_dialog_raise_if_exists (wbcg
, DEFINE_NAMES_KEY
))
1258 state
= g_new0 (NameGuruState
, 1);
1259 if (name_guru_init (state
, wbcg
, FALSE
)) {
1260 go_gtk_notice_dialog (wbcg_toplevel (wbcg
), GTK_MESSAGE_ERROR
,
1261 _("Could not create the Name Guru."));
1268 * dialog_define_names:
1271 * Create and show the define names dialog.
1274 dialog_paste_names (WBCGtk
*wbcg
)
1276 NameGuruState
*state
;
1278 g_return_if_fail (wbcg
!= NULL
);
1280 /* Only one guru per workbook. */
1281 if (wbc_gtk_get_guru (wbcg
))
1284 /* Only pop up one copy per workbook */
1285 if (gnm_dialog_raise_if_exists (wbcg
, PASTE_NAMES_KEY
))
1288 state
= g_new0 (NameGuruState
, 1);
1289 if (name_guru_init (state
, wbcg
, TRUE
)) {
1290 go_gtk_notice_dialog (wbcg_toplevel (wbcg
), GTK_MESSAGE_ERROR
,
1291 _("Could not create the Name Guru."));