2 * dialog-stf-preview.c : by utilizing the stf-parse engine this unit can
3 * render sheet previews and offers
4 * functions for making this preview more interactive.
6 * Copyright 2001 Almer S. Tigelaar <almer@gnome.org>
7 * Copyright 2003 Morten Welinder <terra@gnome.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <https://www.gnu.org/licenses/>.
22 #include <gnumeric-config.h>
23 #include <glib/gi18n-lib.h>
25 #include "dialog-stf-preview.h"
26 #include "dialog-stf.h"
28 #include <gnm-format.h>
29 #include <number-match.h>
33 #include <widgets/gnumeric-lazy-list.h>
36 /******************************************************************************************************************
37 * ADVANCED DRAWING FUNCTIONS
38 ******************************************************************************************************************/
41 render_get_value (gint row
, gint column
, gpointer _rd
, GValue
*value
)
43 RenderData_t
*rd
= (RenderData_t
*)_rd
;
44 GnumericLazyList
*ll
= GNM_LAZY_LIST (gtk_tree_view_get_model (rd
->tree_view
));
45 GPtrArray
*lines
= rd
->lines
;
46 GPtrArray
*line
= (row
< (int)lines
->len
)
47 ? g_ptr_array_index (lines
, row
)
49 const char *text
= (line
&& column
< (int)line
->len
)
50 ? g_ptr_array_index (line
, column
)
53 g_value_init (value
, ll
->column_headers
[column
]);
57 char *tab
= strchr (text
, '\t');
59 copy
= g_strdup (text
);
60 tab
= copy
+ (tab
- text
);
63 tab
= strchr (tab
+ 1, '\t');
69 * Throwing really long strings at Gtk+ is known to cause
70 * trouble, so cut long strings and hope no-one notices.
72 if (g_utf8_strlen (text
, -1) > STF_LINE_LENGTH_LIMIT
) {
73 char *cut
= g_strdup (text
);
74 strcpy (g_utf8_offset_to_pointer (cut
, STF_LINE_LENGTH_LIMIT
- 3),
80 g_value_set_string (value
, text
);
86 /******************************************************************************************************************
87 * STRUCTURE MANIPULATION FUNCTIONS
88 ******************************************************************************************************************/
92 * @data_container: a container in which to put a treeview.
94 * returns : a new renderdata struct
97 stf_preview_new (GtkWidget
*data_container
,
98 GODateConventions
const *date_conv
)
100 RenderData_t
* renderdata
;
101 GnumericLazyList
*ll
;
103 g_return_val_if_fail (data_container
!= NULL
, NULL
);
105 renderdata
= g_new (RenderData_t
, 1);
107 renderdata
->data_container
= data_container
;
108 renderdata
->startrow
= 1;
109 renderdata
->colformats
= g_ptr_array_new ();
110 renderdata
->ignore_formats
= FALSE
;
111 renderdata
->lines_chunk
= NULL
;
112 renderdata
->lines
= NULL
;
114 renderdata
->date_conv
= date_conv
;
116 ll
= gnumeric_lazy_list_new (render_get_value
, renderdata
, 0, 1, G_TYPE_STRING
);
117 renderdata
->tree_view
=
118 GTK_TREE_VIEW (gtk_tree_view_new_with_model (GTK_TREE_MODEL (ll
)));
119 gtk_tree_view_set_grid_lines (renderdata
->tree_view
,
120 GTK_TREE_VIEW_GRID_LINES_VERTICAL
);
121 g_object_ref (renderdata
->tree_view
);
124 renderdata
->colcount
= 0;
127 GtkWidget
*w
= GTK_WIDGET (renderdata
->tree_view
);
128 int width
, height
, vertical_separator
;
129 PangoLayout
*layout
=
130 gtk_widget_create_pango_layout (w
, "Mg19");
132 gtk_widget_style_get (w
,
133 "vertical_separator", &vertical_separator
,
136 pango_layout_get_pixel_size (layout
, &width
, &height
);
138 * Make room for about 80 characters and about 7 lines of data.
139 * (The +2 allows room for the headers and the h-scrollbar.
141 gtk_widget_set_size_request (renderdata
->data_container
,
142 width
* 20, /* About 80 chars. */
143 (height
+ vertical_separator
) * (7 + 2));
144 g_object_unref (layout
);
147 gtk_container_add (GTK_CONTAINER (renderdata
->data_container
),
148 GTK_WIDGET (renderdata
->tree_view
));
149 gtk_widget_show_all (GTK_WIDGET (renderdata
->tree_view
));
156 * @renderdata: a renderdata struct
158 * This will free the @renderdata
163 stf_preview_free (RenderData_t
*renderdata
)
165 g_return_if_fail (renderdata
!= NULL
);
167 stf_preview_colformats_clear (renderdata
);
168 g_ptr_array_free (renderdata
->colformats
, TRUE
);
170 stf_preview_set_lines (renderdata
, NULL
, NULL
);
172 g_object_unref (renderdata
->tree_view
);
178 stf_preview_set_lines (RenderData_t
*renderdata
,
179 GStringChunk
*lines_chunk
,
184 GnumericLazyList
*ll
;
187 g_return_if_fail (renderdata
!= NULL
);
189 /* Empty the table. */
190 gtk_tree_view_set_model (renderdata
->tree_view
, NULL
);
192 if (renderdata
->lines
!= lines
) {
193 if (renderdata
->lines
)
194 stf_parse_general_free (renderdata
->lines
);
195 renderdata
->lines
= lines
;
198 if (renderdata
->lines_chunk
!= lines_chunk
) {
199 if (renderdata
->lines_chunk
)
200 g_string_chunk_free (renderdata
->lines_chunk
);
201 renderdata
->lines_chunk
= lines_chunk
;
207 for (i
= 0; i
< lines
->len
; i
++) {
208 GPtrArray
*line
= g_ptr_array_index (lines
, i
);
209 colcount
= MAX (colcount
, (int)line
->len
);
213 * If we are making large changes we need to hide the treeview
214 * because performance otherwise suffers a lot.
216 hidden
= gtk_widget_get_visible (GTK_WIDGET (renderdata
->tree_view
)) &&
217 (colcount
< renderdata
->colcount
- 1 ||
218 colcount
> renderdata
->colcount
+ 10);
220 gtk_widget_hide (GTK_WIDGET (renderdata
->tree_view
));
222 while (renderdata
->colcount
> colcount
)
223 gtk_tree_view_remove_column
224 (renderdata
->tree_view
,
225 gtk_tree_view_get_column (renderdata
->tree_view
,
226 --(renderdata
->colcount
)));
228 while (renderdata
->colcount
< colcount
) {
229 char *text
= g_strdup_printf (_(COLUMN_CAPTION
),
230 renderdata
->colcount
+ 1);
231 GtkCellRenderer
*cell
= gtk_cell_renderer_text_new ();
232 GtkTreeViewColumn
*column
=
233 gtk_tree_view_column_new_with_attributes
235 "text", renderdata
->colcount
,
238 "single_paragraph_mode", TRUE
,
240 gtk_tree_view_append_column (renderdata
->tree_view
, column
);
242 renderdata
->colcount
++;
245 ll
= gnumeric_lazy_list_new (render_get_value
, renderdata
,
246 MIN (lines
->len
, STF_LINE_DISPLAY_LIMIT
),
248 gnumeric_lazy_list_add_column (ll
, colcount
, G_TYPE_STRING
);
249 gtk_tree_view_set_model (renderdata
->tree_view
, GTK_TREE_MODEL (ll
));
253 gtk_widget_show (GTK_WIDGET (renderdata
->tree_view
));
257 * stf_preview_colformats_clear
258 * @renderdata: a struct containing rendering information
260 * This will clear the @renderdata->colformats array which contains the format of
266 stf_preview_colformats_clear (RenderData_t
*renderdata
)
269 g_return_if_fail (renderdata
!= NULL
);
271 for (i
= 0; i
< renderdata
->colformats
->len
; i
++)
272 go_format_unref (g_ptr_array_index (renderdata
->colformats
, i
));
273 g_ptr_array_free (renderdata
->colformats
, TRUE
);
274 renderdata
->colformats
= g_ptr_array_new ();
278 * stf_preview_colformats_add
279 * @renderdata: a struct containing rendering information
280 * @format: the format of the column
282 * This will add an entry to the @renderdata->colformats array.
283 * The widths of the columns will be set to at least have the width of
289 stf_preview_colformats_add (RenderData_t
*renderdata
, GOFormat
*format
)
292 g_return_if_fail (renderdata
!= NULL
);
293 g_return_if_fail (format
!= NULL
);
295 g_ptr_array_add (renderdata
->colformats
, go_format_ref (format
));
300 stf_preview_get_column (RenderData_t
*renderdata
, int col
)
302 return gtk_tree_view_get_column (renderdata
->tree_view
, col
);
306 stf_preview_get_cell_renderer (RenderData_t
*renderdata
, int col
)
308 GtkCellRenderer
*res
= NULL
;
309 GtkTreeViewColumn
*column
= stf_preview_get_column (renderdata
, col
);
311 GList
*renderers
= gtk_cell_layout_get_cells
312 (GTK_CELL_LAYOUT(column
));
314 res
= renderers
->data
;
315 g_list_free (renderers
);
322 stf_preview_find_column (RenderData_t
*renderdata
, int x
, int *pcol
, int *dx
)
328 /* Figure out what column we pressed in. */
329 for (col
= 0; TRUE
; col
++) {
331 GtkTreeViewColumn
*column
=
332 stf_preview_get_column (renderdata
, col
);
333 GtkCellRenderer
*cell
=
334 stf_preview_get_cell_renderer (renderdata
, col
);
337 if (!column
|| !cell
)
340 gtk_cell_renderer_get_padding (cell
, &padx
, NULL
);
341 cx
= gtk_tree_view_column_get_x_offset (column
);
342 cw
= gtk_tree_view_column_get_width (column
);
344 if (x
< (cx
+ padx
) + cw
) {
345 *dx
= x
- (cx
+ padx
);