[geany/geany-plugins] f47d61: scope - GtkList/TreeStore -> ScpTreeStore; GTK+ 3 support

Dimitar Zhekov git-noreply at xxxxx
Sun Apr 14 15:37:03 UTC 2013


Branch:      refs/heads/master
Author:      Dimitar Zhekov <dimitar.zhekov at gmail.com>
Committer:   Dimitar Zhekov <dimitar.zhekov at gmail.com>
Date:        Sun, 14 Apr 2013 15:37:03 UTC
Commit:      f47d61b5857d6dc613ae854bbe27aaf3da384295
             https://github.com/geany/geany-plugins/commit/f47d61b5857d6dc613ae854bbe27aaf3da384295

Log Message:
-----------
scope - GtkList/TreeStore -> ScpTreeStore; GTK+ 3 support


Modified Paths:
--------------
    scope/ChangeLog
    scope/NEWS
    scope/data/scope.glade
    scope/docs/scope.html
    scope/src/Makefile.am
    scope/src/break.c
    scope/src/common.h
    scope/src/inspect.c
    scope/src/local.c
    scope/src/memory.c
    scope/src/menu.c
    scope/src/menu.h
    scope/src/prefs.c
    scope/src/scope.c
    scope/src/stack.c
    scope/src/stack.h
    scope/src/store.h
    scope/src/store/scptreedata.c
    scope/src/store/scptreedata.h
    scope/src/store/scptreestore.c
    scope/src/store/scptreestore.h
    scope/src/thread.c
    scope/src/thread.h
    scope/src/tooltip.c
    scope/src/utils.c
    scope/src/utils.h
    scope/src/views.c
    scope/src/views.h
    scope/src/watch.c
    scope/wscript_build

Modified: scope/ChangeLog
25 files changed, 24 insertions(+), 1 deletions(-)
===================================================================
@@ -1,3 +1,26 @@
+2013-04-04  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
+
+ * data/scope.glade, src/Makefile.am, src/break.c, src/common.h,
+   src/inspect.c, src/local.c, src/memory.c, src/menu.c, src/scope.c,
+   src/stack.c, src/store.h, src/store/scptreedata.c,
+   src/store/scptreedata.h, src/store/scptreestore.c,
+   src/store/scptreestore.h, src/thread.c, src/utils.c, src/utils.h,
+   src/views.c, src/views.h, src/watch.c, wscript_build:
+   Switched from GtkList/TreeStore to ScpTreeStore.
+ * src/stack.c, src/watch.c:
+   Removed search optimizations, ScpTreeStore is fast enough.
+ * src/menu.c, src/menu.h, src/scope.c:
+   PLUGIN_KEY_GROUP() -> plugin_set_key_group().
+ * src/prefs.c:
+   Removed the stash_tree based plugin_configure(). Looked nice, but
+   there is no indication that stash_tree will be included in the
+   plugin API.
+ * src/scope.c, src/tooltip.c, src/views.c:
+   Changes to support GTK+ 3.
+ * docs/scope.html, src/scope.c:
+   Increased version to 0.87.
+
+
 2013-03-07  Enrico Tröger  <enrico.troeger at uvena.de>
 
  * wscript_build
@@ -48,7 +71,7 @@
 
  * src/debug.c:
    Reverted glibconfig.h include for win32 waitpid()/kill() emulation
-   to glib.h, the new glib versions don't allow individual includes.
+   to glib.h - the new glib versions don't allow individual includes.
 
 
 2013-01-22  Dimitar Zhekov  <dimitar.zhekov at gmail.com>


Modified: scope/NEWS
10 files changed, 10 insertions(+), 0 deletions(-)
===================================================================
@@ -1,3 +1,13 @@
+Scope 0.87 (2013-04-14)
+
+    * Switched to ScpTreeStore.
+
+    * Added GTK+ 3 support.
+
+    * Removed the stash_tree based scope configuration page in
+      Edit -> Plugin Preferences - required a patched Geany.
+
+
 Scope 0.82 (2013-01-15)
 
     * Added Memory subpage.


Modified: scope/data/scope.glade
105 files changed, 57 insertions(+), 48 deletions(-)
===================================================================
@@ -1227,64 +1227,66 @@
       </object>
     </child>
   </object>
-  <object class="GtkListStore" id="thread_store">
+  <object class="ScpTreeStore" id="thread_store">
+    <property name="sublevels">False</property>
     <columns>
       <!-- column-name thread_store_id -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_file -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_line -->
       <column type="gint"/>
       <!-- column-name thread_store_pid -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_group_id -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_state -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_base_name -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_func -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_addr -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_target_id -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name thread_store_core -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
     </columns>
   </object>
-  <object class="GtkListStore" id="break_store">
+  <object class="ScpTreeStore" id="break_store">
+    <property name="sublevels">False</property>
     <columns>
       <!-- column-name break_store_id -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name break_store_file -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name break_store_line -->
       <column type="gint"/>
       <!-- column-name break_store_scid -->
       <column type="gint"/>
       <!-- column-name break_store_type -->
-      <column type="gchar"/>
+      <column type="gchar" utf8_collate="false"/>
       <!-- column-name break_store_enabled -->
       <column type="gboolean"/>
       <!-- column-name break_store_display -->
       <column type="gchararray"/>
       <!-- column-name break_store_func -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name break_store_addr -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name break_store_times -->
       <column type="gint"/>
       <!-- column-name break_store_ignore -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name break_store_cond -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name break_store_script -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name break_store_pending -->
       <column type="gboolean"/>
       <!-- column-name break_store_location -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name break_store_run_apply -->
       <column type="gboolean"/>
       <!-- column-name break_store_temporary -->
@@ -1295,50 +1297,53 @@
       <column type="gboolean"/>
     </columns>
   </object>
-  <object class="GtkListStore" id="stack_store">
+  <object class="ScpTreeStore" id="stack_store">
+    <property name="sublevels">False</property>
     <columns>
       <!-- column-name stack_store_id -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name stack_store_file -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name stack_store_line -->
       <column type="gint"/>
       <!-- column-name stack_store_base_name -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name stack_store_func -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name stack_store_args -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name stack_store_addr -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name stack_store_entry -->
       <column type="gboolean"/>
     </columns>
   </object>
-  <object class="GtkListStore" id="local_store">
+  <object class="ScpTreeStore" id="local_store">
+    <property name="sublevels">False</property>
     <columns>
       <!-- column-name local_store_name -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name local_store_display -->
       <column type="gchararray"/>
       <!-- column-name local_store_value -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name local_store_hb_mode -->
       <column type="gint"/>
       <!-- column-name local_store_mr_mode -->
       <column type="gint"/>
       <!-- column-name local_store_arg1 -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
     </columns>
   </object>
-  <object class="GtkListStore" id="watch_store">
+  <object class="ScpTreeStore" id="watch_store">
+    <property name="sublevels">False</property>
     <columns>
       <!-- column-name watch_store_expr -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name watch_store_display -->
       <column type="gchararray"/>
       <!-- column-name watch_store_value -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name watch_store_hb_mode -->
       <column type="gint"/>
       <!-- column-name watch_store_mr_mode -->
@@ -1349,34 +1354,37 @@
       <column type="gboolean"/>
     </columns>
   </object>
-  <object class="GtkListStore" id="memory_store">
+  <object class="ScpTreeStore" id="memory_store">
+    <property name="sublevels">False</property>
     <columns>
       <!-- column-name memory_store_addr -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name memory_store_bytes -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name memory_store_ascii -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
     </columns>
   </object>
-  <object class="GtkTreeStore" id="inspect_store">
+  <object class="ScpTreeStore" id="inspect_store">
+    <property name="sublevels">True</property>
+    <property name="sublevel-reserved">100</property>
     <columns>
       <!-- column-name inspect_store_var1 -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name inspect_store_display -->
       <column type="gchararray"/>
       <!-- column-name inspect_store_value -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name inspect_store_hb_mode -->
       <column type="gint"/>
       <!-- column-name inspect_store_scid -->
       <column type="gint"/>
       <!-- column-name inspect_store_expr -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name inspect_store_name -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name inspect_store_frame -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name inspect_store_run_apply -->
       <column type="gboolean"/>
       <!-- column-name inspect_store_start -->
@@ -1390,15 +1398,16 @@
       <!-- column-name inspect_store_format -->
       <column type="gint"/>
       <!-- column-name inspect_store_path_expr -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
     </columns>
   </object>
-  <object class="GtkListStore" id="command_store">
+  <object class="ScpTreeStore" id="command_store">
+    <property name="sublevels">False</property>
     <columns>
       <!-- column-name command_store_display -->
       <column type="gchararray"/>
       <!-- column-name command_store_text -->
-      <column type="gchararray"/>
+      <column type="gchararray" utf8_collate="false"/>
       <!-- column-name command_store_locale -->
       <column type="gboolean"/>
     </columns>


Modified: scope/docs/scope.html
6 files changed, 2 insertions(+), 4 deletions(-)
===================================================================
@@ -16,7 +16,7 @@
 
 <center><h2>Scope</h2></center>
 
-<center><h3>A simple GDB front-end</h3></center>
+<center><h3>A relatively simple GDB front-end</h3></center>
 
 <p align="right">"We are like dwarfs sitting on the shoulders of giants."<br>
 -- Bernard of Chartres</p>
@@ -584,8 +584,6 @@
 <p>A disabled check button or check menu item means that the respective functionality is
 unavailable; it doesn't matter if the interface element is checked or not.</p>
 
-<p>All subpages will be updated faster if you keep them unsorted.</p>
-
 <p><b><a name="editing_values">Editing values</a></b></p>
 
 <div>GDB often displays values in format unsuitable for assigning. So when editing a value,
@@ -715,7 +713,7 @@
 
 <b><a name="copyright">Copyright</a></b>
 
-<p>Scope 0.84, Copyright (C) 2013 Dimitar Toshkov Zhekov</p>
+<p>Scope 0.87, Copyright (C) 2013 Dimitar Toshkov Zhekov</p>
 
 <p>The menu and toolbar icons are from <a href="http://netbeans.org">Netbeans</a>, except for
 BreakPoint.</p>


Modified: scope/src/Makefile.am
6 files changed, 5 insertions(+), 1 deletions(-)
===================================================================
@@ -44,7 +44,11 @@ scope_la_SOURCES = \
 	views.c \
 	views.h \
 	watch.c \
-	watch.h
+	watch.h \
+	store/scptreedata.h \
+	store/scptreedata.c \
+	store/scptreestore.h \
+	store/scptreestore.c
 
 scope_la_LIBADD = $(COMMONLIBS) $(VTE_LIBS) $(PTY_LIBS)
 


Modified: scope/src/break.c
254 files changed, 108 insertions(+), 146 deletions(-)
===================================================================
@@ -47,14 +47,14 @@ enum
 	BREAK_MISSING
 };
 
