1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2004 Sebastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * header data read in .wiz file, used in the first page (project selection)
24 *---------------------------------------------------------------------------*/
30 #include <glib/gdir.h>
32 /*---------------------------------------------------------------------------*/
34 #define STRING_CHUNK_SIZE 256
36 /*---------------------------------------------------------------------------*/
41 GStringChunk
* string_pool
;
56 *---------------------------------------------------------------------------*/
59 npw_header_new (NPWHeaderList
* owner
)
63 g_return_val_if_fail (owner
, NULL
);
65 this = g_chunk_new0(NPWHeader
, owner
->data_pool
);
67 this->node
= g_node_append_data (owner
->list
, this);
73 npw_header_free (NPWHeader
* this)
77 node
= g_node_find (this->owner
->list
, G_IN_ORDER
, G_TRAVERSE_ALL
, this);
80 g_node_destroy (node
);
81 /* Memory allocated in string pool and project pool is not free */
86 npw_header_set_name (NPWHeader
* this, const gchar
* name
)
88 this->name
= g_string_chunk_insert (this->owner
->string_pool
, name
);
92 npw_header_get_name (const NPWHeader
* this)
98 npw_header_set_filename (NPWHeader
* this, const gchar
* filename
)
100 this->filename
= g_string_chunk_insert (this->owner
->string_pool
, filename
);
104 npw_header_get_filename (const NPWHeader
* this)
106 return this->filename
;
110 npw_header_set_category (NPWHeader
* this, const gchar
* category
)
112 npw_header_list_organize(this->owner
, category
, this);
113 this->category
= ((NPWHeader
*)this->node
->parent
->data
)->category
;
117 npw_header_get_category (const NPWHeader
* this)
119 return this->category
;
123 npw_header_set_description (NPWHeader
* this, const gchar
* description
)
125 this->description
= g_string_chunk_insert (this->owner
->string_pool
, description
);
129 npw_header_get_description (const NPWHeader
* this)
131 return this->description
;
135 npw_header_set_iconfile (NPWHeader
* this, const gchar
* iconfile
)
137 this->iconfile
= g_string_chunk_insert (this->owner
->string_pool
, iconfile
);
141 npw_header_get_iconfile (const NPWHeader
* this)
143 return this->iconfile
;
147 npw_header_is_leaf(const NPWHeader
* this)
149 return G_NODE_IS_LEAF(this->node
);
154 *---------------------------------------------------------------------------*/
157 npw_header_list_find_parent(NPWHeaderList
* this, const gchar
* category
, gboolean create
)
162 for (node
= g_node_first_child(this->list
); node
!= NULL
; node
= g_node_next_sibling(node
))
166 s
= ((NPWHeader
*)node
->data
)->category
;
169 order
= g_ascii_strcasecmp (s
, category
);
172 /* Find right category */
179 /* Category doesn't exist create a new node */
180 NPWHeader
* new_parent
;
182 new_parent
= npw_header_new (this);
183 new_parent
->category
= g_string_chunk_insert (this->string_pool
, category
);
184 g_node_unlink (new_parent
->node
);
185 g_node_insert_before (this->list
, node
, new_parent
->node
);
186 node
= new_parent
->node
;
197 if (create
&& (node
== NULL
))
199 NPWHeader
* new_parent
;
201 new_parent
= npw_header_new (this);
202 new_parent
->category
= g_string_chunk_insert (this->string_pool
, category
);
203 node
= new_parent
->node
;
209 typedef struct _HeaderListForeachProjectData
211 NPWHeaderForeachFunc func
;
213 } HeaderListForeachProjectData
;
216 cb_header_list_foreach_project (GNode
* node
, gpointer data
)
218 HeaderListForeachProjectData
* d
= (HeaderListForeachProjectData
*)data
;
220 (d
->func
)((NPWHeader
*)node
->data
, d
->data
);
224 npw_header_list_foreach_node (GNode
* list
, NPWHeaderForeachFunc func
, gpointer data
, GTraverseFlags flag
)
226 HeaderListForeachProjectData d
;
228 if (g_node_first_child (list
) == NULL
) return FALSE
;
233 g_node_children_foreach (list
, flag
, cb_header_list_foreach_project
, &d
);
238 /*---------------------------------------------------------------------------*/
241 npw_header_list_new (void)
245 this = g_new (NPWHeaderList
, 1);
246 this->string_pool
= g_string_chunk_new (STRING_CHUNK_SIZE
);
247 this->data_pool
= g_mem_chunk_new ("project pool", sizeof (NPWHeader
), STRING_CHUNK_SIZE
* sizeof (NPWHeader
) / 4, G_ALLOC_ONLY
);
248 this->list
= g_node_new (NULL
);
254 npw_header_list_free (NPWHeaderList
* this)
256 g_return_if_fail (this != NULL
);
258 g_string_chunk_free (this->string_pool
);
259 g_mem_chunk_destroy (this->data_pool
);
260 g_node_destroy (this->list
);
265 npw_header_list_organize(NPWHeaderList
* this, const gchar
* category
, NPWHeader
* header
)
271 /* node without a category stay on top */
272 if ((category
== NULL
) || (*category
== '\0')) return;
274 /* Detach the node */
275 g_node_unlink(header
->node
);
278 parent
= npw_header_list_find_parent(this, category
, TRUE
);
280 /* Insert node as a child in alphabetic order*/
281 name
= npw_header_get_name (header
);
282 for (node
= g_node_first_child(parent
); node
!= NULL
; node
= g_node_next_sibling(node
))
284 if (g_ascii_strcasecmp (npw_header_get_name ((NPWHeader
*)node
->data
), name
) > 0)
286 g_node_insert_before (parent
, node
, header
->node
);
290 g_node_insert(parent
, -1, header
->node
);
294 npw_header_list_foreach_project (const NPWHeaderList
* this, NPWHeaderForeachFunc func
, gpointer data
)
296 return npw_header_list_foreach_node (this->list
, func
, data
, G_TRAVERSE_LEAFS
);
300 npw_header_list_foreach_project_in (const NPWHeaderList
* this, const gchar
* category
, NPWHeaderForeachFunc func
, gpointer data
)
304 /* FIXME: const modified has been removed because the find function
305 * with TRUE as the third argument could create a parent if it
306 * doesn't exist. It could be better to split this function in two */
307 node
= npw_header_list_find_parent((NPWHeaderList
*)this, category
, FALSE
);
308 if (node
== NULL
) return FALSE
;
310 return npw_header_list_foreach_node (node
, func
, data
, G_TRAVERSE_LEAFS
);
314 npw_header_list_foreach_category (const NPWHeaderList
* this, NPWHeaderForeachFunc func
, gpointer data
)
316 return npw_header_list_foreach_node (this->list
, func
, data
, G_TRAVERSE_NON_LEAFS
);