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 "dialog-stf.h"
26 #include <gnm-format.h>
28 #include <command-context.h>
30 #include <sheet-style.h>
32 #include <clipboard.h>
36 /**********************************************************************************************
37 * DIALOG CONTROLLING CODE
38 **********************************************************************************************/
41 * stf_dialog_set_initial_keyboard_focus
42 * @pagedata: mother struct
44 * Sets keyboard focus to an appropriate widget on the page.
49 stf_dialog_set_initial_keyboard_focus (StfDialogData
*pagedata
)
51 GtkWidget
*focus_widget
= NULL
;
52 GtkWidget
*default_widget
= pagedata
->next_button
;
54 switch (gtk_notebook_get_current_page (pagedata
->notebook
)) {
56 focus_widget
= GTK_WIDGET (pagedata
->main
.main_separated
);
59 focus_widget
= GTK_WIDGET (pagedata
->csv
.csv_space
);
62 focus_widget
= GTK_WIDGET (pagedata
->fixed
.fixed_auto
);
65 focus_widget
= pagedata
->finish_button
;
66 default_widget
= pagedata
->finish_button
;
69 g_assert_not_reached ();
73 gtk_widget_grab_focus (focus_widget
);
76 gtk_widget_grab_default (default_widget
);
81 frob_buttons (StfDialogData
*pagedata
)
84 gtk_notebook_get_current_page (pagedata
->notebook
);
86 gtk_widget_set_sensitive (pagedata
->back_button
, pos
!= DPG_MAIN
);
87 gtk_widget_set_sensitive (pagedata
->next_button
, pos
!= DPG_FORMAT
);
91 prepare_page (StfDialogData
*data
)
93 switch (gtk_notebook_get_current_page (data
->notebook
)) {
94 case DPG_MAIN
: stf_dialog_main_page_prepare (data
); break;
95 case DPG_CSV
: stf_dialog_csv_page_prepare (data
); break;
96 case DPG_FIXED
: stf_dialog_fixed_page_prepare (data
); break;
97 case DPG_FORMAT
: stf_dialog_format_page_prepare (data
); break;
104 next_clicked (G_GNUC_UNUSED GtkWidget
*widget
, StfDialogData
*data
)
106 StfDialogPage newpos
;
108 switch (gtk_notebook_get_current_page (data
->notebook
)) {
110 stf_preview_set_lines (data
->main
.renderdata
, NULL
, NULL
);
111 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data
->main
.main_separated
))) {
119 stf_preview_set_lines (data
->csv
.renderdata
, NULL
, NULL
);
124 stf_preview_set_lines (data
->fixed
.renderdata
, NULL
, NULL
);
129 g_assert_not_reached ();
133 gtk_notebook_set_current_page (data
->notebook
, newpos
);
136 stf_dialog_set_initial_keyboard_focus (data
);
140 back_clicked (G_GNUC_UNUSED GtkWidget
*widget
, StfDialogData
*data
)
142 StfDialogPage newpos
;
144 switch (gtk_notebook_get_current_page (data
->notebook
)) {
146 stf_preview_set_lines (data
->format
.renderdata
, NULL
, NULL
);
147 if (data
->parseoptions
->parsetype
== PARSE_TYPE_CSV
)
154 stf_preview_set_lines (data
->fixed
.renderdata
, NULL
, NULL
);
159 stf_preview_set_lines (data
->csv
.renderdata
, NULL
, NULL
);
164 g_assert_not_reached ();
168 gtk_notebook_set_current_page (data
->notebook
, newpos
);
171 stf_dialog_set_initial_keyboard_focus (data
);
176 * stf_dialog_attach_page_signals
177 * @gui: the GtkBuilder gui of the dialog
178 * @pagedata: mother struct
180 * Connects all signals to all pages and fills the mother struct
181 * The page flow looks like:
183 * main_page /- csv_page -\ format_page
189 stf_dialog_attach_page_signals (GtkBuilder
*gui
, StfDialogData
*pagedata
)
191 frob_buttons (pagedata
);
192 /* Signals for individual pages */
194 g_signal_connect (G_OBJECT (pagedata
->next_button
),
196 G_CALLBACK (next_clicked
), pagedata
);
198 g_signal_connect (G_OBJECT (pagedata
->back_button
),
200 G_CALLBACK (back_clicked
), pagedata
);
204 * stf_dialog_editables_enter
205 * @pagedata: mother struct
207 * Make <Ret> in text fields activate default.
212 stf_dialog_editables_enter (StfDialogData
*pagedata
)
217 GTK_WIDGET (&pagedata
->main
.main_startrow
->entry
));
220 GTK_WIDGET (&pagedata
->main
.main_stoprow
->entry
));
223 GTK_WIDGET (pagedata
->csv
.csv_customseparator
));
224 gnumeric_combo_enters
226 pagedata
->csv
.csv_textindicator
);
229 GTK_WIDGET (&pagedata
->fixed
.fixed_colend
->entry
));
230 go_format_sel_editable_enters
231 (pagedata
->format
.format_selector
,
239 * @source: name of the file we are importing (or data) in UTF-8
240 * @data: the data itself
242 * This will start the import.
243 * (NOTE: you have to free the DialogStfResult_t that this function returns yourself)
245 * returns: A DialogStfResult_t struct on success, NULL otherwise.
248 stf_dialog (WBCGtk
*wbcg
,
249 const char *opt_encoding
,
250 gboolean fixed_encoding
,
251 const char *opt_locale
,
252 gboolean fixed_locale
,
258 DialogStfResult_t
*dialogresult
;
259 StfDialogData pagedata
;
260 GtkResponseType resp
;
262 g_return_val_if_fail (opt_encoding
!= NULL
|| !fixed_encoding
, NULL
);
263 g_return_val_if_fail (opt_locale
!= NULL
|| !fixed_locale
, NULL
);
264 g_return_val_if_fail (source
!= NULL
, NULL
);
265 g_return_val_if_fail (data
!= NULL
, NULL
);
267 gui
= gnm_gtk_builder_load ("res:ui/dialog-stf.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
271 pagedata
.encoding
= g_strdup (opt_encoding
);
272 pagedata
.fixed_encoding
= fixed_encoding
;
273 pagedata
.locale
= g_strdup (opt_locale
);
274 pagedata
.fixed_locale
= fixed_locale
;
275 pagedata
.wbcg
= wbcg
;
276 pagedata
.source
= source
;
277 pagedata
.raw_data
= data
;
278 pagedata
.raw_data_len
= data_len
< 0 ? (int)strlen (data
) : data_len
;
279 pagedata
.utf8_data
= NULL
;
282 pagedata
.dialog
= GTK_DIALOG (go_gtk_builder_get_widget (gui
, "stf_dialog"));
283 pagedata
.notebook
= GTK_NOTEBOOK (go_gtk_builder_get_widget (gui
, "stf_notebook"));
284 pagedata
.next_button
= go_gtk_builder_get_widget (gui
, "forward_button");
285 pagedata
.back_button
= go_gtk_builder_get_widget (gui
, "back_button");
286 pagedata
.cancel_button
= go_gtk_builder_get_widget (gui
, "cancel_button");
287 pagedata
.help_button
= go_gtk_builder_get_widget (gui
, "help_button");
288 pagedata
.finish_button
= go_gtk_builder_get_widget (gui
, "finish_button");
289 pagedata
.parseoptions
= NULL
;
291 gtk_widget_set_name (GTK_WIDGET (pagedata
.dialog
), "stf-import");
293 stf_dialog_main_page_init (gui
, &pagedata
);
294 stf_dialog_csv_page_init (gui
, &pagedata
);
295 stf_dialog_fixed_page_init (gui
, &pagedata
);
296 stf_dialog_format_page_init (gui
, &pagedata
);
298 stf_dialog_attach_page_signals (gui
, &pagedata
);
300 stf_dialog_editables_enter (&pagedata
);
302 stf_dialog_set_initial_keyboard_focus (&pagedata
);
304 prepare_page (&pagedata
);
305 frob_buttons (&pagedata
);
307 resp
= go_gtk_dialog_run (pagedata
.dialog
, wbcg_toplevel (wbcg
));
309 if (resp
== GTK_RESPONSE_OK
) {
310 dialogresult
= g_new (DialogStfResult_t
, 1);
312 dialogresult
->text
= pagedata
.utf8_data
;
313 *((char *)pagedata
.cur_end
) = 0;
314 if (dialogresult
->text
!= pagedata
.cur
)
315 strcpy (dialogresult
->text
, pagedata
.cur
);
316 pagedata
.cur
= pagedata
.utf8_data
= NULL
;
318 dialogresult
->encoding
= pagedata
.encoding
;
319 pagedata
.encoding
= NULL
;
321 dialogresult
->colcount
= pagedata
.format
.col_import_count
;
322 dialogresult
->rowcount
= pagedata
.rowcount
;
324 dialogresult
->parseoptions
= pagedata
.parseoptions
;
325 pagedata
.parseoptions
= NULL
;
326 g_free (dialogresult
->parseoptions
->locale
);
327 dialogresult
->parseoptions
->locale
= pagedata
.locale
;
328 pagedata
.locale
= NULL
;
330 if (pagedata
.format
.formats
) {
331 g_ptr_array_free (dialogresult
->parseoptions
->formats
, TRUE
);
332 dialogresult
->parseoptions
->formats
= pagedata
.format
.formats
;
333 pagedata
.format
.formats
= NULL
;
335 g_ptr_array_set_size (dialogresult
->parseoptions
->formats
, 0);
336 dialogresult
->parseoptions
->col_import_array
337 = pagedata
.format
.col_import_array
;
338 dialogresult
->parseoptions
->col_import_array_len
339 = pagedata
.format
.col_import_array_len
;
340 pagedata
.format
.col_import_array
= NULL
;
341 dialogresult
->parseoptions
->col_autofit_array
342 = pagedata
.format
.col_autofit_array
;
343 pagedata
.format
.col_autofit_array
= NULL
;
344 pagedata
.format
.col_import_count
= 0;
345 pagedata
.format
.col_import_array_len
= 0;
350 stf_dialog_main_page_cleanup (&pagedata
);
351 stf_dialog_csv_page_cleanup (&pagedata
);
352 stf_dialog_fixed_page_cleanup (&pagedata
);
353 stf_dialog_format_page_cleanup (&pagedata
);
355 g_object_unref (gui
);
356 g_free (pagedata
.encoding
);
357 g_free (pagedata
.locale
);
358 g_free (pagedata
.utf8_data
);
359 if (pagedata
.parseoptions
)
360 stf_parse_options_free (pagedata
.parseoptions
);
366 * stf_dialog_result_free
367 * @dialogresult: a dialogresult struct
369 * This routine will properly free the members of @dialogresult and
370 * @dialogresult itself
375 stf_dialog_result_free (DialogStfResult_t
*dialogresult
)
377 g_return_if_fail (dialogresult
!= NULL
);
379 stf_parse_options_free (dialogresult
->parseoptions
);
381 g_free (dialogresult
->text
);
382 g_free (dialogresult
->encoding
);
384 g_free (dialogresult
);
388 * stf_dialog_result_attach_formats_to_cr
389 * @dialogresult: a dialogresult struct
392 * Attach the formats of the dialogresult to the given cell region.
397 stf_dialog_result_attach_formats_to_cr (DialogStfResult_t
*dialogresult
,
400 unsigned int col
, targetcol
;
402 g_return_if_fail (dialogresult
!= NULL
);
403 g_return_if_fail (cr
!= NULL
);
406 for (col
= 0; col
< dialogresult
->parseoptions
->formats
->len
; col
++) {
407 if (dialogresult
->parseoptions
->col_import_array
[col
]) {
408 GOFormat
*sf
= g_ptr_array_index
409 (dialogresult
->parseoptions
->formats
, col
);
410 GnmStyleRegion
*sr
= g_new (GnmStyleRegion
, 1);
412 sr
->range
.start
.col
= targetcol
;
413 sr
->range
.start
.row
= 0;
414 sr
->range
.end
.col
= targetcol
;
415 sr
->range
.end
.row
= dialogresult
->rowcount
- 1;
416 sr
->style
= gnm_style_new_default ();
417 gnm_style_set_format (sr
->style
, sf
);
420 cr
->styles
= g_slist_prepend (cr
->styles
, sr
);