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 ******************************************************************************************************************/
91 * stf_preview_new: (skip)
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
));
155 * stf_preview_free: (skip)
156 * @data: a renderdata struct
158 * This will free the @renderdata
161 stf_preview_free (RenderData_t
*renderdata
)
163 g_return_if_fail (renderdata
!= NULL
);
165 stf_preview_colformats_clear (renderdata
);
166 g_ptr_array_free (renderdata
->colformats
, TRUE
);
168 stf_preview_set_lines (renderdata
, NULL
, NULL
);
170 g_object_unref (renderdata
->tree_view
);
176 * stf_preview_set_lines: (skip)
179 stf_preview_set_lines (RenderData_t
*renderdata
,
180 GStringChunk
*lines_chunk
,
185 GnumericLazyList
*ll
;
188 g_return_if_fail (renderdata
!= NULL
);
190 /* Empty the table. */
191 gtk_tree_view_set_model (renderdata
->tree_view
, NULL
);
193 if (renderdata
->lines
!= lines
) {
194 if (renderdata
->lines
)
195 stf_parse_general_free (renderdata
->lines
);
196 renderdata
->lines
= lines
;
199 if (renderdata
->lines_chunk
!= lines_chunk
) {
200 if (renderdata
->lines_chunk
)
201 g_string_chunk_free (renderdata
->lines_chunk
);
202 renderdata
->lines_chunk
= lines_chunk
;
208 for (i
= 0; i
< lines
->len
; i
++) {
209 GPtrArray
*line
= g_ptr_array_index (lines
, i
);
210 colcount
= MAX (colcount
, (int)line
->len
);
214 * If we are making large changes we need to hide the treeview
215 * because performance otherwise suffers a lot.
217 hidden
= gtk_widget_get_visible (GTK_WIDGET (renderdata
->tree_view
)) &&
218 (colcount
< renderdata
->colcount
- 1 ||
219 colcount
> renderdata
->colcount
+ 10);
221 gtk_widget_hide (GTK_WIDGET (renderdata
->tree_view
));
223 while (renderdata
->colcount
> colcount
)
224 gtk_tree_view_remove_column
225 (renderdata
->tree_view
,
226 gtk_tree_view_get_column (renderdata
->tree_view
,
227 --(renderdata
->colcount
)));
229 while (renderdata
->colcount
< colcount
) {
230 char *text
= g_strdup_printf (_(COLUMN_CAPTION
),
231 renderdata
->colcount
+ 1);
232 GtkCellRenderer
*cell
= gtk_cell_renderer_text_new ();
233 GtkTreeViewColumn
*column
=
234 gtk_tree_view_column_new_with_attributes
236 "text", renderdata
->colcount
,
239 "single_paragraph_mode", TRUE
,
241 gtk_tree_view_append_column (renderdata
->tree_view
, column
);
243 renderdata
->colcount
++;
246 ll
= gnumeric_lazy_list_new (render_get_value
, renderdata
,
247 MIN (lines
->len
, STF_LINE_DISPLAY_LIMIT
),
249 gnumeric_lazy_list_add_column (ll
, colcount
, G_TYPE_STRING
);
250 gtk_tree_view_set_model (renderdata
->tree_view
, GTK_TREE_MODEL (ll
));
254 gtk_widget_show (GTK_WIDGET (renderdata
->tree_view
));
258 * stf_preview_colformats_clear: (skip)
259 * @renderdata: a struct containing rendering information
261 * This will clear the @renderdata->colformats array which contains the format of
265 stf_preview_colformats_clear (RenderData_t
*renderdata
)
268 g_return_if_fail (renderdata
!= NULL
);
270 for (i
= 0; i
< renderdata
->colformats
->len
; i
++)
271 go_format_unref (g_ptr_array_index (renderdata
->colformats
, i
));
272 g_ptr_array_free (renderdata
->colformats
, TRUE
);
273 renderdata
->colformats
= g_ptr_array_new ();
277 * stf_preview_colformats_add: (skip)
278 * @renderdata: a struct containing rendering information
279 * @format: the format of the column
281 * This will add an entry to the @renderdata->colformats array.
282 * The widths of the columns will be set to at least have the width of
288 stf_preview_colformats_add (RenderData_t
*renderdata
, GOFormat
*format
)
291 g_return_if_fail (renderdata
!= NULL
);
292 g_return_if_fail (format
!= NULL
);
294 g_ptr_array_add (renderdata
->colformats
, go_format_ref (format
));
298 * stf_preview_get_column: (skip)
301 stf_preview_get_column (RenderData_t
*renderdata
, int col
)
303 return gtk_tree_view_get_column (renderdata
->tree_view
, col
);
307 * stf_preview_get_cell_renderer: (skip)
310 stf_preview_get_cell_renderer (RenderData_t
*renderdata
, int col
)
312 GtkCellRenderer
*res
= NULL
;
313 GtkTreeViewColumn
*column
= stf_preview_get_column (renderdata
, col
);
315 GList
*renderers
= gtk_cell_layout_get_cells
316 (GTK_CELL_LAYOUT(column
));
318 res
= renderers
->data
;
319 g_list_free (renderers
);
326 stf_preview_find_column (RenderData_t
*renderdata
, int x
, int *pcol
, int *dx
)
332 /* Figure out what column we pressed in. */
333 for (col
= 0; TRUE
; col
++) {
335 GtkTreeViewColumn
*column
=
336 stf_preview_get_column (renderdata
, col
);
337 GtkCellRenderer
*cell
=
338 stf_preview_get_cell_renderer (renderdata
, col
);
341 if (!column
|| !cell
)
344 gtk_cell_renderer_get_padding (cell
, &padx
, NULL
);
345 cx
= gtk_tree_view_column_get_x_offset (column
);
346 cw
= gtk_tree_view_column_get_width (column
);
348 if (x
< (cx
+ padx
) + cw
) {
349 *dx
= x
- (cx
+ padx
);