GnuCash  5.6-150-g038405b370+
doclinkcell.c
1 /********************************************************************\
2  * doclinkcell.c -- Document Link checkbox cell *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA gnu@gnu.org *
20  * *
21 \********************************************************************/
22 
23 /*
24  * FILE:
25  * doclinkcell.c
26  *
27  * FUNCTION:
28  * Implements a mouse-click cell that allows a series
29  * of values to be clicked through and return a glyth if
30  * font allows it.
31  *
32  * HISTORY:
33  * Copyright (c) 1998 Linas Vepstas
34  * Copyright (c) 2000 Dave Peticolas
35  * Copyright (c) 2001 Derek Atkins
36  * Copyright (c) 2020 Robert Fewell
37  */
38 
39 #include <config.h>
40 
41 #include <stdlib.h>
42 #include <string.h>
43 #include <time.h>
44 
45 #include "basiccell.h"
46 #include "gnc-engine.h"
47 #include "doclinkcell.h"
48 #include "gnc-ui-util.h"
49 
50 static void gnc_doclink_cell_set_value (BasicCell *_cell, const char *value);
51 
52 const char *
53 gnc_doclink_get_glyph_from_flag (char link_flag)
54 {
55  switch (link_flag)
56  {
57  case WLINK:
58  return GLYPH_LINK;
59  case FLINK:
60  return GLYPH_PAPERCLIP;
61  default:
62  return " ";
63  }
64 }
65 
66 static const char
67 gnc_doclink_get_flag_from_glyph (const char *glyph)
68 {
69  if (strcmp (glyph, GLYPH_LINK) == 0)
70  return WLINK;
71  else if (strcmp (glyph, GLYPH_PAPERCLIP) == 0)
72  return FLINK;
73  else
74  return ' ';
75 }
76 
77 gboolean
78 gnc_doclink_get_use_glyphs (Doclinkcell *cell)
79 {
80  return cell->use_glyphs;
81 }
82 
83 static const char *
84 gnc_doclink_cell_get_string (Doclinkcell *cell, char flag)
85 {
86  static char str[2] = { 0, 0 };
87 
88  if (cell->use_glyphs)
89  return gnc_doclink_get_glyph_from_flag (flag);
90 
91  if (cell->get_string != NULL)
92  return (cell->get_string)(flag);
93 
94  str[0] = flag;
95 
96  return str;
97 }
98 
99 static gboolean
100 gnc_doclink_cell_enter (BasicCell *_cell,
101  int *cursor_position,
102  int *start_selection,
103  int *end_selection)
104 {
105  Doclinkcell *cell = (Doclinkcell *) _cell;
106  char * this_flag;
107 
108  if (cell->confirm_cb &&
109  ! (cell->confirm_cb (cell->flag, cell->confirm_data)))
110  return FALSE;
111 
112  if (cell->read_only == TRUE)
113  return FALSE;
114 
115  /* Find the current flag in the list of flags */
116  this_flag = strchr (cell->flag_order, cell->flag);
117 
118  if (this_flag == NULL || *this_flag == '\0')
119  {
120  /* If it's not there (or the list is empty) use default_flag */
121  cell->flag = cell->default_flag;
122  }
123  else
124  {
125  /* It is in the list -- choose the -next- item in the list (wrapping
126  * around as necessary).
127  */
128  this_flag++;
129  if (*this_flag != '\0')
130  cell->flag = *this_flag;
131  else
132  cell->flag = *(cell->flag_order);
133  }
134 
135  /* And set the display */
136  gnc_doclink_cell_set_flag (cell, cell->flag);
137 
138  return FALSE;
139 }
140 
141 static void
142 gnc_doclink_cell_init (Doclinkcell *cell)
143 {
144  gnc_basic_cell_init (&cell->cell);
145 
146  gnc_doclink_cell_set_flag (cell, '\0');
147  cell->confirm_cb = NULL;
148  cell->get_string = NULL;
149  cell->valid_flags = "";
150  cell->flag_order = "";
151  cell->read_only = FALSE;
152  cell->use_glyphs = FALSE;
153 
154  cell->cell.enter_cell = gnc_doclink_cell_enter;
155  cell->cell.set_value = gnc_doclink_cell_set_value;
156 }
157 
158 BasicCell *
159 gnc_doclink_cell_new (void)
160 {
161  Doclinkcell * cell;
162 
163  cell = g_new0 (Doclinkcell, 1);
164 
165  gnc_doclink_cell_init (cell);
166 
167  return &cell->cell;
168 }
169 
170 /* assumes we are given the untranslated form */
171 static void
172 gnc_doclink_cell_set_value (BasicCell *_cell, const char *value)
173 {
174  Doclinkcell *cell = (Doclinkcell *) _cell;
175  char flag;
176 
177  if (!value || *value == '\0')
178  {
179  cell->flag = cell->default_flag;
180  gnc_basic_cell_set_value_internal (_cell, "");
181  return;
182  }
183 
184  if (cell->use_glyphs)
185  flag = gnc_doclink_get_flag_from_glyph (value);
186  else
187  {
188  flag = cell->default_flag;
189  if (strchr (cell->valid_flags, *value) != NULL)
190  flag = *value;
191  }
192  gnc_doclink_cell_set_flag (cell, flag);
193 }
194 
195 void
196 gnc_doclink_cell_set_flag (Doclinkcell *cell, char flag)
197 {
198  const char *string;
199 
200  g_return_if_fail (cell != NULL);
201 
202  cell->flag = flag;
203  string = gnc_doclink_cell_get_string (cell, flag);
204 
205  gnc_basic_cell_set_value_internal (&cell->cell, string);
206 }
207 
208 char
209 gnc_doclink_cell_get_flag (Doclinkcell *cell)
210 {
211  g_return_val_if_fail (cell != NULL, '\0');
212 
213  return cell->flag;
214 }
215 
216 void
217 gnc_doclink_cell_set_string_getter (Doclinkcell *cell,
218  DoclinkcellStringGetter get_string)
219 {
220  g_return_if_fail (cell != NULL);
221 
222  cell->get_string = get_string;
223 }
224 
225 void
226 gnc_doclink_cell_set_confirm_cb (Doclinkcell *cell, DoclinkcellConfirm confirm_cb,
227  gpointer data)
228 {
229  g_return_if_fail (cell != NULL);
230 
231  cell->confirm_cb = confirm_cb;
232  cell->confirm_data = data;
233 }
234 
235 void
237  char default_flag)
238 {
239  g_return_if_fail (cell != NULL);
240  g_return_if_fail (flags != NULL);
241 
242  cell->valid_flags = (char *)flags;
243  cell->default_flag = default_flag;
244 }
245 
246 void
247 gnc_doclink_cell_set_flag_order (Doclinkcell *cell, const char *flags)
248 {
249  g_return_if_fail (cell != NULL);
250  g_return_if_fail (flags != NULL);
251 
252  cell->flag_order = (char *)flags;
253 }
254 
255 void
256 gnc_doclink_cell_set_read_only (Doclinkcell *cell, gboolean read_only)
257 {
258  g_return_if_fail (cell != NULL);
259 
260  cell->read_only = read_only;
261 }
262 
263 void
264 gnc_doclink_cell_set_use_glyphs (Doclinkcell *cell)
265 {
266 #ifdef MAC_INTEGRATION
267  cell->use_glyphs = FALSE;
268 #else
269  gboolean use_glyphs = TRUE;
270  gchar *test_text;
271  GtkWidget *label;
272  PangoLayout *test_layout;
273  gint count;
274 
275  g_return_if_fail (cell != NULL);
276 
277  label = gtk_label_new (NULL);
278  test_text = g_strconcat (GLYPH_LINK, ",", GLYPH_PAPERCLIP, NULL);
279  test_layout = gtk_widget_create_pango_layout (GTK_WIDGET (label), test_text);
280 
281  pango_layout_set_text (test_layout, test_text, strlen (test_text));
282 
283  count = pango_layout_get_unknown_glyphs_count (test_layout);
284 
285  if (count != 0)
286  use_glyphs = FALSE;
287 
288  g_object_unref (test_layout);
289  g_free (test_text);
290 
291  cell->use_glyphs = use_glyphs;
292 #endif
293 }
utility functions for the GnuCash UI
char * valid_flags
The actual flag value.
Definition: doclinkcell.h:58
The Doclinkcell object implements a cell handler that will cycle through a series of single-character...
Definition: doclinkcell.h:52
char * flag_order
The list of valid flags.
Definition: doclinkcell.h:59
char default_flag
Automatic flag selection order.
Definition: doclinkcell.h:60
void gnc_doclink_cell_set_valid_flags(Doclinkcell *cell, const char *flags, char default_flag)
note that
Definition: doclinkcell.c:236
All type declarations for the whole Gnucash engine.
DoclinkcellStringGetter get_string
Default flag for unknown user input.
Definition: doclinkcell.h:62