Bug 799706 - Rename Namespace

Add a rename namespace button to the Security editor that is enabled by
the selection of a namespace row in the tree view.
This commit is contained in:
Robert Fewell committed 2026-01-08 10:31:39 +00:00
1 parent 966d42b8bf
commit b5185e1823
6 files changed
+307 -7

No files matched your search

+41 -1
View File
@@ -626,7 +626,7 @@ gnc_tree_view_commodity_get_selected_commodity (GncTreeViewCommodity *view)
if (!gtk_tree_selection_get_selected (selection, &s_model, &s_iter))
{
LEAVE("no commodity, get_selected failed");
return FALSE;
return NULL;
}
gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
@@ -644,6 +644,46 @@ gnc_tree_view_commodity_get_selected_commodity (GncTreeViewCommodity *view)
return commodity;
}
/*
* Retrieve the selected namespace from a commodity tree view. The
* commodity tree must be in single selection mode.
*/
gnc_commodity_namespace *
gnc_tree_view_commodity_get_selected_namespace (GncTreeViewCommodity *view)
{
GtkTreeSelection *selection;
GtkTreeModel *model, *f_model, *s_model;
GtkTreeIter iter, f_iter, s_iter;
gnc_commodity_namespace *ns;
g_return_val_if_fail (GNC_IS_TREE_VIEW_COMMODITY(view), NULL);
ENTER("view %p", view);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
if (!gtk_tree_selection_get_selected (selection, &s_model, &s_iter))
{
LEAVE("no namespace, get_selected failed");
return NULL;
}
gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
&f_iter, &s_iter);
f_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(s_model));
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
&iter, &f_iter);
model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER(f_model));
ns = gnc_tree_model_commodity_get_namespace (GNC_TREE_MODEL_COMMODITY(model),
&iter);
LEAVE("namespace %p (%s)", ns,
ns ? gnc_commodity_namespace_get_name(ns) : "");
return ns;
}
/*
* Select the commodity in the commodity tree view.
*/
@@ -182,6 +182,19 @@ gnc_commodity * gnc_tree_view_commodity_get_cursor_commodity (GncTreeViewCommodi
gnc_commodity * gnc_tree_view_commodity_get_selected_commodity (GncTreeViewCommodity *view);
/** This function returns the namespace associated with the selected
* item in the commodity tree view.
*
* @note It only makes sense to call this function when the commodity
* tree is set to select a single item.
*
* @param view A pointer to an commodity tree view.
*
* @return The selected namespace, or NULL if no namespace was selected.
*/
gnc_commodity_namespace * gnc_tree_view_commodity_get_selected_namespace (GncTreeViewCommodity *view);
/** Select the commodity in the associated commodity tree view.
*
* @param view A pointer to an commodity tree view.
+79
View File
@@ -28,6 +28,7 @@
#include <glib/gi18n.h>
#include "dialog-commodity.h"
#include "gnc-commodity.hpp"
#include "dialog-utils.h"
#include "gnc-commodity.h"
#include "gnc-component-manager.h"
@@ -62,6 +63,7 @@ typedef struct
GtkWidget * edit_button;
GtkWidget * remove_button;
gboolean show_currencies;
GtkWidget * rename_namespace_button;
gboolean is_new;
} CommoditiesDialog;
@@ -74,6 +76,9 @@ void gnc_commodities_dialog_add_clicked (GtkWidget *widget, gpointer data);
void gnc_commodities_dialog_edit_clicked (GtkWidget *widget, gpointer data);
void gnc_commodities_dialog_remove_clicked (GtkWidget *widget, gpointer data);
void gnc_commodities_dialog_close_clicked (GtkWidget *widget, gpointer data);
void gnc_commodities_dialog_rename_namespace_clicked (GtkWidget *widget, gpointer data);
void gnc_commodities_show_currencies_toggled (GtkToggleButton *toggle, CommoditiesDialog *cd);
}
@@ -270,6 +275,65 @@ gnc_commodities_dialog_close_clicked (GtkWidget *widget, gpointer data)
gnc_close_gui_component_by_data (DIALOG_COMMODITIES_CM_CLASS, cd);
}
void
gnc_commodities_dialog_rename_namespace_clicked (GtkWidget *widget, gpointer data)
{
auto cd = static_cast<CommoditiesDialog*>(data);
auto ns = gnc_tree_view_commodity_get_selected_namespace (cd->commodity_tree);
if (!ns)
return;
const auto ns_name = gnc_commodity_namespace_get_name (ns);
GtkBuilder *builder = gtk_builder_new();
gnc_builder_add_from_file (builder, "dialog-commodities.glade", "rename_namespace_dialog");
GtkDialog *dialog = GTK_DIALOG(gtk_builder_get_object (builder, "rename_namespace_dialog"));
GtkWidget *entry = GTK_WIDGET(gtk_builder_get_object (builder, "rename_entry"));
GtkWidget *label = GTK_WIDGET(gtk_builder_get_object (builder, "rename_label"));
// Set the name for this dialog so it can be easily manipulated with css
gtk_widget_set_name (GTK_WIDGET(dialog), "gnc-id-rename-namespace");
gnc_widget_style_context_add_class (GTK_WIDGET(dialog), "gnc-class-securities");
// Entry
gtk_entry_set_text (GTK_ENTRY(entry), ns_name);
gtk_editable_select_region (GTK_EDITABLE(entry), 0, -1);
gtk_entry_set_activates_default (GTK_ENTRY(entry), true);
// Set our parent
gtk_window_set_transient_for (GTK_WINDOW(dialog),
GTK_WINDOW(gtk_widget_get_toplevel(widget)));
gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, nullptr);
g_object_unref (G_OBJECT(builder));
gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_OK);
bool rename_ok = false;
while (!rename_ok && gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
{
const auto commodity_table = gnc_get_current_commodities ();
const auto new_ns_name = gtk_entry_get_text (GTK_ENTRY(entry));
if (new_ns_name && *new_ns_name)
{
rename_ok = gnc_commodity_table_rename_namespace (commodity_table,
ns_name,
new_ns_name);
if (rename_ok)
qof_book_mark_session_dirty (gnc_get_current_book());
else
gtk_label_set_text (GTK_LABEL(label),
_("Rename failed, possibly new name exists"));
}
else
gtk_label_set_text (GTK_LABEL(label), _("No new name"));
}
gtk_widget_destroy (GTK_WIDGET(dialog));
}
static void
gnc_commodities_dialog_selection_changed (GtkTreeSelection *selection,
CommoditiesDialog *cd)
@@ -281,6 +345,18 @@ gnc_commodities_dialog_selection_changed (GtkTreeSelection *selection,
remove_ok = commodity && !gnc_commodity_is_iso(commodity);
gtk_widget_set_sensitive (cd->edit_button, commodity != NULL);
gtk_widget_set_sensitive (cd->remove_button, remove_ok);
gtk_widget_set_sensitive (cd->rename_namespace_button, !commodity);
if (!commodity)
{
gnc_commodity_namespace *ns = gnc_tree_view_commodity_get_selected_namespace (cd->commodity_tree);
const char *ns_name = gnc_commodity_namespace_get_name (ns);
gtk_widget_set_sensitive (cd->rename_namespace_button,
!(g_strcmp0 (ns_name, GNC_COMMODITY_NS_LEGACY) == 0 ||
g_strcmp0 (ns_name, GNC_COMMODITY_NS_CURRENCY) == 0));
}
}
void
@@ -351,6 +427,9 @@ gnc_commodities_dialog_create (GtkWidget * parent, CommoditiesDialog *cd)
cd->remove_button = GTK_WIDGET(gtk_builder_get_object (builder, "remove_button"));
cd->edit_button = GTK_WIDGET(gtk_builder_get_object (builder, "edit_button"));
cd->rename_namespace_button = GTK_WIDGET(gtk_builder_get_object (builder, "rename_namespace_button"));
gtk_widget_set_sensitive (cd->rename_namespace_button, FALSE);
/* commodity tree */
scrolled_window = GTK_WIDGET(gtk_builder_get_object (builder, "commodity_list_window"));
view = gnc_tree_view_commodity_new(cd->book,
+128 -6
View File
@@ -1,7 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkDialog" id="rename_namespace_dialog">
<property name="can-focus">False</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="button2">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">_OK</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Rename Namespace</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="rename_entry">
<property name="visible">True</property>
<property name="can-focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="rename_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
<style>
<class name="gnc-class-highlight"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button2</action-widget>
<action-widget response="-5">button1</action-widget>
</action-widgets>
</object>
<object class="GtkWindow" id="securities_window">
<property name="can-focus">False</property>
<property name="border-width">6</property>
@@ -116,6 +222,23 @@
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="rename_namespace_button">
<property name="label" translatable="yes">Rename _Namespace</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Rename the current namespace.</property>
<property name="halign">start</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="gnc_commodities_dialog_rename_namespace_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="add_button">
<property name="label" translatable="yes">_Add</property>
@@ -130,7 +253,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
<property name="position">2</property>
</packing>
</child>
<child>
@@ -148,7 +271,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
<property name="position">3</property>
</packing>
</child>
<child>
@@ -166,7 +289,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
<property name="position">4</property>
</packing>
</child>
<child>
@@ -183,14 +306,13 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
+31
View File
@@ -2134,6 +2134,37 @@ gnc_commodity_table_add_namespace(gnc_commodity_table * table,
return ns;
}
bool
gnc_commodity_table_rename_namespace(const gnc_commodity_table * table,
const char * namespace_name,
const char * new_namespace_name)
{
if (!table || !namespace_name || !new_namespace_name ||
(g_strcmp0 (namespace_name, new_namespace_name) == 0) ||
(g_strcmp0 (new_namespace_name, GNC_COMMODITY_NS_ISO_GUI) == 0) ||
(g_strcmp0 (new_namespace_name, _(GNC_COMMODITY_NS_ISO_GUI)) == 0) ||
gnc_commodity_table_find_namespace (table, new_namespace_name))
return false;
auto ns = gnc_commodity_table_find_namespace (table, namespace_name);
if (!ns)
return false;
ns->name = CACHE_INSERT(static_cast<const char*>(new_namespace_name));
g_hash_table_insert (table->ns_table,
(gpointer) ns->name,
(gpointer) ns);
g_hash_table_remove (table->ns_table,
(gpointer) namespace_name);
CACHE_REMOVE(namespace_name);
qof_instance_set_dirty (&ns->inst);
qof_event_gen (&ns->inst, QOF_EVENT_MODIFY, nullptr);
return true;
}
gnc_commodity_namespace *
gnc_commodity_table_find_namespace(const gnc_commodity_table * table,
+15
View File
@@ -36,6 +36,7 @@
#include <vector>
#include <gnc-commodity.h>
#include <string>
using CommVec = std::vector<gnc_commodity*>;
@@ -51,6 +52,20 @@ using CommVec = std::vector<gnc_commodity*>;
void gnc_quote_source_set_fq_installed (const char* version_string,
const std::vector<std::string>& sources_list);
/** This function renames a namespace.
*
* @param table A pointer to the commodity table
*
* @param namespace_name The name of the namespace to rename.
*
* @param new_namespace_name The new name for the namespace.
*
* @return Return true if rename successful.
*/
bool gnc_commodity_table_rename_namespace(const gnc_commodity_table * table,
const char * namespace_name,
const char * new_namespace_name);
#endif /* GNC_COMMODITY_HPP */
/** @} */
/** @} */