2 * dialog-stf.c: implementation of the STF import dialog
4 * Copyright 2001 Almer S. Tigelaar <almer@gnome.org>
5 * Copyright 2003 Morten Welinder <terra@gnome.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
21 #include <gnumeric-config.h>
22 #include <glib/gi18n-lib.h>
24 #include <dialogs/dialog-stf.h>
26 #include <gnm-format.h>
28 #include <command-context.h>
30 #include <sheet-style.h>
32 #include <clipboard.h>
35 /**********************************************************************************************
36 * DIALOG CONTROLLING CODE
37 **********************************************************************************************/
40 * stf_dialog_set_initial_keyboard_focus
41 * @pagedata: mother struct
43 * Sets keyboard focus to an appropriate widget on the page.
48 stf_dialog_set_initial_keyboard_focus (StfDialogData
*pagedata
)
50 GtkWidget
*focus_widget
= NULL
;
51 GtkWidget
*default_widget
= pagedata
->next_button
;
53 switch (gtk_notebook_get_current_page (pagedata
->notebook
)) {
55 focus_widget
= GTK_WIDGET (pagedata
->main
.main_separated
);
58 focus_widget
= GTK_WIDGET (pagedata
->csv
.csv_space
);
61 focus_widget
= GTK_WIDGET (pagedata
->fixed
.fixed_auto
);
64 focus_widget
= pagedata
->finish_button
;
65 default_widget
= pagedata
->finish_button
;
68 g_assert_not_reached ();
72 gtk_widget_grab_focus (focus_widget
);
75 gtk_widget_grab_default (default_widget
);
80 frob_buttons (StfDialogData
*pagedata
)
83 gtk_notebook_get_current_page (pagedata
->notebook
);
85 gtk_widget_set_sensitive (pagedata
->back_button
, pos
!= DPG_MAIN
);
86 gtk_widget_set_sensitive (pagedata
->next_button
, pos
!= DPG_FORMAT
);
90 prepare_page (StfDialogData
*data
)
92 switch (gtk_notebook_get_current_page (data
->notebook
)) {
93 case DPG_MAIN
: stf_dialog_main_page_prepare (data
); break;
94 case DPG_CSV
: stf_dialog_csv_page_prepare (data
); break;
95 case DPG_FIXED
: stf_dialog_fixed_page_prepare (data
); break;
96 case DPG_FORMAT
: stf_dialog_format_page_prepare (data
); break;
103 next_clicked (G_GNUC_UNUSED GtkWidget
*widget
, StfDialogData
*data
)
105 StfDialogPage newpos
;
107 switch (gtk_notebook_get_current_page (data
->notebook
)) {
109 stf_preview_set_lines (data
->main
.renderdata
, NULL
, NULL
);
110 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data
->main
.main_separated
))) {
118 stf_preview_set_lines (data
->csv
.renderdata
, NULL
, NULL
);
123 stf_preview_set_lines (data
->fixed
.renderdata
, NULL
, NULL
);
128 g_assert_not_reached ();
132 gtk_notebook_set_current_page (data
->notebook
, newpos
);
135 stf_dialog_set_initial_keyboard_focus (data
);
139 back_clicked (G_GNUC_UNUSED GtkWidget
*widget
, StfDialogData
*data
)
141 StfDialogPage newpos
;
143 switch (gtk_notebook_get_current_page (data
->notebook
)) {
145 stf_preview_set_lines (data
->format
.renderdata
, NULL
, NULL
);
146 if (data
->parseoptions
->parsetype
== PARSE_TYPE_CSV
)
153 stf_preview_set_lines (data
->fixed
.renderdata
, NULL
, NULL
);
158 stf_preview_set_lines (data
->csv
.renderdata
, NULL
, NULL
);
163 g_assert_not_reached ();
167 gtk_notebook_set_current_page (data
->notebook
, newpos
);
170 stf_dialog_set_initial_keyboard_focus (data
);
175 * stf_dialog_attach_page_signals
176 * @gui: the GtkBuilder gui of the dialog
177 * @pagedata: mother struct
179 * Connects all signals to all pages and fills the mother struct
180 * The page flow looks like:
182 * main_page /- csv_page -\ format_page
188 stf_dialog_attach_page_signals (GtkBuilder
*gui
, StfDialogData
*pagedata
)
190 frob_buttons (pagedata
);
191 /* Signals for individual pages */
193 g_signal_connect (G_OBJECT (pagedata
->next_button
),
195 G_CALLBACK (next_clicked
), pagedata
);
197 g_signal_connect (G_OBJECT (pagedata
->back_button
),
199 G_CALLBACK (back_clicked
), pagedata
);
203 * stf_dialog_editables_enter
204 * @pagedata: mother struct
206 * Make <Ret> in text fields activate default.
211 stf_dialog_editables_enter (StfDialogData
*pagedata
)
216 GTK_WIDGET (&pagedata
->main
.main_startrow
->entry
));
219 GTK_WIDGET (&pagedata
->main
.main_stoprow
->entry
));
222 GTK_WIDGET (pagedata
->csv
.csv_customseparator
));
223 gnumeric_combo_enters
225 pagedata
->csv
.csv_textindicator
);
228 GTK_WIDGET (&pagedata
->fixed
.fixed_colend
->entry
));
229 go_format_sel_editable_enters
230 (pagedata
->format
.format_selector
,
238 * @source: name of the file we are importing (or data) in UTF-8
239 * @data: the data itself
241 * This will start the import.
242 * (NOTE: you have to free the DialogStfResult_t that this function returns yourself)
244 * returns: A DialogStfResult_t struct on success, NULL otherwise.
247 stf_dialog (WBCGtk
*wbcg
,
248 const char *opt_encoding
,
249 gboolean fixed_encoding
,
250 const char *opt_locale
,
251 gboolean fixed_locale
,
257 DialogStfResult_t
*dialogresult
;
258 StfDialogData pagedata
;
259 GtkResponseType resp
;
261 g_return_val_if_fail (opt_encoding
!= NULL
|| !fixed_encoding
, NULL
);
262 g_return_val_if_fail (opt_locale
!= NULL
|| !fixed_locale
, NULL
);
263 g_return_val_if_fail (source
!= NULL
, NULL
);
264 g_return_val_if_fail (data
!= NULL
, NULL
);
266 gui
= gnm_gtk_builder_load ("res:ui/dialog-stf.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
270 pagedata
.encoding
= g_strdup (opt_encoding
);
271 pagedata
.fixed_encoding
= fixed_encoding
;
272 pagedata
.locale
= g_strdup (opt_locale
);
273 pagedata
.fixed_locale
= fixed_locale
;
274 pagedata
.wbcg
= wbcg
;
275 pagedata
.source
= source
;
276 pagedata
.raw_data
= data
;
277 pagedata
.raw_data_len
= data_len
< 0 ? (int)strlen (data
) : data_len
;
278 pagedata
.utf8_data
= NULL
;
281 pagedata
.dialog
= GTK_DIALOG (go_gtk_builder_get_widget (gui
, "stf_dialog"));
282 pagedata
.notebook
= GTK_NOTEBOOK (go_gtk_builder_get_widget (gui
, "stf_notebook"));
283 pagedata
.next_button
= go_gtk_builder_get_widget (gui
, "forward_button");
284 pagedata
.back_button
= go_gtk_builder_get_widget (gui
, "back_button");
285 pagedata
.cancel_button
= go_gtk_builder_get_widget (gui
, "cancel_button");
286 pagedata
.help_button
= go_gtk_builder_get_widget (gui
, "help_button");
287 pagedata
.finish_button
= go_gtk_builder_get_widget (gui
, "finish_button");
288 pagedata
.parseoptions
= NULL
;
290 gtk_widget_set_name (GTK_WIDGET (pagedata
.dialog
), "stf-import");
292 stf_dialog_main_page_init (gui
, &pagedata
);
293 stf_dialog_csv_page_init (gui
, &pagedata
);
294 stf_dialog_fixed_page_init (gui
, &pagedata
);
295 stf_dialog_format_page_init (gui
, &pagedata
);
297 stf_dialog_attach_page_signals (gui
, &pagedata
);
299 stf_dialog_editables_enter (&pagedata
);
301 stf_dialog_set_initial_keyboard_focus (&pagedata
);
303 prepare_page (&pagedata
);
304 frob_buttons (&pagedata
);
306 resp
= go_gtk_dialog_run (pagedata
.dialog
, wbcg_toplevel (wbcg
));
308 if (resp
== GTK_RESPONSE_OK
) {
309 dialogresult
= g_new (DialogStfResult_t
, 1);
311 dialogresult
->text
= pagedata
.utf8_data
;
312 *((char *)pagedata
.cur_end
) = 0;
313 if (dialogresult
->text
!= pagedata
.cur
)
314 strcpy (dialogresult
->text
, pagedata
.cur
);
315 pagedata
.cur
= pagedata
.utf8_data
= NULL
;
317 dialogresult
->encoding
= pagedata
.encoding
;
318 pagedata
.encoding
= NULL
;
320 dialogresult
->colcount
= pagedata
.format
.col_import_count
;
321 dialogresult
->rowcount
= pagedata
.rowcount
;
323 dialogresult
->parseoptions
= pagedata
.parseoptions
;
324 pagedata
.parseoptions
= NULL
;
325 g_free (dialogresult
->parseoptions
->locale
);
326 dialogresult
->parseoptions
->locale
= pagedata
.locale
;
327 pagedata
.locale
= NULL
;
329 if (pagedata
.format
.formats
) {
330 g_ptr_array_free (dialogresult
->parseoptions
->formats
, TRUE
);
331 dialogresult
->parseoptions
->formats
= pagedata
.format
.formats
;
332 pagedata
.format
.formats
= NULL
;
334 g_ptr_array_set_size (dialogresult
->parseoptions
->formats
, 0);
335 dialogresult
->parseoptions
->col_import_array
336 = pagedata
.format
.col_import_array
;
337 dialogresult
->parseoptions
->col_import_array_len
338 = pagedata
.format
.col_import_array_len
;
339 pagedata
.format
.col_import_array
= NULL
;
340 dialogresult
->parseoptions
->col_autofit_array
341 = pagedata
.format
.col_autofit_array
;
342 pagedata
.format
.col_autofit_array
= NULL
;
343 pagedata
.format
.col_import_count
= 0;
344 pagedata
.format
.col_import_array_len
= 0;
349 stf_dialog_main_page_cleanup (&pagedata
);
350 stf_dialog_csv_page_cleanup (&pagedata
);
351 stf_dialog_fixed_page_cleanup (&pagedata
);
352 stf_dialog_format_page_cleanup (&pagedata
);
354 g_object_unref (gui
);
355 g_free (pagedata
.encoding
);
356 g_free (pagedata
.locale
);
357 g_free (pagedata
.utf8_data
);
358 if (pagedata
.parseoptions
)
359 stf_parse_options_free (pagedata
.parseoptions
);
365 * stf_dialog_result_free
366 * @dialogresult: a dialogresult struct
368 * This routine will properly free the members of @dialogresult and
369 * @dialogresult itself
374 stf_dialog_result_free (DialogStfResult_t
*dialogresult
)
376 g_return_if_fail (dialogresult
!= NULL
);
378 stf_parse_options_free (dialogresult
->parseoptions
);
380 g_free (dialogresult
->text
);
381 g_free (dialogresult
->encoding
);
383 g_free (dialogresult
);
387 * stf_dialog_result_attach_formats_to_cr
388 * @dialogresult: a dialogresult struct
391 * Attach the formats of the dialogresult to the given cell region.
396 stf_dialog_result_attach_formats_to_cr (DialogStfResult_t
*dialogresult
,
399 unsigned int col
, targetcol
;
401 g_return_if_fail (dialogresult
!= NULL
);
402 g_return_if_fail (cr
!= NULL
);
405 for (col
= 0; col
< dialogresult
->parseoptions
->formats
->len
; col
++) {
406 if (dialogresult
->parseoptions
->col_import_array
[col
]) {
407 GOFormat
*sf
= g_ptr_array_index
408 (dialogresult
->parseoptions
->formats
, col
);
409 GnmStyleRegion
*sr
= g_new (GnmStyleRegion
, 1);
411 sr
->range
.start
.col
= targetcol
;
412 sr
->range
.start
.row
= 0;
413 sr
->range
.end
.col
= targetcol
;
414 sr
->range
.end
.row
= dialogresult
->rowcount
- 1;
415 sr
->style
= gnm_style_new_default ();
416 gnm_style_set_format (sr
->style
, sf
);
419 cr
->styles
= g_slist_prepend (cr
->styles
, sr
);