Branch: refs/heads/master Author: Dimitar Zhekov dimitar.zhekov@gmail.com Committer: Dimitar Zhekov dimitar.zhekov@gmail.com Date: Thu, 16 May 2013 18:12:25 UTC Commit: d3b344de660620ce85847b1ed72a75587735d485 https://github.com/geany/geany-plugins/commit/d3b344de660620ce85847b1ed72a75...
Log Message: ----------- scope - added scp_tree_store_traverse()
Modified Paths: -------------- scope/ChangeLog scope/src/store/ChangeLog scope/src/store/scptreestore.c scope/src/store/scptreestore.h scope/src/store/scptreestore.html scope/src/views.c scope/src/views.h
Modified: scope/ChangeLog 8 files changed, 7 insertions(+), 1 deletions(-) =================================================================== @@ -1,3 +1,9 @@ +2013-05-16 Dimitar Zhekov dimitar.zhekov@gmail.com + + * src/store/ChangeLog: + Separate change log for ScpTreeStore - initial release. + + 2013-05-08 Dimitar Zhekov dimitar.zhekov@gmail.com
* src/conterm.c: @@ -8,7 +14,7 @@ * src/view.c: Small improvements. * docs/scope.html, src/scope.c: - Increased version to 0.87. + Increased version to 0.88.
2013-05-04 Dimitar Zhekov dimitar.zhekov@gmail.com
Modified: scope/src/store/ChangeLog 9 files changed, 9 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,9 @@ +2013-05-16 Dimitar Zhekov dimitar.zhekov@gmail.com + + * scptreestore.c, scptreestore.h: + Added scp_tree_store_traverse(). + Moved scp_tree_store_iter_tell() from Extra to Store, it's required + to insert before/after and move. + * scptreestore.html: + Documentation and speed test results for scp_tree_store_traverse(). + Increased version to 0.84.
Modified: scope/src/store/scptreestore.c 84 files changed, 75 insertions(+), 9 deletions(-) =================================================================== @@ -821,6 +821,15 @@ void scp_tree_store_move(ScpTreeStore *store, GtkTreeIter *iter, gint position) scp_move_element(store, array, iter, position, TRUE); }
+gint scp_tree_store_iter_tell(VALIDATE_ONLY ScpTreeStore *store, GtkTreeIter *iter) +{ + g_return_val_if_fail(SCP_IS_TREE_STORE(store), -1); + g_return_val_if_fail(VALID_ITER(iter, store), -1); + g_return_val_if_fail((guint) ITER_INDEX(iter) < ITER_ARRAY(iter)->len, -1); + + return ITER_INDEX(iter); +} + /* Model */
static gint scp_ptr_array_find(GPtrArray *array, AElem *elem) @@ -1531,15 +1540,6 @@ gboolean scp_tree_store_iter_seek(VALIDATE_ONLY ScpTreeStore *store, GtkTreeIter return TRUE; }
-gint scp_tree_store_iter_tell(VALIDATE_ONLY ScpTreeStore *store, GtkTreeIter *iter) -{ - g_return_val_if_fail(SCP_IS_TREE_STORE(store), -1); - g_return_val_if_fail(VALID_ITER(iter, store), -1); - g_return_val_if_fail((guint) ITER_INDEX(iter) < ITER_ARRAY(iter)->len, -1); - - return ITER_INDEX(iter); -} - static gint scp_collate_data(const gchar *key, const gchar *data) { gchar *key1 = g_utf8_collate_key(data, -1); @@ -1663,6 +1663,72 @@ gboolean scp_tree_store_search(ScpTreeStore *store, gboolean sublevels, gboolean return found; }
+static gboolean scp_traverse(ScpTreeStore *store, GPtrArray *array, GtkTreeIter *iter, + gboolean sublevels, ScpTreeStoreTraverseFunc func, gpointer gdata) +{ + if (array) + { + guint i = 0; + + iter->user_data = array; + iter->user_data2 = GINT_TO_POINTER(0); + + while (i < array->len) + { + gint result = func(store, iter, gdata); + + if (result > 0) + return TRUE; + + if (!result) + { + if (sublevels) + { + if (scp_traverse(store, ((AElem *) array->pdata[i])->children, + iter, TRUE, func, gdata) > 0) + { + return TRUE; + } + + iter->user_data = array; + } + + iter->user_data2 = GINT_TO_POINTER(++i); + } + else + scp_tree_store_remove(store, iter); + } + } + + return FALSE; +} + +gboolean scp_tree_store_traverse(ScpTreeStore *store, gboolean sublevels, GtkTreeIter *iter, + GtkTreeIter *parent, ScpTreeStoreTraverseFunc func, gpointer gdata) +{ + ScpTreeStorePrivate *priv = store->priv; + GtkTreeIter iter1; + + g_return_val_if_fail(SCP_IS_TREE_STORE(store), FALSE); + g_return_val_if_fail(VALID_ITER_OR_NULL(parent, store), FALSE); + g_return_val_if_fail(sublevels == FALSE || priv->sublevels == TRUE, FALSE); + g_return_val_if_fail(func != NULL, FALSE); + + if (!iter) + iter = &iter1; + + iter->stamp = priv->stamp; + + if (!scp_traverse(store, (parent ? ITER_ELEM(parent) : priv->root)->children, iter, + sublevels, func, gdata)) + { + iter->stamp = 0; + return FALSE; + } + + return TRUE; +} + /* Class */
static void scp_tree_store_tree_model_init(GtkTreeModelIface *iface)
Modified: scope/src/store/scptreestore.h 6 files changed, 5 insertions(+), 1 deletions(-) =================================================================== @@ -98,6 +98,7 @@ void scp_tree_store_clear_children(ScpTreeStore *store, GtkTreeIter *parent, void scp_tree_store_reorder(ScpTreeStore *store, GtkTreeIter *parent, gint *new_order); void scp_tree_store_swap(ScpTreeStore *store, GtkTreeIter *a, GtkTreeIter *b); void scp_tree_store_move(ScpTreeStore *store, GtkTreeIter *iter, gint position); +gint scp_tree_store_iter_tell(ScpTreeStore *store, GtkTreeIter *iter);
/* Model */ GtkTreeModelFlags scp_tree_store_get_flags(ScpTreeStore *store); @@ -149,9 +150,12 @@ void scp_tree_store_set_allocation(ScpTreeStore *store, guint toplevel_reserved, gint scp_tree_store_compare_func(ScpTreeStore *store, GtkTreeIter *a, GtkTreeIter *b, gpointer data); gboolean scp_tree_store_iter_seek(ScpTreeStore *store, GtkTreeIter *iter, gint position); -gint scp_tree_store_iter_tell(ScpTreeStore *store, GtkTreeIter *iter); gboolean scp_tree_store_search(ScpTreeStore *store, gboolean sublevels, gboolean linear_order, GtkTreeIter *iter, GtkTreeIter *parent, gint column, ...); +typedef gint (*ScpTreeStoreTraverseFunc)(ScpTreeStore *store, GtkTreeIter *iter, + gpointer gdata); +gboolean scp_tree_store_traverse(ScpTreeStore *store, gboolean sublevels, GtkTreeIter *iter, + GtkTreeIter *parent, ScpTreeStoreTraverseFunc func, gpointer gdata);
G_END_DECLS
Modified: scope/src/store/scptreestore.html 65 files changed, 55 insertions(+), 10 deletions(-) =================================================================== @@ -55,9 +55,9 @@ #include "scptreestore.h"</p>
<p>/* Store */<br> -ScpTreeStore *<a href="scp_tree_store_new">scp_tree_store_new</a>(gboolean sublevels, gint +ScpTreeStore *<a href="#scp_tree_store_new">scp_tree_store_new</a>(gboolean sublevels, gint n_columns, ...);<br> -ScpTreeStore *<a href="scp_tree_store_newv">scp_tree_store_newv</a>(gboolean sublevels, gint +ScpTreeStore *<a href="#scp_tree_store_newv">scp_tree_store_newv</a>(gboolean sublevels, gint n_columns, GType *types);<br> gboolean scp_tree_store_set_column_types(ScpTreeStore *store, gint n_columns, GType *types);<br> #define scp_tree_store_set_utf8_collate(store, utf8_collate) @@ -85,16 +85,16 @@ *parent, gint position, ...);<br> #define scp_tree_store_prepend_with_values(store, iter, parent, ...)<br> #define scp_tree_store_append_with_values(store, iter, parent, ...)<br> -void <a href="scp_tree_store_get_valist">scp_tree_store_get_valist</a>(ScpTreeStore *store, +void <a href="#scp_tree_store_get_valist">scp_tree_store_get_valist</a>(ScpTreeStore *store, GtkTreeIter *iter, va_list var_args);<br> -void <a href="scp_tree_store_get">scp_tree_store_get</a>(ScpTreeStore *store, GtkTreeIter +void <a href="#scp_tree_store_get">scp_tree_store_get</a>(ScpTreeStore *store, GtkTreeIter *iter, ...);<br> gboolean scp_tree_store_is_ancestor(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter *descendant);<br> gint scp_tree_store_iter_depth(ScpTreeStore *store, GtkTreeIter *iter);<br> -void <a href="scp_tree_store_clear_children">scp_tree_store_clear_children</a>(ScpTreeStore +void <a href="#scp_tree_store_clear_children">scp_tree_store_clear_children</a>(ScpTreeStore *store, GtkTreeIter *parent, gboolean emit_subsignals);<br> -#define <a href="scp_tree_store_clear">scp_tree_store_clear(store)</a><br> +#define <a href="#scp_tree_store_clear">scp_tree_store_clear(store)</a><br> gboolean scp_tree_store_iter_is_valid(ScpTreeStore *store, GtkTreeIter *iter);<br> void scp_tree_store_reorder(ScpTreeStore *store, GtkTreeIter *parent, gint *new_order);<br> void scp_tree_store_swap(ScpTreeStore *store, GtkTreeIter *a, GtkTreeIter *b);<br> @@ -148,7 +148,7 @@ </p>
<p>/* Extra */<br> -void <a href="scp_tree_store_set_allocation">scp_tree_store_set_allocation</a>(ScpTreeStore +void <a href="#scp_tree_store_set_allocation">scp_tree_store_set_allocation</a>(ScpTreeStore *store, guint toplevel_reserved, guint sublevel_reserved, gboolean sublevel_discard);<br> gint <a href="#scp_tree_store_compare_func">scp_tree_store_compare_func</a>(ScpTreeStore *store, GtkTreeIter *a, GtkTreeIter *b, gpointer data);<br> @@ -157,7 +157,12 @@ gint scp_tree_store_iter_tell(ScpTreeStore *store, GtkTreeIter *iter);<br> gboolean <a href="#scp_tree_store_search">scp_tree_store_search</a>(ScpTreeStore *store, gboolean sublevels, gboolean linear_order, GtkTreeIter *iter, GtkTreeIter *parent, gint column, -...); +...);<br> +typedef gint (*<a href="#ScpTreeStoreTraverseFunc">ScpTreeStoreTraverseFunc</a>)(ScpTreeStore +*store, GtkTreeIter *iter, gpointer gdata);<br> +gboolean <a href="#scp_tree_store_traverse">scp_tree_store_traverse</a>(ScpTreeStore *store, +gboolean sublevels, GtkTreeIter *iter, GtkTreeIter *parent, ScpTreeStoreTraverseFunc func, +gpointer gdata); </p>
<hr> @@ -331,6 +336,30 @@ compare function is ignored, because it requires an iterator, not a value. For string columns, utf8_collate is taken into account.</p>
+<h3><a name="ScpTreeStoreTraverseFunc">ScpTreeStoreTraverseFunc()</a></h3> + +<p><b>gint ScpTreeStoreTraverseFunc(ScpTreeStore *store, GtkTreeIter *iter, gpointer gdata); +</b></p> + +<div>The callback function type for scp_tree_store_traverse(). Return values:</div> +<div class="tab"><tt>TRUE</tt> (or another positive value): stop iterating<br> +<tt>FALSE</tt>: continue iterating<br> +<tt>-1</tt> (or another negative value): remove the current element and continue.</div> + +<h3><a name="scp_tree_store_traverse">scp_tree_store_traverse()</a></h3> + +<p><b>gboolean scp_tree_store_traverse(ScpTreeStore *store, gboolean sublevels, GtkTreeIter +*iter, GtkTreeIter *parent, ScpTreeStoreTraverseFunc func, gpointer gdata);</b></p> + +<div>Traverse the rows under parent.</div> +<div class="tab">iter: optional, may be NULL<br> +parent = NULL: traverse the top-level rows.</div> +<br> +<div>Return values:</div> +<div class="tab"><tt>TRUE</tt> and valid iter if func returns <tt>TRUE</tt> (or +another positive value)<br> +<tt>FALSE</tt> and invalid iter otherwise.</div><br> + <hr>
<h3><a name="properties">Properties</a></h3> @@ -404,6 +433,8 @@ <tr><td>top-level iter search string</td><td>25</td><td>0.003</td><td>0.002</td><td>25</td></tr> <tr><td>top-level linear search double</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr> <tr><td>top-level linear search string</td><td>25</td><td>n/a</td><td>0.001</td><td>25</td></tr> +<tr><td>both levels model foreach</td><td>25</td><td>0.000</td><td>0.000</td><td>25</td></tr> +<tr><td>both levels store traverse</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr> <tr><td>top-level quick sort double</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> <tr><td>top-level quick sort string</td><td>25</td><td>0.001</td><td>0.000</td><td></td></tr> <tr><td>sublevel 1 insert</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> @@ -422,6 +453,8 @@ <tr><td>top-level iter search string</td><td>100</td><td>0.034</td><td>0.027</td><td>100</td></tr> <tr><td>top-level linear search double</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr> <tr><td>top-level linear search string</td><td>100</td><td>n/a</td><td>0.015</td><td>100</td></tr> +<tr><td>both levels model foreach</td><td>100</td><td>0.003</td><td>0.003</td><td>100</td></tr> +<tr><td>both levels store traverse</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr> <tr><td>top-level quick sort double</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr> <tr><td>top-level quick sort string</td><td>100</td><td>0.003</td><td>0.002</td><td></td></tr> <tr><td>sublevel 1 insert</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr> @@ -440,6 +473,8 @@ <tr><td>top-level iter search string</td><td>250</td><td>0.224</td><td>0.183</td><td>250</td></tr> <tr><td>top-level linear search double</td><td>250</td><td>n/a</td><td>0.001</td><td>250</td></tr> <tr><td>top-level linear search string</td><td>250</td><td>n/a</td><td>0.109</td><td>250</td></tr> +<tr><td>both levels model foreach</td><td>250</td><td>0.018</td><td>0.018</td><td>250</td></tr> +<tr><td>both levels store traverse</td><td>250</td><td>n/a</td><td>0.001</td><td>250</td></tr> <tr><td>top-level quick sort double</td><td>250</td><td>0.001</td><td>0.000</td><td></td></tr> <tr><td>top-level quick sort string</td><td>250</td><td>0.009</td><td>0.008</td><td></td></tr> <tr><td>sublevel 1 insert</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr> @@ -449,7 +484,7 @@ <tr><td>sublevel 1 quick sort double</td><td>250</td><td>0.002</td><td>0.000</td><td></td></tr> <tr><td>sublevel 1 quick sort string</td><td>250</td><td>0.015</td><td>0.012</td><td></td></tr>
-<tr><td> </td><td>500</td><td></td><td></td><td></td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> <tr><td>top-level insert</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr> <tr><td>top-level set</td><td>500</td><td>0.003</td><td>0.002</td><td></td></tr> <tr><td>top-level remove</td><td>500</td><td>0.002</td><td>0.001</td><td></td></tr> @@ -458,6 +493,8 @@ <tr><td>top-level iter search string</td><td>500</td><td>0.909</td><td>0.722</td><td>500</td></tr> <tr><td>top-level linear search double</td><td>500</td><td>n/a</td><td>0.005</td><td>500</td></tr> <tr><td>top-level linear search string</td><td>500</td><td>n/a</td><td>0.443</td><td>500</td></tr> +<tr><td>both levels model foreach</td><td>500</td><td>0.077</td><td>0.076</td><td>500</td></tr> +<tr><td>both levels store traverse</td><td>500</td><td>n/a</td><td>0.003</td><td>500</td></tr> <tr><td>top-level quick sort double</td><td>500</td><td>0.003</td><td>0.001</td><td></td></tr> <tr><td>top-level quick sort string</td><td>500</td><td>0.022</td><td>0.018</td><td></td></tr> <tr><td>sublevel 1 insert</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr> @@ -476,6 +513,8 @@ <tr><td>top-level iter search string</td><td>1000</td><td>0.370</td><td>0.273</td><td>100</td></tr> <tr><td>top-level linear search double</td><td>1000</td><td>n/a</td><td>0.002</td><td>100</td></tr> <tr><td>top-level linear search string</td><td>1000</td><td>n/a</td><td>0.182</td><td>100</td></tr> +<tr><td>both levels model foreach</td><td>1000</td><td>0.033</td><td>0.030</td><td>100</td></tr> +<tr><td>both levels store traverse</td><td>1000</td><td>n/a</td><td>0.001</td><td>100</td></tr> <tr><td>top-level quick sort double</td><td>1000</td><td>0.007</td><td>0.002</td><td></td></tr> <tr><td>top-level quick sort string</td><td>1000</td><td>0.050</td><td>0.040</td><td></td></tr> <tr><td>sublevel 1 insert</td><td>1000</td><td>0.006</td><td>0.004</td><td></td></tr> @@ -494,6 +533,8 @@ <tr><td>top-level iter search string</td><td>2500</td><td>2.273</td><td>1.859</td><td>250</td></tr> <tr><td>top-level linear search double</td><td>2500</td><td>n/a</td><td>0.015</td><td>250</td></tr> <tr><td>top-level linear search string</td><td>2500</td><td>n/a</td><td>1.137</td><td>250</td></tr> +<tr><td>both levels model foreach</td><td>2500</td><td>0.182</td><td>0.188</td><td>250</td></tr> +<tr><td>both levels store traverse</td><td>2500</td><td>n/a</td><td>0.009</td><td>250</td></tr> <tr><td>top-level quick sort double</td><td>2500</td><td>0.021</td><td>0.004</td><td></td></tr> <tr><td>top-level quick sort string</td><td>2500</td><td>0.146</td><td>0.117</td><td></td></tr> <tr><td>sublevel 1 insert</td><td>2500</td><td>0.035</td><td>0.014</td><td></td></tr> @@ -512,6 +553,8 @@ <tr><td>top-level iter search string</td><td>5000</td><td>8.775</td><td>7.787</td><td>500</td></tr> <tr><td>top-level linear search double</td><td>5000</td><td>n/a</td><td>0.060</td><td>500</td></tr> <tr><td>top-level linear search string</td><td>5000</td><td>n/a</td><td>4.351</td><td>500</td></tr> +<tr><td>both levels model foreach</td><td>5000</td><td>0.741</td><td>0.754</td><td>500</td></tr> +<tr><td>both levels store traverse</td><td>5000</td><td>n/a</td><td>0.042</td><td>500</td></tr> <tr><td>top-level quick sort double</td><td>5000</td><td>0.046</td><td>0.010</td><td></td></tr> <tr><td>top-level quick sort string</td><td>5000</td><td>0.325</td><td>0.264</td><td></td></tr> <tr><td>sublevel 1 insert</td><td>5000</td><td>0.168</td><td>0.040</td><td></td></tr> @@ -530,6 +573,8 @@ <tr><td>top-level iter search string</td><td>10000</td><td>37.555</td><td>31.020</td><td>1000</td></tr> <tr><td>top-level linear search double</td><td>10000</td><td>n/a</td><td>0.304</td><td>1000</td></tr> <tr><td>top-level linear search string</td><td>10000</td><td>n/a</td><td>18.896</td><td>1000</td></tr> +<tr><td>both levels model foreach</td><td>10000</td><td>2.969</td><td>3.136</td><td>1000</td></tr> +<tr><td>both levels store traverse</td><td>10000</td><td>n/a</td><td>0.238</td><td>1000</td></tr> <tr><td>top-level quick sort double</td><td>10000</td><td>0.112</td><td>0.022</td><td></td></tr> <tr><td>top-level quick sort string</td><td>10000</td><td>0.720</td><td>0.580</td><td></td></tr> <tr><td>sublevel 1 insert</td><td>10000</td><td>1.152</td><td>0.132</td><td></td></tr> @@ -647,7 +692,7 @@ <p>ScpTreeStore was initially written for the Scope plugin of Geany light IDE, which relies heavily on stores.</p>
-<p><b>ScpTreeStore 0.83, Copyright (C) 2013 Dimitar Toshkov Zhekov</b></p> +<p><b>ScpTreeStore 0.84, Copyright (C) 2013 Dimitar Toshkov Zhekov</b></p>
<p>ScpTreeStore is distributed under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any
Modified: scope/src/views.c 6 files changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -263,7 +263,7 @@ static void on_display_editing_started(G_GNUC_UNUSED GtkCellRenderer *cell, }
GtkTreeView *view_connect(const char *name, ScpTreeStore **store, GtkTreeSelection **selection, - const TreeCell *cell_info, const char *window, GObject **display) + const TreeCell *cell_info, const char *window, GObject **display_cell) { guint i; GtkScrolledWindow *scrolled = GTK_SCROLLED_WINDOW(get_widget(window)); @@ -284,11 +284,11 @@ GtkTreeView *view_connect(const char *name, ScpTreeStore **store, GtkTreeSelecti g_signal_connect(cell, "editing-started", G_CALLBACK(on_editing_started), hadjustment);
- if (display && i == 0) + if (display_cell && i == 0) { g_signal_connect(cell, "editing-started", G_CALLBACK(on_display_editing_started), *store); - *display = G_OBJECT(cell); + *display_cell = G_OBJECT(cell); } } else
Modified: scope/src/views.h 2 files changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -64,7 +64,7 @@ enum
GtkTreeView *view_create(const char *name, ScpTreeStore **store, GtkTreeSelection **selection); GtkTreeView *view_connect(const char *name, ScpTreeStore **store, GtkTreeSelection **selection, - const TreeCell *cell_info, const char *window, GObject **display); + const TreeCell *cell_info, const char *window, GObject **display_cell); /* note: 2 references to column */ #define view_set_sort_func(store, column, compare) \ scp_tree_store_set_sort_func((store), (column), (GtkTreeIterCompareFunc) (compare), \
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
plugins-commits@lists.geany.org