2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * merge.c: document merge module
6 * Copyright (C) 2001 Jim Evins <evins@snaught.com>.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "merge-text.h"
32 /*===========================================*/
34 /*===========================================*/
42 glMergeInput * (*open) (glMergeType, GList *, gchar *);
43 void (*close) (glMergeInput *);
44 glMergeRecord * (*get_record) (glMergeInput *);
45 GList * (*get_raw_record) (glMergeInput *);
49 /*===========================================*/
51 /*===========================================*/
53 static TypeTexts type_text[GL_MERGE_N_TYPES];
55 static BackendFunctions func[GL_MERGE_N_TYPES];
57 /*===========================================*/
58 /* Local function prototypes */
59 /*===========================================*/
62 /*****************************************************************************/
63 /* Initialize module. */
64 /*****************************************************************************/
70 gl_debug (DEBUG_MERGE, "START");
72 /* Register backend functions and data. */
77 func[i].get_record = NULL;
78 func[i].get_raw_record = NULL;
79 type_text[i].short_text = "None";
80 type_text[i].long_text = _("None");
82 i = GL_MERGE_TEXT_TAB;
83 func[i].open = gl_merge_text_open;
84 func[i].close = gl_merge_text_close;
85 func[i].get_record = gl_merge_text_get_record;
86 func[i].get_raw_record = gl_merge_text_get_raw_record;
87 type_text[i].short_text = "Text/Tab";
88 type_text[i].long_text = _("Text with tab separators");
90 i = GL_MERGE_TEXT_COMMA;
91 func[i].open = gl_merge_text_open;
92 func[i].close = gl_merge_text_close;
93 func[i].get_record = gl_merge_text_get_record;
94 func[i].get_raw_record = gl_merge_text_get_raw_record;
95 type_text[i].short_text = "Text/Comma";
96 type_text[i].long_text = _("Text with comma separators");
98 i = GL_MERGE_TEXT_COLON;
99 func[i].open = gl_merge_text_open;
100 func[i].close = gl_merge_text_close;
101 func[i].get_record = gl_merge_text_get_record;
102 func[i].get_raw_record = gl_merge_text_get_raw_record;
103 type_text[i].short_text = "Text/Colon";
104 type_text[i].long_text = _("Text with colon separators");
106 gl_debug (DEBUG_MERGE, "END");
109 /*****************************************************************************/
110 /* Create new merge information structure. */
111 /*****************************************************************************/
112 glMerge *gl_merge_new (void)
114 gl_debug (DEBUG_MERGE, "");
116 return g_new0 (glMerge, 1);
119 /*****************************************************************************/
120 /* Duplicate merge information structure. */
121 /*****************************************************************************/
122 glMerge *gl_merge_dup (glMerge *orig)
126 gl_debug (DEBUG_MERGE, "START");
128 new = gl_merge_new ();
130 new->type = orig->type;
131 new->src = g_strdup (orig->src);
132 new->field_defs = gl_merge_dup_field_def_list (orig->field_defs);
134 gl_debug (DEBUG_MERGE, "END");
138 /*****************************************************************************/
139 /* Free existing merge information structure. */
140 /*****************************************************************************/
141 void gl_merge_free (glMerge **merge)
143 gl_debug (DEBUG_MERGE, "START");
145 g_free ((*merge)->src);
146 (*merge)->src = NULL;
147 gl_merge_free_field_def_list (&(*merge)->field_defs);
151 gl_debug (DEBUG_MERGE, "END");
154 /*****************************************************************************/
155 /* Lookup type from short text. */
156 /*****************************************************************************/
158 gl_merge_text_to_type (gchar * text)
162 gl_debug (DEBUG_MERGE, "START");
164 for (type = 0; type < GL_MERGE_N_TYPES; type++) {
165 if (g_strcasecmp (text, type_text[type].short_text) == 0) {
166 gl_debug (DEBUG_MERGE, "END");
171 gl_debug (DEBUG_MERGE, "END");
173 return GL_MERGE_NONE;
176 /*****************************************************************************/
177 /* Lookup short text for given type. */
178 /*****************************************************************************/
180 gl_merge_type_to_text (glMergeType type)
182 gl_debug (DEBUG_MERGE, "");
184 return g_strdup (type_text[type].short_text);
187 /*****************************************************************************/
188 /* Lookup type from long descriptive text. */
189 /*****************************************************************************/
191 gl_merge_long_text_to_type (gchar * text)
195 gl_debug (DEBUG_MERGE, "START");
197 for (type = 0; type < GL_MERGE_N_TYPES; type++) {
198 if (g_strcasecmp (text, type_text[type].long_text) == 0) {
199 gl_debug (DEBUG_MERGE, "END");
204 gl_debug (DEBUG_MERGE, "END");
205 return GL_MERGE_NONE;
208 /*****************************************************************************/
209 /* Lookup longer, more descriptive text for given type. */
210 /*****************************************************************************/
212 gl_merge_type_to_long_text (glMergeType type)
214 gl_debug (DEBUG_MERGE, "");
216 return g_strdup (type_text[type].long_text);
219 /*****************************************************************************/
220 /* Retrieve a list of descriptive texts for all available types. */
221 /*****************************************************************************/
223 gl_merge_get_long_texts_list (void)
228 gl_debug (DEBUG_MERGE, "START");
230 for (type = 0; type < GL_MERGE_N_TYPES; type++) {
232 list = g_list_append (list, gl_merge_type_to_long_text (type));
236 gl_debug (DEBUG_MERGE, "END");
240 /*****************************************************************************/
241 /* Free list of descriptive texts. */
242 /*****************************************************************************/
244 gl_merge_free_long_texts_list (GList ** list)
248 gl_debug (DEBUG_MERGE, "START");
250 for (p = *list; p != NULL; p = p->next) {
258 gl_debug (DEBUG_MERGE, "END");
261 /*****************************************************************************/
262 /* Duplicate field definitions. */
263 /*****************************************************************************/
264 GList *gl_merge_dup_field_def_list (GList * orig)
267 glMergeFieldDefinition *fd_new, *fd_orig;
269 gl_debug (DEBUG_MERGE, "START");
272 for (p_orig = orig; p_orig != NULL; p_orig = p_orig->next) {
273 fd_orig = (glMergeFieldDefinition *) p_orig->data;
274 fd_new = g_new0 (glMergeFieldDefinition, 1);
276 fd_new->key = g_strdup (fd_orig->key);
277 fd_new->loc = g_strdup (fd_orig->loc);
279 new = g_list_append (new, fd_new);
282 gl_debug (DEBUG_MERGE, "END");
286 /*****************************************************************************/
287 /* Free list of field definitions. */
288 /*****************************************************************************/
290 gl_merge_free_field_def_list (GList ** list)
293 glMergeFieldDefinition *field_def;
295 gl_debug (DEBUG_MERGE, "START");
297 for (p = *list; p != NULL; p = p->next) {
298 field_def = (glMergeFieldDefinition *) p->data;
300 g_free (field_def->key);
301 field_def->key = NULL;
302 g_free (field_def->loc);
303 field_def->loc = NULL;
312 gl_debug (DEBUG_MERGE, "END");
315 /*****************************************************************************/
316 /* Extract a list of valid keys from field definitions list */
317 /*****************************************************************************/
319 gl_merge_get_key_list (GList * field_defs)
322 glMergeFieldDefinition *field_def;
324 gl_debug (DEBUG_MERGE, "START");
327 for (p = field_defs; p != NULL; p = p->next) {
328 field_def = (glMergeFieldDefinition *) p->data;
330 keys = g_list_append (keys, g_strdup (field_def->key));
333 gl_debug (DEBUG_MERGE, "END");
338 /*****************************************************************************/
339 /* Free a list of keys. */
340 /*****************************************************************************/
342 gl_merge_free_key_list (GList ** keys)
346 gl_debug (DEBUG_MERGE, "START");
348 for (p = *keys; p != NULL; p = p->next) {
356 gl_debug (DEBUG_MERGE, "END");
359 /*****************************************************************************/
360 /* Lookup key for given locator. */
361 /*****************************************************************************/
363 gl_merge_find_key (GList * field_defs,
367 glMergeFieldDefinition *field_def;
369 gl_debug (DEBUG_MERGE, "START");
371 for (p = field_defs; p != NULL; p = p->next) {
372 field_def = (glMergeFieldDefinition *) p->data;
374 if (strcmp (loc, field_def->loc) == 0) {
375 gl_debug (DEBUG_MERGE, "END");
376 return g_strdup (field_def->key);
381 gl_debug (DEBUG_MERGE, "END");
386 /*****************************************************************************/
387 /* Open merge source front-end. */
388 /*****************************************************************************/
390 gl_merge_open (glMergeType type,
394 gl_debug (DEBUG_MERGE, "");
396 return func[type].open (type, field_defs, src);
399 /*****************************************************************************/
400 /* Close merge source front-end. */
401 /*****************************************************************************/
403 gl_merge_close (glMergeInput * input)
405 gl_debug (DEBUG_MERGE, "START");
407 if ( input != NULL ) {
408 func[input->type].close (input);
411 gl_debug (DEBUG_MERGE, "END");
414 /*****************************************************************************/
415 /* Get next record from merge source, NULL if exhausted (front-end). */
416 /*****************************************************************************/
418 gl_merge_get_record (glMergeInput * input)
420 gl_debug (DEBUG_MERGE, "");
422 if ( input == NULL ) {
425 return func[input->type].get_record (input);
428 /*****************************************************************************/
429 /* Get next record (raw) from merge source, NULL if exhausted (front-end). */
430 /*****************************************************************************/
432 gl_merge_get_raw_record (glMergeInput * input)
434 gl_debug (DEBUG_MERGE, "");
436 if ( input == NULL ) {
439 return func[input->type].get_raw_record (input);
442 /*****************************************************************************/
443 /* Free a merge record (list of fields) */
444 /*****************************************************************************/
446 gl_merge_free_record (glMergeRecord ** record)
451 gl_debug (DEBUG_MERGE, "START");
453 for (p = (*record)->field_list; p != NULL; p = p->next) {
454 field = (glMergeField *) p->data;
458 g_free (field->value);
465 g_list_free ((*record)->field_list);
466 (*record)->field_list = NULL;
471 gl_debug (DEBUG_MERGE, "END");
474 /*****************************************************************************/
475 /* Free a merge record (list of fields) */
476 /*****************************************************************************/
478 gl_merge_free_raw_record (GList ** record)
481 glMergeRawField *field;
483 gl_debug (DEBUG_MERGE, "START");
485 for (p = *record; p != NULL; p = p->next) {
486 field = (glMergeRawField *) p->data;
490 g_free (field->value);
498 g_list_free (*record);
501 gl_debug (DEBUG_MERGE, "END");
504 /*****************************************************************************/
505 /* Find key in given record and evaluate. */
506 /*****************************************************************************/
508 gl_merge_eval_key (gchar * key,
509 glMergeRecord * record)
514 gl_debug (DEBUG_MERGE, "START");
516 if ( record != NULL ) {
517 for (p = record->field_list; p != NULL; p = p->next) {
518 field = (glMergeField *) p->data;
520 if (strcmp (key, field->key) == 0) {
521 gl_debug (DEBUG_MERGE, "END");
522 return g_strdup (field->value);
528 gl_debug (DEBUG_MERGE, "END");
533 /*****************************************************************************/
534 /* Read all records from merge source. */
535 /*****************************************************************************/
537 gl_merge_read_data(glMergeType type,
542 glMergeRecord *record;
543 GList *record_list = NULL;
545 gl_debug (DEBUG_MERGE, "START");
547 mp = gl_merge_open (type, field_defs, src);
548 while ( (record = gl_merge_get_record (mp)) != NULL ) {
549 record_list = g_list_append( record_list, record );
553 gl_debug (DEBUG_MERGE, "END");
558 /*****************************************************************************/
559 /* Free a list of records. */
560 /*****************************************************************************/
562 gl_merge_free_data (GList ** record_list)
565 glMergeRecord *record;
567 gl_debug (DEBUG_MERGE, "START");
569 for (p = *record_list; p != NULL; p = p->next) {
570 record = (glMergeRecord *) p->data;
572 gl_merge_free_record( &record );
576 g_list_free (*record_list);
579 gl_debug (DEBUG_MERGE, "END");
582 /*****************************************************************************/
583 /* Count selected records. */
584 /*****************************************************************************/
586 gl_merge_count_records (GList *record_list)
589 glMergeRecord *record;
592 gl_debug (DEBUG_MERGE, "START");
595 for ( p=record_list; p!=NULL; p=p->next ) {
596 record = (glMergeRecord *)p->data;
598 if ( record->select_flag ) count ++;
601 gl_debug (DEBUG_MERGE, "END");