mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-04 10:38:29 +02:00
nmt_newt_listbox_clear() did not reset active and active_key, which in the case of NmtEditConnectionList meant that after the connection list was rebuilt, the selection would appear to be in the same place, but active_key would still point to the connection that used to be in that row, rather than the one currently in that row, so if you immediately hit Edit or Delete, you'd get unexpected results. (It also meant that it was possible for the selection to land on a header row instead of a connection row.) This was particularly bad in the case of the Delete button, since active_key would be left pointing to a freed NMConnection in that case. Fix NmtNewtListbox, and then add code to NmtEditConnectionList to preserve the selection itself when rebuilding the list.
568 lines
18 KiB
C
568 lines
18 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program 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
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Copyright 2013 Red Hat, Inc.
|
|
*/
|
|
|
|
/**
|
|
* SECTION:nmt-edit-connection-list
|
|
* @short_description: Connection list for "nmtui edit"
|
|
*
|
|
* #NmtEditConnectionList is the list of connections displayed by
|
|
* "nmtui edit".
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <glib/gi18n-lib.h>
|
|
|
|
#include "nmtui.h"
|
|
#include "nmtui-edit.h"
|
|
#include "nmt-edit-connection-list.h"
|
|
#include "nmt-editor.h"
|
|
|
|
#include "nm-editor-utils.h"
|
|
|
|
G_DEFINE_TYPE (NmtEditConnectionList, nmt_edit_connection_list, NMT_TYPE_NEWT_GRID)
|
|
|
|
#define NMT_EDIT_CONNECTION_LIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_EDIT_CONNECTION_LIST, NmtEditConnectionListPrivate))
|
|
|
|
typedef struct {
|
|
GSList *connections;
|
|
|
|
gboolean grouped;
|
|
NmtEditConnectionListFilter connection_filter;
|
|
gpointer connection_filter_data;
|
|
|
|
NmtNewtListbox *listbox;
|
|
NmtNewtButtonBox *buttons;
|
|
|
|
NmtNewtWidget *add;
|
|
NmtNewtWidget *edit;
|
|
NmtNewtWidget *delete;
|
|
NmtNewtWidget *extra;
|
|
} NmtEditConnectionListPrivate;
|
|
|
|
enum {
|
|
PROP_0,
|
|
|
|
PROP_GROUPED,
|
|
PROP_CONNECTION_FILTER,
|
|
PROP_CONNECTION_FILTER_DATA,
|
|
PROP_EXTRA_WIDGET,
|
|
PROP_CONNECTIONS,
|
|
PROP_NUM_CONNECTIONS,
|
|
|
|
LAST_PROP
|
|
};
|
|
|
|
enum {
|
|
ADD_CONNECTION,
|
|
EDIT_CONNECTION,
|
|
REMOVE_CONNECTION,
|
|
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
static void add_clicked (NmtNewtButton *button, gpointer list);
|
|
static void edit_clicked (NmtNewtButton *button, gpointer list);
|
|
static void delete_clicked (NmtNewtButton *button, gpointer list);
|
|
static void listbox_activated (NmtNewtWidget *listbox, gpointer list);
|
|
|
|
/**
|
|
* nmt_edit_connection_list_get_connections:
|
|
* @list: an #NmtEditConnectionList
|
|
*
|
|
* Gets the list's list of connections
|
|
*
|
|
* Returns: (transfer none) (element-type #NMConnection): the
|
|
* list of connections.
|
|
*/
|
|
GSList *
|
|
nmt_edit_connection_list_get_connections (NmtEditConnectionList *list)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list);
|
|
|
|
return priv->connections;
|
|
}
|
|
|
|
static void
|
|
nmt_edit_connection_list_init (NmtEditConnectionList *list)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list);
|
|
NmtNewtWidget *listbox, *buttons;
|
|
NmtNewtGrid *grid = NMT_NEWT_GRID (list);
|
|
|
|
listbox = g_object_new (NMT_TYPE_NEWT_LISTBOX,
|
|
"flags", NMT_NEWT_LISTBOX_SCROLL | NMT_NEWT_LISTBOX_BORDER,
|
|
"skip-null-keys", TRUE,
|
|
NULL);
|
|
priv->listbox = NMT_NEWT_LISTBOX (listbox);
|
|
nmt_newt_grid_add (grid, listbox, 0, 0);
|
|
nmt_newt_grid_set_flags (grid, listbox,
|
|
NMT_NEWT_GRID_FILL_X | NMT_NEWT_GRID_FILL_Y |
|
|
NMT_NEWT_GRID_EXPAND_X | NMT_NEWT_GRID_EXPAND_Y);
|
|
g_signal_connect (priv->listbox, "activated", G_CALLBACK (listbox_activated), list);
|
|
|
|
buttons = nmt_newt_button_box_new (NMT_NEWT_BUTTON_BOX_VERTICAL);
|
|
priv->buttons = NMT_NEWT_BUTTON_BOX (buttons);
|
|
nmt_newt_grid_add (grid, buttons, 1, 0);
|
|
nmt_newt_widget_set_padding (buttons, 1, 1, 0, 1);
|
|
nmt_newt_grid_set_flags (grid, buttons,
|
|
NMT_NEWT_GRID_FILL_X | NMT_NEWT_GRID_FILL_Y |
|
|
NMT_NEWT_GRID_EXPAND_Y);
|
|
|
|
priv->add = nmt_newt_button_box_add_start (priv->buttons, _("Add"));
|
|
g_signal_connect (priv->add, "clicked", G_CALLBACK (add_clicked), list);
|
|
|
|
priv->edit = nmt_newt_button_box_add_start (priv->buttons, _("Edit..."));
|
|
g_signal_connect (priv->edit, "clicked", G_CALLBACK (edit_clicked), list);
|
|
|
|
priv->delete = nmt_newt_button_box_add_start (priv->buttons, _("Delete"));
|
|
g_signal_connect (priv->delete, "clicked", G_CALLBACK (delete_clicked), list);
|
|
}
|
|
|
|
static int
|
|
sort_by_timestamp (gconstpointer a,
|
|
gconstpointer b)
|
|
{
|
|
NMSettingConnection *s_con_a, *s_con_b;
|
|
guint64 time_a, time_b;
|
|
|
|
s_con_a = nm_connection_get_setting_connection ((NMConnection *) a);
|
|
s_con_b = nm_connection_get_setting_connection ((NMConnection *) b);
|
|
|
|
time_a = nm_setting_connection_get_timestamp (s_con_a);
|
|
time_b = nm_setting_connection_get_timestamp (s_con_b);
|
|
|
|
return (int) (time_b - time_a);
|
|
}
|
|
|
|
static void nmt_edit_connection_list_rebuild (NmtEditConnectionList *list);
|
|
|
|
static void
|
|
rebuild_on_connection_updated (NMRemoteConnection *connection,
|
|
gpointer list)
|
|
{
|
|
nmt_edit_connection_list_rebuild (list);
|
|
}
|
|
|
|
static void
|
|
free_connections (NmtEditConnectionList *list)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list);
|
|
NMConnection *conn;
|
|
GSList *iter;
|
|
|
|
for (iter = priv->connections; iter; iter = iter->next) {
|
|
conn = iter->data;
|
|
|
|
g_signal_handlers_disconnect_by_func (conn, G_CALLBACK (rebuild_on_connection_updated), list);
|
|
g_object_unref (conn);
|
|
}
|
|
g_slist_free (priv->connections);
|
|
}
|
|
|
|
static void
|
|
nmt_edit_connection_list_rebuild (NmtEditConnectionList *list)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list);
|
|
GSList *iter, *next;
|
|
gboolean did_header = FALSE, did_vpn = FALSE;
|
|
NMEditorConnectionTypeData **types;
|
|
NMConnection *conn, *selected_conn;
|
|
int i, row, selected_row;
|
|
|
|
selected_row = nmt_newt_listbox_get_active (priv->listbox);
|
|
selected_conn = nmt_newt_listbox_get_active_key (priv->listbox);
|
|
|
|
free_connections (list);
|
|
priv->connections = nm_remote_settings_list_connections (nm_settings);
|
|
for (iter = priv->connections; iter; iter = next) {
|
|
conn = iter->data;
|
|
next = iter->next;
|
|
|
|
if ( priv->connection_filter
|
|
&& !priv->connection_filter (list, conn, priv->connection_filter_data)) {
|
|
priv->connections = g_slist_delete_link (priv->connections, iter);
|
|
continue;
|
|
}
|
|
|
|
g_signal_connect (conn, NM_REMOTE_CONNECTION_UPDATED,
|
|
G_CALLBACK (rebuild_on_connection_updated), list);
|
|
g_signal_connect (conn, NM_REMOTE_CONNECTION_REMOVED,
|
|
G_CALLBACK (rebuild_on_connection_updated), list);
|
|
g_object_ref (iter->data);
|
|
}
|
|
priv->connections = g_slist_sort (priv->connections, sort_by_timestamp);
|
|
g_object_notify (G_OBJECT (list), "connections");
|
|
g_object_notify (G_OBJECT (list), "num-connections");
|
|
|
|
nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->edit),
|
|
priv->connections != NULL);
|
|
nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->delete),
|
|
priv->connections != NULL);
|
|
|
|
nmt_newt_listbox_clear (priv->listbox);
|
|
|
|
if (!priv->grouped) {
|
|
/* Just add the connections in order */
|
|
for (iter = priv->connections, row = 0; iter; iter = iter->next, row++) {
|
|
conn = iter->data;
|
|
nmt_newt_listbox_append (priv->listbox, nm_connection_get_id (conn), conn);
|
|
if (conn == selected_conn)
|
|
selected_row = row;
|
|
}
|
|
if (selected_row >= row)
|
|
selected_row = row - 1;
|
|
nmt_newt_listbox_set_active (priv->listbox, selected_row);
|
|
|
|
return;
|
|
}
|
|
|
|
types = nm_editor_utils_get_connection_type_list ();
|
|
for (i = row = 0; types[i]; i++) {
|
|
if (types[i]->setting_type == NM_TYPE_SETTING_VPN) {
|
|
if (did_vpn)
|
|
continue;
|
|
did_vpn = TRUE;
|
|
}
|
|
|
|
did_header = FALSE;
|
|
|
|
for (iter = priv->connections; iter; iter = iter->next) {
|
|
NMSetting *setting;
|
|
char *indented;
|
|
|
|
conn = iter->data;
|
|
setting = nm_connection_get_setting (conn, types[i]->setting_type);
|
|
if (!setting)
|
|
continue;
|
|
if (!nm_connection_is_type (conn, nm_setting_get_name (setting)))
|
|
continue;
|
|
|
|
if (!did_header) {
|
|
nmt_newt_listbox_append (priv->listbox, types[i]->name, NULL);
|
|
if (row == selected_row)
|
|
selected_row++;
|
|
row++;
|
|
did_header = TRUE;
|
|
}
|
|
|
|
indented = g_strdup_printf (" %s", nm_connection_get_id (conn));
|
|
nmt_newt_listbox_append (priv->listbox, indented, conn);
|
|
g_free (indented);
|
|
|
|
if (conn == selected_conn)
|
|
selected_row = row;
|
|
row++;
|
|
}
|
|
}
|
|
|
|
if (selected_row >= row)
|
|
selected_row = row - 1;
|
|
nmt_newt_listbox_set_active (priv->listbox, selected_row);
|
|
}
|
|
|
|
static void
|
|
rebuild_on_new_connection (NMRemoteSettings *settings,
|
|
NMRemoteConnection *connection,
|
|
gpointer list)
|
|
{
|
|
nmt_edit_connection_list_rebuild (list);
|
|
}
|
|
|
|
static void
|
|
nmt_edit_connection_list_constructed (GObject *object)
|
|
{
|
|
NmtEditConnectionList *list = NMT_EDIT_CONNECTION_LIST (object);
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list);
|
|
|
|
if (priv->extra)
|
|
nmt_newt_button_box_add_widget_end (priv->buttons, priv->extra);
|
|
|
|
g_signal_connect (nm_settings, NM_REMOTE_SETTINGS_NEW_CONNECTION,
|
|
G_CALLBACK (rebuild_on_new_connection), list);
|
|
|
|
nmt_edit_connection_list_rebuild (list);
|
|
|
|
G_OBJECT_CLASS (nmt_edit_connection_list_parent_class)->constructed (object);
|
|
}
|
|
|
|
static void
|
|
add_clicked (NmtNewtButton *button, gpointer list)
|
|
{
|
|
g_signal_emit (list, signals[ADD_CONNECTION], 0);
|
|
}
|
|
|
|
static void
|
|
edit_clicked (NmtNewtButton *button, gpointer list)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list);
|
|
NMConnection *connection;
|
|
|
|
connection = nmt_newt_listbox_get_active_key (priv->listbox);
|
|
g_return_if_fail (connection != NULL);
|
|
|
|
g_signal_emit (list, signals[EDIT_CONNECTION], 0, connection);
|
|
}
|
|
|
|
static void
|
|
delete_clicked (NmtNewtButton *button, gpointer list)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list);
|
|
NMRemoteConnection *connection;
|
|
|
|
connection = nmt_newt_listbox_get_active_key (priv->listbox);
|
|
g_return_if_fail (connection != NULL);
|
|
|
|
g_signal_emit (list, signals[REMOVE_CONNECTION], 0, connection);
|
|
}
|
|
|
|
static void
|
|
listbox_activated (NmtNewtWidget *listbox, gpointer list)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list);
|
|
|
|
edit_clicked (NMT_NEWT_BUTTON (priv->edit), list);
|
|
}
|
|
|
|
static void
|
|
nmt_edit_connection_list_finalize (GObject *object)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (object);
|
|
|
|
free_connections (NMT_EDIT_CONNECTION_LIST (object));
|
|
g_clear_object (&priv->extra);
|
|
|
|
G_OBJECT_CLASS (nmt_edit_connection_list_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
nmt_edit_connection_list_set_property (GObject *object,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (object);
|
|
|
|
switch (prop_id) {
|
|
case PROP_GROUPED:
|
|
priv->grouped = g_value_get_boolean (value);
|
|
break;
|
|
case PROP_CONNECTION_FILTER:
|
|
priv->connection_filter = g_value_get_pointer (value);
|
|
break;
|
|
case PROP_CONNECTION_FILTER_DATA:
|
|
priv->connection_filter_data = g_value_get_pointer (value);
|
|
break;
|
|
case PROP_EXTRA_WIDGET:
|
|
priv->extra = g_value_get_object (value);
|
|
if (priv->extra)
|
|
g_object_ref_sink (priv->extra);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
nmt_edit_connection_list_get_property (GObject *object,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (object);
|
|
GPtrArray *connections;
|
|
GSList *iter;
|
|
|
|
switch (prop_id) {
|
|
case PROP_GROUPED:
|
|
g_value_set_boolean (value, priv->grouped);
|
|
break;
|
|
case PROP_CONNECTION_FILTER:
|
|
g_value_set_pointer (value, priv->connection_filter);
|
|
break;
|
|
case PROP_CONNECTION_FILTER_DATA:
|
|
g_value_set_pointer (value, priv->connection_filter_data);
|
|
break;
|
|
case PROP_EXTRA_WIDGET:
|
|
g_value_set_object (value, priv->extra);
|
|
break;
|
|
case PROP_CONNECTIONS:
|
|
connections = g_ptr_array_new_with_free_func (g_object_unref);
|
|
for (iter = priv->connections; iter; iter = iter->next)
|
|
g_ptr_array_add (connections, g_object_ref (iter->data));
|
|
g_value_take_boxed (value, connections);
|
|
break;
|
|
case PROP_NUM_CONNECTIONS:
|
|
g_value_set_int (value, g_slist_length (priv->connections));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
nmt_edit_connection_list_class_init (NmtEditConnectionListClass *list_class)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (list_class);
|
|
|
|
g_type_class_add_private (list_class, sizeof (NmtEditConnectionListPrivate));
|
|
|
|
/* virtual methods */
|
|
object_class->constructed = nmt_edit_connection_list_constructed;
|
|
object_class->set_property = nmt_edit_connection_list_set_property;
|
|
object_class->get_property = nmt_edit_connection_list_get_property;
|
|
object_class->finalize = nmt_edit_connection_list_finalize;
|
|
|
|
/* signals */
|
|
|
|
/**
|
|
* NmtEditConnectionList::add-connection:
|
|
* @list: the #NmtEditConnectionList
|
|
*
|
|
* Emitted when the user clicks the list's "Add" button.
|
|
*/
|
|
signals[ADD_CONNECTION] =
|
|
g_signal_new ("add-connection",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
G_SIGNAL_RUN_FIRST,
|
|
G_STRUCT_OFFSET (NmtEditConnectionListClass, add_connection),
|
|
NULL, NULL, NULL,
|
|
G_TYPE_NONE, 0);
|
|
|
|
/**
|
|
* NmtEditConnectionList::edit-connection:
|
|
* @list: the #NmtEditConnectionList
|
|
* @connection: the connection to edit
|
|
*
|
|
* Emitted when the user clicks the list's "Edit" button, or
|
|
* hits "Return" on the listbox.
|
|
*/
|
|
signals[EDIT_CONNECTION] =
|
|
g_signal_new ("edit-connection",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
G_SIGNAL_RUN_FIRST,
|
|
G_STRUCT_OFFSET (NmtEditConnectionListClass, edit_connection),
|
|
NULL, NULL, NULL,
|
|
G_TYPE_NONE, 1,
|
|
NM_TYPE_CONNECTION);
|
|
|
|
/**
|
|
* NmtEditConnectionList::remove-connection:
|
|
* @list: the #NmtEditConnectionList
|
|
* @connection: the connection to remove
|
|
*
|
|
* Emitted when the user clicks the list's "Delete" button.
|
|
*/
|
|
signals[REMOVE_CONNECTION] =
|
|
g_signal_new ("remove-connection",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
G_SIGNAL_RUN_FIRST,
|
|
G_STRUCT_OFFSET (NmtEditConnectionListClass, remove_connection),
|
|
NULL, NULL, NULL,
|
|
G_TYPE_NONE, 1,
|
|
NM_TYPE_CONNECTION);
|
|
|
|
/* properties */
|
|
|
|
/**
|
|
* NmtEditConnectionList:grouped:
|
|
*
|
|
* If %TRUE, connections should be grouped by type, with headers
|
|
* indicating the types (as in the main connection list). If %FALSE,
|
|
* they will not be grouped (as in slave connection lists).
|
|
*/
|
|
g_object_class_install_property (object_class, PROP_GROUPED,
|
|
g_param_spec_boolean ("grouped", "", "",
|
|
TRUE,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
/**
|
|
* NmtEditConnectionListFilter:
|
|
* @list: the #NmtEditConnectionList
|
|
* @connection: an #NMConnection
|
|
* @user_data: the user data
|
|
*
|
|
* Decides whether @connection should be displayed in @list.
|
|
*
|
|
* Returns: %TRUE or %FALSE
|
|
*/
|
|
/**
|
|
* NmtEditConnectionList:connection-filter:
|
|
*
|
|
* A callback function for filtering which connections appear in
|
|
* the list.
|
|
*/
|
|
g_object_class_install_property (object_class, PROP_CONNECTION_FILTER,
|
|
g_param_spec_pointer ("connection-filter", "", "",
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_STATIC_STRINGS));
|
|
/**
|
|
* NmtEditConnectionList:connection-filter-data:
|
|
*
|
|
* Data for the #NmtEditConnectionList:connection-filter.
|
|
*/
|
|
g_object_class_install_property (object_class, PROP_CONNECTION_FILTER_DATA,
|
|
g_param_spec_pointer ("connection-filter-data", "", "",
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
/**
|
|
* NmtEditConnectionList:extra-widget:
|
|
*
|
|
* An extra button widget to display at the bottom of the button
|
|
* box.
|
|
*/
|
|
g_object_class_install_property (object_class, PROP_EXTRA_WIDGET,
|
|
g_param_spec_object ("extra-widget", "", "",
|
|
NMT_TYPE_NEWT_WIDGET,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
/**
|
|
* NmtEditConnectionList:connections:
|
|
*
|
|
* The list of connections in the widget.
|
|
*
|
|
* Element-Type: #NMConnection
|
|
*/
|
|
g_object_class_install_property (object_class, PROP_CONNECTIONS,
|
|
g_param_spec_boxed ("connections", "", "",
|
|
G_TYPE_PTR_ARRAY,
|
|
G_PARAM_READABLE |
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
/**
|
|
* NmtEditConnectionList:num-connections:
|
|
*
|
|
* The number of connections in the widget.
|
|
*/
|
|
g_object_class_install_property (object_class, PROP_NUM_CONNECTIONS,
|
|
g_param_spec_int ("num-connections", "", "",
|
|
0, G_MAXINT, 0,
|
|
G_PARAM_READABLE |
|
|
G_PARAM_STATIC_STRINGS));
|
|
}
|