-static gint break_id_compare(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
+static gint break_id_compare(ScpTreeStore *store, GtkTreeIter *a, GtkTreeIter *b,
 	G_GNUC_UNUSED gpointer gdata)
 {
-	char *s1, *s2;
+	const char *s1, *s2;
 	gint result;
 
-	gtk_tree_model_get(model, a, BREAK_ID, &s1, -1);
-	gtk_tree_model_get(model, b, BREAK_ID, &s2, -1);
+	scp_tree_store_get(store, a, BREAK_ID, &s1, -1);
+	scp_tree_store_get(store, b, BREAK_ID, &s2, -1);
 	result = utils_atoi0(s1) - utils_atoi0(s2);
 
 	if (!result && s1 && s2)
@@ -67,16 +67,15 @@ static gint break_id_compare(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b
 		result = atoi(p1 + (*p1 == '.')) - atoi(p2 + (*p2 == '.'));
 	}
 
-	g_free(s1);
-	g_free(s2);
 	return result;
 }
 
-static gint break_location_compare(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
+static gint break_location_compare(ScpTreeStore *store, GtkTreeIter *a, GtkTreeIter *b,
 	G_GNUC_UNUSED gpointer gdata)
 {
-	gint result = model_seek_compare(model, a, b, NULL);
-	return result ? result : model_string_compare(model, a, b, BREAK_LOCATION);
+	gint result = store_seek_compare(store, a, b, NULL);
+	return result ? result : scp_tree_store_compare_func(store, a, b,
+		GINT_TO_POINTER(BREAK_LOCATION));
 }
 
 static const char
@@ -130,28 +129,25 @@ static void break_type_set_data_func(G_GNUC_UNUSED GtkTreeViewColumn *column,
 	g_string_free(string, TRUE);
 }
 
-static GtkListStore *store;
-static GtkTreeModel *model;
-static GtkTreeSortable *sortable;
+static ScpTreeStore *store;
 static GtkTreeSelection *selection;
 static gint scid_gen = 0;
 
 static void break_mark(GtkTreeIter *iter, gboolean mark)
 {
-	char *file;
+	const char *file;
 	gint line;
 	gboolean enabled;
 
-	gtk_tree_model_get(model, iter, BREAK_FILE, &file, BREAK_LINE, &line, BREAK_ENABLED,
+	scp_tree_store_get(store, iter, BREAK_FILE, &file, BREAK_LINE, &line, BREAK_ENABLED,
 		&enabled, -1);
 	utils_mark(file, line, mark, MARKER_BREAKPT + enabled);
-	g_free(file);
 }
 
 static void break_enable(GtkTreeIter *iter, gboolean enable)
 {
 	break_mark(iter, FALSE);
-	gtk_list_store_set(store, iter, BREAK_ENABLED, enable, -1);
+	scp_tree_store_set(store, iter, BREAK_ENABLED, enable, -1);
 	break_mark(iter, TRUE);
 }
 
@@ -160,12 +156,12 @@ static void on_break_enabled_toggled(G_GNUC_UNUSED GtkCellRendererToggle *render
 {
 	GtkTreeIter iter;
 	DebugState state = debug_state();
-	char *id;
+	const char *id;
 	gint scid;
 	gboolean enabled;
 
-	gtk_tree_model_get_iter_from_string(model, &iter, path_str);
-	gtk_tree_model_get(model, &iter, BREAK_ID, &id, BREAK_SCID, &scid, BREAK_ENABLED,
+	scp_tree_store_get_iter_from_string(store, &iter, path_str);
+	scp_tree_store_get(store, &iter, BREAK_ID, &id, BREAK_SCID, &scid, BREAK_ENABLED,
 		&enabled, -1);
 	enabled ^= TRUE;
 
@@ -180,8 +176,6 @@ static void on_break_enabled_toggled(G_GNUC_UNUSED GtkCellRendererToggle *render
 	}
 	else
 		plugin_beep();
-
-	g_free(id);
 }
 
 #define EDITCOLS 3
@@ -198,11 +192,11 @@ static void on_break_column_edited(G_GNUC_UNUSED GtkCellRendererText *renderer,
 	gint index = GPOINTER_TO_INT(gdata) - 1;
 	const gchar *set_text = validate_column(new_text, index > 0);
 	GtkTreeIter iter;
-	char *id;
+	const char *id;
 	char type;
 
-	gtk_tree_model_get_iter_from_string(model, &iter, path_str);
-	gtk_tree_model_get(model, &iter, BREAK_ID, &id, BREAK_TYPE, &type, -1);
+	scp_tree_store_get_iter_from_string(store, &iter, path_str);
+	scp_tree_store_get(store, &iter, BREAK_ID, &id, BREAK_TYPE, &type, -1);
 
 	if (id && (debug_state() & DS_SENDABLE))
 	{
@@ -213,11 +207,9 @@ static void on_break_column_edited(G_GNUC_UNUSED GtkCellRendererText *renderer,
 		g_free(locale);
 	}
 	else if (!id)
-		gtk_list_store_set(store, &iter, index + BREAK_IGNORE, set_text, -1);
+		scp_tree_store_set(store, &iter, index + BREAK_IGNORE, set_text, -1);
 	else
 		plugin_beep();
-
-	g_free(id);
 }
 
 static void on_break_ignore_editing_started(G_GNUC_UNUSED GtkCellRenderer *cell,
@@ -280,22 +272,19 @@ static void append_script_command(const ParseNode *node, GString *string)
 
 static void break_iter_applied(GtkTreeIter *iter, const char *id)
 {
-	gchar *columns[EDITCOLS];
+	const gchar *columns[EDITCOLS];
 	gboolean enabled;
 	char type;
 	gint index;
 
-	gtk_tree_model_get(model, iter, BREAK_ENABLED, &enabled, BREAK_IGNORE, &columns[0],
+	scp_tree_store_get(store, iter, BREAK_ENABLED, &enabled, BREAK_IGNORE, &columns[0],
 		BREAK_COND, &columns[1], BREAK_SCRIPT, &columns[2], BREAK_TYPE, &type, -1);
 
 	if (strchr(BP_BORTS, type))
 	{
 		if (strchr(BP_BREAKS, type))
-		{
-			g_free(columns[0]);
 			columns[0] = NULL;
-		}
-		g_free(columns[1]);
+
 		columns[1] = NULL;
 	}
 	else if (!enabled)
@@ -311,7 +300,6 @@ static void break_iter_applied(GtkTreeIter *iter, const char *id)
 				locale);
 			g_free(locale);
 		}
-		g_free(columns[index]);
 	}
 }
 
@@ -365,7 +353,7 @@ static void break_node_parse(const ParseNode *node, BreakData *bd)
 			const ParseNode *script = parse_find_node(nodes, "script");
 			GtkTreeIter iter1;
 
-			if (model_find(model, &iter1, BREAK_ID, id))
+			if (store_find(store, &iter1, BREAK_ID, id))
 			{
 				bd->iter = iter1;
 				break_mark(iter, FALSE);
@@ -411,14 +399,15 @@ static void break_node_parse(const ParseNode *node, BreakData *bd)
 					utils_get_display_from_locale(location, HB_DEFAULT);
 
 				if (leading)
-					gtk_list_store_append(store, iter);
+					scp_tree_store_append(store, iter, NULL);
 				else
 				{
-					gtk_list_store_insert_after(store, &iter1, iter);
+					scp_tree_store_insert(store, &iter1, NULL,
+						scp_tree_store_iter_tell(store, iter) + 1);
 					bd->iter = iter1;
 				}
 
-				gtk_list_store_set(store, iter, BREAK_SCID, ++scid_gen, BREAK_TYPE,
+				scp_tree_store_set(store, iter, BREAK_SCID, ++scid_gen, BREAK_TYPE,
 					type, BREAK_DISPLAY, display, BREAK_PENDING, pending,
 					BREAK_LOCATION, location, BREAK_RUN_APPLY, leading && borts,
 					BREAK_DISCARD, !persist, -1);
@@ -444,11 +433,11 @@ static void break_node_parse(const ParseNode *node, BreakData *bd)
 						(GFunc) append_script_command, string);
 				}
 
-				gtk_list_store_set(store, iter, BREAK_SCRIPT, string->str, -1);
+				scp_tree_store_set(store, iter, BREAK_SCRIPT, string->str, -1);
 				g_string_free(string, TRUE);
 			}
 			else
-				gtk_list_store_set(store, iter, BREAK_SCRIPT, NULL, -1);
+				scp_tree_store_set(store, iter, BREAK_SCRIPT, NULL, -1);
 		}
 
 		if (borts || bd->stage != BG_APPLY)
@@ -457,13 +446,13 @@ static void break_node_parse(const ParseNode *node, BreakData *bd)
 				HB_DEFAULT);
 			const char *ignore = parse_find_value(nodes, "ignore");
 
-			gtk_list_store_set(store, iter, BREAK_ENABLED, enabled, BREAK_COND, cond,
+			scp_tree_store_set(store, iter, BREAK_ENABLED, enabled, BREAK_COND, cond,
 				strchr(BP_BREAKS, type) || bd->stage != BG_APPLY ? BREAK_IGNORE : -1,
 				ignore ? ignore : parse_find_value(nodes, "pass"), -1);
 			g_free(cond);
 		}
 
-		gtk_list_store_set(store, iter, BREAK_ID, id, BREAK_FILE, loc.file, BREAK_LINE,
+		scp_tree_store_set(store, iter, BREAK_ID, id, BREAK_FILE, loc.file, BREAK_LINE,
 			loc.line, BREAK_FUNC, loc.func, BREAK_ADDR, loc.addr, BREAK_TIMES,
 			utils_atoi0(times), BREAK_MISSING, FALSE, BREAK_TEMPORARY, temporary, -1);
 
@@ -491,7 +480,7 @@ void on_break_inserted(GArray *nodes)
 			bd.stage = BG_GOTO;
 		else if (*token)
 		{
-			iff (model_find(model, &bd.iter, BREAK_SCID, token), "%s: b_scid not found",
+			iff (store_find(store, &bd.iter, BREAK_SCID, token), "%s: b_scid not found",
 				token)
 			{
 				bd.stage = BG_APPLY;
@@ -509,12 +498,12 @@ static void break_apply(GtkTreeIter *iter, gboolean thread)
 	GString *command = g_string_sized_new(0x1FF);
 	gint scid;
 	char type;
-	char *ignore, *location;
+	const char *ignore, *location;
 	gboolean enabled, pending, temporary;
-	gchar *cond;
+	const gchar *cond;
 	gboolean borts;
 
-	gtk_tree_model_get(model, iter, BREAK_SCID, &scid, BREAK_TYPE, &type, BREAK_ENABLED,
+	scp_tree_store_get(store, iter, BREAK_SCID, &scid, BREAK_TYPE, &type, BREAK_ENABLED,
 		&enabled, BREAK_IGNORE, &ignore, BREAK_COND, &cond, BREAK_LOCATION, &location,
 		BREAK_PENDING, &pending, BREAK_TEMPORARY, &temporary, -1);
 
@@ -559,39 +548,36 @@ static void break_apply(GtkTreeIter *iter, gboolean thread)
 	g_string_append_printf(command, " %s", location);
 	debug_send_command(F, command->str);
 	g_string_free(command, TRUE);
-	g_free(ignore);
-	g_free(location);
-	g_free(cond);
 }
 
 static void break_clear(GtkTreeIter *iter)
 {
 	char type;
 
-	gtk_tree_model_get(model, iter, BREAK_TYPE, &type, -1);
-	gtk_list_store_set(store, iter, BREAK_ID, NULL, BREAK_ADDR, NULL,
+	scp_tree_store_get(store, iter, BREAK_TYPE, &type, -1);
+	scp_tree_store_set(store, iter, BREAK_ID, NULL, BREAK_ADDR, NULL,
 		strchr(BP_BORTS, type) ? -1 : BREAK_TEMPORARY, FALSE, -1);
 }
 
 static gboolean break_remove(GtkTreeIter *iter)
 {
 	break_mark(iter, FALSE);
-	return gtk_list_store_remove(store, iter);
+	return scp_tree_store_remove(store, iter);
 }
 
 static gboolean break_remove_all(const char *pref, gboolean force)
 {
 	GtkTreeIter iter;
 	int len = strlen(pref);
-	gboolean valid = gtk_tree_model_get_iter_first(model, &iter);
+	gboolean valid = scp_tree_store_get_iter_first(store, &iter);
 	gboolean found = FALSE;
 
 	while (valid)
 	{
-		char *id;
+		const char *id;
 		gboolean discard;
 
-		gtk_tree_model_get(model, &iter, BREAK_ID, &id, BREAK_DISCARD, &discard, -1);
+		scp_tree_store_get(store, &iter, BREAK_ID, &id, BREAK_DISCARD, &discard, -1);
 
 		if (id && !strncmp(id, pref, len) && strchr(".", id[len]))
 		{
@@ -600,15 +586,13 @@ static gboolean break_remove_all(const char *pref, gboolean force)
 			if (discard || force)
 			{
 				valid = break_remove(&iter);
-				g_free(id);
 				continue;
 			}
 
 			break_clear(&iter);
 		}
 
-		g_free(id);
-		valid = gtk_tree_model_iter_next(model, &iter);
+		valid = scp_tree_store_iter_next(store, &iter);
 	}
 
 	return found;
@@ -624,7 +608,7 @@ void on_break_done(GArray *nodes)
 		case '0' :
 		case '1' :
 		{
-			iff (model_find(model, &iter, BREAK_SCID, token + 1), "%s: b_scid not found",
+			iff (store_find(store, &iter, BREAK_SCID, token + 1), "%s: b_scid not found",
 				token)
 			{
 				break_enable(&iter, *token == '1');
@@ -648,36 +632,34 @@ void on_break_done(GArray *nodes)
 
 static void break_iter_missing(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata)
 {
-	gtk_list_store_set(store, iter, BREAK_MISSING, TRUE, -1);
+	scp_tree_store_set(store, iter, BREAK_MISSING, TRUE, -1);
 }
 
 static void breaks_missing(void)
 {
 	GtkTreeIter iter;
-	gboolean valid = gtk_tree_model_get_iter_first(model, &iter);
+	gboolean valid = scp_tree_store_get_iter_first(store, &iter);
 
 	while (valid)
 	{
-		char *id;
+		const char *id;
 		gboolean discard, missing;
 
-		gtk_tree_model_get(model, &iter, BREAK_ID, &id, BREAK_DISCARD, &discard,
+		scp_tree_store_get(store, &iter, BREAK_ID, &id, BREAK_DISCARD, &discard,
 			BREAK_MISSING, &missing, -1);
-		g_free(id);
 
 		if (id && missing)
 		{
 			if (discard)
 			{
 				valid = break_remove(&iter);
-				g_free(id);
 				continue;
 			}
 
 			break_clear(&iter);
 		}
 
-		valid = gtk_tree_model_iter_next(model, &iter);
+		valid = scp_tree_store_iter_next(store, &iter);
 	}
 }
 
@@ -689,7 +671,7 @@ void on_break_list(GArray *nodes)
 		BreakData bd;
 
 		if (refresh)
-			model_foreach(model, (GFunc) break_iter_missing, NULL);
+			store_foreach(store, (GFunc) break_iter_missing, NULL);
 
 		bd.stage = BG_DISCARD;
 		array_foreach(nodes, (GFunc) break_node_parse, &bd);
@@ -714,7 +696,7 @@ void on_break_stopped(GArray *nodes)
 			{
 				GtkTreeIter iter;
 
-				if (model_find(model, &iter, BREAK_ID, id))
+				if (store_find(store, &iter, BREAK_ID, id))
 					break_enable(&iter, FALSE);
 			}
 			else if (!strcmp(disp, "del"))
@@ -758,74 +740,71 @@ void on_break_features(GArray *nodes)
 
 static void break_delete(GtkTreeIter *iter)
 {
-	char *id;
+	const char *id;
 
-	gtk_tree_model_get(model, iter, BREAK_ID, &id, -1);
+	scp_tree_store_get(store, iter, BREAK_ID, &id, -1);
 
 	if (debug_state() == DS_INACTIVE || !id)
 		break_remove(iter);
 	else
 		debug_send_format(N, "023%s-break-delete %s", id, id);
-
-	g_free(id);
 }
 
 static void break_iter_mark(GtkTreeIter *iter, GeanyDocument *doc)
 {
-	char *file;
+	const char *file;
 	gint line;
 	gboolean enabled;
 
-	gtk_tree_model_get(model, iter, BREAK_FILE, &file, BREAK_LINE, &line,
+	scp_tree_store_get(store, iter, BREAK_FILE, &file, BREAK_LINE, &line,
 		BREAK_ENABLED, &enabled, -1);
 
 	if (line && !utils_filenamecmp(file, doc->real_path))
 		sci_set_marker_at_line(doc->editor->sci, line - 1, MARKER_BREAKPT + enabled);
-	g_free(file);
 }
 
 void breaks_mark(GeanyDocument *doc)
 {
 	if (doc->real_path)
-		model_foreach(model, (GFunc) break_iter_mark, doc);
+		store_foreach(store, (GFunc) break_iter_mark, doc);
 }
 
 void breaks_clear(void)
 {
 	GtkTreeIter iter;
-	gboolean valid = gtk_tree_model_get_iter_first(model, &iter);
+	gboolean valid = scp_tree_store_get_iter_first(store, &iter);
 
 	while (valid)
 	{
 		gboolean discard;
 
-		gtk_tree_model_get(model, &iter, BREAK_DISCARD, &discard, -1);
+		scp_tree_store_get(store, &iter, BREAK_DISCARD, &discard, -1);
 
 		if (discard)
 			valid = break_remove(&iter);
 		else
 		{
 			break_clear(&iter);
-			valid = gtk_tree_model_iter_next(model, &iter);
+			valid = scp_tree_store_iter_next(store, &iter);
 		}
 	}
 }
 
 static void break_iter_reset(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata)
 {
-	gtk_list_store_set(store, iter, BREAK_TIMES, 0, -1);
+	scp_tree_store_set(store, iter, BREAK_TIMES, 0, -1);
 }
 
 void breaks_reset(void)
 {
-	model_foreach(model, (GFunc) break_iter_reset, NULL);
+	store_foreach(store, (GFunc) break_iter_reset, NULL);
 }
 
 static void break_iter_apply(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata)
 {
 	gboolean run_apply;
 
-	gtk_tree_model_get(model, iter, BREAK_RUN_APPLY, &run_apply, -1);
+	scp_tree_store_get(store, iter, BREAK_RUN_APPLY, &run_apply, -1);
 
 	if (run_apply)
 		break_apply(iter, FALSE);
@@ -833,7 +812,7 @@ static void break_iter_apply(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata)
 
 void breaks_apply(void)
 {
-	model_foreach(model, (GFunc) break_iter_apply, NULL);
+	store_foreach(store, (GFunc) break_iter_apply, NULL);
 }
 
 void breaks_query_async(GString *commands)
@@ -850,7 +829,7 @@ static void break_relocate(GtkTreeIter *iter, const char *real_path, gint line)
 	char *location = g_strdup_printf("%s:%d", real_path, line);
 	gchar *display = utils_get_utf8_basename(location);
 
-	gtk_list_store_set(store, iter, BREAK_FILE, real_path, BREAK_LINE, line, BREAK_DISPLAY,
+	scp_tree_store_set(store, iter, BREAK_FILE, real_path, BREAK_LINE, line, BREAK_DISPLAY,
 		display, BREAK_LOCATION, location, -1);
 
 	g_free(display);
@@ -861,16 +840,16 @@ void breaks_delta(ScintillaObject *sci, const char *real_path, gint start, gint
 	gboolean active)
 {
 	GtkTreeIter iter;
-	gboolean valid = gtk_tree_model_get_iter_first(model, &iter);
+	gboolean valid = scp_tree_store_get_iter_first(store, &iter);
 
 	while (valid)
 	{
-		char *file;
+		const char *file;
 		gint line;
 		gboolean enabled;
-		char *location;
+		const char *location;
 
-		gtk_tree_model_get(model, &iter, BREAK_FILE, &file, BREAK_LINE, &line,
+		scp_tree_store_get(store, &iter, BREAK_FILE, &file, BREAK_LINE, &line,
 			BREAK_ENABLED, &enabled, BREAK_LOCATION, &location, -1);
 
 		if (--line >= 0 && start <= line && !utils_filenamecmp(file, real_path))
@@ -888,38 +867,33 @@ void breaks_delta(ScintillaObject *sci, const char *real_path, gint start, gint
 				if (split && isdigit(split[1]))
 					break_relocate(&iter, real_path, line);
 				else
-					gtk_list_store_set(store, &iter, BREAK_LINE, line, -1);
+					scp_tree_store_set(store, &iter, BREAK_LINE, line, -1);
 			}
 			else
 			{
 				sci_delete_marker_at_line(sci, start, MARKER_BREAKPT + enabled);
-				valid = gtk_list_store_remove(store, &iter);
-				g_free(file);
-				g_free(location);
+				valid = scp_tree_store_remove(store, &iter);
 				continue;
 			}
 		}
 
-		g_free(file);
-		g_free(location);
-		valid = gtk_tree_model_iter_next(model, &iter);
+		valid = scp_tree_store_iter_next(store, &iter);
 	}
 }
 
 static void break_iter_check(GtkTreeIter *iter, guint *active)
 {
-	char *id;
+	const char *id;
 	gboolean enabled;
 
-	gtk_tree_model_get(model, iter, BREAK_ID, &id, BREAK_ENABLED, &enabled, -1);
+	scp_tree_store_get(store, iter, BREAK_ID, &id, BREAK_ENABLED, &enabled, -1);
 	*active += enabled && id;
-	g_free(id);
 }
 
 guint breaks_active(void)
 {
 	guint active = 0;
-	model_foreach(model, (GFunc) break_iter_check, &active);
+	store_foreach(store, (GFunc) break_iter_check, &active);
 	return active;
 }
 
@@ -928,15 +902,15 @@ void on_break_toggle(G_GNUC_UNUSED const MenuItem *menu_item)
 	GeanyDocument *doc = document_get_current();
 	gint doc_line = utils_current_line(doc);
 	GtkTreeIter iter, iter1;
-	gboolean valid = gtk_tree_model_get_iter_first(model, &iter);
+	gboolean valid = scp_tree_store_get_iter_first(store, &iter);
 	gint found = 0;
 
 	while (valid)
 	{
-		char *id, *file;
+		const char *id, *file;
 		gint line;
 
-		gtk_tree_model_get(model, &iter, BREAK_ID, &id, BREAK_FILE, &file, BREAK_LINE,
+		scp_tree_store_get(store, &iter, BREAK_ID, &id, BREAK_FILE, &file, BREAK_LINE,
 			&line, -1);
 
 		if (line == doc_line && !utils_filenamecmp(file, doc->real_path))
@@ -947,8 +921,6 @@ void on_break_toggle(G_GNUC_UNUSED const MenuItem *menu_item)
 					_("There are two or more breakpoints at %s:%d.\n"
 					"Use the breakpoint list to remove the exact one."),
 					doc->file_name, doc_line);
-				g_free(id);
-				g_free(file);
 				return;
 			}
 
@@ -956,9 +928,7 @@ void on_break_toggle(G_GNUC_UNUSED const MenuItem *menu_item)
 			iter1 = iter;
 		}
 
-		g_free(id);
-		g_free(file);
-		valid = gtk_tree_model_iter_next(model, &iter);
+		valid = scp_tree_store_iter_next(store, &iter);
 	}
 
 	if (found)
@@ -967,10 +937,9 @@ void on_break_toggle(G_GNUC_UNUSED const MenuItem *menu_item)
 		debug_send_format(N, "-break-insert %s:%d", doc->real_path, doc_line);
 	else
 	{
-		gtk_list_store_append(store, &iter);
+		scp_tree_store_append_with_values(store, &iter, NULL, BREAK_SCID, ++scid_gen,
+			BREAK_TYPE, 'b', BREAK_ENABLED, TRUE, BREAK_RUN_APPLY, TRUE, -1);
 		break_relocate(&iter, doc->real_path, doc_line);
-		gtk_list_store_set(store, &iter, BREAK_SCID, ++scid_gen, BREAK_TYPE, 'b',
-			BREAK_ENABLED, TRUE, BREAK_RUN_APPLY, TRUE, -1);
 		utils_tree_set_cursor(selection, &iter, 0.5);
 		sci_set_marker_at_line(doc->editor->sci, doc_line - 1, MARKER_BREAKPT + TRUE);
 	}
@@ -989,8 +958,8 @@ static void break_iter_unmark(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata)
 
 void breaks_delete_all(void)
 {
-	model_foreach(model, (GFunc) break_iter_unmark, NULL);
-	gtk_list_store_clear(store);
+	store_foreach(store, (GFunc) break_iter_unmark, NULL);
+	store_clear(store);
 	scid_gen = 0;
 }
 
@@ -1035,14 +1004,14 @@ static gboolean break_load(GKeyFile *config, const char *section)
 		if (!strings[STRING_FILE])
 			line = 0;
 
-		gtk_list_store_append(store, &iter);
-		gtk_list_store_set(store, &iter, BREAK_FILE, strings[STRING_FILE], BREAK_LINE,
-			line, BREAK_SCID, ++scid_gen, BREAK_TYPE, type, BREAK_ENABLED, enabled,
-			BREAK_DISPLAY, strings[STRING_DISPLAY], BREAK_FUNC, strings[STRING_FUNC],
-			BREAK_IGNORE, ignore, BREAK_COND, strings[STRING_COND], BREAK_SCRIPT,
-			strings[STRING_SCRIPT], BREAK_PENDING, pending, BREAK_LOCATION,
-			strings[STRING_LOCATION], BREAK_RUN_APPLY, run_apply, BREAK_TEMPORARY,
-			temporary, -1);
+		scp_tree_store_append_with_values(store, &iter, NULL, BREAK_FILE,
+			strings[STRING_FILE], BREAK_LINE, line, BREAK_SCID, ++scid_gen, BREAK_TYPE,
+			type, BREAK_ENABLED, enabled, BREAK_DISPLAY, strings[STRING_DISPLAY],
+			BREAK_FUNC, strings[STRING_FUNC], BREAK_IGNORE, ignore, BREAK_COND,
+			strings[STRING_COND], BREAK_SCRIPT, strings[STRING_SCRIPT], BREAK_PENDING,
+			pending, BREAK_LOCATION, strings[STRING_LOCATION], BREAK_RUN_APPLY,
+			run_apply, BREAK_TEMPORARY, temporary, -1);
+
 		break_mark(&iter, TRUE);
 		valid = TRUE;
 	}
@@ -1063,7 +1032,7 @@ static gboolean break_save(GKeyFile *config, const char *section, GtkTreeIter *i
 {
 	gboolean discard;
 
-	gtk_tree_model_get(model, iter, BREAK_DISCARD, &discard, -1);
+	scp_tree_store_get(store, iter, BREAK_DISCARD, &discard, -1);
 
 	if (!discard)
 	{
@@ -1071,9 +1040,9 @@ static gboolean break_save(GKeyFile *config, const char *section, GtkTreeIter *i
 		gint line;
 		char type;
 		gboolean enabled, pending, run_apply, temporary;
-		char *strings[STRING_COUNT];
+		const char *strings[STRING_COUNT];
 
-		gtk_tree_model_get(model, iter, BREAK_FILE, &strings[STRING_FILE], BREAK_LINE,
+		scp_tree_store_get(store, iter, BREAK_FILE, &strings[STRING_FILE], BREAK_LINE,
 			&line, BREAK_TYPE, &type, BREAK_ENABLED, &enabled, BREAK_DISPLAY,
 			&strings[STRING_DISPLAY], BREAK_FUNC, &strings[STRING_FUNC], BREAK_IGNORE,
 			&strings[STRING_IGNORE], BREAK_COND, &strings[STRING_COND], BREAK_SCRIPT,
@@ -1094,7 +1063,7 @@ static gboolean break_save(GKeyFile *config, const char *section, GtkTreeIter *i
 		for (i = 0; i < STRING_COUNT; i++)
 		{
 			if (strings[i])
-				utils_key_file_set_string(config, section, string_names[i], strings[i]);
+				g_key_file_set_string(config, section, string_names[i], strings[i]);
 			else
 				g_key_file_remove_key(config, section, string_names[i], NULL);
 		}
@@ -1112,7 +1081,7 @@ static gboolean break_save(GKeyFile *config, const char *section, GtkTreeIter *i
 
 void breaks_save(GKeyFile *config)
 {
-	model_save(model, config, "break", break_save);
+	store_save(store, config, "break", break_save);
 }
 
 static GObject *block_cells[EDITCOLS];
@@ -1124,15 +1093,14 @@ static void on_break_selection_changed(GtkTreeSelection *selection,
 
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 	{
-		char *id;
+		const char *id;
 		gboolean editable;
 		gint index;
 
-		gtk_tree_model_get(model, &iter, BREAK_ID, &id, -1);
+		scp_tree_store_get(store, &iter, BREAK_ID, &id, -1);
 		editable = !id || !strchr(id, '.');
 		for (index = 0; index < EDITCOLS; index++)
 			g_object_set(block_cells[index], "editable", editable, NULL);
-		g_free(id);
 	}
 }
 
@@ -1146,12 +1114,12 @@ static gboolean on_break_query_tooltip(G_GNUC_UNUSED GtkWidget *widget, gint x,
 
 	if (gtk_tree_view_get_tooltip_context(tree, &x, &y, keyboard_tip, NULL, NULL, &iter))
 	{
-		char *file, *func;
+		const char *file, *func;
 		gint line;
 		GString *text = g_string_sized_new(0xFF);
 
 		gtk_tree_view_set_tooltip_cell(tree, tooltip, NULL, break_display_column, NULL);
-		gtk_tree_model_get(model, &iter, BREAK_FILE, &file, BREAK_LINE, &line, BREAK_FUNC,
+		scp_tree_store_get(store, &iter, BREAK_FILE, &file, BREAK_LINE, &line, BREAK_FUNC,
 			&func, -1);
 
 		if (file)
@@ -1160,7 +1128,6 @@ static gboolean on_break_query_tooltip(G_GNUC_UNUSED GtkWidget *widget, gint x,
 			if (line)
 				g_string_append_printf(text, ":%d", line);
 			has_tip = TRUE;
-			g_free(file);
 		}
 
 		if (func)
@@ -1169,7 +1136,6 @@ static gboolean on_break_query_tooltip(G_GNUC_UNUSED GtkWidget *widget, gint x,
 				g_string_append(text, ", ");
 			g_string_append(text, func);
 			has_tip = TRUE;
-			g_free(func);
 		}
 
 		gtk_tooltip_set_text(tooltip, text->str);
@@ -1186,7 +1152,7 @@ static void on_break_refresh(G_GNUC_UNUSED const MenuItem *menu_item)
 
 static void on_break_unsorted(G_GNUC_UNUSED const MenuItem *menu_item)
 {
-	gtk_tree_sortable_set_sort_column_id(sortable, BREAK_SCID, GTK_SORT_ASCENDING);
+	scp_tree_store_set_sort_column_id(store, BREAK_SCID, GTK_SORT_ASCENDING);
 }
 
 static void on_break_insert(G_GNUC_UNUSED const MenuItem *menu_item)
@@ -1233,7 +1199,7 @@ static void on_break_run_apply(const MenuItem *menu_item)
 	GtkTreeIter iter;
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_list_store_set(store, &iter, BREAK_RUN_APPLY,
+	scp_tree_store_set(store, &iter, BREAK_RUN_APPLY,
 		gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item->widget)), -1);
 }
 
@@ -1294,11 +1260,9 @@ static guint break_menu_extra_state(void)
 
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 	{
-		char *id, *file;
+		const char *id, *file;
 
-		gtk_tree_model_get(model, &iter, BREAK_ID, &id, BREAK_FILE, &file, -1);
-		g_free(id);
-		g_free(file);
+		scp_tree_store_get(store, &iter, BREAK_ID, &id, BREAK_FILE, &file, -1);
 
 		return (!id << DS_INDEX_1) | ((file != NULL) << DS_INDEX_2) |
 			((!id || !strchr(id, '.')) << DS_INDEX_3);
@@ -1323,7 +1287,7 @@ static void on_break_menu_show(G_GNUC_UNUSED GtkWidget *widget, const MenuItem *
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 	{
 		gboolean run_apply;
-		gtk_tree_model_get(model, &iter, BREAK_RUN_APPLY, &run_apply, -1);
+		scp_tree_store_get(store, &iter, BREAK_RUN_APPLY, &run_apply, -1);
 		menu_item_set_active(menu_item, run_apply);
 	}
 }
@@ -1339,16 +1303,14 @@ void break_init(void)
 	GtkWidget *menu;
 	guint i;
 
-	tree = view_connect("break_view", &model, &selection, break_cells, "break_window", NULL);
-	store = GTK_LIST_STORE(model);
-	sortable = GTK_TREE_SORTABLE(store);
+	tree = view_connect("break_view", &store, &selection, break_cells, "break_window", NULL);
 	gtk_tree_view_column_set_cell_data_func(get_column("break_type_column"),
 		GTK_CELL_RENDERER(get_object("break_type")), break_type_set_data_func, NULL, NULL);
 	g_signal_connect(get_object("break_ignore"), "editing-started",
 		G_CALLBACK(on_break_ignore_editing_started), NULL);
-	view_set_sort_func(sortable, BREAK_ID, break_id_compare);
-	view_set_sort_func(sortable, BREAK_IGNORE, model_gint_compare);
-	view_set_sort_func(sortable, BREAK_LOCATION, break_location_compare);
+	view_set_sort_func(store, BREAK_ID, break_id_compare);
+	view_set_sort_func(store, BREAK_IGNORE, store_gint_compare);
+	view_set_sort_func(store, BREAK_LOCATION, break_location_compare);
 
 	for (i = 0; i < EDITCOLS; i++)
 		block_cells[i] = get_object(break_cells[i + 1].name);
@@ -1369,5 +1331,5 @@ void break_init(void)
 
 void break_finalize(void)
 {
-	model_foreach(model, (GFunc) break_iter_unmark, NULL);
+	store_foreach(store, (GFunc) break_iter_unmark, NULL);
 }


Modified: scope/src/common.h
1 files changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -39,6 +39,7 @@
 #include "program.h"
 #include "stack.h"
 #include "scope.h"
+#include "store.h"
 #include "thread.h"
 #include "tooltip.h"
 #include "utils.h"


Modified: scope/src/inspect.c
266 files changed, 110 insertions(+), 156 deletions(-)
===================================================================
@@ -53,25 +53,14 @@ enum
 };
 
 static GtkTreeView *tree;
-static GtkTreeStore *store;
-static GtkTreeModel *model;
+static ScpTreeStore *store;
 static GtkTreeSelection *selection;
 static gint scid_gen = 0;
 
-static void remove_children(GtkTreeIter *parent)
-{
-	GtkTreeIter iter;
-	gboolean valid = gtk_tree_model_iter_children(model, &iter, parent);
-
-	while (valid)
-		valid = gtk_tree_store_remove(store, &iter);
-}
-
 static void append_stub(GtkTreeIter *parent, const gchar *text, gboolean expand)
 {
-	GtkTreeIter iter;
-	gtk_tree_store_append(store, &iter, parent);
-	gtk_tree_store_set(store, &iter, INSPECT_EXPR, text, INSPECT_EXPAND, expand, -1);
+	scp_tree_store_append_with_values(store, NULL, parent, INSPECT_EXPR, text,
+		INSPECT_EXPAND, expand, -1);
 }
 
 #define append_ellipsis(parent, expand) append_stub((parent), _("..."), (expand))
@@ -86,7 +75,7 @@ static gboolean inspect_find_recursive(GtkTreeIter *iter, gint i, const char *ke
 		{
 			gint scid;
 
-			gtk_tree_model_get(model, iter, INSPECT_SCID, &scid, -1);
+			scp_tree_store_get(store, iter, INSPECT_SCID, &scid, -1);
 			if (scid == i)
 				return TRUE;
 		}
@@ -96,7 +85,7 @@ static gboolean inspect_find_recursive(GtkTreeIter *iter, gint i, const char *ke
 			size_t len;
 			gboolean match;
 
-			gtk_tree_model_get(model, iter, INSPECT_VAR1, &var1, -1);
+			scp_tree_store_get(store, iter, INSPECT_VAR1, &var1, -1);
 			len = var1 ? strlen(var1) : 0;
 			match = var1 && !strncmp(key, var1, len);
 			g_free(var1);
@@ -114,21 +103,21 @@ static gboolean inspect_find_recursive(GtkTreeIter *iter, gint i, const char *ke
 		{
 			GtkTreeIter child;
 
-			if (gtk_tree_model_iter_children(model, &child, iter) &&
+			if (scp_tree_store_iter_children(store, &child, iter) &&
 				inspect_find_recursive(&child, i, key))
 			{
 				*iter = child;
 				return TRUE;
 			}
 		}
-	} while (gtk_tree_model_iter_next(model, iter));
+	} while (scp_tree_store_iter_next(store, iter));
 
 	return FALSE;
 }
 
 static gboolean inspect_find(GtkTreeIter *iter, gboolean string, const char *key)
 {
-	if (gtk_tree_model_get_iter_first(model, iter) &&
+	if (scp_tree_store_get_iter_first(store, iter) &&
 		inspect_find_recursive(iter, atoi(key), string ? key : NULL))
 	{
 		return TRUE;
@@ -144,25 +133,25 @@ static gint inspect_get_scid(GtkTreeIter *iter)
 {
 	gint scid;
 
-	gtk_tree_model_get(model, iter, INSPECT_SCID, &scid, -1);
+	scp_tree_store_get(store, iter, INSPECT_SCID, &scid, -1);
 	if (!scid)
-		gtk_tree_store_set(store, iter, INSPECT_SCID, scid = ++scid_gen, -1);
+		scp_tree_store_set(store, iter, INSPECT_SCID, scid = ++scid_gen, -1);
 
 	return scid;
 }
 
 static void inspect_expand(GtkTreeIter *iter)
 {
-	char *var1, *s;
+	const char *var1;
+	char *s;
 	gint scid, start, count, numchild;
 
 	scid = inspect_get_scid(iter);
-	gtk_tree_model_get(model, iter, INSPECT_VAR1, &var1, INSPECT_START, &start,
+	scp_tree_store_get(store, iter, INSPECT_VAR1, &var1, INSPECT_START, &start,
 		INSPECT_COUNT, &count, INSPECT_NUMCHILD, &numchild, -1);
 	s = g_strdup_printf("%d", start);
 	debug_send_format(N, "07%c%d%d-var-list-children 1 %s %d %d", '0' + (int) strlen(s) - 1,
 		start, scid, var1, start, count ? start + count : numchild);
-	g_free(var1);
 	g_free(s);
 }
 
@@ -171,7 +160,7 @@ static void on_jump_to_menu_item_activate(GtkMenuItem *menuitem, G_GNUC_UNUSED g
 	GtkTreeIter iter;
 	const gchar *expr = gtk_menu_item_get_label(menuitem);
 
-	if (model_find(model, &iter, INSPECT_EXPR, expr))
+	if (store_find(store, &iter, INSPECT_EXPR, expr))
 		utils_tree_set_cursor(selection, &iter, 0);
 }
 
@@ -235,7 +224,7 @@ static gchar *inspect_redisplay(GtkTreeIter *iter, const char *value, gchar *dis
 {
 	gint hb_mode;
 
-	gtk_tree_model_get(model, iter, INSPECT_HB_MODE, &hb_mode, -1);
+	scp_tree_store_get(store, iter, INSPECT_HB_MODE, &hb_mode, -1);
 	g_free(display);
 	return value && *value ? utils_get_display_from_7bit(value, hb_mode) : g_strdup("??");
 }
@@ -245,8 +234,8 @@ static gint inspect_variable_store(GtkTreeIter *iter, const ParseVariable *var)
 	gint format;
 	gboolean expand;
 
-	gtk_tree_model_get(model, iter, INSPECT_EXPAND, &expand, INSPECT_FORMAT, &format, -1);
-	gtk_tree_store_set(store, iter, INSPECT_VAR1, var->name, INSPECT_DISPLAY, var->display,
+	scp_tree_store_get(store, iter, INSPECT_EXPAND, &expand, INSPECT_FORMAT, &format, -1);
+	scp_tree_store_set(store, iter, INSPECT_VAR1, var->name, INSPECT_DISPLAY, var->display,
 		INSPECT_VALUE, var->value, INSPECT_NUMCHILD, var->numchild, -1);
 
 	if (var->numchild)
@@ -267,14 +256,14 @@ void on_inspect_variable(GArray *nodes)
 	GtkTreeIter iter;
 	const char *token = parse_grab_token(nodes);
 
-	iff (model_find(model, &iter, INSPECT_SCID, token), "%s: no vid", token)
+	iff (store_find(store, &iter, INSPECT_SCID, token), "%s: no vid", token)
 	{
 		ParseVariable var;
 		gint format;
 
 		parse_variable(nodes, &var, "numchild");
 		var.display = inspect_redisplay(&iter, var.value, var.display);
-		remove_children(&iter);
+		scp_tree_store_clear_children(store, &iter, FALSE);
 
 		if ((format = inspect_variable_store(&iter, &var)) != FORMAT_NATURAL)
 		{
@@ -308,7 +297,7 @@ void on_inspect_format(GArray *nodes)
 		{
 			gchar *display = inspect_redisplay(&iter, value, NULL);
 
-			gtk_tree_store_set(store, &iter, INSPECT_DISPLAY, display, INSPECT_VALUE,
+			scp_tree_store_set(store, &iter, INSPECT_DISPLAY, display, INSPECT_VALUE,
 				&value, INSPECT_FORMAT, format, -1);
 			g_free(display);
 		}
@@ -326,9 +315,9 @@ static void inspect_node_append(const ParseNode *node, GtkTreeIter *parent)
 	{
 		GtkTreeIter iter;
 
-		gtk_tree_store_append(store, &iter, parent);
+		scp_tree_store_append(store, &iter, parent);
 		inspect_variable_store(&iter, &var);
-		gtk_tree_store_set(store, &iter, INSPECT_EXPR, var.expr ? var.expr : var.name,
+		scp_tree_store_set(store, &iter, INSPECT_EXPR, var.expr ? var.expr : var.name,
 			INSPECT_HB_MODE, var.hb_mode, INSPECT_FORMAT, FORMAT_NATURAL, -1);
 		parse_variable_free(&var);
 	}
@@ -346,23 +335,23 @@ void on_inspect_children(GArray *nodes)
 		if (inspect_find(&iter, FALSE, token + size))
 		{
 			gint from;
-			GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
+			GtkTreePath *path = scp_tree_store_get_path(store, &iter);
 
 			token[size] = '\0';
 			from = atoi(token + 1);
-			remove_children(&iter);
+			scp_tree_store_clear_children(store, &iter, FALSE);
 
 			if ((nodes = parse_find_array(nodes, "children")) == NULL)
 				append_stub(&iter, _("no children in range"), FALSE);
 			else
 			{
 				gint numchild, end;
-				char *var1;
+				const char *var1;
 
 				if (from)
 					append_ellipsis(&iter, FALSE);
 
-				gtk_tree_model_get(model, &iter, INSPECT_VAR1, &var1,
+				scp_tree_store_get(store, &iter, INSPECT_VAR1, &var1,
 					INSPECT_NUMCHILD, &numchild, -1);
 
 				array_foreach(nodes, (GFunc) inspect_node_append, &iter);
@@ -373,7 +362,6 @@ void on_inspect_children(GArray *nodes)
 					debug_send_format(N, "04-var-set-update-range %s %d %d", var1,
 						from, end);
 				}
-				g_free(var1);
 
 				if (nodes->len ? end < numchild : !from)
 					append_ellipsis(&iter, FALSE);
@@ -387,8 +375,8 @@ void on_inspect_children(GArray *nodes)
 
 static void inspect_iter_clear(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata)
 {
-	remove_children(iter);
-	gtk_tree_store_set(store, iter, INSPECT_DISPLAY, NULL, INSPECT_VALUE, NULL,
+	scp_tree_store_clear_children(store, iter, FALSE);
+	scp_tree_store_set(store, iter, INSPECT_DISPLAY, NULL, INSPECT_VALUE, NULL,
 		INSPECT_VAR1, NULL, INSPECT_NUMCHILD, 0, INSPECT_PATH_EXPR, NULL, -1);
 
 	if (gtk_tree_selection_iter_is_selected(selection, iter))
@@ -408,7 +396,7 @@ void on_inspect_ndeleted(GArray *nodes)
 			if (*token == '0')
 				inspect_iter_clear(&iter, NULL);
 			else
-				gtk_tree_store_remove(store, &iter);
+				scp_tree_store_remove(store, &iter);
 		}
 	}
 }
@@ -419,7 +407,7 @@ void on_inspect_path_expr(GArray *nodes)
 	GtkTreeIter iter;
 
 	if (inspect_find(&iter, FALSE, token))
-		gtk_tree_store_set(store, &iter, INSPECT_PATH_EXPR, parse_lead_value(nodes), -1);
+		scp_tree_store_set(store, &iter, INSPECT_PATH_EXPR, parse_lead_value(nodes), -1);
 }
 
 static void inspect_node_change(const ParseNode *node, G_GNUC_UNUSED gpointer gdata)
@@ -437,7 +425,7 @@ static void inspect_node_change(const ParseNode *node, G_GNUC_UNUSED gpointer gd
 
 			if (!g_strcmp0(in_scope, "false"))
 			{
-				gtk_tree_store_set(store, &iter, INSPECT_DISPLAY, _("out of scope"),
+				scp_tree_store_set(store, &iter, INSPECT_DISPLAY, _("out of scope"),
 					INSPECT_VALUE, NULL, -1);
 			}
 			else if (!g_strcmp0(in_scope, "invalid"))
@@ -451,12 +439,12 @@ static void inspect_node_change(const ParseNode *node, G_GNUC_UNUSED gpointer gd
 
 				if (var.children)
 				{
-					remove_children(&iter);
+					scp_tree_store_clear_children(store, &iter, FALSE);
 					inspect_variable_store(&iter, &var);
 				}
 				else
 				{
-					gtk_tree_store_set(store, &iter, INSPECT_DISPLAY, var.display,
+					scp_tree_store_set(store, &iter, INSPECT_DISPLAY, var.display,
 						INSPECT_VALUE, var.value, -1);
 				}
 			}
@@ -474,16 +462,14 @@ void on_inspect_changelist(GArray *nodes)
 static void inspect_apply(GtkTreeIter *iter)
 {
 	gint scid;
-	gchar *expr;
-	char *name, *frame, *locale;
+	const gchar *expr;
+	const char *name, *frame;
+	char *locale;
 
-	gtk_tree_model_get(model, iter, INSPECT_EXPR, &expr, INSPECT_SCID, &scid,
+	scp_tree_store_get(store, iter, INSPECT_EXPR, &expr, INSPECT_SCID, &scid,
 		INSPECT_NAME, &name, INSPECT_FRAME, &frame, -1);
 	locale = utils_get_locale_from_utf8(expr);
 	debug_send_format(F, "07%d-var-create %s %s %s", scid, name, frame, locale);
-	g_free(expr);
-	g_free(name);
-	g_free(frame);
 	g_free(locale);
 }
 
@@ -493,12 +479,11 @@ void on_inspect_signal(const char *name)
 
 	iff (isalpha(*name), "%s: invalid var name", name)
 	{
-		iff (model_find(model, &iter, INSPECT_NAME, name), "%s: var not found", name)
+		iff (store_find(store, &iter, INSPECT_NAME, name), "%s: var not found", name)
 		{
-			char *var1;
+			const char *var1;
 
-			gtk_tree_model_get(model, &iter, INSPECT_VAR1, &var1, -1);
-			g_free(var1);
+			scp_tree_store_get(store, &iter, INSPECT_VAR1, &var1, -1);
 
 			iff (!var1, "%s: already applied", name)
 				inspect_apply(&iter);
@@ -508,7 +493,7 @@ void on_inspect_signal(const char *name)
 
 void inspects_clear(void)
 {
-	model_foreach(model, (GFunc) inspect_iter_clear, NULL);
+	store_foreach(store, (GFunc) inspect_iter_clear, NULL);
 }
 
 gboolean inspects_update(void)
@@ -528,20 +513,19 @@ gboolean inspects_current(void)
 
 static void inspect_iter_apply(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata)
 {
-	char *frame;
+	const char *frame;
 	gboolean run_apply;
 
-	gtk_tree_model_get(model, iter, INSPECT_FRAME, &frame, INSPECT_RUN_APPLY, &run_apply,
+	scp_tree_store_get(store, iter, INSPECT_FRAME, &frame, INSPECT_RUN_APPLY, &run_apply,
 		-1);
 
 	if (run_apply && !isdigit(*frame))
 		inspect_apply(iter);
-	g_free(frame);
 }
 
 void inspects_apply(void)
 {
-	model_foreach(model, (GFunc) inspect_iter_apply, NULL);
+	store_foreach(store, (GFunc) inspect_iter_apply, NULL);
 }
 
 static gboolean inspect_name_valid(const char *name)
@@ -581,7 +565,7 @@ static void on_inspect_ok_button_clicked(G_GNUC_UNUSED GtkButton *button,
 	GtkTreeIter iter;
 	const char *name = gtk_entry_get_text(inspect_name);
 
-	if ((strcmp(name, "-") && model_find(model, &iter, INSPECT_NAME, name)) ||
+	if ((strcmp(name, "-") && store_find(store, &iter, INSPECT_NAME, name)) ||
 		inspect_find(&iter, TRUE, name))
 	{
 		show_error(_("Duplicate inspect variable name."));
@@ -594,7 +578,7 @@ static void inspect_dialog_store(GtkTreeIter *iter)
 {
 	const gchar *expr = gtk_entry_get_text(inspect_expr);
 
-	gtk_tree_store_set(store, iter, INSPECT_EXPR, expr, INSPECT_PATH_EXPR, expr,
+	scp_tree_store_set(store, iter, INSPECT_EXPR, expr, INSPECT_PATH_EXPR, expr,
 		INSPECT_NAME, gtk_entry_get_text(inspect_name),
 		INSPECT_FRAME, gtk_entry_get_text(inspect_frame),
 		INSPECT_RUN_APPLY, gtk_toggle_button_get_active(inspect_run_apply), -1);
@@ -614,15 +598,15 @@ void inspect_add(const gchar *text)
 		const gchar *expr = gtk_entry_get_text(inspect_expr);
 		const ParseMode *pm = parse_mode_find(expr);
 
-		gtk_tree_store_append(store, &iter, NULL);
-		if (debug_state() != DS_INACTIVE)
-			gtk_widget_set_sensitive(jump_to_item, TRUE);
-		inspect_dialog_store(&iter);
-		gtk_tree_store_set(store, &iter, INSPECT_HB_MODE, pm->hb_mode, INSPECT_SCID,
-			++scid_gen, INSPECT_FORMAT, FORMAT_NATURAL, INSPECT_COUNT,
+		scp_tree_store_append_with_values(store, &iter, NULL, INSPECT_HB_MODE, pm->hb_mode,
+			INSPECT_SCID, ++scid_gen, INSPECT_FORMAT, FORMAT_NATURAL, INSPECT_COUNT,
 			option_inspect_count, INSPECT_EXPAND, option_inspect_expand, -1);
+		inspect_dialog_store(&iter);
 		utils_tree_set_cursor(selection, &iter, -1);
 
+		if (debug_state() != DS_INACTIVE)
+			gtk_widget_set_sensitive(jump_to_item, TRUE);
+
 		if (debug_state() & DS_DEBUG)
 			inspect_apply(&iter);
 	}
@@ -631,7 +615,7 @@ void inspect_add(const gchar *text)
 static void on_inspect_display_edited(G_GNUC_UNUSED GtkCellRendererText *renderer,
 	gchar *path_str, gchar *new_text, G_GNUC_UNUSED gpointer gdata)
 {
-	view_display_edited(model, debug_state() & DS_SENDABLE, path_str, "07-var-assign %s %s",
+	view_display_edited(store, debug_state() & DS_SENDABLE, path_str, "07-var-assign %s %s",
 		new_text);
 }
 
@@ -648,28 +632,27 @@ void inspects_update_state(DebugState state)
 	static gboolean last_active = FALSE;
 	gboolean active = state != DS_INACTIVE;
 	GtkTreeIter iter;
-	char *var1 = NULL;
+	const char *var1 = NULL;
 	gint numchild = 0;
 
 	if ((state & DS_SENDABLE) && gtk_tree_selection_get_selected(selection, NULL, &iter))
 	{
-		gtk_tree_model_get(model, &iter, INSPECT_VAR1, &var1, INSPECT_NUMCHILD, &numchild,
+		scp_tree_store_get(store, &iter, INSPECT_VAR1, &var1, INSPECT_NUMCHILD, &numchild,
 			-1);
 	}
 	g_object_set(inspect_display, "editable", var1 && !numchild, NULL);
-	g_free(var1);
 
 	if (active != last_active)
 	{
 		gtk_widget_set_sensitive(jump_to_item, active &&
-			gtk_tree_model_get_iter_first(model, &iter));
+			scp_tree_store_get_iter_first(store, &iter));
 		last_active = active;
 	}
 }
 
 void inspects_delete_all(void)
 {
-	gtk_tree_store_clear(store);
+	store_clear(store);
 	scid_gen = 0;
 }
 
@@ -691,13 +674,11 @@ static gboolean inspect_load(GKeyFile *config, const char *section)
 		frame && inspect_frame_valid(frame) && (unsigned) start <= EXPAND_MAX &&
 		(unsigned) count <= EXPAND_MAX && (unsigned) format < FORMAT_COUNT)
 	{
-		GtkTreeIter iter;
-
-		gtk_tree_store_append(store, &iter, NULL);
-		gtk_tree_store_set(store, &iter, INSPECT_EXPR, expr, INSPECT_PATH_EXPR, expr,
-			INSPECT_HB_MODE, hb_mode, INSPECT_SCID, ++scid_gen, INSPECT_NAME, name,
-			INSPECT_FRAME, frame, INSPECT_RUN_APPLY, run_apply, INSPECT_START, start,
-			INSPECT_COUNT, count, INSPECT_EXPAND, expand, INSPECT_FORMAT, format, -1);
+		scp_tree_store_append_with_values(store, NULL, NULL, INSPECT_EXPR, expr,
+			INSPECT_PATH_EXPR, expr, INSPECT_HB_MODE, hb_mode, INSPECT_SCID, ++scid_gen,
+			INSPECT_NAME, name, INSPECT_FRAME, frame, INSPECT_RUN_APPLY, run_apply,
+			INSPECT_START, start, INSPECT_COUNT, count, INSPECT_EXPAND, expand,
+			INSPECT_FORMAT, format, -1);
 		valid = TRUE;
 	}
 
@@ -716,18 +697,18 @@ void inspects_load(GKeyFile *config)
 static gboolean inspect_save(GKeyFile *config, const char *section, GtkTreeIter *iter)
 {
 	gint hb_mode, start, count, format;
-	char *name, *frame;
-	gchar *expr;
+	const char *name, *frame;
+	const gchar *expr;
 	gboolean run_apply, expand;
 
-	gtk_tree_model_get(model, iter, INSPECT_EXPR, &expr, INSPECT_HB_MODE, &hb_mode,
+	scp_tree_store_get(store, iter, INSPECT_EXPR, &expr, INSPECT_HB_MODE, &hb_mode,
 		INSPECT_NAME, &name, INSPECT_FRAME, &frame, INSPECT_RUN_APPLY, &run_apply,
 		INSPECT_START, &start, INSPECT_COUNT, &count, INSPECT_EXPAND, &expand,
 		INSPECT_FORMAT, &format, -1);
-	utils_key_file_set_string(config, section, "name", name);
-	utils_key_file_set_string(config, section, "expr", expr);
+	g_key_file_set_string(config, section, "name", name);
+	g_key_file_set_string(config, section, "expr", expr);
 	g_key_file_set_integer(config, section, "hbit", hb_mode);
-	utils_key_file_set_string(config, section, "frame", frame);
+	g_key_file_set_string(config, section, "frame", frame);
 	g_key_file_set_boolean(config, section, "run_apply", run_apply);
 	g_key_file_set_integer(config, section, "start", start);
 	g_key_file_set_integer(config, section, "count", count);
@@ -738,7 +719,7 @@ static gboolean inspect_save(GKeyFile *config, const char *section, GtkTreeIter
 
 void inspects_save(GKeyFile *config)
 {
-	model_save(model, config, "inspect", inspect_save);
+	store_save(store, config, "inspect", inspect_save);
 }
 
 static void on_inspect_refresh(G_GNUC_UNUSED const MenuItem *menu_item)
@@ -749,26 +730,25 @@ static void on_inspect_refresh(G_GNUC_UNUSED const MenuItem *menu_item)
 static void on_inspect_add(G_GNUC_UNUSED const MenuItem *menu_item)
 {
 	GtkTreeIter iter;
-	gchar *expr = NULL;
+	const gchar *expr = NULL;
 
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
-		gtk_tree_model_get(model, &iter, INSPECT_PATH_EXPR, &expr, -1);
+		scp_tree_store_get(store, &iter, INSPECT_PATH_EXPR, &expr, -1);
 
 	inspect_add(expr);
-	g_free(expr);
 }
 
 static void on_inspect_edit(G_GNUC_UNUSED const MenuItem *menu_item)
 {
 	GtkTreeIter iter;
-	gchar *expr;
-	char *name, *frame;
+	const gchar *expr;
+	const char *name, *frame;
 	gboolean run_apply;
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, INSPECT_EXPR, &expr, INSPECT_NAME, &name,
+	scp_tree_store_get(store, &iter, INSPECT_EXPR, &expr, INSPECT_NAME, &name,
 		INSPECT_FRAME, &frame, INSPECT_RUN_APPLY, &run_apply, -1);
-	gtk_tree_store_set(store, &iter, INSPECT_NAME, "-", -1);  /* for duplicate name check */
+	scp_tree_store_set(store, &iter, INSPECT_NAME, "-", -1);  /* for duplicate name check */
 
 	gtk_entry_set_text(inspect_expr, expr);
 	gtk_entry_set_text(inspect_name, name);
@@ -783,27 +763,20 @@ static void on_inspect_edit(G_GNUC_UNUSED const MenuItem *menu_item)
 		inspect_dialog_store(&iter);
 	}
 	else
-		gtk_tree_store_set(store, &iter, INSPECT_NAME, name, -1);
-
-	g_free(expr);
-	g_free(name);
-	g_free(frame);
+		scp_tree_store_set(store, &iter, INSPECT_NAME, name, -1);
 }
 
 static void on_inspect_apply(G_GNUC_UNUSED const MenuItem *menu_item)
 {
 	GtkTreeIter iter;
-	char *var1;
+	const char *var1;
 	gint scid;
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, INSPECT_SCID, &scid, INSPECT_VAR1, &var1, -1);
+	scp_tree_store_get(store, &iter, INSPECT_SCID, &scid, INSPECT_VAR1, &var1, -1);
 
 	if (var1)
-	{
 		debug_send_format(N, "070%d-var-delete %s", scid, var1);
-		g_free(var1);
-	}
 	else
 		inspect_apply(&iter);
 }
@@ -816,22 +789,21 @@ static void on_inspect_apply(G_GNUC_UNUSED const MenuItem *menu_item)
 static void on_inspect_expand(G_GNUC_UNUSED const MenuItem *menu_item)
 {
 	GtkTreeIter iter;
-	char *name;
+	const char *name;
 	gint start, count;
 	gboolean expand;
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, INSPECT_NAME, &name, INSPECT_START, &start,
+	scp_tree_store_get(store, &iter, INSPECT_NAME, &name, INSPECT_START, &start,
 		INSPECT_COUNT, &count, INSPECT_EXPAND, &expand, -1);
 	gtk_spin_button_set_value(expand_start, start);
 	gtk_spin_button_set_value(expand_count, count);
 	gtk_toggle_button_set_active(expand_automatic, expand);
 	gtk_widget_set_sensitive(GTK_WIDGET(expand_automatic), name != NULL);
-	g_free(name);
 
 	if (gtk_dialog_run(GTK_DIALOG(expand_dialog)) == GTK_RESPONSE_ACCEPT)
 	{
-		gtk_tree_store_set(store, &iter,
+		scp_tree_store_set(store, &iter,
 			INSPECT_START, gtk_spin_button_get_value_as_int(expand_start),
 			INSPECT_COUNT, gtk_spin_button_get_value_as_int(expand_count),
 			INSPECT_EXPAND, gtk_toggle_button_get_active(expand_automatic), -1);
@@ -857,19 +829,18 @@ static void on_inspect_format_update(const MenuItem *menu_item)
 {
 	GtkTreeIter iter;
 	gint format = GPOINTER_TO_INT(menu_item->gdata);
-	char *var1;
+	const char *var1;
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, INSPECT_VAR1, &var1, -1);
+	scp_tree_store_get(store, &iter, INSPECT_VAR1, &var1, -1);
 
 	if (var1)
 	{
 		debug_send_format(N, "07%d-var-set-format %s %s", inspect_get_scid(&iter), var1,
 			inspect_formats[format]);
-		g_free(var1);
 	}
 	else
-		gtk_tree_store_set(store, &iter, INSPECT_FORMAT, format, -1);
+		scp_tree_store_set(store, &iter, INSPECT_FORMAT, format, -1);
 }
 
 static void on_inspect_hbit_display(const MenuItem *menu_item)
@@ -879,29 +850,27 @@ static void on_inspect_hbit_display(const MenuItem *menu_item)
 
 static void inspect_hbit_update_iter(GtkTreeIter *iter, gint hb_mode)
 {
-	char *var1, *value;
+	const char *var1, *value;
 
-	gtk_tree_model_get(model, iter, INSPECT_VAR1, &var1, INSPECT_VALUE, &value, -1);
-	gtk_tree_store_set(store, iter, INSPECT_HB_MODE, hb_mode, -1);
+	scp_tree_store_get(store, iter, INSPECT_VAR1, &var1, INSPECT_VALUE, &value, -1);
+	scp_tree_store_set(store, iter, INSPECT_HB_MODE, hb_mode, -1);
 
 	if (var1)
 	{
 		gchar *display = inspect_redisplay(iter, value, NULL);
-		gtk_tree_store_set(store, iter, INSPECT_DISPLAY, display, -1);
+		scp_tree_store_set(store, iter, INSPECT_DISPLAY, display, -1);
 		g_free(display);
 	}
-	g_free(var1);
-	g_free(value);
 }
 
 static void on_inspect_hbit_update(const MenuItem *menu_item)
 {
 	GtkTreeIter iter;
-	char *expr, *name;
+	const char *expr, *name;
 	gint hb_mode = GPOINTER_TO_INT(menu_item->gdata);
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, INSPECT_EXPR, &expr, INSPECT_NAME, &name, -1);
+	scp_tree_store_get(store, &iter, INSPECT_EXPR, &expr, INSPECT_NAME, &name, -1);
 	inspect_hbit_update_iter(&iter, hb_mode);
 	parse_mode_update(expr, MODE_HBIT, hb_mode);
 
@@ -909,30 +878,24 @@ static void on_inspect_hbit_update(const MenuItem *menu_item)
 	{
 		char *reverse = parse_mode_reentry(expr);
 
-		if (model_find(model, &iter, INSPECT_EXPR, reverse))
+		if (store_find(store, &iter, INSPECT_EXPR, reverse))
 			inspect_hbit_update_iter(&iter, hb_mode);
 		g_free(reverse);
 	}
-
-	g_free(expr);
-	g_free(name);
 }
 
 static void on_inspect_delete(G_GNUC_UNUSED const MenuItem *menu_item)
 {
 	GtkTreeIter iter;
-	char *var1;
+	const char *var1;
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, INSPECT_VAR1, &var1, -1);
+	scp_tree_store_get(store, &iter, INSPECT_VAR1, &var1, -1);
 
 	if (var1)
-	{
 		debug_send_format(N, "071%d-var-delete %s", inspect_get_scid(&iter), var1);
-		g_free(var1);
-	}
 	else
-		gtk_tree_store_remove(store, &iter);
+		scp_tree_store_remove(store, &iter);
 }
 
 #define DS_EDITABLE (DS_BASICS | DS_EXTRA_2)
@@ -972,13 +935,11 @@ static guint inspect_menu_extra_state(void)
 
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 	{
-		char *var1, *name;
+		const char *var1, *name;
 		gint numchild;
 
-		gtk_tree_model_get(model, &iter, INSPECT_VAR1, &var1, INSPECT_NAME, &name,
+		scp_tree_store_get(store, &iter, INSPECT_VAR1, &var1, INSPECT_NAME, &name,
 			INSPECT_NUMCHILD, &numchild, -1);
-		g_free(var1);
-		g_free(name);
 
 		if (name || var1)
 		{
@@ -996,7 +957,7 @@ static void on_inspect_selection_changed(G_GNUC_UNUSED GtkTreeSelection *selecti
 	G_GNUC_UNUSED gpointer gdata)
 {
 	GtkTreeIter iter;
-	char *name = NULL;
+	const char *name = NULL;
 
 	if (gtk_widget_get_visible(inspect_dialog))
 		gtk_widget_hide(inspect_dialog);
@@ -1004,23 +965,21 @@ static void on_inspect_selection_changed(G_GNUC_UNUSED GtkTreeSelection *selecti
 		gtk_widget_hide(expand_dialog);
 
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
-		gtk_tree_model_get(model, &iter, INSPECT_NAME, &name, -1);
+		scp_tree_store_get(store, &iter, INSPECT_NAME, &name, -1);
 
 	gtk_tree_view_set_reorderable(tree, name != NULL);
 	inspects_update_state(debug_state());
-	g_free(name);
 }
 
 static gboolean inspect_test_expand_row(G_GNUC_UNUSED GtkTreeView *tree_view,
 	GtkTreeIter *iter, G_GNUC_UNUSED GtkTreePath *path, G_GNUC_UNUSED gpointer gdata)
 {
 	GtkTreeIter child;
-	char *var1;
+	const char *var1;
 	gboolean expand;
 
-	gtk_tree_model_iter_children(model, &child, iter);
-	gtk_tree_model_get(model, &child, INSPECT_VAR1, &var1, INSPECT_EXPAND, &expand, -1);
-	g_free(var1);
+	scp_tree_store_iter_children(store, &child, iter);
+	scp_tree_store_get(store, &child, INSPECT_VAR1, &var1, INSPECT_EXPAND, &expand, -1);
 
 	if (var1 || !expand)
 		return FALSE;
@@ -1068,12 +1027,11 @@ gboolean on_inspect_drag_motion(G_GNUC_UNUSED GtkWidget *widget,
 	if (gtk_tree_view_get_dest_row_at_pos(tree, x, y, &path, &pos))
 	{
 		GtkTreeIter iter;
-		char *name;
+		const char *name;
 
-		gtk_tree_model_get_iter(model, &iter, path);
+		scp_tree_store_get_iter(store, &iter, path);
 		gtk_tree_path_free(path);
-		gtk_tree_model_get(model, &iter, INSPECT_NAME, &name, -1);
-		g_free(name);
+		scp_tree_store_get(store, &iter, INSPECT_NAME, &name, -1);
 
 		if (!name || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE ||
 			pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER)
@@ -1091,9 +1049,9 @@ static void on_inspect_menu_show(G_GNUC_UNUSED GtkWidget *widget, G_GNUC_UNUSED
 
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 	{
-		char *var1, *path_expr;
+		const char *var1, *path_expr;
 
-		gtk_tree_model_get(model, &iter, INSPECT_VAR1, &var1, INSPECT_PATH_EXPR,
+		scp_tree_store_get(store, &iter, INSPECT_VAR1, &var1, INSPECT_PATH_EXPR,
 			&path_expr, -1);
 		menu_item_set_active(apply_item, var1 != NULL);
 
@@ -1102,9 +1060,6 @@ static void on_inspect_menu_show(G_GNUC_UNUSED GtkWidget *widget, G_GNUC_UNUSED
 			debug_send_format(N, "04%d-var-info-path-expression %s",
 				inspect_get_scid(&iter), var1);
 		}
-
-		g_free(var1);
-		g_free(path_expr);
 	}
 }
 
@@ -1129,17 +1084,16 @@ void inspect_init(void)
 		NULL);
 	gtk_notebook_append_page(geany_sidebar, inspect_page, get_widget("inspect_label"));
 
-	tree = view_connect("inspect_view", &model, &selection, inspect_cells, "inspect_window",
+	tree = view_connect("inspect_view", &store, &selection, inspect_cells, "inspect_window",
 		&inspect_display);
 	g_signal_connect(tree, "test-expand-row", G_CALLBACK(inspect_test_expand_row), NULL);
 	g_signal_connect(tree, "key-press-event", G_CALLBACK(on_inspect_key_press), NULL);
 	g_signal_connect(tree, "button-press-event", G_CALLBACK(on_inspect_button_press), NULL);
 	g_signal_connect(tree, "drag-motion", G_CALLBACK(on_inspect_drag_motion), NULL);
 
-	store = GTK_TREE_STORE(model);
-	g_signal_connect(model, "row-inserted", G_CALLBACK(on_inspect_row_inserted), NULL);
-	g_signal_connect(model, "row-changed", G_CALLBACK(on_inspect_row_changed), NULL);
-	g_signal_connect(model, "row-deleted", G_CALLBACK(on_inspect_row_deleted), NULL);
+	g_signal_connect(store, "row-inserted", G_CALLBACK(on_inspect_row_inserted), NULL);
+	g_signal_connect(store, "row-changed", G_CALLBACK(on_inspect_row_changed), NULL);
+	g_signal_connect(store, "row-deleted", G_CALLBACK(on_inspect_row_deleted), NULL);
 
 	g_signal_connect(selection, "changed", G_CALLBACK(on_inspect_selection_changed), NULL);
 	menu = menu_select("inspect_menu", &inspect_menu_info, selection);


Modified: scope/src/local.c
25 files changed, 11 insertions(+), 14 deletions(-)
===================================================================
@@ -31,14 +31,13 @@ enum
 	LOCAL_ARG1
 };
 
-static GtkListStore *store;
-static GtkTreeModel *model;
+static ScpTreeStore *store;
 static GtkTreeSelection *selection;
 
 static void on_local_display_edited(G_GNUC_UNUSED GtkCellRendererText *renderer,
 	gchar *path_str, gchar *new_text, G_GNUC_UNUSED gpointer gdata)
 {
-	view_display_edited(model, thread_state >= THREAD_STOPPED && frame_id, path_str,
+	view_display_edited(store, thread_state >= THREAD_STOPPED && frame_id, path_str,
 		"07-gdb-set var %s=%s", new_text);
 }
 
@@ -68,10 +67,10 @@ static void local_node_variable(const ParseNode *node, const LocalData *ld)
 
 			if (!arg1 || ld->entry || !g_str_has_suffix(var.name, "@entry"))
 			{
-				gtk_list_store_append(store, &iter);
-				gtk_list_store_set(store, &iter, LOCAL_NAME, var.name, LOCAL_DISPLAY,
-					var.display, LOCAL_VALUE, var.value, LOCAL_HB_MODE, var.hb_mode,
-					LOCAL_MR_MODE, var.mr_mode, LOCAL_ARG1, arg1, -1);
+				scp_tree_store_append_with_values(store, &iter, NULL, LOCAL_NAME,
+					var.name, LOCAL_DISPLAY, var.display, LOCAL_VALUE, var.value,
+					LOCAL_HB_MODE, var.hb_mode, LOCAL_MR_MODE, var.mr_mode,
+					LOCAL_ARG1, arg1, -1);
 
 				if (!g_strcmp0(var.name, ld->name))
 					gtk_tree_selection_select_iter(selection, &iter);
@@ -93,7 +92,7 @@ void on_local_variables(GArray *nodes)
 		LocalData ld = { NULL, stack_entry() };
 
 		if (gtk_tree_selection_get_selected(selection, NULL, &iter))
-			gtk_tree_model_get(model, &iter, LOCAL_NAME, &ld.name, -1);
+			gtk_tree_model_get((GtkTreeModel *) store, &iter, LOCAL_NAME, &ld.name, -1);
 
 		locals_clear();
 		array_foreach(parse_lead_array(nodes), (GFunc) local_node_variable, &ld);
@@ -103,7 +102,7 @@ void on_local_variables(GArray *nodes)
 
 void locals_clear(void)
 {
-	gtk_list_store_clear(store);
+	store_clear(store);
 }
 
 static void local_send_update(char token)
@@ -156,12 +155,11 @@ static void on_local_modify(const MenuItem *menu_item)
 static void on_local_watch(G_GNUC_UNUSED const MenuItem *menu_item)
 {
 	GtkTreeIter iter;
-	char *name;
+	const char *name;
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, LOCAL_NAME, &name, -1);
+	scp_tree_store_get(store, &iter, LOCAL_NAME, &name, -1);
 	watch_add(name);
-	g_free(name);
 }
 
 static void on_local_inspect(G_GNUC_UNUSED const MenuItem *menu_item)
@@ -233,10 +231,9 @@ void local_init(void)
 {
 	GtkWidget *menu;
 
-	view_connect("local_view", &model, &selection, local_cells, "local_window",
+	view_connect("local_view", &store, &selection, local_cells, "local_window",
 		&local_display);
 	menu = menu_select("local_menu", &local_menu_info, selection);
-	store = GTK_LIST_STORE(model);
 
 	g_signal_connect(menu, "show", G_CALLBACK(on_local_menu_show), NULL);
 	g_signal_connect(get_widget("local_modify"), "button-release-event",


Modified: scope/src/memory.c
43 files changed, 17 insertions(+), 26 deletions(-)
===================================================================
@@ -31,8 +31,7 @@ enum
 	MEMORY_ASCII
 };
 
-static GtkListStore *store;
-static GtkTreeModel *model;
+static ScpTreeStore *store;
 static GtkTreeSelection *selection;
 
 static void on_memory_bytes_edited(G_GNUC_UNUSED GtkCellRendererText *renderer, gchar *path_str,
@@ -41,11 +40,11 @@ static void on_memory_bytes_edited(G_GNUC_UNUSED GtkCellRendererText *renderer,
 	if (*new_text && (debug_state() & DS_SENDABLE))
 	{
 		GtkTreeIter iter;
-		char *addr, *bytes;
+		const char *addr, *bytes;
 		guint i;
 
-		gtk_tree_model_get_iter_from_string(model, &iter, path_str);
-		gtk_tree_model_get(model, &iter, MEMORY_ADDR, &addr, MEMORY_BYTES, &bytes, -1);
+		scp_tree_store_get_iter_from_string(store, &iter, path_str);
+		scp_tree_store_get(store, &iter, MEMORY_ADDR, &addr, MEMORY_BYTES, &bytes, -1);
 
 		for (i = 0; bytes[i]; i++)
 			if (!(isxdigit(bytes[i]) ? isxdigit(new_text[i]) : new_text[i] == ' '))
@@ -58,9 +57,6 @@ static void on_memory_bytes_edited(G_GNUC_UNUSED GtkCellRendererText *renderer,
 			utils_strchrepl(new_text, ' ', '\0');
 			debug_send_format(T, "07-data-write-memory-bytes 0x%s%s", addr, new_text);
 		}
-
-		g_free(addr);
-		g_free(bytes);
 	}
 	else
 		plugin_blink();
@@ -153,7 +149,7 @@ static void write_block(guint64 start, const char *contents, guint count)
 		GString *ascii = g_string_new(" ");
 		gint n = 0;
 
-		gtk_list_store_append(store, &iter);
+		scp_tree_store_append(store, &iter, NULL);
 
 		while (n < bytes_per_line)
 		{
@@ -189,7 +185,7 @@ static void write_block(guint64 start, const char *contents, guint count)
 				g_string_append_c(bytes, ' ');
 		}
 
-		gtk_list_store_set(store, &iter, MEMORY_ADDR, addr, MEMORY_BYTES, bytes->str,
+		scp_tree_store_set(store, &iter, MEMORY_ADDR, addr, MEMORY_BYTES, bytes->str,
 			MEMORY_ASCII, ascii->str, -1);
 
 		g_free(addr);
@@ -235,9 +231,9 @@ void on_memory_read_bytes(GArray *nodes)
 		char *addr = NULL;
 
 		if (gtk_tree_selection_get_selected(selection, NULL, &iter))
-			gtk_tree_model_get(model, &iter, MEMORY_ADDR, &addr, -1);
+			gtk_tree_model_get((GtkTreeModel *) store, &iter, MEMORY_ADDR, &addr, -1);
 
-		gtk_list_store_clear(store);
+		store_clear(store);
 		memory_count = 0;
 
 		if (pref_memory_bytes_per_line != back_bytes_per_line)
@@ -252,7 +248,7 @@ void on_memory_read_bytes(GArray *nodes)
 
 		if (addr)
 		{
-			if (model_find(model, &iter, MEMORY_ADDR, addr))
+			if (store_find(store, &iter, MEMORY_ADDR, addr))
 				utils_tree_set_cursor(selection, &iter, -1);
 			g_free(addr);
 		}
@@ -261,7 +257,7 @@ void on_memory_read_bytes(GArray *nodes)
 
 void memory_clear(void)
 {
-	gtk_list_store_clear(store);
+	store_clear(store);
 }
 
 gboolean memory_update(void)
@@ -302,27 +298,23 @@ static void on_memory_read(G_GNUC_UNUSED const MenuItem *menu_item)
 
 static void on_memory_copy(G_GNUC_UNUSED const MenuItem *menu_item)
 {
-	GtkTreeModel *model;
 	GtkTreeIter iter;
-	char *addr, *bytes;
-	gchar *ascii;
+	const char *addr, *bytes;
+	const gchar *ascii;
 	gchar *string;
 
-	gtk_tree_selection_get_selected(selection, &model, &iter);
-	gtk_tree_model_get(model, &iter, MEMORY_ADDR, &addr, MEMORY_BYTES, &bytes,
+	gtk_tree_selection_get_selected(selection, NULL, &iter);
+	scp_tree_store_get(store, &iter, MEMORY_ADDR, &addr, MEMORY_BYTES, &bytes,
 		MEMORY_ASCII, &ascii, -1);
 	string = g_strdup_printf("%s%s%s", addr, bytes, ascii);
 	gtk_clipboard_set_text(gtk_widget_get_clipboard(menu_item->widget,
 		GDK_SELECTION_CLIPBOARD), string, -1);
-	g_free(addr);
-	g_free(bytes);
-	g_free(ascii);
 	g_free(string);
 }
 
 static void on_memory_clear(G_GNUC_UNUSED const MenuItem *menu_item)
 {
-	gtk_list_store_clear(store);
+	store_clear(store);
 	memory_count = 0;
 }
 
@@ -387,10 +379,9 @@ static gboolean on_memory_key_press(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey
 
 void memory_init(void)
 {
-	GtkWidget *tree = GTK_WIDGET(view_connect("memory_view", &model, &selection,
+	GtkWidget *tree = GTK_WIDGET(view_connect("memory_view", &store, &selection,
 		memory_cells, "memory_window", NULL));
 
-	store = GTK_LIST_STORE(model);
 	memory_font = *pref_memory_font ? pref_memory_font : pref_vte_font;
 	ui_widget_modify_font_from_string(tree, memory_font);
 	g_signal_connect(get_object("memory_bytes"), "editing-started",
@@ -405,7 +396,7 @@ void memory_init(void)
 
 	if (pointer_size > MAX_POINTER_SIZE)
 	{
-		msgwin_status_add(_("Scope: pointer size > 8, Data disabled."));
+		msgwin_status_add(_("Scope: pointer size > %d, Data disabled."), MAX_POINTER_SIZE);
 		gtk_widget_hide(tree);
 	}
 	else


Modified: scope/src/menu.c
65 files changed, 28 insertions(+), 37 deletions(-)
===================================================================
@@ -204,14 +204,14 @@ void menu_mode_display(GtkTreeSelection *selection, const MenuItem *menu_item, g
 	menu_item_set_active(menu_item + mode + 1, TRUE);
 }
 
-static void menu_mode_update_iter(GtkTreeModel *model, GtkTreeIter *iter, gint new_mode,
+static void menu_mode_update_iter(ScpTreeStore *store, GtkTreeIter *iter, gint new_mode,
 	gboolean hbit)
 {
 	gint hb_mode, mr_mode;
-	char *value;
+	const char *value;
 	gchar *display;
 
-	gtk_tree_model_get(model, iter, COLUMN_VALUE, &value, COLUMN_HB_MODE, &hb_mode,
+	scp_tree_store_get(store, iter, COLUMN_VALUE, &value, COLUMN_HB_MODE, &hb_mode,
 		COLUMN_MR_MODE, &mr_mode, -1);
 
 	if (hbit)
@@ -220,32 +220,30 @@ static void menu_mode_update_iter(GtkTreeModel *model, GtkTreeIter *iter, gint n
 		mr_mode = new_mode;
 
 	display = parse_get_display_from_7bit(value, hb_mode, mr_mode);
-	gtk_list_store_set(GTK_LIST_STORE(model), iter, COLUMN_HB_MODE, hb_mode,
-		COLUMN_MR_MODE, mr_mode, value ? COLUMN_DISPLAY : -1, display, -1);
-	g_free(value);
+	scp_tree_store_set(store, iter, COLUMN_HB_MODE, hb_mode, COLUMN_MR_MODE, mr_mode,
+		value ? COLUMN_DISPLAY : -1, display, -1);
 	g_free(display);
 }
 
 void menu_mode_update(GtkTreeSelection *selection, gint new_mode, gboolean hbit)
 {
-	GtkTreeModel *model;
+	ScpTreeStore *store;
 	GtkTreeIter iter;
-	char *name;
+	const char *name;
 
-	gtk_tree_selection_get_selected(selection, &model, &iter);
-	gtk_tree_model_get(model, &iter, COLUMN_NAME, &name, -1);
-	menu_mode_update_iter(model, &iter, new_mode, hbit);
+	scp_tree_selection_get_selected(selection, &store, &iter);
+	scp_tree_store_get(store, &iter, COLUMN_NAME, &name, -1);
+	menu_mode_update_iter(store, &iter, new_mode, hbit);
 	parse_mode_update(name, hbit ? MODE_HBIT : MODE_MEMBER, new_mode);
 
 	if (hbit)
 	{
 		char *reverse = parse_mode_reentry(name);
 
-		if (model_find(model, &iter, COLUMN_NAME, reverse))
-			menu_mode_update_iter(model, &iter, new_mode, TRUE);
+		if (store_find(store, &iter, COLUMN_NAME, reverse))
+			menu_mode_update_iter(store, &iter, new_mode, TRUE);
 		g_free(reverse);
 	}
-	g_free(name);
 }
 
 void menu_mber_display(GtkTreeSelection *selection, const MenuItem *menu_item)
@@ -298,14 +296,14 @@ void menu_mber_button_release(GtkTreeSelection *selection, GtkWidget *item,
 
 void menu_copy(GtkTreeSelection *selection, const MenuItem *menu_item)
 {
-	GtkTreeModel *model;
+	ScpTreeStore *store;
 	GtkTreeIter iter;
-	gchar *name, *display;
-	char *value;
+	const gchar *name, *display;
+	const char *value;
 	GString *string;
 
-	gtk_tree_selection_get_selected(selection, &model, &iter);
-	gtk_tree_model_get(model, &iter, COLUMN_NAME, &name, COLUMN_DISPLAY, &display,
+	scp_tree_selection_get_selected(selection, &store, &iter);
+	scp_tree_store_get(store, &iter, COLUMN_NAME, &name, COLUMN_DISPLAY, &display,
 		COLUMN_VALUE, &value, -1);
 	string = g_string_new(name);
 
@@ -315,9 +313,6 @@ void menu_copy(GtkTreeSelection *selection, const MenuItem *menu_item)
 	gtk_clipboard_set_text(gtk_widget_get_clipboard(menu_item->widget,
 		GDK_SELECTION_CLIPBOARD), string->str, string->len);
 
-	g_free(name);
-	g_free(display);
-	g_free(value);
 	g_string_free(string, TRUE);
 }
 
@@ -368,31 +363,28 @@ static void menu_evaluate_modify(const gchar *expr, const char *value, const gch
 
 void menu_modify(GtkTreeSelection *selection, const MenuItem *menu_item)
 {
-	GtkTreeModel *model;
+	ScpTreeStore *store;
 	GtkTreeIter iter;
-	gchar *name;
-	char *value;
+	const gchar *name;
+	const char *value;
 	gint hb_mode;
 
-	gtk_tree_selection_get_selected(selection, &model, &iter);
-	gtk_tree_model_get(model, &iter, COLUMN_NAME, &name, COLUMN_VALUE, &value, COLUMN_HB_MODE,
+	scp_tree_selection_get_selected(selection, &store, &iter);
+	scp_tree_store_get(store, &iter, COLUMN_NAME, &name, COLUMN_VALUE, &value, COLUMN_HB_MODE,
 		&hb_mode, -1);
 	menu_evaluate_modify(name, value, _("Modify"), hb_mode, menu_item ? MR_MODIFY : MR_MODSTR,
 		"07");
-	g_free(name);
-	g_free(value);
 }
 
 void menu_inspect(GtkTreeSelection *selection)
 {
-	GtkTreeModel *model;
+	ScpTreeStore *store;
 	GtkTreeIter iter;
-	char *name;
+	const char *name;
 
-	gtk_tree_selection_get_selected(selection, &model, &iter);
-	gtk_tree_model_get(model, &iter, COLUMN_NAME, &name, -1);
+	scp_tree_selection_get_selected(selection, &store, &iter);
+	scp_tree_store_get(store, &iter, COLUMN_NAME, &name, -1);
 	inspect_add(name);
-	g_free(name);
 }
 
 void on_menu_display_booleans(const MenuItem *menu_item)
@@ -492,9 +484,8 @@ static void on_popup_evaluate_button_release(GtkWidget *widget, GdkEventButton *
 	{ "inspect",  N_("Inspect variable") }
 };
 
-void menu_set_popup_keybindings(guint item)
+void menu_set_popup_keybindings(GeanyKeyGroup *scope_key_group, guint item)
 {
-	extern GeanyKeyGroup *plugin_key_group;
 	const MenuKey *menu_key = popup_menu_keys;
 	const MenuItem *menu_item;
 
@@ -502,7 +493,7 @@ void menu_set_popup_keybindings(guint item)
 
 	for (menu_item = popup_menu_items; menu_item->name; menu_item++, menu_key++, item++)
 	{
-		keybindings_set_item(plugin_key_group, item, on_popup_key, 0, 0, menu_key->name,
+		keybindings_set_item(scope_key_group, item, on_popup_key, 0, 0, menu_key->name,
 			_(menu_key->label), popup_menu_items[item].widget);
 	}
 }


Modified: scope/src/menu.h
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -95,7 +95,7 @@ void menu_mber_button_release(GtkTreeSelection *selection, GtkWidget *item,
 	const gchar *label;
 } MenuKey;
 
-void menu_set_popup_keybindings(guint item);
+void menu_set_popup_keybindings(GeanyKeyGroup *scope_key_group, guint item);
 void menu_clear(void);
 void menu_update_state(DebugState state);
 


Modified: scope/src/prefs.c
47 files changed, 0 insertions(+), 47 deletions(-)
===================================================================
@@ -198,43 +198,6 @@ char *prefs_file_name(void)
 	return g_build_filename(geany->app->configdir, "plugins", "scope", "scope.conf", NULL);
 }
 
-#ifdef stash_tree_setup
-static void on_configure_response(G_GNUC_UNUSED GtkDialog *dialog, gint response,
-	gpointer gdata)
-{
-	if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
-	{
-		char *configfile = prefs_file_name();
-
-		stash_tree_update(GTK_TREE_VIEW(gdata));
-		prefs_configure();
-		scope_configure();
-		stash_group_save_to_file(scope_group, configfile, G_KEY_FILE_KEEP_COMMENTS);
-		g_free(configfile);
-	}
-}
-
-static GPtrArray *pref_groups;
-
-GtkWidget *plugin_configure(GtkDialog *dialog)
-{
-	GtkWidget *vbox = gtk_vbox_new(FALSE, 6);
-	GtkWidget *window = gtk_scrolled_window_new(NULL, NULL);
-	GtkTreeView *tree = GTK_TREE_VIEW(gtk_tree_view_new());
-
-	gtk_box_pack_start(GTK_BOX(vbox), window, TRUE, TRUE, 0);
-	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(window), GTK_POLICY_AUTOMATIC,
-		GTK_POLICY_AUTOMATIC);
-	gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(tree));
-	stash_tree_setup(pref_groups, tree);
-	stash_tree_display(tree);
-	g_signal_connect(dialog, "response", G_CALLBACK(on_configure_response), tree);
-	gtk_widget_show_all(vbox);
-
-	return vbox;
-}
-#endif  /* stash_tree_setup */
-
 static void on_document_save(G_GNUC_UNUSED GObject *obj, GeanyDocument *doc,
 	G_GNUC_UNUSED gpointer gdata)
 {
@@ -297,12 +260,6 @@ void prefs_init(void)
 	stash_group_add_string(group, &pref_memory_font, "memory_font", "");
 	scope_group = group;
 
-#ifdef stash_tree_setup
-	pref_groups = g_ptr_array_new();
-	stash_group_set_various(group, TRUE);
-	g_ptr_array_add(pref_groups, group);
-#endif
-
 	config_item = ui_add_config_file_menu_item(configfile, NULL, NULL);
 	plugin_signal_connect(geany_plugin, NULL, "document-save", FALSE,
 		G_CALLBACK(on_document_save), NULL);
@@ -395,8 +352,4 @@ void prefs_finalize(void)
 	utils_stash_group_free(terminal_group);
 	for (i = 0; i < MARKER_COUNT; i++)
 		utils_stash_group_free(marker_group[i]);
-
-#ifdef stash_tree_setup
-	g_ptr_array_free(pref_groups, TRUE);
-#endif
 }


Modified: scope/src/scope.c
28 files changed, 21 insertions(+), 7 deletions(-)
===================================================================
@@ -32,7 +32,8 @@
 PLUGIN_VERSION_CHECK(215)
 
 PLUGIN_SET_TRANSLATABLE_INFO(LOCALEDIR, GETTEXT_PACKAGE, _("Scope Debugger"),
-	_("Simple GDB front-end."), "0.84" , "Dimitar Toshkov Zhekov <dimitar.zhekov at gmail.com>")
+	_("Relatively simple GDB front-end."), "0.87" ,
+	"Dimitar Toshkov Zhekov <dimitar.zhekov at gmail.com>")
 
 /* Keybinding(s) */
 enum
@@ -56,8 +57,6 @@ enum
 	COUNT_KB
 };
 
-PLUGIN_KEY_GROUP(scope, COUNT_KB)
-
 static MenuKey debug_menu_keys[EVALUATE_KB] =
 {
 	{ "setup_program", N_("Setup program") },
@@ -235,11 +234,19 @@ void statusbar_update_state(DebugState state)
 		if (state == DS_INACTIVE)
 		{
 			gtk_widget_hide(debug_statusbar);
+		#if GTK_CHECK_VERSION(3, 0, 0)
+			gtk_window_set_has_resize_grip(GTK_WINDOW(geany->main_widgets->window), TRUE);
+		#else
 			gtk_statusbar_set_has_resize_grip(geany_statusbar, TRUE);
+		#endif
 		}
 		else if (last_state == DS_INACTIVE)
 		{
+		#if GTK_CHECK_VERSION(3, 0, 0)
+			gtk_window_set_has_resize_grip(GTK_WINDOW(geany->main_widgets->window), FALSE);
+		#else
 			gtk_statusbar_set_has_resize_grip(geany_statusbar, FALSE);
+		#endif
 			gtk_widget_show(debug_statusbar);
 		}
 
@@ -485,18 +492,26 @@ void open_debug_panel(void)
 
 void plugin_init(G_GNUC_UNUSED GeanyData *gdata)
 {
+	GeanyKeyGroup *scope_key_group;
+	char *gladefile = g_build_filename(PLUGINDATADIR, "scope.glade", NULL);
 	GError *gerror = NULL;
 	GtkWidget *menubar1 = find_widget(geany->main_widgets->window, "menubar1");
 	guint item;
 	const MenuKey *menu_key = debug_menu_keys;
 	ToolItem *tool_item = toolbar_items;
 	const ScopeCallback *scb;
-	char *gladefile = g_build_filename(PLUGINDATADIR, "scope.glade", NULL);
 
 	main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
+	scope_key_group = plugin_set_key_group(geany_plugin, "scope", COUNT_KB, NULL);
 	builder = gtk_builder_new();
 	gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE);
 
+	if (!g_type_from_name("ScpTreeStore"))
+	{
+		plugin_module_make_resident(geany_plugin);
+		scp_tree_store_get_type();
+	}
+
 	if (!gtk_builder_add_from_file(builder, gladefile, &gerror))
 	{
 		msgwin_status_add(_("Scope: %s."), gerror->message);
@@ -525,7 +540,7 @@ void plugin_init(G_GNUC_UNUSED GeanyData *gdata)
 
 	for (item = 0; item < EVALUATE_KB; item++, menu_key++)
 	{
-		keybindings_set_item(plugin_key_group, item, on_scope_key, 0, 0, menu_key->name,
+		keybindings_set_item(scope_key_group, item, on_scope_key, 0, 0, menu_key->name,
 			_(menu_key->label), debug_menu_items[item].widget);
 	}
 
@@ -555,7 +570,7 @@ void plugin_init(G_GNUC_UNUSED GeanyData *gdata)
 	local_init();
 	memory_init();
 	menu_init();
-	menu_set_popup_keybindings(item);
+	menu_set_popup_keybindings(scope_key_group, item);
 
 	for (item = 0; tool_item->index != -1; item++, tool_item++)
 	{
@@ -602,7 +617,6 @@ void plugin_cleanup(void)
 	thread_finalize();
 	break_finalize();
 	memory_finalize();
-	stack_finalize();
 	menu_finalize();
 	views_finalize();
 	utils_finalize();


Modified: scope/src/stack.c
106 files changed, 31 insertions(+), 75 deletions(-)
===================================================================
@@ -33,9 +33,7 @@ enum
 	STACK_ENTRY
 };
 
-static GtkListStore *store;
-static GtkTreeModel *model;
-static GtkTreeSortable *sortable;
+static ScpTreeStore *store;
 static GtkTreeSelection *selection;
 
 static void stack_node_location(const ParseNode *node, const char *fid)
@@ -51,11 +49,11 @@ static void stack_node_location(const ParseNode *node, const char *fid)
 			GtkTreeIter iter;
 
 			parse_location(nodes, &loc);
-			gtk_list_store_append(store, &iter);
-			gtk_list_store_set(store, &iter, STACK_ID, id, STACK_FILE, loc.file,
-				STACK_LINE, loc.line, STACK_BASE_NAME, loc.base_name, STACK_FUNC,
-				loc.func, STACK_ARGS, NULL, STACK_ADDR, loc.addr, STACK_ENTRY,
-				loc.func ? parse_mode_find(loc.func)->entry : TRUE, -1);
+			scp_tree_store_append_with_values(store, &iter, NULL, STACK_ID, id,
+				STACK_FILE, loc.file, STACK_LINE, loc.line, STACK_BASE_NAME,
+				loc.base_name, STACK_FUNC, loc.func, STACK_ARGS, NULL, STACK_ADDR,
+				loc.addr, STACK_ENTRY, !loc.func || parse_mode_find(loc.func)->entry,
+				-1);
 			parse_location_free(&loc);
 
 			if (!g_strcmp0(id, fid))
@@ -64,7 +62,7 @@ static void stack_node_location(const ParseNode *node, const char *fid)
 	}
 }
 
-char *frame_id = NULL;
+const char *frame_id = NULL;
 
 void on_stack_frames(GArray *nodes)
 {
@@ -80,7 +78,7 @@ void on_stack_frames(GArray *nodes)
 		{
 			GtkTreeIter iter;
 
-			if (model_find(model, &iter, STACK_ID, "0"))
+			if (store_find(store, &iter, STACK_ID, "0"))
 				utils_tree_set_cursor(selection, &iter, -1);
 		}
 	}
@@ -115,14 +113,7 @@ static void append_argument_variable(const ParseNode *node, const StackData *sd)
 	}
 }
 
-typedef struct _ArgsData
-{
-	gboolean sorted;
-	GtkTreeIter iter;
-	gboolean valid;
-} ArgsData;
-
-static void stack_node_arguments(const ParseNode *node, ArgsData *ad)
+static void stack_node_arguments(const ParseNode *node, G_GNUC_UNUSED gpointer gdata)
 {
 	iff (node->type == PT_ARRAY, "stack-args: contains value")
 	{
@@ -133,28 +124,17 @@ static void stack_node_arguments(const ParseNode *node, ArgsData *ad)
 
 		iff (id && nodes, "no level or args")
 		{
-			if (ad->valid)
-			{
-				char *fid;
-
-				gtk_tree_model_get(model, &ad->iter, STACK_ID, &fid, -1);
-				ad->valid = !strcmp(id, fid);
-				g_free(fid);
-			}
-
-			if (!ad->valid)
-				ad->valid = model_find(model, &ad->iter, STACK_ID, id);
+			GtkTreeIter iter;
 
-			iff (ad->valid, "%s: level not found", id)
+			iff (store_find(store, &iter, STACK_ID, id), "%s: level not found", id)
 			{
 				StackData sd;
 
 				sd.string = g_string_sized_new(0xFF);
-				gtk_tree_model_get(model, &ad->iter, STACK_ENTRY, &sd.entry, -1);
+				scp_tree_store_get(store, &iter, STACK_ENTRY, &sd.entry, -1);
 				array_foreach(nodes, (GFunc) append_argument_variable, &sd);
-				gtk_list_store_set(store, &ad->iter, STACK_ARGS, sd.string->str, -1);
+				scp_tree_store_set(store, &iter, STACK_ARGS, sd.string->str, -1);
 				g_string_free(sd.string, TRUE);
-				ad->valid = ad->sorted && gtk_tree_model_iter_next(model, &ad->iter);
 			}
 		}
 	}
@@ -163,17 +143,7 @@ static void stack_node_arguments(const ParseNode *node, ArgsData *ad)
 void on_stack_arguments(GArray *nodes)
 {
 	if (!g_strcmp0(parse_grab_token(nodes), thread_id))
-	{
-		gint column_id;
-		GtkSortType order;
-		ArgsData ad;
-
-		gtk_tree_sortable_get_sort_column_id(sortable, &column_id, &order);
-		ad.sorted = column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID ||
-			(column_id == STACK_ID && order == GTK_SORT_ASCENDING);
-		ad.valid = ad.sorted && gtk_tree_model_get_iter_first(model, &ad.iter);
-		array_foreach(parse_lead_array(nodes), (GFunc) stack_node_arguments, &ad);
-	}
+		array_foreach(parse_lead_array(nodes), (GFunc) stack_node_arguments, NULL);
 }
 
 void on_stack_follow(GArray *nodes)
@@ -186,7 +156,7 @@ void on_stack_follow(GArray *nodes)
 		{
 			GtkTreeIter iter;
 
-			iff (model_find(model, &iter, STACK_ID, id), "%s: level not found", id)
+			iff (store_find(store, &iter, STACK_ID, id), "%s: level not found", id)
 				utils_tree_set_cursor(selection, &iter, 0.5);
 		}
 	}
@@ -198,13 +168,13 @@ gboolean stack_entry(void)
 	gboolean entry;
 
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, STACK_ENTRY, &entry, -1);
+	scp_tree_store_get(store, &iter, STACK_ENTRY, &entry, -1);
 	return entry;
 }
 
 void stack_clear(void)
 {
-	gtk_list_store_clear(store);
+	store_clear(store);
 }
 
 static void stack_send_update(char token)
@@ -224,10 +194,8 @@ static void on_stack_selection_changed(GtkTreeSelection *selection,
 {
 	GtkTreeIter iter;
 
-	g_free(frame_id);
-
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
-		gtk_tree_model_get(model, &iter, STACK_ID, &frame_id, -1);
+		scp_tree_store_get(store, &iter, STACK_ID, &frame_id, -1);
 	else
 		frame_id = NULL;
 
@@ -257,7 +225,7 @@ static void on_stack_synchronize(const MenuItem *menu_item)
 
 static void on_stack_unsorted(G_GNUC_UNUSED const MenuItem *menu_item)
 {
-	gtk_tree_sortable_set_sort_column_id(sortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
+	scp_tree_store_set_sort_column_id(store, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
 		GTK_SORT_ASCENDING);
 }
 
@@ -276,23 +244,22 @@ static void on_stack_show_address(const MenuItem *menu_item)
 
 typedef struct _EntryData
 {
-	char *func;
+	const char *func;
 	gboolean entry;
 	gint count;
 } EntryData;
 
 static void stack_iter_show_entry(GtkTreeIter *iter, EntryData *ed)
 {
-	char *func;
+	const char *func;
 
-	gtk_tree_model_get(model, iter, STACK_FUNC, &func, -1);
+	scp_tree_store_get(store, iter, STACK_FUNC, &func, -1);
 
 	if (func && !strcmp(func, ed->func))
 	{
-		gtk_list_store_set(store, iter, STACK_ENTRY, ed->entry, -1);
+		scp_tree_store_set(store, iter, STACK_ENTRY, ed->entry, -1);
 		ed->count++;
 	}
-	g_free(func);
 }
 
 static void on_stack_show_entry(const MenuItem *menu_item)
@@ -303,10 +270,9 @@ static void on_stack_show_entry(const MenuItem *menu_item)
 
 	view_dirty(VIEW_LOCALS);
 	gtk_tree_selection_get_selected(selection, NULL, &iter);
-	gtk_tree_model_get(model, &iter, STACK_FUNC, &ed.func, -1);
+	scp_tree_store_get(store, &iter, STACK_FUNC, &ed.func, -1);
 	parse_mode_update(ed.func, MODE_ENTRY, ed.entry);
-	model_foreach(model, (GFunc) stack_iter_show_entry, &ed);
-	g_free(ed.func);
+	store_foreach(store, (GFunc) stack_iter_show_entry, &ed);
 
 	if (ed.count == 1)
 	{
@@ -337,11 +303,8 @@ static guint stack_menu_extra_state(void)
 
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 	{
-		char *file, *func;
-
-		gtk_tree_model_get(model, &iter, STACK_FILE, &file, STACK_FUNC, &func, -1);
-		g_free(file);
-		g_free(func);
+		const char *file, *func;
+		scp_tree_store_get(store, &iter, STACK_FILE, &file, STACK_FUNC, &func, -1);
 		return ((file != NULL) << DS_INDEX_2) | ((func != NULL) << DS_INDEX_3);
 	}
 
@@ -357,7 +320,7 @@ static void on_stack_menu_show(G_GNUC_UNUSED GtkWidget *widget, const MenuItem *
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 	{
 		gboolean entry;
-		gtk_tree_model_get(model, &iter, STACK_ENTRY, &entry, -1);
+		scp_tree_store_get(store, &iter, STACK_ENTRY, &entry, -1);
 		menu_item_set_active(menu_item, entry);
 	}
 	menu_item_set_active(menu_item + 1, stack_show_address);
@@ -371,13 +334,11 @@ static void on_stack_synchronize_button_release(GtkWidget *widget, GdkEventButto
 
 void stack_init(void)
 {
-	GtkTreeView *tree = view_create("stack_view", &model, &selection);
+	GtkTreeView *tree = view_create("stack_view", &store, &selection);
 	GtkWidget *menu = menu_select("stack_menu", &stack_menu_info, selection);
 
-	store = GTK_LIST_STORE(model);
-	sortable = GTK_TREE_SORTABLE(store);
-	view_set_sort_func(sortable, STACK_ID, model_gint_compare);
-	view_set_sort_func(sortable, STACK_FILE, model_seek_compare);
+	view_set_sort_func(store, STACK_ID, store_gint_compare);
+	view_set_sort_func(store, STACK_FILE, store_seek_compare);
 	view_set_line_data_func("stack_line_column", "stack_line", STACK_LINE);
 	gtk_widget_set_has_tooltip(GTK_WIDGET(tree), TRUE);
 	g_signal_connect(tree, "query-tooltip", G_CALLBACK(on_view_query_tooltip),
@@ -394,8 +355,3 @@ void stack_init(void)
 	g_signal_connect(get_widget("stack_synchronize"), "button-release-event",
 		G_CALLBACK(on_stack_synchronize_button_release), menu);
 }
-
-void stack_finalize(void)
-{
-	g_free(frame_id);
-}


Modified: scope/src/stack.h
3 files changed, 1 insertions(+), 2 deletions(-)
===================================================================
@@ -19,7 +19,7 @@
 
 #ifndef STACK_H
 
-extern char *frame_id;
+extern const char *frame_id;
 
 void on_stack_frames(GArray *nodes);
 void on_stack_arguments(GArray *nodes);
@@ -30,7 +30,6 @@
 gboolean stack_update(void);
 
 void stack_init(void);
-void stack_finalize(void);
 
 #define STACK_H 1
 #endif


Modified: scope/src/store.h
11 files changed, 11 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,11 @@
+#ifndef STORE_H
+
+#include "store/scptreestore.h"
+
+#define scp_tree_store_get_iter_from_string(store, iter, path_str) \
+	gtk_tree_model_get_iter_from_string((GtkTreeModel *) (store), (iter), (path_str))
+#define scp_tree_selection_get_selected(selection, p_store, iter) \
+	gtk_tree_selection_get_selected((selection), (GtkTreeModel **) (p_store), (iter))
+
+#define STORE_H 1
+#endif


Modified: scope/src/store/scptreedata.c
369 files changed, 369 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,369 @@
+/* gtktreedatalist.c
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb at redhat.com>
+ *
+ * scptreedata.c
+ * Copyright 2013 Dimitar Toshkov Zhekov <dimitar.zhekov at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "scptreedata.h"
+
+#if !GLIB_CHECK_VERSION(2, 30, 0)
+#define G_VALUE_INIT { 0, { { 0 } } }
+#endif
+
+GType scp_tree_data_get_fundamental_type(GType type)
+{
+	type = G_TYPE_FUNDAMENTAL(type);
+	return G_UNLIKELY(type == G_TYPE_INTERFACE && g_type_is_a(type, G_TYPE_OBJECT))
+		? G_TYPE_OBJECT : type;
+}
+
+void scp_tree_data_free(ScpTreeData *data, GType type)
+{
+	if (data->v_pointer)
+	{
+		switch (scp_tree_data_get_fundamental_type(type))
+		{
+			case G_TYPE_STRING  : g_free(data->v_string); break;
+			case G_TYPE_OBJECT  : g_object_unref(data->v_pointer); break;
+			case G_TYPE_BOXED   : g_boxed_free(type, data->v_pointer); break;
+		#if GLIB_CHECK_VERSION(2, 26, 0)
+			case G_TYPE_VARIANT : g_variant_unref(data->v_pointer);
+		#endif
+		}
+	}
+}
+
+void scp_tree_data_warn_unsupported_type(const char *prefix, GType type)
+{
+	g_warning("%s: Unsupported type %s", prefix, g_type_name(type));
+}
+
+gboolean scp_tree_data_check_type(GType type)
+{
+	static const GType types[] =
+	{
+		G_TYPE_INT,
+		G_TYPE_UINT,
+		G_TYPE_STRING,
+		G_TYPE_BOOLEAN,
+		G_TYPE_LONG,
+		G_TYPE_ULONG,
+		G_TYPE_FLOAT,
+		G_TYPE_DOUBLE,
+		G_TYPE_CHAR,
+		G_TYPE_UCHAR,
+		G_TYPE_INT64,
+		G_TYPE_UINT64,
+		G_TYPE_ENUM,
+		G_TYPE_FLAGS,
+		G_TYPE_POINTER,
+		G_TYPE_OBJECT,
+		G_TYPE_BOXED,
+	#if GLIB_CHECK_VERSION(2, 26, 0)
+		G_TYPE_VARIANT,
+	#endif
+		G_TYPE_INVALID
+	};
+
+	gint i;
+	type = scp_tree_data_get_fundamental_type(type);
+
+	for (i = 0; types[i] != G_TYPE_INVALID; i++)
+		if (types[i] == type)
+			return TRUE;
+
+	return FALSE;
+}
+
+void scp_tree_data_to_value(const ScpTreeData *data, GType type, GValue *value)
+{
+	g_value_init(value, type);
+
+	switch (scp_tree_data_get_fundamental_type(type))
+	{
+		case G_TYPE_INT     : g_value_set_int(value, data->v_int); break;
+		case G_TYPE_UINT    : g_value_set_uint(value, data->v_uint); break;
+		case G_TYPE_STRING  : g_value_set_string(value, data->v_string); break;
+		case G_TYPE_BOOLEAN : g_value_set_boolean(value, data->v_int); break;
+		case G_TYPE_LONG    : g_value_set_long(value, data->v_long); break;
+		case G_TYPE_ULONG   : g_value_set_ulong(value, data->v_ulong); break;
+		case G_TYPE_FLOAT   : g_value_set_float(value, data->v_float); break;
+		case G_TYPE_DOUBLE  : g_value_set_double(value, data->v_double); break;
+	#if GLIB_CHECK_VERSION(2, 32, 0)
+		case G_TYPE_CHAR    : g_value_set_schar(value, data->v_char); break;
+	#else
+		case G_TYPE_CHAR    : g_value_set_char(value, data->v_char); break;
+	#endif
+		case G_TYPE_UCHAR   : g_value_set_uchar(value, data->v_uchar); break;
+		case G_TYPE_INT64   : g_value_set_int64(value, data->v_int64); break;
+		case G_TYPE_UINT64  : g_value_set_uint64 (value, data->v_uint64); break;
+		case G_TYPE_ENUM    : g_value_set_enum(value, data->v_int); break;
+		case G_TYPE_FLAGS   : g_value_set_flags(value, data->v_uint); break;@@ Diff output truncated at 100000 characters. @@

--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Plugins-Commits mailing list