nmtui: initial import of nmtui

nmtui is a TUI (curses-based Text User Interface) for NetworkManager
This commit is contained in:
Dan Winship
2013-12-02 16:20:26 -05:00
parent 72922f2068
commit 3bda3fb60c
129 changed files with 24528 additions and 1 deletions

6
.gitignore vendored
View File

@@ -215,6 +215,12 @@ valgrind-*.log
/cli/src/nmcli /cli/src/nmcli
/tui/newt/libnmt-newt.a
/tui/nmtui
/tui/nmtui-connect
/tui/nmtui-edit
/tui/nmtui-hostname
/tools/generate-settings-spec /tools/generate-settings-spec
/vapi/*.vapi /vapi/*.vapi

View File

@@ -9,6 +9,7 @@ SUBDIRS = \
src \ src \
callouts \ callouts \
cli \ cli \
tui \
tools \ tools \
policy \ policy \
data \ data \

View File

@@ -653,6 +653,17 @@ else
libndp_location=system libndp_location=system
fi fi
AC_ARG_WITH(nmtui, AS_HELP_STRING([--with-nmtui=yes|no], [Build nmtui]))
if test "$with_nmtui" != no; then
PKG_CHECK_MODULES(NEWT, [libnewt >= 0.52.15], [build_nmtui=yes], [build_nmtui=no])
else
build_nmtui=no
fi
if test "$with_nmtui" = yes -a "$build_nmtui" = no; then
AC_MSG_ERROR([You must have libnewt installed to build nmtui.])
fi
AM_CONDITIONAL(BUILD_NMTUI, test "$build_nmtui" = yes)
NM_COMPILER_WARNINGS NM_COMPILER_WARNINGS
@@ -741,6 +752,8 @@ tools/Makefile
cli/Makefile cli/Makefile
cli/src/Makefile cli/src/Makefile
cli/completion/Makefile cli/completion/Makefile
tui/Makefile
tui/newt/Makefile
test/Makefile test/Makefile
initscript/RedHat/NetworkManager initscript/RedHat/NetworkManager
initscript/Debian/NetworkManager initscript/Debian/NetworkManager
@@ -817,6 +830,7 @@ echo " modemmanager-1: $with_modem_manager_1"
echo " concheck: $enable_concheck" echo " concheck: $enable_concheck"
echo " libndp: $libndp_location" echo " libndp: $libndp_location"
echo " libteamdctl: $enable_teamdctl" echo " libteamdctl: $enable_teamdctl"
echo " nmtui: $build_nmtui"
echo echo
echo "Configuration plugins" echo "Configuration plugins"

View File

@@ -61,4 +61,34 @@ src/nm-sleep-monitor-systemd.c
src/settings/plugins/ifcfg-rh/reader.c src/settings/plugins/ifcfg-rh/reader.c
src/settings/nm-settings-utils.c src/settings/nm-settings-utils.c
test/nm-online.c test/nm-online.c
tui/newt/nmt-newt-utils.c
tui/nm-editor-utils.c
tui/nm-ui-utils.c
tui/nmt-connect-connection-list.c
tui/nmt-device-entry.c
tui/nmt-edit-connection-list.c
tui/nmt-editor.c
tui/nmt-mtu-entry.c
tui/nmt-page-bond.c
tui/nmt-page-bridge-port.c
tui/nmt-page-bridge.c
tui/nmt-page-ethernet.c
tui/nmt-page-infiniband.c
tui/nmt-page-ip4.c
tui/nmt-page-ip6.c
tui/nmt-page-main.c
tui/nmt-page-team-port.c
tui/nmt-page-team.c
tui/nmt-page-vlan.c
tui/nmt-page-wifi.c
tui/nmt-password-dialog.c
tui/nmt-password-fields.c
tui/nmt-route-editor.c
tui/nmt-route-table.c
tui/nmt-secret-agent.c
tui/nmt-slave-list.c
tui/nmt-widget-list.c
tui/nmtui-connect.c
tui/nmtui-edit.c
tui/nmtui-hostname.c
tui/nmtui.c

122
tui/Makefile.am Normal file
View File

@@ -0,0 +1,122 @@
if BUILD_NMTUI
SUBDIRS = newt .
AM_CPPFLAGS= \
-I$(top_srcdir) \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
-I$(top_srcdir)/libnm-util \
-I$(top_builddir)/libnm-util \
-I$(top_srcdir)/libnm-glib \
-I$(srcdir)/newt \
$(GLIB_CFLAGS) \
$(NEWT_CFLAGS) \
$(DBUS_CFLAGS) \
$(GUDEV_CFLAGS) \
-DLOCALEDIR=\""$(localedir)"\" \
$(NULL)
bin_PROGRAMS = nmtui
bin_SCRIPTS = nmtui-edit nmtui-connect nmtui-hostname
nmtui_SOURCES = \
nmtui.c \
nmtui.h \
nmtui-connect.c \
nmtui-connect.h \
nmtui-edit.c \
nmtui-edit.h \
nmtui-hostname.c \
nmtui-hostname.h \
\
nm-editor-bindings.c \
nm-editor-bindings.h \
nm-editor-utils.c \
nm-editor-utils.h \
nm-gvaluearray-compat.h \
nm-ui-utils.c \
nm-ui-utils.h \
\
nmt-address-list.c \
nmt-address-list.h \
nmt-connect-connection-list.c \
nmt-connect-connection-list.h \
nmt-device-entry.c \
nmt-device-entry.h \
nmt-edit-connection-list.c \
nmt-edit-connection-list.h \
nmt-editor-page.c \
nmt-editor-page.h \
nmt-editor.c \
nmt-editor.h \
nmt-ip-entry.c \
nmt-ip-entry.h \
nmt-mac-entry.c \
nmt-mac-entry.h \
nmt-mtu-entry.c \
nmt-mtu-entry.h \
nmt-page-bond.c \
nmt-page-bond.h \
nmt-page-bridge.c \
nmt-page-bridge.h \
nmt-page-bridge-port.c \
nmt-page-bridge-port.h \
nmt-page-device.c \
nmt-page-device.h \
nmt-page-ethernet.c \
nmt-page-ethernet.h \
nmt-page-grid.c \
nmt-page-grid.h \
nmt-page-infiniband.c \
nmt-page-infiniband.h \
nmt-page-ip4.c \
nmt-page-ip4.h \
nmt-page-ip6.c \
nmt-page-ip6.h \
nmt-page-main.c \
nmt-page-main.h \
nmt-page-team.c \
nmt-page-team.h \
nmt-page-team-port.c \
nmt-page-team-port.h \
nmt-page-vlan.c \
nmt-page-vlan.h \
nmt-page-wifi.c \
nmt-page-wifi.h \
nmt-password-dialog.c \
nmt-password-dialog.h \
nmt-password-fields.c \
nmt-password-fields.h \
nmt-route-editor.c \
nmt-route-editor.h \
nmt-route-entry.c \
nmt-route-entry.h \
nmt-route-table.c \
nmt-route-table.h \
nmt-secret-agent.c \
nmt-secret-agent.h \
nmt-slave-list.c \
nmt-slave-list.h \
nmt-utils.c \
nmt-utils.h \
nmt-widget-list.c \
nmt-widget-list.h \
$(NULL)
nmtui_LDADD = \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/libnm-glib/libnm-glib.la \
$(builddir)/newt/libnmt-newt.a \
$(GUDEV_LIBS) \
$(DBUS_LIBS) \
$(NEWT_LIBS) \
$(GLIB_LIBS) \
$(NULL)
$(bin_SCRIPTS):
ln -s nmtui $@
CLEANFILES = $(bin_SCRIPTS)
endif

51
tui/newt/Makefile.am Normal file
View File

@@ -0,0 +1,51 @@
AM_CPPFLAGS= \
$(GLIB_CFLAGS) \
$(NEWT_CFLAGS) \
$(NULL)
noinst_LIBRARIES = libnmt-newt.a
libnmt_newt_a_SOURCES = \
nmt-newt.h \
nmt-newt-types.h \
nmt-newt-button.c \
nmt-newt-button.h \
nmt-newt-button-box.c \
nmt-newt-button-box.h \
nmt-newt-checkbox.c \
nmt-newt-checkbox.h \
nmt-newt-component.c \
nmt-newt-component.h \
nmt-newt-container.c \
nmt-newt-container.h \
nmt-newt-entry.c \
nmt-newt-entry.h \
nmt-newt-entry-numeric.c \
nmt-newt-entry-numeric.h \
nmt-newt-form.c \
nmt-newt-form.h \
nmt-newt-grid.c \
nmt-newt-grid.h \
nmt-newt-hacks.c \
nmt-newt-hacks.h \
nmt-newt-label.c \
nmt-newt-label.h \
nmt-newt-listbox.c \
nmt-newt-listbox.h \
nmt-newt-popup.c \
nmt-newt-popup.h \
nmt-newt-section.c \
nmt-newt-section.h \
nmt-newt-separator.c \
nmt-newt-separator.h \
nmt-newt-stack.c \
nmt-newt-stack.h \
nmt-newt-textbox.c \
nmt-newt-textbox.h \
nmt-newt-toggle-button.c \
nmt-newt-toggle-button.h \
nmt-newt-utils.c \
nmt-newt-utils.h \
nmt-newt-widget.c \
nmt-newt-widget.h \
$(NULL)

View File

@@ -0,0 +1,391 @@
/* -*- 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-newt-button-box
* @short_description: A container for #NmtNewtButtons
*
* #NmtNewtButtonBox is a container for creating and holding
* #NmtNewtButtons.
*
* A button box can be either horizontally or vertically laid out, and
* has two sections within it: the "start" (left or top) and "end"
* (right or bottom). Buttons are added from left to right or top to bottom
* within each of the two sections.
*/
#include "config.h"
#include <string.h>
#include "nmt-newt-button-box.h"
#include "nmt-newt-button.h"
G_DEFINE_TYPE (NmtNewtButtonBox, nmt_newt_button_box, NMT_TYPE_NEWT_CONTAINER)
#define NMT_NEWT_BUTTON_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_BUTTON_BOX, NmtNewtButtonBoxPrivate))
typedef struct {
NmtNewtButtonBoxOrientation orientation;
GPtrArray *start_buttons, *end_buttons;
} NmtNewtButtonBoxPrivate;
enum {
PROP_0,
PROP_ORIENTATION,
LAST_PROP
};
/**
* NmtNewtButtonBoxOrientation:
* @NMT_NEWT_BUTTON_BOX_HORIZONTAL: horizontal
* @NMT_NEWT_BUTTON_BOX_VERTICAL: vertical
*
* The orientation of an #NmtNewtButtonBox
*/
/**
* nmt_newt_button_box_new:
* @orientation: the orientation
*
* Creates a new #NmtNewtButtonBox
*
* Returns: a new #NmtNewtButtonBox
*/
NmtNewtWidget *
nmt_newt_button_box_new (NmtNewtButtonBoxOrientation orientation)
{
return g_object_new (NMT_TYPE_NEWT_BUTTON_BOX,
"orientation", orientation,
NULL);
}
static void
nmt_newt_button_box_init (NmtNewtButtonBox *bbox)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (bbox);
priv->start_buttons = g_ptr_array_new ();
priv->end_buttons = g_ptr_array_new ();
}
/**
* nmt_newt_button_box_add_start:
* @bbox: an #NmtNewtButtonBox
* @label: the label for the newt button
*
* Creates a new #NmtNewtButton with the given @label, adds it
* to the "start" section of @bbox, and returns the newly-created
* button.
*
* Returns: the newly-created button, already added to @bbox
*/
NmtNewtWidget *
nmt_newt_button_box_add_start (NmtNewtButtonBox *bbox,
const char *label)
{
NmtNewtWidget *button;
button = nmt_newt_button_new (label);
nmt_newt_button_box_add_widget_start (bbox, button);
return button;
}
/**
* nmt_newt_button_box_add_widget_start:
* @bbox: an #NmtNewtButtonBox
* @widget: the #NmtNewtWidget to add
*
* Adds the given widget to the "start" section of @bbox.
*/
void
nmt_newt_button_box_add_widget_start (NmtNewtButtonBox *bbox,
NmtNewtWidget *widget)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (bbox);
NMT_NEWT_CONTAINER_CLASS (nmt_newt_button_box_parent_class)->
add (NMT_NEWT_CONTAINER (bbox), widget);
g_ptr_array_add (priv->start_buttons, widget);
}
/**
* nmt_newt_button_box_add_end:
* @bbox: an #NmtNewtButtonBox
* @label: the label for the newt button
*
* Creates a new #NmtNewtButton with the given @label, adds it
* to the "end" section of @bbox, and returns the newly-created
* button.
*
* Returns: the newly-created button, already added to @bbox
*/
NmtNewtWidget *
nmt_newt_button_box_add_end (NmtNewtButtonBox *bbox,
const char *label)
{
NmtNewtWidget *button;
button = nmt_newt_button_new (label);
nmt_newt_button_box_add_widget_end (bbox, button);
return button;
}
/**
* nmt_newt_button_box_add_widget_end:
* @bbox: an #NmtNewtButtonBox
* @widget: the #NmtNewtWidget to add
*
* Adds the given widget to the "end" section of @bbox.
*/
void
nmt_newt_button_box_add_widget_end (NmtNewtButtonBox *bbox,
NmtNewtWidget *widget)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (bbox);
NMT_NEWT_CONTAINER_CLASS (nmt_newt_button_box_parent_class)->
add (NMT_NEWT_CONTAINER (bbox), widget);
g_ptr_array_add (priv->end_buttons, widget);
}
static void
nmt_newt_button_box_remove (NmtNewtContainer *container,
NmtNewtWidget *child)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (container);
int i;
NMT_NEWT_CONTAINER_CLASS (nmt_newt_button_box_parent_class)->
remove (container, child);
for (i = 0; i < priv->start_buttons->len; i++) {
if (priv->start_buttons->pdata[i] == (gpointer) child) {
g_ptr_array_remove_index (priv->start_buttons, i);
return;
}
}
for (i = 0; i < priv->end_buttons->len; i++) {
if (priv->end_buttons->pdata[i] == (gpointer) child) {
g_ptr_array_remove_index (priv->end_buttons, i);
return;
}
}
}
static void
add_buttons (GPtrArray *buttons, GPtrArray *cos)
{
NmtNewtWidget *child;
newtComponent *child_cos;
int i, c;
for (i = 0; i < buttons->len; i++) {
child = buttons->pdata[i];
if (!nmt_newt_widget_get_visible (child))
continue;
child_cos = nmt_newt_widget_get_components (child);
for (c = 0; child_cos[c]; c++)
g_ptr_array_add (cos, child_cos[c]);
g_free (child_cos);
}
}
static newtComponent *
nmt_newt_button_box_get_components (NmtNewtWidget *widget)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (widget);
GPtrArray *cos;
cos = g_ptr_array_new ();
add_buttons (priv->start_buttons, cos);
add_buttons (priv->end_buttons, cos);
g_ptr_array_add (cos, NULL);
return (newtComponent *) g_ptr_array_free (cos, FALSE);
}
static void
size_request_buttons (NmtNewtButtonBox *bbox,
GPtrArray *buttons,
int *width,
int *height)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (bbox);
int child_width, child_height;
int i;
for (i = 0; i < buttons->len; i++) {
NmtNewtWidget *child = buttons->pdata[i];
nmt_newt_widget_size_request (child, &child_width, &child_height);
if (priv->orientation == NMT_NEWT_BUTTON_BOX_HORIZONTAL) {
*width += child_width;
if (i > 0)
*width += 1;
*height = MAX (*height, child_height);
} else {
*height += child_height;
if (i > 0)
*height += 1;
*width = MAX (*width, child_width);
}
}
}
static void
nmt_newt_button_box_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
NmtNewtButtonBox *bbox = NMT_NEWT_BUTTON_BOX (widget);
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (widget);
*width = *height = 0;
size_request_buttons (bbox, priv->start_buttons, width, height);
size_request_buttons (bbox, priv->end_buttons, width, height);
if (priv->start_buttons && priv->end_buttons) {
if (priv->orientation == NMT_NEWT_BUTTON_BOX_HORIZONTAL)
*width += 1;
else
*height += 1;
}
}
static void
nmt_newt_button_box_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (widget);
NmtNewtWidget *child;
int child_x, child_y, child_width, child_height;
int i;
child_x = x;
child_y = y;
for (i = 0; i < priv->start_buttons->len; i++) {
child = priv->start_buttons->pdata[i];
nmt_newt_widget_size_request (child, &child_width, &child_height);
if (priv->orientation == NMT_NEWT_BUTTON_BOX_HORIZONTAL) {
nmt_newt_widget_size_allocate (child,
child_x, child_y + (height - child_height) / 2,
child_width, child_height);
child_x += child_width + 1;
} else {
nmt_newt_widget_size_allocate (child,
child_x + (width - child_width) / 2, child_y,
child_width, child_height);
child_y += child_height + 1;
}
}
if (priv->orientation == NMT_NEWT_BUTTON_BOX_HORIZONTAL)
child_x = x + width;
else
child_y = y + height;
for (i = priv->end_buttons->len - 1; i >= 0; i--) {
child = priv->end_buttons->pdata[i];
nmt_newt_widget_size_request (child, &child_width, &child_height);
if (priv->orientation == NMT_NEWT_BUTTON_BOX_HORIZONTAL) {
nmt_newt_widget_size_allocate (child,
child_x - child_width,
child_y + (height - child_height) / 2,
child_width, child_height);
child_x -= child_width + 1;
} else {
nmt_newt_widget_size_allocate (child,
child_x + (width - child_width) / 2,
child_y - child_height,
child_width, child_height);
child_y -= child_height + 1;
}
}
}
static void
nmt_newt_button_box_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (object);
switch (prop_id) {
case PROP_ORIENTATION:
priv->orientation = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_button_box_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtButtonBoxPrivate *priv = NMT_NEWT_BUTTON_BOX_GET_PRIVATE (object);
switch (prop_id) {
case PROP_ORIENTATION:
g_value_set_int (value, priv->orientation);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_button_box_class_init (NmtNewtButtonBoxClass *bbox_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (bbox_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (bbox_class);
NmtNewtContainerClass *container_class = NMT_NEWT_CONTAINER_CLASS (bbox_class);
g_type_class_add_private (bbox_class, sizeof (NmtNewtButtonBoxPrivate));
object_class->get_property = nmt_newt_button_box_get_property;
object_class->set_property = nmt_newt_button_box_set_property;
widget_class->get_components = nmt_newt_button_box_get_components;
widget_class->size_request = nmt_newt_button_box_size_request;
widget_class->size_allocate = nmt_newt_button_box_size_allocate;
container_class->remove = nmt_newt_button_box_remove;
g_object_class_install_property (object_class, PROP_ORIENTATION,
g_param_spec_int ("orientation", "", "",
0, G_MAXINT, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -0,0 +1,65 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_BUTTON_BOX_H
#define NMT_NEWT_BUTTON_BOX_H
#include "nmt-newt-grid.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_BUTTON_BOX (nmt_newt_button_box_get_type ())
#define NMT_NEWT_BUTTON_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_BUTTON_BOX, NmtNewtButtonBox))
#define NMT_NEWT_BUTTON_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_BUTTON_BOX, NmtNewtButtonBoxClass))
#define NMT_IS_NEWT_BUTTON_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_BUTTON_BOX))
#define NMT_IS_NEWT_BUTTON_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_BUTTON_BOX))
#define NMT_NEWT_BUTTON_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_BUTTON_BOX, NmtNewtButtonBoxClass))
struct _NmtNewtButtonBox {
NmtNewtContainer parent;
};
typedef struct {
NmtNewtContainerClass parent;
} NmtNewtButtonBoxClass;
GType nmt_newt_button_box_get_type (void);
typedef enum {
NMT_NEWT_BUTTON_BOX_HORIZONTAL,
NMT_NEWT_BUTTON_BOX_VERTICAL
} NmtNewtButtonBoxOrientation;
NmtNewtWidget *nmt_newt_button_box_new (NmtNewtButtonBoxOrientation orientation);
NmtNewtWidget *nmt_newt_button_box_add_start (NmtNewtButtonBox *bbox,
const char *label);
NmtNewtWidget *nmt_newt_button_box_add_end (NmtNewtButtonBox *bbox,
const char *label);
void nmt_newt_button_box_add_widget_start (NmtNewtButtonBox *bbox,
NmtNewtWidget *widget);
void nmt_newt_button_box_add_widget_end (NmtNewtButtonBox *bbox,
NmtNewtWidget *widget);
G_END_DECLS
#endif /* NMT_NEWT_BUTTON_BOX_H */

260
tui/newt/nmt-newt-button.c Normal file
View File

@@ -0,0 +1,260 @@
/* -*- 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-newt-button
* @short_description: Push buttons
*
* #NmtNewtButton implements a button widget.
*/
#include "config.h"
#include "nmt-newt-button.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtButton, nmt_newt_button, NMT_TYPE_NEWT_COMPONENT)
#define NMT_NEWT_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_BUTTON, NmtNewtButtonPrivate))
typedef struct {
char *label;
} NmtNewtButtonPrivate;
enum {
PROP_0,
PROP_LABEL,
LAST_PROP
};
enum {
CLICKED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
/**
* nmt_newt_button_new:
* @label: the (initial) button label
*
* Creates a new button.
*
* Returns: a new #NmtNewtButton
*/
NmtNewtWidget *
nmt_newt_button_new (const char *label)
{
return g_object_new (NMT_TYPE_NEWT_BUTTON,
"label", label,
NULL);
}
/**
* nmt_newt_button_set_label:
* @button: an #NmtNewtButton
* @label: the new label
*
* Updates @button's label.
*/
void
nmt_newt_button_set_label (NmtNewtButton *button,
const char *label)
{
NmtNewtButtonPrivate *priv = NMT_NEWT_BUTTON_GET_PRIVATE (button);
if (!g_strcmp0 (priv->label, label))
return;
g_free (priv->label);
priv->label = g_strdup (label);
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (button));
}
/**
* nmt_newt_button_get_label:
* @button: an #NmtNewtButton
*
* Gets @button's label.
*
* Returns: @button's label.
*/
const char *
nmt_newt_button_get_label (NmtNewtButton *button)
{
NmtNewtButtonPrivate *priv = NMT_NEWT_BUTTON_GET_PRIVATE (button);
return priv->label;
}
static void
nmt_newt_button_init (NmtNewtButton *button)
{
}
static void
nmt_newt_button_finalize (GObject *object)
{
NmtNewtButtonPrivate *priv = NMT_NEWT_BUTTON_GET_PRIVATE (object);
g_free (priv->label);
G_OBJECT_CLASS (nmt_newt_button_parent_class)->finalize (object);
}
static newtComponent
nmt_newt_button_build_component (NmtNewtComponent *component,
gboolean sensitive)
{
NmtNewtButtonPrivate *priv = NMT_NEWT_BUTTON_GET_PRIVATE (component);
newtComponent co;
char *label = NULL, *label_lc;
if (sensitive) {
label_lc = nmt_newt_locale_from_utf8 (priv->label);
co = newtCompactButton (-1, -1, label_lc);
g_free (label_lc);
} else {
label = g_strdup_printf (" <%s>", priv->label);
label_lc = nmt_newt_locale_from_utf8 (label);
co = newtLabel (-1, -1, label_lc);
g_free (label_lc);
newtLabelSetColors (co, NMT_NEWT_COLORSET_DISABLED_BUTTON);
}
return co;
}
static void
nmt_newt_button_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
NMT_NEWT_WIDGET_CLASS (nmt_newt_button_parent_class)->size_request (widget, width, height);
/* remove the automatically-added left padding */
(*width)--;
}
static void
nmt_newt_button_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
/* account for the automatically-added left padding */
x--;
width++;
NMT_NEWT_WIDGET_CLASS (nmt_newt_button_parent_class)->size_allocate (widget, x, y, width, height);
}
static void
nmt_newt_button_activated (NmtNewtWidget *widget)
{
g_signal_emit (widget, signals[CLICKED], 0);
NMT_NEWT_WIDGET_CLASS (nmt_newt_button_parent_class)->activated (widget);
}
static void
nmt_newt_button_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_LABEL:
nmt_newt_button_set_label (NMT_NEWT_BUTTON (object),
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_button_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtButtonPrivate *priv = NMT_NEWT_BUTTON_GET_PRIVATE (object);
switch (prop_id) {
case PROP_LABEL:
g_value_set_string (value, priv->label);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_button_class_init (NmtNewtButtonClass *button_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (button_class);
NmtNewtComponentClass *component_class = NMT_NEWT_COMPONENT_CLASS (button_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (button_class);
g_type_class_add_private (button_class, sizeof (NmtNewtButtonPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_button_set_property;
object_class->get_property = nmt_newt_button_get_property;
object_class->finalize = nmt_newt_button_finalize;
widget_class->size_request = nmt_newt_button_size_request;
widget_class->size_allocate = nmt_newt_button_size_allocate;
widget_class->activated = nmt_newt_button_activated;
component_class->build_component = nmt_newt_button_build_component;
/* signals */
/**
* NmtNewtButton::clicked:
* @button: the #NmtNewtButton
*
* Emitted when the button is clicked.
*/
signals[CLICKED] =
g_signal_new ("clicked",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
/* properties */
/**
* NmtNewtButton:label:
*
* The button's label
*/
g_object_class_install_property (object_class, PROP_LABEL,
g_param_spec_string ("label", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -0,0 +1,53 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_BUTTON_H
#define NMT_NEWT_BUTTON_H
#include "nmt-newt-component.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_BUTTON (nmt_newt_button_get_type ())
#define NMT_NEWT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_BUTTON, NmtNewtButton))
#define NMT_NEWT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_BUTTON, NmtNewtButtonClass))
#define NMT_IS_NEWT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_BUTTON))
#define NMT_IS_NEWT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_BUTTON))
#define NMT_NEWT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_BUTTON, NmtNewtButtonClass))
struct _NmtNewtButton {
NmtNewtComponent parent;
};
typedef struct {
NmtNewtComponentClass parent;
} NmtNewtButtonClass;
GType nmt_newt_button_get_type (void);
NmtNewtWidget *nmt_newt_button_new (const char *label);
void nmt_newt_button_set_label (NmtNewtButton *button,
const char *label);
const char *nmt_newt_button_get_label (NmtNewtButton *button);
G_END_DECLS
#endif /* NMT_NEWT_BUTTON_H */

View File

@@ -0,0 +1,235 @@
/* -*- 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-newt-checkbox
* @short_description: Checkboxes
*
* #NmtNewtCheckbox implements a checkbox widget.
*/
#include "config.h"
#include "nmt-newt-checkbox.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtCheckbox, nmt_newt_checkbox, NMT_TYPE_NEWT_COMPONENT)
#define NMT_NEWT_CHECKBOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_CHECKBOX, NmtNewtCheckboxPrivate))
typedef struct {
char *label_lc;
gboolean active;
} NmtNewtCheckboxPrivate;
enum {
PROP_0,
PROP_LABEL,
PROP_ACTIVE,
LAST_PROP
};
#define CHECKBOX_INACTIVE ' '
#define CHECKBOX_ACTIVE 'X'
#define CHECKBOX_STATES " X"
/**
* nmt_newt_checkbox_new:
* @label: the (initial) checkbox label
*
* Creates a new checkbox.
*
* Returns: a new #NmtNewtCheckbox
*/
NmtNewtWidget *
nmt_newt_checkbox_new (const char *label)
{
return g_object_new (NMT_TYPE_NEWT_CHECKBOX,
"label", label,
NULL);
}
/**
* nmt_newt_checkbox_set_active:
* @checkbox: an #NmtNewtCheckbox
* @active: whether @checkbox should be checked
*
* Updates @checkbox's checked state
*/
void
nmt_newt_checkbox_set_active (NmtNewtCheckbox *checkbox,
gboolean active)
{
NmtNewtCheckboxPrivate *priv = NMT_NEWT_CHECKBOX_GET_PRIVATE (checkbox);
newtComponent co;
active = !!active;
if (active == priv->active)
return;
priv->active = active;
co = nmt_newt_component_get_component (NMT_NEWT_COMPONENT (checkbox));
if (co)
newtCheckboxSetValue (co, priv->active ? CHECKBOX_ACTIVE : CHECKBOX_INACTIVE);
g_object_notify (G_OBJECT (checkbox), "active");
}
/**
* nmt_newt_checkbox_get_active:
* @checkbox: an #NmtNewtCheckbox
*
* Gets @checkbox's checked state
*
* Returns: @checkbox's checked state
*/
gboolean
nmt_newt_checkbox_get_active (NmtNewtCheckbox *checkbox)
{
NmtNewtCheckboxPrivate *priv = NMT_NEWT_CHECKBOX_GET_PRIVATE (checkbox);
return priv->active;
}
static void
nmt_newt_checkbox_init (NmtNewtCheckbox *checkbox)
{
}
static void
nmt_newt_checkbox_finalize (GObject *object)
{
NmtNewtCheckboxPrivate *priv = NMT_NEWT_CHECKBOX_GET_PRIVATE (object);
g_free (priv->label_lc);
G_OBJECT_CLASS (nmt_newt_checkbox_parent_class)->finalize (object);
}
static void
checkbox_toggled_callback (newtComponent co,
void *checkbox)
{
NmtNewtCheckboxPrivate *priv = NMT_NEWT_CHECKBOX_GET_PRIVATE (checkbox);
gboolean active;
active = (newtCheckboxGetValue (co) == CHECKBOX_ACTIVE);
if (active != priv->active) {
priv->active = active;
g_object_notify (checkbox, "active");
}
}
static newtComponent
nmt_newt_checkbox_build_component (NmtNewtComponent *component,
gboolean sensitive)
{
NmtNewtCheckboxPrivate *priv = NMT_NEWT_CHECKBOX_GET_PRIVATE (component);
newtComponent co;
co = newtCheckbox (-1, -1, priv->label_lc,
priv->active ? CHECKBOX_ACTIVE : CHECKBOX_INACTIVE,
CHECKBOX_STATES, NULL);
if (!sensitive)
newtCheckboxSetFlags (co, NEWT_FLAG_DISABLED, NEWT_FLAGS_SET);
newtComponentAddCallback (co, checkbox_toggled_callback, component);
return co;
}
static void
nmt_newt_checkbox_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtCheckbox *checkbox = NMT_NEWT_CHECKBOX (object);
NmtNewtCheckboxPrivate *priv = NMT_NEWT_CHECKBOX_GET_PRIVATE (object);
switch (prop_id) {
case PROP_LABEL:
g_free (priv->label_lc);
priv->label_lc = nmt_newt_locale_from_utf8 (g_value_get_string (value));
break;
case PROP_ACTIVE:
nmt_newt_checkbox_set_active (checkbox, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_checkbox_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtCheckboxPrivate *priv = NMT_NEWT_CHECKBOX_GET_PRIVATE (object);
switch (prop_id) {
case PROP_LABEL:
g_value_take_string (value, nmt_newt_locale_to_utf8 (priv->label_lc));
break;
case PROP_ACTIVE:
g_value_set_boolean (value, priv->active);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_checkbox_class_init (NmtNewtCheckboxClass *checkbox_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (checkbox_class);
NmtNewtComponentClass *component_class = NMT_NEWT_COMPONENT_CLASS (checkbox_class);
g_type_class_add_private (checkbox_class, sizeof (NmtNewtCheckboxPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_checkbox_set_property;
object_class->get_property = nmt_newt_checkbox_get_property;
object_class->finalize = nmt_newt_checkbox_finalize;
component_class->build_component = nmt_newt_checkbox_build_component;
/**
* NmtNewtCheckbox:label:
*
* The checkbox's label
*/
g_object_class_install_property (object_class, PROP_LABEL,
g_param_spec_string ("label", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtCheckbox:active:
*
* The checkbox's checked state
*/
g_object_class_install_property (object_class, PROP_ACTIVE,
g_param_spec_boolean ("active", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -0,0 +1,53 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_CHECKBOX_H
#define NMT_NEWT_CHECKBOX_H
#include "nmt-newt-component.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_CHECKBOX (nmt_newt_checkbox_get_type ())
#define NMT_NEWT_CHECKBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_CHECKBOX, NmtNewtCheckbox))
#define NMT_NEWT_CHECKBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_CHECKBOX, NmtNewtCheckboxClass))
#define NMT_IS_NEWT_CHECKBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_CHECKBOX))
#define NMT_IS_NEWT_CHECKBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_CHECKBOX))
#define NMT_NEWT_CHECKBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_CHECKBOX, NmtNewtCheckboxClass))
struct _NmtNewtCheckbox {
NmtNewtComponent parent;
};
typedef struct {
NmtNewtComponentClass parent;
} NmtNewtCheckboxClass;
GType nmt_newt_checkbox_get_type (void);
NmtNewtWidget *nmt_newt_checkbox_new (const char *label);
void nmt_newt_checkbox_set_active (NmtNewtCheckbox *checkbox,
gboolean active);
gboolean nmt_newt_checkbox_get_active (NmtNewtCheckbox *checkbox);
G_END_DECLS
#endif /* NMT_NEWT_CHECKBOX_H */

View File

@@ -0,0 +1,307 @@
/* -*- 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-newt-component
* @short_description: Base class for widgets that wrap #newtComponents
*
* #NmtNewtComponent is the abstract class for #NmtNewtWidgets that
* wrap a (single) #newtComponent.
*/
#include "config.h"
#include "nmt-newt-component.h"
#include "nmt-newt-form.h"
#include "nmt-newt-hacks.h"
G_DEFINE_ABSTRACT_TYPE (NmtNewtComponent, nmt_newt_component, NMT_TYPE_NEWT_WIDGET)
#define NMT_NEWT_COMPONENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_COMPONENT, NmtNewtComponentPrivate))
typedef struct {
newtComponent co;
gboolean own_component;
gboolean sensitive;
} NmtNewtComponentPrivate;
enum {
PROP_0,
PROP_COMPONENT,
PROP_SENSITIVE,
LAST_PROP
};
static void
nmt_newt_component_init (NmtNewtComponent *component)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (component);
priv->sensitive = TRUE;
}
static void
nmt_newt_component_unrealize (NmtNewtWidget *widget)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (widget);
if (!priv->co)
return;
newtComponentAddCallback (priv->co, NULL, NULL);
newtComponentAddDestroyCallback (priv->co, NULL, NULL);
if (priv->own_component)
newtComponentDestroy (priv->co);
priv->co = NULL;
}
static void
component_destroy_callback (newtComponent co,
void *component)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (component);
priv->own_component = FALSE;
nmt_newt_widget_unrealize (component);
nmt_newt_widget_needs_rebuild (component);
}
static void
nmt_newt_component_realize (NmtNewtWidget *widget)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (widget);
nmt_newt_component_unrealize (widget);
priv->co = NMT_NEWT_COMPONENT_GET_CLASS (widget)->
build_component (NMT_NEWT_COMPONENT (widget), priv->sensitive);
priv->own_component = TRUE;
if (!priv->sensitive)
newtComponentTakesFocus (priv->co, FALSE);
newtComponentAddDestroyCallback (priv->co, component_destroy_callback, widget);
}
static newtComponent *
nmt_newt_component_get_components (NmtNewtWidget *widget)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (widget);
newtComponent *cos;
priv->own_component = FALSE;
cos = g_new0 (newtComponent, 2);
cos[0] = priv->co;
return cos;
}
static NmtNewtWidget *
nmt_newt_component_find_component (NmtNewtWidget *widget,
newtComponent co)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (widget);
if (co == priv->co)
return widget;
else
return NULL;
}
static void
nmt_newt_component_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (widget);
newtComponentGetSize (priv->co, width, height);
}
static void
nmt_newt_component_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (widget);
newtGrid grid;
/* You can't directly place a newtComponent, so we create a newtGrid,
* position the component within that, and then place the grid.
*/
grid = newtCreateGrid (1, 1);
newtGridSetField (grid, 0, 0,
NEWT_GRID_COMPONENT, priv->co,
x, y, 0, 0,
NEWT_ANCHOR_LEFT | NEWT_ANCHOR_TOP, 0);
newtGridPlace (grid, 0, 0);
newtGridFree (grid, FALSE);
}
static newtComponent
nmt_newt_component_get_focus_component (NmtNewtWidget *widget)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (widget);
return priv->co;
}
/**
* nmt_newt_component_get_component:
* @component: an #NmtNewtComponent
*
* A simpler version of nmt_newt_widget_get_components() for the
* single-component case. Also, unlike
* nmt_newt_widget_get_component(), this does not realize the widget
* if it isn't already realized. FIXME: why?
*
* Returns: @component's #newtComponent
*/
newtComponent
nmt_newt_component_get_component (NmtNewtComponent *component)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (component);
return priv->co;
}
/**
* nmt_newt_component_get_sensitive:
* @component: an #NmtNewtComponent
*
* Gets @component's #NmtNewtComponent:sensitive property, indicating
* whether the widget is available for manipulation. Insensitive
* components will be skipped over in the keyboard tab chain, and may
* be displayed differently.
*
* Returns: @component's #NmtNewtComponent:sensitive property
*/
gboolean
nmt_newt_component_get_sensitive (NmtNewtComponent *component)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (component);
return priv->sensitive;
}
/**
* nmt_newt_component_set_sensitive:
* @component: an #NmtNewtComponent
* @sensitive: whether @component should be sensitive
*
* Sets @component's #NmtNewtComponent:sensitive property.
*/
void
nmt_newt_component_set_sensitive (NmtNewtComponent *component,
gboolean sensitive)
{
NmtNewtComponentPrivate *priv = NMT_NEWT_COMPONENT_GET_PRIVATE (component);
sensitive = !!sensitive;
if (priv->sensitive == sensitive)
return;
priv->sensitive = sensitive;
g_object_notify (G_OBJECT (component), "sensitive");
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (component));
}
static void
nmt_newt_component_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtComponent *component = NMT_NEWT_COMPONENT (object);
switch (prop_id) {
case PROP_SENSITIVE:
nmt_newt_component_set_sensitive (component, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_component_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtComponent *component = NMT_NEWT_COMPONENT (object);
switch (prop_id) {
case PROP_COMPONENT:
g_value_set_pointer (value, nmt_newt_component_get_component (component));
break;
case PROP_SENSITIVE:
g_value_set_boolean (value, nmt_newt_component_get_sensitive (component));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_component_class_init (NmtNewtComponentClass *component_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (component_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (component_class);
g_type_class_add_private (component_class, sizeof (NmtNewtComponentPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_component_set_property;
object_class->get_property = nmt_newt_component_get_property;
widget_class->realize = nmt_newt_component_realize;
widget_class->unrealize = nmt_newt_component_unrealize;
widget_class->get_components = nmt_newt_component_get_components;
widget_class->find_component = nmt_newt_component_find_component;
widget_class->size_request = nmt_newt_component_size_request;
widget_class->size_allocate = nmt_newt_component_size_allocate;
widget_class->get_focus_component = nmt_newt_component_get_focus_component;
/* properties */
/**
* NmtNewtComponent:component:
*
* The component's #newtComponent
*/
g_object_class_install_property (object_class, PROP_COMPONENT,
g_param_spec_pointer ("component", "", "",
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtComponent:sensitive:
*
* Whether the component is sensitive. Insensitive components will
* be skipped over in the keyboard tab chain, and may be displayed
* differently.
*/
g_object_class_install_property (object_class, PROP_SENSITIVE,
g_param_spec_boolean ("sensitive", "", "",
TRUE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -0,0 +1,57 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_COMPONENT_H
#define NMT_NEWT_COMPONENT_H
#include "nmt-newt-widget.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_COMPONENT (nmt_newt_component_get_type ())
#define NMT_NEWT_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_COMPONENT, NmtNewtComponent))
#define NMT_NEWT_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_COMPONENT, NmtNewtComponentClass))
#define NMT_IS_NEWT_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_COMPONENT))
#define NMT_IS_NEWT_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_COMPONENT))
#define NMT_NEWT_COMPONENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_COMPONENT, NmtNewtComponentClass))
struct _NmtNewtComponent {
NmtNewtWidget parent;
};
typedef struct {
NmtNewtWidgetClass parent;
/* methods */
newtComponent (*build_component) (NmtNewtComponent *component,
gboolean sensitive);
} NmtNewtComponentClass;
GType nmt_newt_component_get_type (void);
newtComponent nmt_newt_component_get_component (NmtNewtComponent *component);
gboolean nmt_newt_component_get_sensitive (NmtNewtComponent *component);
void nmt_newt_component_set_sensitive (NmtNewtComponent *component,
gboolean sensitive);
G_END_DECLS
#endif /* NMT_NEWT_COMPONENT_H */

View File

@@ -0,0 +1,252 @@
/* -*- 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-newt-container
* @short_description: Base class for containers
*
* #NmtNewtContainer is the base class for #NmtNewtWidgets that
* contain other widgets.
*
* #NmtNewtGrid is the most generic container type.
*/
#include "config.h"
#include <string.h>
#include "nmt-newt-container.h"
#include "nmt-newt-component.h"
G_DEFINE_ABSTRACT_TYPE (NmtNewtContainer, nmt_newt_container, NMT_TYPE_NEWT_WIDGET)
#define NMT_NEWT_CONTAINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_CONTAINER, NmtNewtContainerPrivate))
typedef struct {
GPtrArray *children;
} NmtNewtContainerPrivate;
static void child_needs_rebuild (NmtNewtWidget *widget, gpointer user_data);
static void
nmt_newt_container_init (NmtNewtContainer *container)
{
NmtNewtContainerPrivate *priv = NMT_NEWT_CONTAINER_GET_PRIVATE (container);
priv->children = g_ptr_array_new ();
}
static void
nmt_newt_container_finalize (GObject *object)
{
NmtNewtContainer *container = NMT_NEWT_CONTAINER (object);
NmtNewtContainerPrivate *priv = NMT_NEWT_CONTAINER_GET_PRIVATE (object);
while (priv->children->len)
nmt_newt_container_remove (container, priv->children->pdata[0]);
G_OBJECT_CLASS (nmt_newt_container_parent_class)->finalize (object);
}
static void
nmt_newt_container_realize (NmtNewtWidget *widget)
{
NmtNewtContainerPrivate *priv = NMT_NEWT_CONTAINER_GET_PRIVATE (widget);
int i;
for (i = 0; i < priv->children->len; i++)
nmt_newt_widget_realize (priv->children->pdata[i]);
}
static void
nmt_newt_container_unrealize (NmtNewtWidget *widget)
{
NmtNewtContainerPrivate *priv = NMT_NEWT_CONTAINER_GET_PRIVATE (widget);
int i;
for (i = 0; i < priv->children->len; i++)
nmt_newt_widget_unrealize (priv->children->pdata[i]);
}
static void
child_needs_rebuild (NmtNewtWidget *widget,
gpointer user_data)
{
NmtNewtWidget *container = user_data;
nmt_newt_widget_needs_rebuild (container);
}
static void
nmt_newt_container_real_child_validity_changed (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtNewtContainerPrivate *priv;
int i;
if (widget) {
if (!nmt_newt_widget_get_visible (widget))
return;
if (!nmt_newt_widget_get_valid (widget)) {
nmt_newt_widget_set_valid (NMT_NEWT_WIDGET (container), FALSE);
return;
}
}
priv = NMT_NEWT_CONTAINER_GET_PRIVATE (container);
for (i = 0; i < priv->children->len; i++) {
widget = priv->children->pdata[i];
if ( nmt_newt_widget_get_visible (widget)
&& !nmt_newt_widget_get_valid (widget)) {
nmt_newt_widget_set_valid (NMT_NEWT_WIDGET (container), FALSE);
return;
}
}
nmt_newt_widget_set_valid (NMT_NEWT_WIDGET (container), TRUE);
}
static void
nmt_newt_container_child_validity_changed (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NMT_NEWT_CONTAINER_GET_CLASS (container)->child_validity_changed (container, widget);
}
static void
child_validity_notify (GObject *object,
GParamSpec *pspec,
gpointer container)
{
nmt_newt_container_child_validity_changed (container, NMT_NEWT_WIDGET (object));
}
static void
nmt_newt_container_real_add (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtNewtContainerPrivate *priv = NMT_NEWT_CONTAINER_GET_PRIVATE (container);
g_signal_connect (widget, "needs-rebuild", G_CALLBACK (child_needs_rebuild), container);
g_signal_connect (widget, "notify::valid", G_CALLBACK (child_validity_notify), container);
g_ptr_array_add (priv->children, g_object_ref_sink (widget));
nmt_newt_widget_set_parent (widget, NMT_NEWT_WIDGET (container));
nmt_newt_container_child_validity_changed (container, widget);
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (container));
}
static void
nmt_newt_container_real_remove (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtNewtContainerPrivate *priv = NMT_NEWT_CONTAINER_GET_PRIVATE (container);
int i;
for (i = 0; i < priv->children->len; i++) {
if (widget == priv->children->pdata[i]) {
g_ptr_array_remove_index (priv->children, i);
g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (child_needs_rebuild), container);
g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (child_validity_notify), container);
nmt_newt_widget_set_parent (widget, NULL);
g_object_unref (widget);
nmt_newt_container_child_validity_changed (container, NULL);
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (container));
return;
}
}
}
/**
* nmt_newt_container_remove:
* @container: the #NmtNewtContainer
* @widget: the child to remove
*
* Removes @widget from @container.
*
* Note that there is not a corresponding
* <literal>nmt_newt_container_add ()</literal>; you must use
* container-type-specific methods to add widgets to containers.
*/
void
nmt_newt_container_remove (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NMT_NEWT_CONTAINER_GET_CLASS (container)->remove (container, widget);
}
static NmtNewtWidget *
nmt_newt_container_find_component (NmtNewtWidget *widget,
newtComponent co)
{
NmtNewtContainerPrivate *priv = NMT_NEWT_CONTAINER_GET_PRIVATE (widget);
NmtNewtWidget *found, *child;
int i;
for (i = 0; i < priv->children->len; i++) {
child = priv->children->pdata[i];
found = nmt_newt_widget_find_component (child, co);
if (found)
return found;
}
return NULL;
}
/**
* nmt_newt_container_get_children:
* @container: an #NmtNewtContainer
*
* Gets a list of @container's children.
*
* Returns: (transfer full): a list of @container's children.
*/
GSList *
nmt_newt_container_get_children (NmtNewtContainer *container)
{
NmtNewtContainerPrivate *priv = NMT_NEWT_CONTAINER_GET_PRIVATE (container);
GSList *ret;
int i;
for (i = 0, ret = NULL; i < priv->children->len; i++)
ret = g_slist_prepend (ret, g_object_ref (priv->children->pdata[i]));
return g_slist_reverse (ret);
}
static void
nmt_newt_container_class_init (NmtNewtContainerClass *container_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (container_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (container_class);
g_type_class_add_private (container_class, sizeof (NmtNewtContainerPrivate));
/* virtual methods */
object_class->finalize = nmt_newt_container_finalize;
widget_class->realize = nmt_newt_container_realize;
widget_class->unrealize = nmt_newt_container_unrealize;
widget_class->find_component = nmt_newt_container_find_component;
container_class->add = nmt_newt_container_real_add;
container_class->remove = nmt_newt_container_real_remove;
container_class->child_validity_changed = nmt_newt_container_real_child_validity_changed;
}

View File

@@ -0,0 +1,61 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_CONTAINER_H
#define NMT_NEWT_CONTAINER_H
#include "nmt-newt-widget.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_CONTAINER (nmt_newt_container_get_type ())
#define NMT_NEWT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_CONTAINER, NmtNewtContainer))
#define NMT_NEWT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_CONTAINER, NmtNewtContainerClass))
#define NMT_IS_NEWT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_CONTAINER))
#define NMT_IS_NEWT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_CONTAINER))
#define NMT_NEWT_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_CONTAINER, NmtNewtContainerClass))
struct _NmtNewtContainer {
NmtNewtWidget parent;
};
typedef struct {
NmtNewtWidgetClass parent;
/* methods */
void (*add) (NmtNewtContainer *container,
NmtNewtWidget *child);
void (*remove) (NmtNewtContainer *container,
NmtNewtWidget *child);
void (*child_validity_changed) (NmtNewtContainer *container,
NmtNewtWidget *child);
} NmtNewtContainerClass;
GType nmt_newt_container_get_type (void);
void nmt_newt_container_remove (NmtNewtContainer *container,
NmtNewtWidget *widget);
GSList *nmt_newt_container_get_children (NmtNewtContainer *container);
G_END_DECLS
#endif /* NMT_NEWT_CONTAINER_H */

View File

@@ -0,0 +1,213 @@
/* -*- 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-newt-entry-numeric
* @short_description: Numeric text entry
*
* #NmtNewtEntryNumeric implements a numeric-only #NmtNewtEntry.
*
* #NmtNewtEntryNumeric provides its own #NmtNewtEntryFilter and
* #NmtNewtEntryValidator functions, so you should not set your own.
*/
#include "config.h"
#include <stdlib.h>
#include "nmt-newt-entry-numeric.h"
G_DEFINE_TYPE (NmtNewtEntryNumeric, nmt_newt_entry_numeric, NMT_TYPE_NEWT_ENTRY)
#define NMT_NEWT_ENTRY_NUMERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_ENTRY_NUMERIC, NmtNewtEntryNumericPrivate))
typedef struct {
int min, max;
} NmtNewtEntryNumericPrivate;
enum {
PROP_0,
PROP_MINIMUM,
PROP_MAXIMUM,
LAST_PROP
};
/**
* nmt_newt_entry_numeric_new:
* @width: the entry's width in characters
* @min: the minimum valid value
* @max: the maximum valid value
*
* Creates a new #NmtNewtEntryNumeric, accepting values in pthe
* indicated range.
*
* Returns: a new #NmtNewtEntryNumeric
*/
NmtNewtWidget *
nmt_newt_entry_numeric_new (int width,
int min,
int max)
{
return g_object_new (NMT_TYPE_NEWT_ENTRY_NUMERIC,
"width", width,
"minimum", min,
"maximum", max,
NULL);
}
static gboolean
newt_entry_numeric_filter (NmtNewtEntry *entry,
const char *text,
int ch,
int position,
gpointer user_data)
{
NmtNewtEntryNumericPrivate *priv = NMT_NEWT_ENTRY_NUMERIC_GET_PRIVATE (entry);
if (g_ascii_isdigit (ch))
return TRUE;
if (ch == '-' && position == 0 && priv->min < 0)
return TRUE;
return FALSE;
}
static gboolean
newt_entry_numeric_validate (NmtNewtEntry *entry,
const char *text,
gpointer user_data)
{
NmtNewtEntryNumericPrivate *priv = NMT_NEWT_ENTRY_NUMERIC_GET_PRIVATE (entry);
int val;
char *end;
if (!*text)
return FALSE;
val = strtoul (text, &end, 10);
if (*end)
return FALSE;
if (val < priv->min || val > priv->max)
return FALSE;
return TRUE;
}
static void
nmt_newt_entry_numeric_init (NmtNewtEntryNumeric *entry)
{
nmt_newt_entry_set_filter (NMT_NEWT_ENTRY (entry), newt_entry_numeric_filter, NULL);
nmt_newt_entry_set_validator (NMT_NEWT_ENTRY (entry), newt_entry_numeric_validate, NULL);
}
static void
nmt_newt_entry_numeric_constructed (GObject *object)
{
NmtNewtEntryNumericPrivate *priv = NMT_NEWT_ENTRY_NUMERIC_GET_PRIVATE (object);
if (!*nmt_newt_entry_get_text (NMT_NEWT_ENTRY (object))) {
char buf[32];
g_snprintf (buf, sizeof (buf), "%d", priv->min);
nmt_newt_entry_set_text (NMT_NEWT_ENTRY (object), buf);
}
G_OBJECT_CLASS (nmt_newt_entry_numeric_parent_class)->constructed (object);
}
static void
nmt_newt_entry_numeric_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtEntryNumericPrivate *priv = NMT_NEWT_ENTRY_NUMERIC_GET_PRIVATE (object);
switch (prop_id) {
case PROP_MINIMUM:
priv->min = g_value_get_int (value);
break;
case PROP_MAXIMUM:
priv->max = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_entry_numeric_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtEntryNumericPrivate *priv = NMT_NEWT_ENTRY_NUMERIC_GET_PRIVATE (object);
switch (prop_id) {
case PROP_MINIMUM:
g_value_set_int (value, priv->min);
break;
case PROP_MAXIMUM:
g_value_set_int (value, priv->max);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_entry_numeric_class_init (NmtNewtEntryNumericClass *entry_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (entry_class);
g_type_class_add_private (entry_class, sizeof (NmtNewtEntryNumericPrivate));
/* virtual methods */
object_class->constructed = nmt_newt_entry_numeric_constructed;
object_class->set_property = nmt_newt_entry_numeric_set_property;
object_class->get_property = nmt_newt_entry_numeric_get_property;
/**
* NmtNewtEntryNumeric:minimum:
*
* The minimum #NmtNewtWidget:valid value for the entry. If this
* is non-negative, then the entry will not allow negative numbers
* to be entered.
*/
g_object_class_install_property (object_class, PROP_MINIMUM,
g_param_spec_int ("minimum", "", "",
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtEntryNumeric:maximum:
*
* The maximum #NmtNewtWidget:valid value for the entry.
*/
g_object_class_install_property (object_class, PROP_MAXIMUM,
g_param_spec_int ("maximum", "", "",
G_MININT, G_MAXINT, G_MAXINT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -0,0 +1,51 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_ENTRY_NUMERIC_H
#define NMT_NEWT_ENTRY_NUMERIC_H
#include "nmt-newt-entry.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_ENTRY_NUMERIC (nmt_newt_entry_numeric_get_type ())
#define NMT_NEWT_ENTRY_NUMERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_ENTRY_NUMERIC, NmtNewtEntryNumeric))
#define NMT_NEWT_ENTRY_NUMERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_ENTRY_NUMERIC, NmtNewtEntryNumericClass))
#define NMT_IS_NEWT_ENTRY_NUMERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_ENTRY_NUMERIC))
#define NMT_IS_NEWT_ENTRY_NUMERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_ENTRY_NUMERIC))
#define NMT_NEWT_ENTRY_NUMERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_ENTRY_NUMERIC, NmtNewtEntryNumericClass))
struct _NmtNewtEntryNumeric {
NmtNewtEntry parent;
};
typedef struct {
NmtNewtEntryClass parent;
} NmtNewtEntryNumericClass;
GType nmt_newt_entry_numeric_get_type (void);
NmtNewtWidget *nmt_newt_entry_numeric_new (int width,
int min,
int max);
G_END_DECLS
#endif /* NMT_NEWT_ENTRY_NUMERIC_H */

536
tui/newt/nmt-newt-entry.c Normal file
View File

@@ -0,0 +1,536 @@
/* -*- 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-newt-entry
* @short_description: Text entries
*
* #NmtNewtEntry implements entry widgets, with optional filtering and
* validation.
*
* See also #NmtNewtEntryNumeric, for numeric-only entries.
*/
#include "config.h"
#include <string.h>
#include "nmt-newt-entry.h"
#include "nmt-newt-form.h"
#include "nmt-newt-hacks.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtEntry, nmt_newt_entry, NMT_TYPE_NEWT_COMPONENT)
#define NMT_NEWT_ENTRY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_ENTRY, NmtNewtEntryPrivate))
typedef struct {
int width;
NmtNewtEntryFlags flags;
char *text;
int last_cursor_pos;
guint idle_update;
NmtNewtEntryFilter filter;
gpointer filter_data;
NmtNewtEntryValidator validator;
gpointer validator_data;
} NmtNewtEntryPrivate;
enum {
PROP_0,
PROP_TEXT,
PROP_WIDTH,
PROP_FLAGS,
PROP_PASSWORD,
LAST_PROP
};
/**
* NmtNewtEntryFlags:
* @NMT_NEWT_ENTRY_NOSCROLL: the entry content should not scroll left
* and right
* @NMT_NEWT_ENTRY_PASSWORD: the entry should show '*'s instead of its
* actual contents
* @NMT_NEWT_ENTRY_NONEMPTY: the entry should be considered not
* #NmtNewtWidget:valid if it is empty.
*
* Flags describing an #NmtNewtEntry
*/
/**
* nmt_newt_entry_new:
* @width: the width in characters for the entry
* @flags: flags describing the entry
*
* Creates a new #NmtNewtEntry.
*
* Returns: a new #NmtNewtEntry
*/
NmtNewtWidget *
nmt_newt_entry_new (int width,
NmtNewtEntryFlags flags)
{
return g_object_new (NMT_TYPE_NEWT_ENTRY,
"width", width,
"flags", flags,
NULL);
}
/**
* NmtNewtEntryFilter:
* @entry: the #NmtNewtEntry
* @text: the current contents of @entry
* @ch: the character just typed
* @position: the position of the cursor in @entry
* @user_data: the data passed to nmt_newt_entry_set_filter()
*
* Callback function used to filter the contents of an entry.
*
* Returns: %TRUE if @ch should be accepted, %FALSE if not
*/
/**
* nmt_newt_entry_set_filter:
* @entry: an #NmtNewtEntry
* @filter: the function to use to filter the entry
* @user_data: data for @filter
*
* Sets a #NmtNewtEntryFilter on @entry, to allow filtering out
* certain characters from the entry.
*
* Note that @filter will only be called for printable characters (eg,
* not for cursor-control characters or the like), and that it will
* only be called for user input, not, eg, for
* nmt_newt_entry_set_text().
*/
void
nmt_newt_entry_set_filter (NmtNewtEntry *entry,
NmtNewtEntryFilter filter,
gpointer user_data)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
priv->filter = filter;
priv->filter_data = user_data;
}
static void
nmt_newt_entry_check_valid (NmtNewtEntry *entry)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
gboolean valid;
if ( (priv->flags & NMT_NEWT_ENTRY_NONEMPTY)
&& *priv->text == '\0')
valid = FALSE;
else if (priv->validator)
valid = !!priv->validator (entry, priv->text, priv->validator_data);
else
valid = TRUE;
nmt_newt_widget_set_valid (NMT_NEWT_WIDGET (entry), valid);
}
/**
* NmtNewtEntryValidator:
* @entry: the #NmtNewtEntry
* @text: the current contents of @entry
* @user_data: the data passed to nmt_newt_entry_set_validator()
*
* Callback function used to validate the contents of an entry.
*
* Returns: whether the entry is #NmtNewtWidget:valid
*/
/**
* nmt_newt_entry_set_validator:
* @entry: an #NmtNewtEntry
* @validator: the function to use to validate the entry
* @user_data: data for @validator
*
* Sets a #NmtNewtEntryValidator on @entry, to allow validation of
* the entry contents. If @validator returns %FALSE, then the entry
* will not be considered #NmtNewtWidget:valid.
*/
void
nmt_newt_entry_set_validator (NmtNewtEntry *entry,
NmtNewtEntryValidator validator,
gpointer user_data)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
priv->validator = validator;
priv->validator_data = user_data;
nmt_newt_entry_check_valid (entry);
}
static void
nmt_newt_entry_set_text_internal (NmtNewtEntry *entry,
const char *text,
newtComponent co)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
if (!text)
text = "";
if (!strcmp (priv->text, text))
return;
g_free (priv->text);
priv->text = g_strdup (text);
if (co) {
char *text_lc;
text_lc = priv->text ? nmt_newt_locale_from_utf8 (priv->text) : NULL;
newtEntrySet (co, text_lc, TRUE);
g_free (text_lc);
priv->last_cursor_pos = -1;
}
g_object_freeze_notify (G_OBJECT (entry));
nmt_newt_entry_check_valid (entry);
g_object_notify (G_OBJECT (entry), "text");
g_object_thaw_notify (G_OBJECT (entry));
}
/**
* nmt_newt_entry_set_text:
* @entry: an #NmtNewtEntry
* @text: the new text
*
* Updates @entry's text. Note that this skips the entry's
* #NmtNewtEntryFilter, but will cause its #NmtNewtEntryValidator to
* be re-run.
*/
void
nmt_newt_entry_set_text (NmtNewtEntry *entry,
const char *text)
{
newtComponent co;
co = nmt_newt_component_get_component (NMT_NEWT_COMPONENT (entry));
nmt_newt_entry_set_text_internal (entry, text, co);
}
/**
* nmt_newt_entry_get_text:
* @entry: an #NmtNewtEntry
*
* Gets @entry's text
*
* Returns: @entry's text
*/
const char *
nmt_newt_entry_get_text (NmtNewtEntry *entry)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
return priv->text;
}
/**
* nmt_newt_entry_set_width:
* @entry: an #NmtNewtEntpry
* @widget: the new width
*
* Updates @entry's width
*/
void
nmt_newt_entry_set_width (NmtNewtEntry *entry,
int width)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
if (priv->width == width)
return;
priv->width = width;
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (entry));
g_object_notify (G_OBJECT (entry), "width");
}
/**
* nmt_newt_entry_get_width:
* @entry: an #NmtNewtEntry
*
* Gets @entry's width
*
* Returns: @entry's width
*/
int
nmt_newt_entry_get_width (NmtNewtEntry *entry)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
return priv->width;
}
static void
nmt_newt_entry_init (NmtNewtEntry *entry)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
priv->text = g_strdup ("");
priv->last_cursor_pos = -1;
}
static void
nmt_newt_entry_constructed (GObject *object)
{
nmt_newt_entry_check_valid (NMT_NEWT_ENTRY (object));
G_OBJECT_CLASS (nmt_newt_entry_parent_class)->constructed (object);
}
static void
nmt_newt_entry_finalize (GObject *object)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (object);
g_free (priv->text);
if (priv->idle_update)
g_source_remove (priv->idle_update);
G_OBJECT_CLASS (nmt_newt_entry_parent_class)->finalize (object);
}
static gboolean
idle_update_entry (gpointer entry)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
newtComponent co = nmt_newt_component_get_component (entry);
char *text;
priv->idle_update = 0;
if (!co)
return FALSE;
priv->last_cursor_pos = newtEntryGetCursorPosition (co);
text = nmt_newt_locale_to_utf8 (newtEntryGetValue (co));
nmt_newt_entry_set_text_internal (entry, text, NULL);
g_free (text);
return FALSE;
}
static int
entry_filter (newtComponent entry,
void *self,
int ch,
int cursor)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (self);
if (g_ascii_isprint (ch)) {
if (priv->filter) {
char *text = nmt_newt_locale_to_utf8 (newtEntryGetValue (entry));
if (!priv->filter (self, text, ch, cursor, priv->filter_data)) {
g_free (text);
return 0;
}
g_free (text);
}
}
if (!priv->idle_update)
priv->idle_update = g_idle_add (idle_update_entry, self);
return ch;
}
static guint
convert_flags (NmtNewtEntryFlags flags)
{
guint newt_flags = NEWT_FLAG_RETURNEXIT;
if (!(flags & NMT_NEWT_ENTRY_NOSCROLL))
newt_flags |= NEWT_FLAG_SCROLL;
if (flags & NMT_NEWT_ENTRY_PASSWORD)
newt_flags |= NEWT_FLAG_PASSWORD;
return newt_flags;
}
static newtComponent
nmt_newt_entry_build_component (NmtNewtComponent *component,
gboolean sensitive)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (component);
newtComponent co;
char *text_lc;
int flags;
flags = convert_flags (priv->flags);
if (!sensitive)
flags |= NEWT_FLAG_DISABLED;
text_lc = priv->text ? nmt_newt_locale_from_utf8 (priv->text) : NULL;
co = newtEntry (-1, -1, text_lc, priv->width, NULL, flags);
g_free (text_lc);
if (priv->last_cursor_pos != -1)
newtEntrySetCursorPosition (co, priv->last_cursor_pos);
newtEntrySetFilter (co, entry_filter, component);
return co;
}
static void
nmt_newt_entry_activated (NmtNewtWidget *widget)
{
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (widget);
if (priv->idle_update) {
g_source_remove (priv->idle_update);
idle_update_entry (widget);
}
NMT_NEWT_WIDGET_CLASS (nmt_newt_entry_parent_class)->activated (widget);
}
static void
nmt_newt_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtEntry *entry = NMT_NEWT_ENTRY (object);
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
switch (prop_id) {
case PROP_TEXT:
nmt_newt_entry_set_text (entry, g_value_get_string (value));
break;
case PROP_WIDTH:
nmt_newt_entry_set_width (entry, g_value_get_int (value));
break;
case PROP_FLAGS:
priv->flags = g_value_get_uint (value);
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (entry));
break;
case PROP_PASSWORD:
if (g_value_get_boolean (value))
priv->flags |= NMT_NEWT_ENTRY_PASSWORD;
else
priv->flags &= ~NMT_NEWT_ENTRY_PASSWORD;
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (entry));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_entry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtEntry *entry = NMT_NEWT_ENTRY (object);
NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (entry);
switch (prop_id) {
case PROP_TEXT:
g_value_set_string (value, nmt_newt_entry_get_text (entry));
break;
case PROP_WIDTH:
g_value_set_int (value, priv->width);
break;
case PROP_FLAGS:
g_value_set_uint (value, priv->flags);
break;
case PROP_PASSWORD:
g_value_set_boolean (value, (priv->flags & NMT_NEWT_ENTRY_PASSWORD) != 0);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_entry_class_init (NmtNewtEntryClass *entry_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (entry_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (entry_class);
NmtNewtComponentClass *component_class = NMT_NEWT_COMPONENT_CLASS (entry_class);
g_type_class_add_private (entry_class, sizeof (NmtNewtEntryPrivate));
/* virtual methods */
object_class->constructed = nmt_newt_entry_constructed;
object_class->set_property = nmt_newt_entry_set_property;
object_class->get_property = nmt_newt_entry_get_property;
object_class->finalize = nmt_newt_entry_finalize;
widget_class->activated = nmt_newt_entry_activated;
component_class->build_component = nmt_newt_entry_build_component;
/**
* NmtNewtEntry:text
*
* The entry's text
*/
g_object_class_install_property (object_class, PROP_TEXT,
g_param_spec_string ("text", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtEntry:width
*
* The entry's width in characters
*/
g_object_class_install_property (object_class, PROP_WIDTH,
g_param_spec_int ("width", "", "",
-1, 80, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtEntry:flags
*
* The entry's #NmtNewtEntryFlags
*/
g_object_class_install_property (object_class, PROP_FLAGS,
g_param_spec_uint ("flags", "", "",
0, 0xFFFF, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtEntry:password
*
* %TRUE if #NmtNewtEntry:flags contains %NMT_NEWT_ENTRY_PASSWORD,
* %FALSE if not.
*/
g_object_class_install_property (object_class, PROP_PASSWORD,
g_param_spec_boolean ("password", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

74
tui/newt/nmt-newt-entry.h Normal file
View File

@@ -0,0 +1,74 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_ENTRY_H
#define NMT_NEWT_ENTRY_H
#include "nmt-newt-component.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_ENTRY (nmt_newt_entry_get_type ())
#define NMT_NEWT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_ENTRY, NmtNewtEntry))
#define NMT_NEWT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_ENTRY, NmtNewtEntryClass))
#define NMT_IS_NEWT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_ENTRY))
#define NMT_IS_NEWT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_ENTRY))
#define NMT_NEWT_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_ENTRY, NmtNewtEntryClass))
struct _NmtNewtEntry {
NmtNewtComponent parent;
};
typedef struct {
NmtNewtComponentClass parent;
} NmtNewtEntryClass;
GType nmt_newt_entry_get_type (void);
typedef gboolean (*NmtNewtEntryFilter) (NmtNewtEntry *, const char *text, int ch, int position, gpointer);
typedef gboolean (*NmtNewtEntryValidator) (NmtNewtEntry *, const char *text, gpointer);
typedef enum {
NMT_NEWT_ENTRY_NOSCROLL = (1 << 0),
NMT_NEWT_ENTRY_PASSWORD = (1 << 1),
NMT_NEWT_ENTRY_NONEMPTY = (1 << 2)
} NmtNewtEntryFlags;
NmtNewtWidget *nmt_newt_entry_new (int width,
NmtNewtEntryFlags flags);
void nmt_newt_entry_set_filter (NmtNewtEntry *entry,
NmtNewtEntryFilter filter,
gpointer user_data);
void nmt_newt_entry_set_validator (NmtNewtEntry *entry,
NmtNewtEntryValidator validator,
gpointer user_data);
void nmt_newt_entry_set_text (NmtNewtEntry *entry,
const char *text);
const char *nmt_newt_entry_get_text (NmtNewtEntry *entry);
void nmt_newt_entry_set_width (NmtNewtEntry *entry,
int width);
int nmt_newt_entry_get_width (NmtNewtEntry *entry);
G_END_DECLS
#endif /* NMT_NEWT_ENTRY_H */

656
tui/newt/nmt-newt-form.c Normal file
View File

@@ -0,0 +1,656 @@
/* -*- 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-newt-form
* @short_description: The top-level NmtNewt widget
*
* #NmtNewtForm is the top-level widget that contains and presents a
* "form" (aka dialog) to the user.
*/
#include "config.h"
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <glib/gi18n-lib.h>
#include "nmt-newt-form.h"
#include "nmt-newt-button.h"
#include "nmt-newt-grid.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtForm, nmt_newt_form, NMT_TYPE_NEWT_CONTAINER)
#define NMT_NEWT_FORM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_FORM, NmtNewtFormPrivate))
typedef struct {
newtComponent form;
NmtNewtWidget *content;
guint x, y, width, height;
guint padding;
gboolean fixed_x, fixed_y;
gboolean fixed_width, fixed_height;
char *title_lc;
gboolean dirty, escape_exits;
NmtNewtWidget *focus;
#ifdef HAVE_NEWTFORMGETSCROLLPOSITION
int scroll_position = 0;
#endif
} NmtNewtFormPrivate;
enum {
PROP_0,
PROP_TITLE,
PROP_FULLSCREEN,
PROP_X,
PROP_Y,
PROP_WIDTH,
PROP_HEIGHT,
PROP_PADDING,
PROP_ESCAPE_EXITS,
LAST_PROP
};
static void nmt_newt_form_redraw (NmtNewtForm *form);
/**
* nmt_newt_form_new:
* @title: (allow-none): the form title
*
* Creates a new form, which will be shown centered on the screen.
* Compare nmt_newt_form_new_fullscreen(). You can also position a
* form manually by setting its #NmtNewtForm:x and #NmtNewtForm:y
* properties, either at construct time or later.
*
* If @title is NULL, the form will have no title.
*
* Returns: a new #NmtNewtForm
*/
NmtNewtForm *
nmt_newt_form_new (const char *title)
{
return g_object_new (NMT_TYPE_NEWT_FORM,
"title", title,
NULL);
}
/**
* nmt_newt_form_new_fullscreen:
* @title: (allow-none): the form title
*
* Creates a new fullscreen form. Compare nmt_newt_form_new().
*
* If @title is NULL, the form will have no title.
*
* Returns: a new #NmtNewtForm
*/
NmtNewtForm *
nmt_newt_form_new_fullscreen (const char *title)
{
return g_object_new (NMT_TYPE_NEWT_FORM,
"title", title,
"fullscreen", TRUE,
NULL);
}
static void
nmt_newt_form_init (NmtNewtForm *form)
{
g_object_ref_sink (form);
}
static void
nmt_newt_form_finalize (GObject *object)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (object);
g_free (priv->title_lc);
g_clear_object (&priv->focus);
G_OBJECT_CLASS (nmt_newt_form_parent_class)->finalize (object);
}
static void
nmt_newt_form_needs_rebuild (NmtNewtWidget *widget)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (widget);
if (!priv->dirty) {
priv->dirty = TRUE;
nmt_newt_form_redraw (NMT_NEWT_FORM (widget));
}
}
static void
nmt_newt_form_remove (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (container);
NmtNewtContainerClass *parent_class = NMT_NEWT_CONTAINER_CLASS (nmt_newt_form_parent_class);
g_return_if_fail (widget == priv->content);
parent_class->remove (container, widget);
priv->content = NULL;
}
/**
* nmt_newt_form_set_content:
* @form: the #NmtNewtForm
* @content: the form's content
*
* Sets @form's content to be @content.
*/
void
nmt_newt_form_set_content (NmtNewtForm *form,
NmtNewtWidget *content)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (form);
NmtNewtContainerClass *parent_class = NMT_NEWT_CONTAINER_CLASS (nmt_newt_form_parent_class);
if (priv->content)
nmt_newt_form_remove (NMT_NEWT_CONTAINER (form), priv->content);
priv->content = content;
if (priv->content)
parent_class->add (NMT_NEWT_CONTAINER (form), content);
}
static void
nmt_newt_form_build (NmtNewtForm *form)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (form);
int screen_height, screen_width, form_height, form_width;
newtComponent *cos;
int i;
priv->dirty = FALSE;
nmt_newt_widget_realize (priv->content);
nmt_newt_widget_size_request (priv->content, &form_width, &form_height);
newtGetScreenSize (&screen_width, &screen_height);
if (!priv->fixed_width)
priv->width = MIN (form_width + 2 * priv->padding, screen_width - 2);
if (!priv->fixed_height)
priv->height = MIN (form_height + 2 * priv->padding, screen_height - 2);
if (!priv->fixed_x)
priv->x = (screen_width - form_width) / 2;
if (!priv->fixed_y)
priv->y = (screen_height - form_height) / 2;
nmt_newt_widget_size_allocate (priv->content,
priv->padding,
priv->padding,
priv->width - 2 * priv->padding,
priv->height - 2 * priv->padding);
if (priv->height - 2 * priv->padding < form_height) {
newtComponent scroll_bar =
newtVerticalScrollbar (priv->width - 1, 0, priv->height,
NEWT_COLORSET_WINDOW,
NEWT_COLORSET_ACTCHECKBOX);
priv->form = newtForm (scroll_bar, NULL, NEWT_FLAG_NOF12);
newtFormAddComponent (priv->form, scroll_bar);
newtFormSetHeight (priv->form, priv->height - 2);
} else
priv->form = newtForm (NULL, NULL, NEWT_FLAG_NOF12);
if (priv->escape_exits)
newtFormAddHotKey (priv->form, NEWT_KEY_ESCAPE);
cos = nmt_newt_widget_get_components (priv->content);
for (i = 0; cos[i]; i++)
newtFormAddComponent (priv->form, cos[i]);
g_free (cos);
if (priv->focus) {
newtComponent fco;
fco = nmt_newt_widget_get_focus_component (priv->focus);
if (fco)
newtFormSetCurrent (priv->form, fco);
}
#ifdef HAVE_NEWTFORMGETSCROLLPOSITION
if (priv->scroll_position)
newtFormSetScrollPosition (priv->form, priv->scroll_position);
#endif
newtOpenWindow (priv->x, priv->y, priv->width, priv->height, priv->title_lc);
}
static void
nmt_newt_form_destroy (NmtNewtForm *form)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (form);
#ifdef HAVE_NEWTFORMGETSCROLLPOSITION
priv->scroll_position = newtFormGetScrollPosition (priv->form);
#endif
newtFormDestroy (priv->form);
priv->form = NULL;
newtPopWindow ();
nmt_newt_widget_unrealize (priv->content);
}
static void
nmt_newt_form_iterate (NmtNewtForm *form)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (form);
NmtNewtWidget *focus;
struct newtExitStruct es;
if (priv->dirty) {
nmt_newt_form_destroy (form);
nmt_newt_form_build (form);
}
newtFormSetTimer (priv->form, 1);
newtFormRun (priv->form, &es);
if (es.reason == NEWT_EXIT_TIMER)
return;
if ( es.reason == NEWT_EXIT_HOTKEY
|| es.reason == NEWT_EXIT_ERROR) {
g_clear_object (&priv->focus);
nmt_newt_form_quit (form);
return;
}
if (es.reason == NEWT_EXIT_COMPONENT) {
focus = nmt_newt_widget_find_component (priv->content, es.u.co);
if (focus) {
nmt_newt_form_set_focus (form, focus);
nmt_newt_widget_activated (focus);
}
} else {
focus = nmt_newt_widget_find_component (priv->content,
newtFormGetCurrent (priv->form));
if (focus)
nmt_newt_form_set_focus (form, focus);
}
}
static GSList *form_stack;
static GSource *keypress_source;
static gboolean
nmt_newt_form_keypress_callback (int fd,
GIOCondition condition,
gpointer user_data)
{
g_return_val_if_fail (form_stack != NULL, FALSE);
nmt_newt_form_iterate (form_stack->data);
return TRUE;
}
static gboolean
nmt_newt_form_timeout_callback (gpointer user_data)
{
if (form_stack)
nmt_newt_form_iterate (form_stack->data);
return FALSE;
}
static void
nmt_newt_form_redraw (NmtNewtForm *form)
{
g_timeout_add (0, nmt_newt_form_timeout_callback, NULL);
}
static void
nmt_newt_form_real_show (NmtNewtForm *form)
{
if (!keypress_source) {
GIOChannel *io;
io = g_io_channel_unix_new (STDIN_FILENO);
keypress_source = g_io_create_watch (io, G_IO_IN);
g_source_set_can_recurse (keypress_source, TRUE);
g_source_set_callback (keypress_source,
(GSourceFunc) nmt_newt_form_keypress_callback,
NULL, NULL);
g_source_attach (keypress_source, NULL);
g_io_channel_unref (io);
}
nmt_newt_form_build (form);
form_stack = g_slist_prepend (form_stack, g_object_ref (form));
nmt_newt_form_redraw (form);
}
/**
* nmt_newt_form_show:
* @form: an #NmtNewtForm
*
* Displays @form and begins running it asynchronously in the default
* #GMainContext. If another form is currently running, it will remain
* visible in the background, but will not be able to receive keyboard
* input until @form exits.
*
* Call nmt_newt_form_quit() to quit the form.
*/
void
nmt_newt_form_show (NmtNewtForm *form)
{
NMT_NEWT_FORM_GET_CLASS (form)->show (form);
}
/**
* nmt_newt_form_run_sync:
* @form: an #NmtNewtForm
*
* Displays @form as with nmt_newt_form_show(), but then iterates the
* #GMainContext internally until @form exits.
*
* Returns: the widget whose activation caused @form to exit, or
* %NULL if it was not caused by a widget. FIXME: this exit value is
* sort of weird and may not be 100% accurate anyway.
*/
NmtNewtWidget *
nmt_newt_form_run_sync (NmtNewtForm *form)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (form);
nmt_newt_form_show (form);
while (priv->form)
g_main_context_iteration (NULL, TRUE);
return priv->focus;
}
/**
* nmt_newt_form_quit:
* @form: an #NmtNewtForm
*
* Causes @form to exit.
*/
void
nmt_newt_form_quit (NmtNewtForm *form)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (form);
g_return_if_fail (priv->form != NULL);
nmt_newt_form_destroy (form);
form_stack = g_slist_remove (form_stack, form);
g_object_unref (form);
if (form_stack)
nmt_newt_form_iterate (form_stack->data);
else if (keypress_source) {
g_source_destroy (keypress_source);
g_clear_pointer (&keypress_source, g_source_unref);
}
}
/**
* nmt_newt_form_set_focus:
* @form: an #NmtNewtForm
* @widget: the widget to focus
*
* Focuses @widget in @form.
*/
void
nmt_newt_form_set_focus (NmtNewtForm *form,
NmtNewtWidget *widget)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (form);
g_return_if_fail (priv->form != NULL);
if (priv->focus == widget)
return;
if (priv->focus)
g_object_unref (priv->focus);
priv->focus = widget;
if (priv->focus)
g_object_ref (priv->focus);
}
static void
nmt_newt_form_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (object);
int screen_width, screen_height;
switch (prop_id) {
case PROP_TITLE:
if (g_value_get_string (value)) {
priv->title_lc = nmt_newt_locale_from_utf8 (g_value_get_string (value));
} else
priv->title_lc = NULL;
break;
case PROP_FULLSCREEN:
if (g_value_get_boolean (value)) {
newtGetScreenSize (&screen_width, &screen_height);
priv->x = priv->y = 2;
priv->fixed_x = priv->fixed_y = TRUE;
priv->width = screen_width - 4;
priv->height = screen_height - 4;
priv->fixed_width = priv->fixed_height = TRUE;
}
break;
case PROP_X:
if (g_value_get_uint (value)) {
priv->x = g_value_get_uint (value);
priv->fixed_x = TRUE;
}
break;
case PROP_Y:
if (g_value_get_uint (value)) {
priv->y = g_value_get_uint (value);
priv->fixed_y = TRUE;
}
break;
case PROP_WIDTH:
if (g_value_get_uint (value)) {
priv->width = g_value_get_uint (value);
priv->fixed_width = TRUE;
}
break;
case PROP_HEIGHT:
if (g_value_get_uint (value)) {
priv->height = g_value_get_uint (value);
priv->fixed_height = TRUE;
}
break;
case PROP_PADDING:
priv->padding = g_value_get_uint (value);
break;
case PROP_ESCAPE_EXITS:
priv->escape_exits = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_form_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE (object);
switch (prop_id) {
case PROP_TITLE:
if (priv->title_lc) {
g_value_take_string (value, nmt_newt_locale_to_utf8 (priv->title_lc));
} else
g_value_set_string (value, NULL);
break;
case PROP_X:
g_value_set_uint (value, priv->x);
break;
case PROP_Y:
g_value_set_uint (value, priv->y);
break;
case PROP_WIDTH:
g_value_set_uint (value, priv->width);
break;
case PROP_HEIGHT:
g_value_set_uint (value, priv->height);
break;
case PROP_PADDING:
g_value_set_uint (value, priv->padding);
break;
case PROP_ESCAPE_EXITS:
g_value_set_boolean (value, priv->escape_exits);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_form_class_init (NmtNewtFormClass *form_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (form_class);
NmtNewtContainerClass *container_class = NMT_NEWT_CONTAINER_CLASS (form_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (form_class);
g_type_class_add_private (form_class, sizeof (NmtNewtFormPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_form_set_property;
object_class->get_property = nmt_newt_form_get_property;
object_class->finalize = nmt_newt_form_finalize;
widget_class->needs_rebuild = nmt_newt_form_needs_rebuild;
container_class->remove = nmt_newt_form_remove;
form_class->show = nmt_newt_form_real_show;
/**
* NmtNewtForm:title:
*
* The form's title. If non-%NULL, this will be displayed above
* the form in its border.
*/
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
/**
* NmtNewtForm:fullscreen:
*
* If %TRUE, the form will fill the entire "screen" (ie, terminal
* window).
*/
g_object_class_install_property (object_class, PROP_FULLSCREEN,
g_param_spec_boolean ("fullscreen", "", "",
FALSE,
G_PARAM_WRITABLE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
/**
* NmtNewtForm:x:
*
* The form's x coordinate. By default, the form will be centered
* on the screen.
*/
g_object_class_install_property (object_class, PROP_X,
g_param_spec_uint ("x", "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
/**
* NmtNewtForm:y:
*
* The form's y coordinate. By default, the form will be centered
* on the screen.
*/
g_object_class_install_property (object_class, PROP_Y,
g_param_spec_uint ("y", "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
/**
* NmtNewtForm:width:
*
* The form's width. By default, this will be determined by the
* width of the form's content.
*/
g_object_class_install_property (object_class, PROP_WIDTH,
g_param_spec_uint ("width", "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
/**
* NmtNewtForm:height:
*
* The form's height. By default, this will be determined by the
* height of the form's content.
*/
g_object_class_install_property (object_class, PROP_HEIGHT,
g_param_spec_uint ("height", "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
/**
* NmtNewtForm:padding:
*
* The padding between the form's content and its border.
*/
g_object_class_install_property (object_class, PROP_PADDING,
g_param_spec_uint ("padding", "", "",
0, G_MAXUINT, 1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
/**
* NmtNewtForm:escape-exits:
*
* If %TRUE, then hitting the Escape key will cause the form to
* exit.
*/
g_object_class_install_property (object_class, PROP_ESCAPE_EXITS,
g_param_spec_boolean ("escape-exits", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
}

62
tui/newt/nmt-newt-form.h Normal file
View File

@@ -0,0 +1,62 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_FORM_H
#define NMT_NEWT_FORM_H
#include "nmt-newt-container.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_FORM (nmt_newt_form_get_type ())
#define NMT_NEWT_FORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_FORM, NmtNewtForm))
#define NMT_NEWT_FORM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_FORM, NmtNewtFormClass))
#define NMT_IS_NEWT_FORM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_FORM))
#define NMT_IS_NEWT_FORM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_FORM))
#define NMT_NEWT_FORM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_FORM, NmtNewtFormClass))
struct _NmtNewtForm {
NmtNewtContainer parent;
};
typedef struct {
NmtNewtContainerClass parent;
void (*show) (NmtNewtForm *form);
} NmtNewtFormClass;
GType nmt_newt_form_get_type (void);
NmtNewtForm *nmt_newt_form_new (const char *title);
NmtNewtForm *nmt_newt_form_new_fullscreen (const char *title);
void nmt_newt_form_set_content (NmtNewtForm *form,
NmtNewtWidget *content);
void nmt_newt_form_show (NmtNewtForm *form);
NmtNewtWidget *nmt_newt_form_run_sync (NmtNewtForm *form);
void nmt_newt_form_quit (NmtNewtForm *form);
void nmt_newt_form_set_focus (NmtNewtForm *form,
NmtNewtWidget *widget);
G_END_DECLS
#endif /* NMT_NEWT_FORM_H */

472
tui/newt/nmt-newt-grid.c Normal file
View File

@@ -0,0 +1,472 @@
/* -*- 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-newt-grid
* @short_description: Grid container
*
* #NmtNewtGrid is the most general-purpose container widget in NmtNewt.
*
* An #NmtNewtGrid consists of a number of rows and columns. There is
* no pre-established maximum row or columns. Rather, rows and columns
* exist if and only if there are widgets in them.
*
* The width of each column is the width of the widest widget in that
* column, and the height of each row is the height of the tallest
* widget in that row. Empty rows and empty columns take up no space,
* so a grid with a single widget at 0,0 would look exactly the same
* if the widget was at 5,10 instead.
*
* If a widget's cell ends up being larger than the widget's requested
* size, then by default the widget will be centered in its cell.
* However, this can be modified by changing its #NmtNewtGridFlags.
* FIXME: the FILL/ANCHOR flags can be implemented in #NmtNewtWidget
* and so should move there. Less clear about the EXPAND flags, which
* must be implemented by the container...
*/
#include "config.h"
#include <string.h>
#include "nmt-newt-grid.h"
G_DEFINE_TYPE (NmtNewtGrid, nmt_newt_grid, NMT_TYPE_NEWT_CONTAINER)
#define NMT_NEWT_GRID_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_GRID, NmtNewtGridPrivate))
typedef struct {
NmtNewtWidget *widget;
int x, y;
NmtNewtGridFlags flags;
int req_height, req_width;
} NmtNewtGridChild;
typedef struct {
GArray *children;
int max_x, max_y;
int *row_heights, *col_widths;
gboolean *expand_rows, *expand_cols;
int n_expand_rows, n_expand_cols;
int req_height, req_width;
} NmtNewtGridPrivate;
/**
* nmt_newt_grid_new:
*
* Creates a new #NmtNewtGrid
*
* Returns: a new #NmtNewtGrid
*/
NmtNewtWidget *
nmt_newt_grid_new (void)
{
return g_object_new (NMT_TYPE_NEWT_GRID, NULL);
}
static void
nmt_newt_grid_init (NmtNewtGrid *grid)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (grid);
priv->children = g_array_new (FALSE, FALSE, sizeof (NmtNewtGridChild));
}
static void
nmt_newt_grid_finalize (GObject *object)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (object);
g_array_unref (priv->children);
g_clear_pointer (&priv->row_heights, g_free);
g_clear_pointer (&priv->col_widths, g_free);
g_clear_pointer (&priv->expand_rows, g_free);
g_clear_pointer (&priv->expand_cols, g_free);
G_OBJECT_CLASS (nmt_newt_grid_parent_class)->finalize (object);
}
static int
child_sort_func (gconstpointer a,
gconstpointer b)
{
NmtNewtGridChild *child_a = (NmtNewtGridChild *)a;
NmtNewtGridChild *child_b = (NmtNewtGridChild *)b;
if (child_a->y != child_b->y)
return child_a->y - child_b->y;
else
return child_a->x - child_b->x;
}
static newtComponent *
nmt_newt_grid_get_components (NmtNewtWidget *widget)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (widget);
NmtNewtGridChild *children;
GPtrArray *cos;
newtComponent *child_cos;
int i, c;
g_array_sort (priv->children, child_sort_func);
children = (NmtNewtGridChild *)priv->children->data;
cos = g_ptr_array_new ();
for (i = 0; i < priv->children->len; i++) {
if (!nmt_newt_widget_get_visible (children[i].widget))
continue;
child_cos = nmt_newt_widget_get_components (children[i].widget);
for (c = 0; child_cos[c]; c++)
g_ptr_array_add (cos, child_cos[c]);
g_free (child_cos);
}
g_ptr_array_add (cos, NULL);
return (newtComponent *) g_ptr_array_free (cos, FALSE);
}
static void
nmt_newt_grid_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
NmtNewtGrid *grid = NMT_NEWT_GRID (widget);
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (grid);
NmtNewtGridChild *children = (NmtNewtGridChild *)priv->children->data;
int row, col, i;
g_free (priv->row_heights);
g_free (priv->col_widths);
g_free (priv->expand_rows);
g_free (priv->expand_cols);
priv->row_heights = g_new0 (int, priv->max_y + 1);
priv->col_widths = g_new0 (int, priv->max_x + 1);
priv->expand_rows = g_new0 (gboolean, priv->max_y + 1);
priv->expand_cols = g_new0 (gboolean, priv->max_x + 1);
priv->n_expand_rows = priv->n_expand_cols = 0;
for (row = 0; row < priv->max_y + 1; row++) {
for (col = 0; col < priv->max_x + 1; col++) {
for (i = 0; i < priv->children->len; i++) {
if (children[i].x != col || children[i].y != row)
continue;
if (!nmt_newt_widget_get_visible (children[i].widget))
continue;
nmt_newt_widget_size_request (children[i].widget,
&children[i].req_width,
&children[i].req_height);
if (children[i].req_height > priv->row_heights[row])
priv->row_heights[row] = children[i].req_height;
if (children[i].req_width > priv->col_widths[col])
priv->col_widths[col] = children[i].req_width;
if ( (children[i].flags & NMT_NEWT_GRID_EXPAND_X)
&& !priv->expand_cols[children[i].x]) {
priv->expand_cols[children[i].x] = TRUE;
priv->n_expand_cols++;
}
if ( (children[i].flags & NMT_NEWT_GRID_EXPAND_Y)
&& !priv->expand_rows[children[i].y]) {
priv->expand_rows[children[i].y] = TRUE;
priv->n_expand_rows++;
}
}
}
}
priv->req_height = priv->req_width = 0;
for (row = 0; row < priv->max_y + 1; row++)
priv->req_height += priv->row_heights[row];
for (col = 0; col < priv->max_x + 1; col++)
priv->req_width += priv->col_widths[col];
*height = priv->req_height;
*width = priv->req_width;
}
static void
nmt_newt_grid_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (widget);
NmtNewtGridChild *children = (NmtNewtGridChild *)priv->children->data, *child;
int i, row, col;
int child_x, child_y, child_width, child_height;
int extra, extra_all, extra_some;
extra = width - priv->req_width;
if (extra > 0 && priv->n_expand_cols) {
extra_all = extra / priv->n_expand_cols;
extra_some = extra % priv->n_expand_cols;
for (col = 0; col < priv->max_x + 1; col++) {
if (!priv->expand_cols[col])
continue;
priv->col_widths[col] += extra_all;
if (extra_some) {
priv->col_widths[col]++;
extra_some--;
}
}
}
extra = height - priv->req_height;
if (extra > 0 && priv->n_expand_rows) {
extra_all = extra / priv->n_expand_rows;
extra_some = extra % priv->n_expand_rows;
for (row = 0; row < priv->max_y + 1; row++) {
if (!priv->expand_rows[row])
continue;
priv->row_heights[row] += extra_all;
if (extra_some) {
priv->row_heights[row]++;
extra_some--;
}
}
}
for (i = 0; i < priv->children->len; i++) {
child = &children[i];
if (!nmt_newt_widget_get_visible (child->widget))
continue;
child_x = x;
for (col = 0; col < child->x; col++)
child_x += priv->col_widths[col];
if ((child->flags & NMT_NEWT_GRID_FILL_X) == NMT_NEWT_GRID_FILL_X) {
child_width = priv->col_widths[child->x];
} else {
child_width = child->req_width;
if (child->flags & NMT_NEWT_GRID_ANCHOR_RIGHT)
child_x += priv->col_widths[child->x] - child->req_width;
else if (!(child->flags & NMT_NEWT_GRID_ANCHOR_LEFT))
child_x += (priv->col_widths[child->x] - child->req_width) / 2;
}
child_y = y;
for (row = 0; row < child->y; row++)
child_y += priv->row_heights[row];
if ((child->flags & NMT_NEWT_GRID_FILL_Y) == NMT_NEWT_GRID_FILL_Y) {
child_height = priv->row_heights[child->y];
} else {
child_height = child->req_height;
if (child->flags & NMT_NEWT_GRID_ANCHOR_BOTTOM)
child_y += priv->row_heights[child->y] - child->req_height;
else if (!(child->flags & NMT_NEWT_GRID_ANCHOR_TOP))
child_y += (priv->row_heights[child->y] - child->req_height) / 2;
}
nmt_newt_widget_size_allocate (child->widget,
child_x, child_y,
child_width, child_height);
}
}
static void
nmt_newt_grid_find_size (NmtNewtGrid *grid)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (grid);
NmtNewtGridChild *children = (NmtNewtGridChild *)priv->children->data;
int i;
priv->max_x = priv->max_y = 0;
for (i = 0; i < priv->children->len; i++) {
if (children[i].x > priv->max_x)
priv->max_x = children[i].x;
if (children[i].y > priv->max_y)
priv->max_y = children[i].y;
}
}
/**
* nmt_newt_grid_add:
* @grid: an #NmtNewtGrid
* @widget: the widget to add
* @x: x coordinate
* @y: y coordinate
*
* Adds @widget to @grid at @x, @y. See the discussion above for more
* details of exactly how this works.
*/
void
nmt_newt_grid_add (NmtNewtGrid *grid,
NmtNewtWidget *widget,
int x,
int y)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (grid);
NmtNewtGridChild child;
NMT_NEWT_CONTAINER_CLASS (nmt_newt_grid_parent_class)->add (NMT_NEWT_CONTAINER (grid), widget);
memset (&child, 0, sizeof (child));
child.widget = widget;
child.x = x;
child.y = y;
child.flags = NMT_NEWT_GRID_FILL_X | NMT_NEWT_GRID_FILL_Y;
g_array_append_val (priv->children, child);
if (x > priv->max_x)
priv->max_x = x;
if (y > priv->max_y)
priv->max_y = y;
}
static int
find_child (NmtNewtGrid *grid,
NmtNewtWidget *widget)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (grid);
NmtNewtGridChild *children = (NmtNewtGridChild *)priv->children->data;
int i;
for (i = 0; i < priv->children->len; i++) {
if (children[i].widget == widget)
return i;
}
return -1;
}
static void
nmt_newt_grid_remove (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtNewtGrid *grid = NMT_NEWT_GRID (container);
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (grid);
int i;
i = find_child (grid, widget);
if (i != -1) {
g_array_remove_index (priv->children, i);
nmt_newt_grid_find_size (grid);
}
NMT_NEWT_CONTAINER_CLASS (nmt_newt_grid_parent_class)->remove (container, widget);
}
/**
* nmt_newt_grid_move:
* @grid: an #NmtNewtGrid
* @widget: a child of @grid
* @x: x coordinate
* @y: y coordinate
*
* Moves @widget to the given new coordinates.
*/
void
nmt_newt_grid_move (NmtNewtGrid *grid,
NmtNewtWidget *widget,
int x,
int y)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (grid);
NmtNewtGridChild *children = (NmtNewtGridChild *)priv->children->data;
int i;
i = find_child (grid, widget);
if (i != -1 && (children[i].x != x || children[i].y != y)) {
children[i].x = x;
children[i].y = y;
nmt_newt_grid_find_size (grid);
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (grid));
}
}
/**
* NmtNewtGridFlags:
* @NMT_NEWT_GRID_EXPAND_X: The widget's cell should expand
* horizontally if the grid as a whole is given more width than
* it requested.
* @NMT_NEWT_GRID_EXPAND_Y: The widget's cell should expand
* vertically if the grid as a whole is given more height than
* it requested.
* @NMT_NEWT_GRID_ANCHOR_LEFT: If the widget's cell is wider than
* the widget requested, the widget should be anchored to the
* left of its cell rather than being centered.
* @NMT_NEWT_GRID_ANCHOR_RIGHT: If the widget's cell is wider than
* the widget requested, the widget should be anchored to the
* right of its cell rather than being centered.
* @NMT_NEWT_GRID_FILL_X: If the widget's cell is wider than
* the widget requested, the widget should be allocated the
* full width of the cell; this is equivalent to specifying
* both %NMT_NEWT_GRID_ANCHOR_LEFT and %NMT_NEWT_GRID_ANCHOR_RIGHT.
* @NMT_NEWT_GRID_ANCHOR_TOP: If the widget's cell is taller than
* the widget requested, the widget should be anchored to the
* top of its cell rather than being centered.
* @NMT_NEWT_GRID_ANCHOR_BOTTOM: If the widget's cell is taller than
* the widget requested, the widget should be anchored to the
* bottom of its cell rather than being centered.
* @NMT_NEWT_GRID_FILL_Y: If the widget's cell is taller than
* the widget requested, the widget should be allocated the
* full height of the cell; this is equivalent to specifying
* both %NMT_NEWT_GRID_ANCHOR_TOP and %NMT_NEWT_GRID_ANCHOR_BOTTOM.
*
* Flags describing how a widget is placed within its grid cell.
*/
/**
* nmt_newt_grid_set_flags:
* @grid: an #NmtNewtGrid
* @widget: a child of @grid
* @flags: #NmtNewtGridFlags for @widget
*
* Sets the #NmtNewtGridFlags on @widget
*/
void
nmt_newt_grid_set_flags (NmtNewtGrid *grid,
NmtNewtWidget *widget,
NmtNewtGridFlags flags)
{
NmtNewtGridPrivate *priv = NMT_NEWT_GRID_GET_PRIVATE (grid);
NmtNewtGridChild *children = (NmtNewtGridChild *)priv->children->data;
int i;
i = find_child (grid, widget);
if (i != -1)
children[i].flags = flags;
}
static void
nmt_newt_grid_class_init (NmtNewtGridClass *grid_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (grid_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (grid_class);
NmtNewtContainerClass *container_class = NMT_NEWT_CONTAINER_CLASS (grid_class);
g_type_class_add_private (grid_class, sizeof (NmtNewtGridPrivate));
/* virtual methods */
object_class->finalize = nmt_newt_grid_finalize;
widget_class->get_components = nmt_newt_grid_get_components;
widget_class->size_request = nmt_newt_grid_size_request;
widget_class->size_allocate = nmt_newt_grid_size_allocate;
container_class->remove = nmt_newt_grid_remove;
}

72
tui/newt/nmt-newt-grid.h Normal file
View File

@@ -0,0 +1,72 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_GRID_H
#define NMT_NEWT_GRID_H
#include "nmt-newt-container.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_GRID (nmt_newt_grid_get_type ())
#define NMT_NEWT_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_GRID, NmtNewtGrid))
#define NMT_NEWT_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_GRID, NmtNewtGridClass))
#define NMT_IS_NEWT_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_GRID))
#define NMT_IS_NEWT_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_GRID))
#define NMT_NEWT_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_GRID, NmtNewtGridClass))
struct _NmtNewtGrid {
NmtNewtContainer parent;
};
typedef struct {
NmtNewtContainerClass parent;
} NmtNewtGridClass;
GType nmt_newt_grid_get_type (void);
typedef enum {
NMT_NEWT_GRID_EXPAND_X = (1 << 0),
NMT_NEWT_GRID_EXPAND_Y = (1 << 1),
NMT_NEWT_GRID_ANCHOR_LEFT = (1 << 2),
NMT_NEWT_GRID_ANCHOR_RIGHT = (1 << 3),
NMT_NEWT_GRID_FILL_X = NMT_NEWT_GRID_ANCHOR_LEFT | NMT_NEWT_GRID_ANCHOR_RIGHT,
NMT_NEWT_GRID_ANCHOR_TOP = (1 << 4),
NMT_NEWT_GRID_ANCHOR_BOTTOM = (1 << 5),
NMT_NEWT_GRID_FILL_Y = NMT_NEWT_GRID_ANCHOR_TOP | NMT_NEWT_GRID_ANCHOR_BOTTOM,
} NmtNewtGridFlags;
NmtNewtWidget *nmt_newt_grid_new (void);
void nmt_newt_grid_add (NmtNewtGrid *grid,
NmtNewtWidget *widget,
int x,
int y);
void nmt_newt_grid_move (NmtNewtGrid *grid,
NmtNewtWidget *widget,
int x,
int y);
void nmt_newt_grid_set_flags (NmtNewtGrid *grid,
NmtNewtWidget *widget,
NmtNewtGridFlags flags);
G_END_DECLS
#endif /* NMT_NEWT_GRID_H */

103
tui/newt/nmt-newt-hacks.c Normal file
View File

@@ -0,0 +1,103 @@
/* -*- 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-newt-hacks
* @short_description: Hacks!
*
* This contains hacky cheating implementations of certain newt
* functions that were added after 0.52.15.
*/
#include "config.h"
#include "nmt-newt-hacks.h"
#if !defined (HAVE_NEWTCOMPONENTGETSIZE) || !defined (HAVE_NEWTENTRYGETCURSORPOSITION)
struct newtComponent_0_52_15_struct_hack {
int height, width;
int top, left;
int takesFocus;
int isMapped;
struct componentOps *ops;
newtCallback callback;
void *callbackData;
newtCallback destroyCallback;
void *destroyCallbackData;
void *data;
};
#endif
#ifndef HAVE_NEWTCOMPONENTGETSIZE
void
newtComponentGetSize (newtComponent component,
int *width,
int *height)
{
struct newtComponent_0_52_15_struct_hack *hack = (void *) component;
*width = hack->width;
*height = hack->height;
}
void
newtComponentGetPosition (newtComponent component,
int *left,
int *top)
{
struct newtComponent_0_52_15_struct_hack *hack = (void *) component;
*left = hack->left;
*top = hack->top;
}
#endif
#ifndef HAVE_NEWTENTRYGETCURSORPOSITION
struct newtEntry_0_52_15_struct_hack {
int flags;
char *buf;
const char **resultPtr;
int bufAlloced;
int bufUsed;
int cursorPosition;
/* ... */
};
int
newtEntryGetCursorPosition (newtComponent component)
{
struct newtComponent_0_52_15_struct_hack *co_hack = (void *) component;
struct newtEntry_0_52_15_struct_hack *entry_hack = co_hack->data;
return entry_hack->cursorPosition;
}
void
newtEntrySetCursorPosition (newtComponent component,
int position)
{
struct newtComponent_0_52_15_struct_hack *co_hack = (void *) component;
struct newtEntry_0_52_15_struct_hack *entry_hack = co_hack->data;
entry_hack->cursorPosition = position;
}
#endif

42
tui/newt/nmt-newt-hacks.h Normal file
View File

@@ -0,0 +1,42 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_HACKS_H
#define NMT_NEWT_HACKS_H
#include "config.h"
#include <newt.h>
#ifndef HAVE_NEWTCOMPONENTGETSIZE
void newtComponentGetSize (newtComponent component,
int *width,
int *height);
void newtComponentGetPosition (newtComponent component,
int *left,
int *top);
#endif
#ifndef HAVE_NEWTENTRYGETCURSORPOSITION
int newtEntryGetCursorPosition (newtComponent component);
void newtEntrySetCursorPosition (newtComponent component,
int position);
#endif
#endif /* NMT_NEWT_HACKS_H */

323
tui/newt/nmt-newt-label.c Normal file
View File

@@ -0,0 +1,323 @@
/* -*- 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-newt-label
* @short_description: Labels
*
* #NmtNewtLabel implements a single-line label.
*
* See also #NmtNewtTextbox, for multiline.
*/
#include "config.h"
#include <string.h>
#include "nmt-newt-label.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtLabel, nmt_newt_label, NMT_TYPE_NEWT_COMPONENT)
#define NMT_NEWT_LABEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_LABEL, NmtNewtLabelPrivate))
typedef struct {
char *text;
NmtNewtLabelStyle style;
gboolean highlight;
} NmtNewtLabelPrivate;
enum {
PROP_0,
PROP_TEXT,
PROP_STYLE,
PROP_HIGHLIGHT,
LAST_PROP
};
/**
* nmt_newt_label_new:
* @text: the initial label text
*
* Creates a new #NmtNewtLabel
*
* Returns: a new #NmtNewtLabel
*/
NmtNewtWidget *
nmt_newt_label_new (const char *text)
{
return g_object_new (NMT_TYPE_NEWT_LABEL,
"text", text,
NULL);
}
/**
* nmt_newt_label_set_text:
* @label: an #NmtNewtLabel
* @text: the new text
*
* Updates @label's text.
*/
void
nmt_newt_label_set_text (NmtNewtLabel *label,
const char *text)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (label);
if (!g_strcmp0 (priv->text, text))
return;
g_free (priv->text);
priv->text = g_strdup (text);
g_object_notify (G_OBJECT (label), "text");
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (label));
}
/**
* nmt_newt_label_get_text:
* @label: an #NmtNewtLabel
*
* Gets @label's text
*
* Returns: @label's text
*/
const char *
nmt_newt_label_get_text (NmtNewtLabel *label)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (label);
return priv->text;
}
/**
* NmtNewtLabelStyle:
* @NMT_NEWT_LABEL_NORMAL: a normal label
* @NMT_NEWT_LABEL_PLAIN: a "plain-looking" label
*
* The label style. Normal labels are blue. Plain labels are black,
* making them look more like they are text in their own right rather
* than just being a label for something else.
*/
/**
* nmt_newt_label_set_style:
* @label: an #NmtNewtLabel
* @style: the #NmtNewtLabelStyle
*
* Sets the style of @label
*/
void
nmt_newt_label_set_style (NmtNewtLabel *label,
NmtNewtLabelStyle style)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (label);
if (priv->style == style)
return;
priv->style = style;
g_object_notify (G_OBJECT (label), "style");
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (label));
}
/**
* nmt_newt_label_get_style:
* @label: an #NmtNewtLabel
*
* Gets the style of @label
*
* Returns: the style of @label
*/
NmtNewtLabelStyle
nmt_newt_label_get_style (NmtNewtLabel *label)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (label);
return priv->style;
}
/**
* nmt_newt_label_set_highlight:
* @label: an #NmtNewtLabel
* @highlight: %TRUE if @label should be highlighted
*
* Sets whether @label is highlighted. Highlighted labels are red;
* this is generally used to highlight invalid widgets.
*/
void
nmt_newt_label_set_highlight (NmtNewtLabel *label,
gboolean highlight)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (label);
highlight = !!highlight;
if (priv->highlight == highlight)
return;
priv->highlight = highlight;
g_object_notify (G_OBJECT (label), "highlight");
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (label));
}
/**
* nmt_newt_label_get_highlight:
* @label: an #NmtNewtLabel
*
* Gets whether @label is highlighted.
*
* Returns: whether @label is highlighted.
*/
gboolean
nmt_newt_label_get_highlight (NmtNewtLabel *label)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (label);
return priv->highlight;
}
static void
nmt_newt_label_init (NmtNewtLabel *label)
{
}
static void
nmt_newt_label_finalize (GObject *object)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (object);
g_free (priv->text);
G_OBJECT_CLASS (nmt_newt_label_parent_class)->finalize (object);
}
static newtComponent
nmt_newt_label_build_component (NmtNewtComponent *component,
gboolean sensitive)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (component);
newtComponent co;
char *text_lc;
text_lc = nmt_newt_locale_from_utf8 (priv->text);
co = newtLabel (-1, -1, text_lc);
g_free (text_lc);
if (priv->highlight)
newtLabelSetColors (co, NMT_NEWT_COLORSET_BAD_LABEL);
else if (priv->style == NMT_NEWT_LABEL_PLAIN)
newtLabelSetColors (co, NMT_NEWT_COLORSET_PLAIN_LABEL);
return co;
}
static void
nmt_newt_label_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtLabel *label = NMT_NEWT_LABEL (object);
switch (prop_id) {
case PROP_TEXT:
nmt_newt_label_set_text (label, g_value_get_string (value));
break;
case PROP_STYLE:
nmt_newt_label_set_style (label, g_value_get_int (value));
break;
case PROP_HIGHLIGHT:
nmt_newt_label_set_highlight (label, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_label_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtLabelPrivate *priv = NMT_NEWT_LABEL_GET_PRIVATE (object);
switch (prop_id) {
case PROP_TEXT:
g_value_set_string (value, priv->text);
break;
case PROP_STYLE:
g_value_set_int (value, priv->style);
break;
case PROP_HIGHLIGHT:
g_value_set_boolean (value, priv->highlight);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_label_class_init (NmtNewtLabelClass *label_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (label_class);
NmtNewtComponentClass *component_class = NMT_NEWT_COMPONENT_CLASS (label_class);
g_type_class_add_private (label_class, sizeof (NmtNewtLabelPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_label_set_property;
object_class->get_property = nmt_newt_label_get_property;
object_class->finalize = nmt_newt_label_finalize;
component_class->build_component = nmt_newt_label_build_component;
/**
* NmtNewtLabel:text:
*
* The label's text
*/
g_object_class_install_property (object_class, PROP_TEXT,
g_param_spec_string ("text", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtLabel:style:
*
* The label's #NmtNewtLabelStyle
*/
g_object_class_install_property (object_class, PROP_STYLE,
g_param_spec_int ("style", "", "",
0, G_MAXINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtLabel:highlight:
*
* Whether the label is highlighted.
*/
g_object_class_install_property (object_class, PROP_HIGHLIGHT,
g_param_spec_boolean ("highlight", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

66
tui/newt/nmt-newt-label.h Normal file
View File

@@ -0,0 +1,66 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_LABEL_H
#define NMT_NEWT_LABEL_H
#include "nmt-newt-component.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_LABEL (nmt_newt_label_get_type ())
#define NMT_NEWT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_LABEL, NmtNewtLabel))
#define NMT_NEWT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_LABEL, NmtNewtLabelClass))
#define NMT_IS_NEWT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_LABEL))
#define NMT_IS_NEWT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_LABEL))
#define NMT_NEWT_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_LABEL, NmtNewtLabelClass))
struct _NmtNewtLabel {
NmtNewtComponent parent;
};
typedef struct {
NmtNewtComponentClass parent;
} NmtNewtLabelClass;
GType nmt_newt_label_get_type (void);
typedef enum {
NMT_NEWT_LABEL_NORMAL,
NMT_NEWT_LABEL_PLAIN
} NmtNewtLabelStyle;
NmtNewtWidget *nmt_newt_label_new (const char *text);
void nmt_newt_label_set_text (NmtNewtLabel *label,
const char *text);
const char *nmt_newt_label_get_text (NmtNewtLabel *label);
void nmt_newt_label_set_style (NmtNewtLabel *label,
NmtNewtLabelStyle style);
NmtNewtLabelStyle nmt_newt_label_get_style (NmtNewtLabel *label);
void nmt_newt_label_set_highlight (NmtNewtLabel *label,
gboolean highlight);
gboolean nmt_newt_label_get_highlight (NmtNewtLabel *label);
G_END_DECLS
#endif /* NMT_NEWT_LABEL_H */

539
tui/newt/nmt-newt-listbox.c Normal file
View File

@@ -0,0 +1,539 @@
/* -*- 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-newt-listbox
* @short_description: Single-choice listboxes
*
* #NmtNewtListbox implements a single-choice listbox.
*
* A listbox has some number of rows, each associated with an
* arbitrary pointer value. The pointer values do not need to be
* unique, but some APIs will not be usable if they aren't. You
* can also cause rows with %NULL keys to be treated specially.
*
* The listbox will emit #NmtNewtWidget::activate when the user
* presses Return on a selection.
*/
#include "config.h"
#include "nmt-newt-listbox.h"
#include "nmt-newt-form.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtListbox, nmt_newt_listbox, NMT_TYPE_NEWT_COMPONENT)
#define NMT_NEWT_LISTBOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_LISTBOX, NmtNewtListboxPrivate))
typedef struct {
int height, alloc_height, width;
gboolean fixed_height;
NmtNewtListboxFlags flags;
GPtrArray *entries;
GPtrArray *keys;
int active;
gpointer active_key;
gboolean skip_null_keys;
} NmtNewtListboxPrivate;
enum {
PROP_0,
PROP_HEIGHT,
PROP_FLAGS,
PROP_ACTIVE,
PROP_ACTIVE_KEY,
PROP_SKIP_NULL_KEYS,
LAST_PROP
};
/**
* NmtNewtListboxFlags:
* @NMT_NEWT_LISTBOX_SCROLL: the listbox should have a scroll bar.
* @NMT_NEWT_LISTBOX_BORDER: the listbox should have a border around it.
*
* Flags describing an #NmtNewtListbox
*/
/**
* nmt_newt_listbox_new:
* @height: the height of the listbox, or -1 for no fixed height
* @flags: the listbox flags
*
* Creates a new #NmtNewtListbox
*
* Returns: a new #NmtNewtListbox
*/
NmtNewtWidget *
nmt_newt_listbox_new (int height,
NmtNewtListboxFlags flags)
{
return g_object_new (NMT_TYPE_NEWT_LISTBOX,
"height", height,
"flags", flags,
NULL);
}
/**
* nmt_newt_listbox_append:
* @listbox: an #NmtNewtListbox
* @entry: the text for the new row
* @key: (allow-none): the key associated with @entry
*
* Adds a row to @listbox.
*/
void
nmt_newt_listbox_append (NmtNewtListbox *listbox,
const char *entry,
gpointer key)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
g_ptr_array_add (priv->entries, nmt_newt_locale_from_utf8 (entry));
g_ptr_array_add (priv->keys, key);
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (listbox));
}
/**
* nmt_newt_listbox_clear:
* @listbox: an #NmtNewtListbox
*
* Clears the contents of @listbox.
*/
void
nmt_newt_listbox_clear (NmtNewtListbox *listbox)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
g_ptr_array_set_size (priv->entries, 0);
g_ptr_array_set_size (priv->keys, 0);
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (listbox));
}
/**
* nmt_newt_listbox_set_active:
* @listbox: an #NmtNewtListbox
* @active: the row to make active
*
* Sets @active to be the currently-selected row in @listbox,
* scrolling it into view if needed.
*/
void
nmt_newt_listbox_set_active (NmtNewtListbox *listbox,
int active)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
if (active == priv->active)
return;
g_return_if_fail (active >= 0 && active < priv->entries->len);
g_return_if_fail (!priv->skip_null_keys || priv->keys->pdata[active]);
priv->active = active;
priv->active_key = priv->keys->pdata[active];
g_object_notify (G_OBJECT (listbox), "active");
g_object_notify (G_OBJECT (listbox), "active-key");
}
/**
* nmt_newt_listbox_set_active_key:
* @listbox: an #NmtNewtListbox
* @active_key: the key for the row to make active
*
* Selects the (first) row in @listbox with @active_key as its key,
* scrolling it into view if needed.
*/
void
nmt_newt_listbox_set_active_key (NmtNewtListbox *listbox,
gpointer active_key)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
int i;
if (active_key == priv->active_key)
return;
g_return_if_fail (!priv->skip_null_keys || active_key);
for (i = 0; i < priv->keys->len; i++) {
if (priv->keys->pdata[i] == active_key) {
priv->active = i;
priv->active_key = active_key;
g_object_notify (G_OBJECT (listbox), "active");
g_object_notify (G_OBJECT (listbox), "active-key");
return;
}
}
}
/**
* nmt_newt_listbox_get_active:
* @listbox: an #NmtNewtListbox
*
* Gets the currently-selected row in @listbox.
*
* Returns: the currently-selected row in @listbox.
*/
int
nmt_newt_listbox_get_active (NmtNewtListbox *listbox)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
return priv->active;
}
/**
* nmt_newt_listbox_get_active_key:
* @listbox: an #NmtNewtListbox
*
* Gets the key of the currently-selected row in @listbox.
*
* Returns: the key of the currently-selected row in @listbox.
*/
gpointer
nmt_newt_listbox_get_active_key (NmtNewtListbox *listbox)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
return priv->active_key;
}
/**
* nmt_newt_listbox_set_height:
* @listbox: an #NmtNewtListbox
* @height: the new height, or -1 for no fixed heigh
*
* Updates @listbox's height.
*/
void
nmt_newt_listbox_set_height (NmtNewtListbox *listbox,
int height)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
priv->height = height;
priv->fixed_height = priv->height != 0;
g_object_notify (G_OBJECT (listbox), "height");
}
static void
nmt_newt_listbox_init (NmtNewtListbox *listbox)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
priv->entries = g_ptr_array_new_with_free_func (g_free);
priv->keys = g_ptr_array_new ();
priv->active = -1;
}
static void
nmt_newt_listbox_finalize (GObject *object)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (object);
g_ptr_array_unref (priv->entries);
g_ptr_array_unref (priv->keys);
G_OBJECT_CLASS (nmt_newt_listbox_parent_class)->finalize (object);
}
static void
nmt_newt_listbox_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (widget);
NMT_NEWT_WIDGET_CLASS (nmt_newt_listbox_parent_class)->
size_request (widget, width, height);
priv->alloc_height = -1;
if (!priv->fixed_height)
*height = 1;
priv->width = *width;
}
static void
nmt_newt_listbox_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (widget);
if (width > priv->width) {
newtListboxSetWidth (nmt_newt_component_get_component (NMT_NEWT_COMPONENT (widget)),
width);
}
NMT_NEWT_WIDGET_CLASS (nmt_newt_listbox_parent_class)->
size_allocate (widget, x, y, width, height);
priv->alloc_height = height;
if (!priv->fixed_height && height != priv->height) {
priv->height = height;
nmt_newt_widget_needs_rebuild (widget);
}
}
static void
update_active_internal (NmtNewtListbox *listbox,
int new_active)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
if (priv->active == new_active)
return;
if (new_active >= priv->keys->len)
return;
if (priv->skip_null_keys && !priv->keys->pdata[new_active]) {
if (new_active > priv->active) {
while ( new_active < priv->entries->len
&& !priv->keys->pdata[new_active])
new_active++;
} else {
while ( new_active >= 0
&& !priv->keys->pdata[new_active])
new_active--;
}
if ( new_active < 0
|| new_active >= priv->entries->len
|| !priv->keys->pdata[new_active]) {
g_assert (priv->active >= 0 && priv->active < priv->entries->len);
return;
}
}
nmt_newt_listbox_set_active (listbox, new_active);
}
static void
selection_changed_callback (newtComponent co,
void *user_data)
{
NmtNewtListbox *listbox = user_data;
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (listbox);
int new_active;
new_active = GPOINTER_TO_UINT (newtListboxGetCurrent (co));
update_active_internal (listbox, new_active);
if (priv->active != new_active)
newtListboxSetCurrent (co, priv->active);
}
static guint
convert_flags (NmtNewtListboxFlags flags)
{
guint newt_flags = NEWT_FLAG_RETURNEXIT;
if (flags & NMT_NEWT_LISTBOX_SCROLL)
newt_flags |= NEWT_FLAG_SCROLL;
if (flags & NMT_NEWT_LISTBOX_BORDER)
newt_flags |= NEWT_FLAG_BORDER;
return newt_flags;
}
static newtComponent
nmt_newt_listbox_build_component (NmtNewtComponent *component,
gboolean sensitive)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (component);
newtComponent co;
int i, active;
if (priv->active == -1)
update_active_internal (NMT_NEWT_LISTBOX (component), 0);
active = priv->active;
co = newtListbox (-1, -1, priv->height, convert_flags (priv->flags));
newtComponentAddCallback (co, selection_changed_callback, component);
for (i = 0; i < priv->entries->len; i++) {
newtListboxAppendEntry (co, priv->entries->pdata[i], GUINT_TO_POINTER (i));
if (active == -1 && priv->keys->pdata[i] == priv->active_key)
active = i;
}
if (active != -1)
newtListboxSetCurrent (co, active);
return co;
}
static void
nmt_newt_listbox_activated (NmtNewtWidget *widget)
{
NmtNewtListbox *listbox = NMT_NEWT_LISTBOX (widget);
newtComponent co = nmt_newt_component_get_component (NMT_NEWT_COMPONENT (widget));
nmt_newt_listbox_set_active (listbox, GPOINTER_TO_UINT (newtListboxGetCurrent (co)));
NMT_NEWT_WIDGET_CLASS (nmt_newt_listbox_parent_class)->activated (widget);
}
static void
nmt_newt_listbox_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtListbox *listbox = NMT_NEWT_LISTBOX (object);
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (object);
switch (prop_id) {
case PROP_HEIGHT:
priv->height = g_value_get_int (value);
priv->fixed_height = (priv->height != 0);
break;
case PROP_FLAGS:
priv->flags = g_value_get_uint (value);
break;
case PROP_ACTIVE:
nmt_newt_listbox_set_active (listbox, g_value_get_int (value));
break;
case PROP_ACTIVE_KEY:
nmt_newt_listbox_set_active_key (listbox, g_value_get_pointer (value));
break;
case PROP_SKIP_NULL_KEYS:
priv->skip_null_keys = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_listbox_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (object);
switch (prop_id) {
case PROP_HEIGHT:
g_value_set_int (value, priv->height);
break;
case PROP_FLAGS:
g_value_set_uint (value, priv->flags);
break;
case PROP_ACTIVE:
g_value_set_int (value, priv->active);
break;
case PROP_ACTIVE_KEY:
g_value_set_pointer (value, priv->active_key);
break;
case PROP_SKIP_NULL_KEYS:
g_value_set_boolean (value, priv->skip_null_keys);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_listbox_class_init (NmtNewtListboxClass *listbox_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (listbox_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (listbox_class);
NmtNewtComponentClass *component_class = NMT_NEWT_COMPONENT_CLASS (listbox_class);
g_type_class_add_private (listbox_class, sizeof (NmtNewtListboxPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_listbox_set_property;
object_class->get_property = nmt_newt_listbox_get_property;
object_class->finalize = nmt_newt_listbox_finalize;
widget_class->size_request = nmt_newt_listbox_size_request;
widget_class->size_allocate = nmt_newt_listbox_size_allocate;
widget_class->activated = nmt_newt_listbox_activated;
component_class->build_component = nmt_newt_listbox_build_component;
/* properties */
/**
* NmtNewtListbox:height:
*
* The listbox's height, or -1 if it has no fixed height.
*/
g_object_class_install_property (object_class, PROP_HEIGHT,
g_param_spec_int ("height", "", "",
-1, 255, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtListbox:flags:
*
* The listbox's #NmtNewtListboxFlags.
*/
g_object_class_install_property (object_class, PROP_FLAGS,
g_param_spec_uint ("flags", "", "",
0, 0xFFFF, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtListbox:active:
*
* The currently-selected row.
*/
g_object_class_install_property (object_class, PROP_ACTIVE,
g_param_spec_int ("active", "", "",
0, G_MAXINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtListbox:active-key:
*
* The key of the currently-selected row.
*/
g_object_class_install_property (object_class, PROP_ACTIVE_KEY,
g_param_spec_pointer ("active-key", "", "",
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtListbox:skip-null-keys:
*
* If %TRUE, rows with %NULL key values will be skipped over when
* navigating the list with the arrow keys.
*/
g_object_class_install_property (object_class, PROP_SKIP_NULL_KEYS,
g_param_spec_boolean ("skip-null-keys", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -0,0 +1,71 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_LISTBOX_H
#define NMT_NEWT_LISTBOX_H
#include "nmt-newt-component.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_LISTBOX (nmt_newt_listbox_get_type ())
#define NMT_NEWT_LISTBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_LISTBOX, NmtNewtListbox))
#define NMT_NEWT_LISTBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_LISTBOX, NmtNewtListboxClass))
#define NMT_IS_NEWT_LISTBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_LISTBOX))
#define NMT_IS_NEWT_LISTBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_LISTBOX))
#define NMT_NEWT_LISTBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_LISTBOX, NmtNewtListboxClass))
struct _NmtNewtListbox {
NmtNewtComponent parent;
};
typedef struct {
NmtNewtComponentClass parent;
} NmtNewtListboxClass;
GType nmt_newt_listbox_get_type (void);
typedef enum {
NMT_NEWT_LISTBOX_SCROLL = (1 << 0),
NMT_NEWT_LISTBOX_BORDER = (1 << 1)
} NmtNewtListboxFlags;
NmtNewtWidget *nmt_newt_listbox_new (int height,
NmtNewtListboxFlags flags);
void nmt_newt_listbox_set_height (NmtNewtListbox *listbox,
int active);
void nmt_newt_listbox_append (NmtNewtListbox *listbox,
const char *entry,
gpointer key);
void nmt_newt_listbox_clear (NmtNewtListbox *listbox);
void nmt_newt_listbox_set_active (NmtNewtListbox *listbox,
int active);
void nmt_newt_listbox_set_active_key (NmtNewtListbox *listbox,
gpointer active_key);
int nmt_newt_listbox_get_active (NmtNewtListbox *listbox);
gpointer nmt_newt_listbox_get_active_key (NmtNewtListbox *listbox);
G_END_DECLS
#endif /* NMT_NEWT_LISTBOX_H */

343
tui/newt/nmt-newt-popup.c Normal file
View File

@@ -0,0 +1,343 @@
/* -*- 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-newt-popup
* @short_description: Pop-up menus
*
* #NmtNewtPopup implements a pop-up menu. When inactive, they appear
* the same as #NmtNewtButtons, displaying the label from the
* #NmtNewtPopup:active entry. When activated, they pop up a temporary
* #NmtNewtForm containing an #NmtNewtListbox to select from.
*/
#include "config.h"
#include <glib/gi18n-lib.h>
#include "nmt-newt-popup.h"
#include "nmt-newt-form.h"
#include "nmt-newt-hacks.h"
#include "nmt-newt-listbox.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtPopup, nmt_newt_popup, NMT_TYPE_NEWT_BUTTON)
#define NMT_NEWT_POPUP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_POPUP, NmtNewtPopupPrivate))
typedef struct {
GArray *entries;
int active;
} NmtNewtPopupPrivate;
enum {
PROP_0,
PROP_ACTIVE,
PROP_ACTIVE_ID,
LAST_PROP
};
/**
* NmtNewtPopupEntry:
* @label: the user-visible label for the entry
* @id: the internal ID of the entry
*
* A single entry in a pop-up menu.
*/
/**
* nmt_newt_popup_new:
* @entries: an array of #NmtNewtPopupEntry, terminated by an
* entry with a %NULL label
*
* Creates a new #NmtNewtPopup with the given entries.
*
* Returns: a new #NmtNewtPopup
*/
NmtNewtWidget *
nmt_newt_popup_new (NmtNewtPopupEntry *entries)
{
NmtNewtWidget *widget;
NmtNewtPopupPrivate *priv;
int i;
widget = g_object_new (NMT_TYPE_NEWT_POPUP, NULL);
priv = NMT_NEWT_POPUP_GET_PRIVATE (widget);
for (i = 0; entries[i].label; i++) {
NmtNewtPopupEntry entry;
entry.label = nmt_newt_locale_from_utf8 (_(entries[i].label));
entry.id = g_strdup (entries[i].id);
g_array_append_val (priv->entries, entry);
}
return widget;
}
static void
popup_entry_clear_func (NmtNewtPopupEntry *entry)
{
g_free (entry->label);
g_free (entry->id);
}
static void
nmt_newt_popup_init (NmtNewtPopup *popup)
{
NmtNewtPopupPrivate *priv = NMT_NEWT_POPUP_GET_PRIVATE (popup);
priv->entries = g_array_sized_new (FALSE, FALSE, sizeof (NmtNewtPopupEntry), 10);
g_array_set_clear_func (priv->entries, (GDestroyNotify) popup_entry_clear_func);
}
static void
nmt_newt_popup_finalize (GObject *object)
{
NmtNewtPopupPrivate *priv = NMT_NEWT_POPUP_GET_PRIVATE (object);
g_array_unref (priv->entries);
G_OBJECT_CLASS (nmt_newt_popup_parent_class)->finalize (object);
}
static newtComponent
nmt_newt_popup_build_component (NmtNewtComponent *component,
gboolean sensitive)
{
NmtNewtPopupPrivate *priv = NMT_NEWT_POPUP_GET_PRIVATE (component);
NmtNewtPopupEntry *entries = (NmtNewtPopupEntry *)priv->entries->data;
nmt_newt_button_set_label (NMT_NEWT_BUTTON (component),
entries[priv->active].label);
return NMT_NEWT_COMPONENT_CLASS (nmt_newt_popup_parent_class)->
build_component (component, sensitive);
}
static void
nmt_newt_popup_activated (NmtNewtWidget *widget)
{
NmtNewtPopupPrivate *priv = NMT_NEWT_POPUP_GET_PRIVATE (widget);
NmtNewtPopupEntry *entries = (NmtNewtPopupEntry *)priv->entries->data;
NmtNewtForm *form;
NmtNewtWidget *listbox, *ret;
int button_x, button_y;
int window_x, window_y;
int list_w, list_h;
int i, active;
listbox = nmt_newt_listbox_new (priv->entries->len, 0);
nmt_newt_widget_set_exit_on_activate (listbox, TRUE);
for (i = 0; i < priv->entries->len; i++)
nmt_newt_listbox_append (NMT_NEWT_LISTBOX (listbox), entries[i].label, NULL);
nmt_newt_listbox_set_active (NMT_NEWT_LISTBOX (listbox), priv->active);
nmt_newt_widget_size_request (listbox, &list_w, &list_h);
newtComponentGetPosition (nmt_newt_component_get_component (NMT_NEWT_COMPONENT (widget)),
&button_x, &button_y);
window_x = button_x + 4;
window_y = button_y + 2 - priv->active;
form = g_object_new (NMT_TYPE_NEWT_FORM,
"x", window_x,
"y", window_y,
"width", list_w,
"height", list_h,
"padding", 0,
"escape-exits", TRUE,
NULL);
nmt_newt_form_set_content (form, listbox);
ret = nmt_newt_form_run_sync (form);
if (ret == listbox)
active = nmt_newt_listbox_get_active (NMT_NEWT_LISTBOX (listbox));
else
active = priv->active;
g_object_unref (form);
if (active != priv->active) {
priv->active = active;
g_object_notify (G_OBJECT (widget), "active");
g_object_notify (G_OBJECT (widget), "active-id");
nmt_newt_widget_needs_rebuild (widget);
}
NMT_NEWT_WIDGET_CLASS (nmt_newt_popup_parent_class)->activated (widget);
}
/**
* nmt_newt_popup_get_active:
* @popup: a #NmtNewtPopup
*
* Gets the index of the active entry in @popup.
*
* Returns: the index of the active entry in @popup.
*/
int
nmt_newt_popup_get_active (NmtNewtPopup *popup)
{
NmtNewtPopupPrivate *priv = NMT_NEWT_POPUP_GET_PRIVATE (popup);
return priv->active;
}
/**
* nmt_newt_popup_set_active:
* @popup: a #NmtNewtPopup
* @active: the index of the new active entry
*
* Sets the active entry in @popup.
*/
void
nmt_newt_popup_set_active (NmtNewtPopup *popup,
int active)
{
NmtNewtPopupPrivate *priv = NMT_NEWT_POPUP_GET_PRIVATE (popup);
active = CLAMP (active, 0, priv->entries->len - 1);
if (active != priv->active) {
priv->active = active;
g_object_notify (G_OBJECT (popup), "active");
g_object_notify (G_OBJECT (popup), "active-id");
}
}
/**
* nmt_newt_popup_get_active_id:
* @popup: a #NmtNewtPopup
*
* Gets the textual ID of the active entry in @popup.
*
* Returns: the ID of the active entry in @popup.
*/
const char *
nmt_newt_popup_get_active_id (NmtNewtPopup *popup)
{
NmtNewtPopupPrivate *priv = NMT_NEWT_POPUP_GET_PRIVATE (popup);
NmtNewtPopupEntry *entries = (NmtNewtPopupEntry *)priv->entries->data;
return entries[priv->active].id;
}
/**
* nmt_newt_popup_set_active_id:
* @popup: a #NmtNewtPopup
* @active_id: the ID of the new active entry
*
* Sets the active entry in @popup.
*/
void
nmt_newt_popup_set_active_id (NmtNewtPopup *popup,
const char *active_id)
{
NmtNewtPopupPrivate *priv = NMT_NEWT_POPUP_GET_PRIVATE (popup);
NmtNewtPopupEntry *entries = (NmtNewtPopupEntry *)priv->entries->data;
int i;
for (i = 0; i < priv->entries->len; i++) {
if (!g_strcmp0 (active_id, entries[i].id)) {
nmt_newt_popup_set_active (popup, i);
return;
}
}
}
static void
nmt_newt_popup_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtPopup *popup = NMT_NEWT_POPUP (object);
switch (prop_id) {
case PROP_ACTIVE:
nmt_newt_popup_set_active (popup, g_value_get_uint (value));
break;
case PROP_ACTIVE_ID:
nmt_newt_popup_set_active_id (popup, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_popup_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtPopup *popup = NMT_NEWT_POPUP (object);
switch (prop_id) {
case PROP_ACTIVE:
g_value_set_uint (value, nmt_newt_popup_get_active (popup));
break;
case PROP_ACTIVE_ID:
g_value_set_string (value, nmt_newt_popup_get_active_id (popup));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_popup_class_init (NmtNewtPopupClass *popup_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (popup_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (popup_class);
NmtNewtComponentClass *component_class = NMT_NEWT_COMPONENT_CLASS (popup_class);
g_type_class_add_private (popup_class, sizeof (NmtNewtPopupPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_popup_set_property;
object_class->get_property = nmt_newt_popup_get_property;
object_class->finalize = nmt_newt_popup_finalize;
widget_class->activated = nmt_newt_popup_activated;
component_class->build_component = nmt_newt_popup_build_component;
/**
* NmtNewtPopup:active:
*
* The index of the currently-active entry.
*/
g_object_class_install_property (object_class, PROP_ACTIVE,
g_param_spec_uint ("active", "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtPopup:active-id:
*
* The textual ID of the currently-active entry.
*/
g_object_class_install_property (object_class, PROP_ACTIVE_ID,
g_param_spec_string ("active-id", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

62
tui/newt/nmt-newt-popup.h Normal file
View File

@@ -0,0 +1,62 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_POPUP_H
#define NMT_NEWT_POPUP_H
#include "nmt-newt-button.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_POPUP (nmt_newt_popup_get_type ())
#define NMT_NEWT_POPUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_POPUP, NmtNewtPopup))
#define NMT_NEWT_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_POPUP, NmtNewtPopupClass))
#define NMT_IS_NEWT_POPUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_POPUP))
#define NMT_IS_NEWT_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_POPUP))
#define NMT_NEWT_POPUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_POPUP, NmtNewtPopupClass))
struct _NmtNewtPopup {
NmtNewtButton parent;
};
typedef struct {
NmtNewtButtonClass parent;
} NmtNewtPopupClass;
GType nmt_newt_popup_get_type (void);
typedef struct {
char *label;
char *id;
} NmtNewtPopupEntry;
NmtNewtWidget *nmt_newt_popup_new (NmtNewtPopupEntry *entries);
int nmt_newt_popup_get_active (NmtNewtPopup *popup);
void nmt_newt_popup_set_active (NmtNewtPopup *popup,
int active);
const char *nmt_newt_popup_get_active_id (NmtNewtPopup *popup);
void nmt_newt_popup_set_active_id (NmtNewtPopup *popup,
const char *active_id);
G_END_DECLS
#endif /* NMT_NEWT_POPUP_H */

408
tui/newt/nmt-newt-section.c Normal file
View File

@@ -0,0 +1,408 @@
/* -*- 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-newt-section
* @short_description: A collapsible section
*
* #NmtNewtSection is a container with two children; the header and
* the body. The header is always visible, but the body is only
* visible when the container is #NmtNewtSection:open.
*
* Note that there is no default way to open and close an
* #NmtNewtSection. You need to implement this yourself. (Eg, by
* binding the #NmtToggleButton:active property of an #NmtToggleButton
* in the section's header to the section's #NmtNewtSection:open
* property.)
*
* In addition to the header and body, the #NmtNewtSection also draws
* a border along the left side, indicating the extent of the section.
*/
#include "config.h"
#include <string.h>
#include "nmt-newt-section.h"
#include "nmt-newt-grid.h"
#include "nmt-newt-label.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtSection, nmt_newt_section, NMT_TYPE_NEWT_CONTAINER)
#define NMT_NEWT_SECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_SECTION, NmtNewtSectionPrivate))
typedef struct {
NmtNewtWidget *header;
int hheight_req, hwidth_req;
NmtNewtWidget *body;
int bheight_req, bwidth_req;
NmtNewtWidget *border_grid;
NmtNewtWidget *border_open_label;
NmtNewtWidget *border_closed_label;
NmtNewtWidget *border_end_label;
GPtrArray *border_line_labels;
gboolean open;
} NmtNewtSectionPrivate;
static char *closed_glyph, *open_glyph, *line_glyph, *end_glyph;
enum {
PROP_0,
PROP_OPEN,
LAST_PROP
};
/**
* nmt_newt_section_new:
*
* Creates a new #NmtNewtSection
*
* Returns: a new #NmtNewtSection
*/
NmtNewtWidget *
nmt_newt_section_new (void)
{
return g_object_new (NMT_TYPE_NEWT_SECTION,
NULL);
}
static void
nmt_newt_section_init (NmtNewtSection *section)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (section);
NmtNewtContainerClass *parent_class = NMT_NEWT_CONTAINER_CLASS (nmt_newt_section_parent_class);
priv->border_grid = nmt_newt_grid_new ();
parent_class->add (NMT_NEWT_CONTAINER (section), priv->border_grid);
priv->border_open_label = nmt_newt_label_new (open_glyph);
nmt_newt_widget_set_visible (priv->border_open_label, FALSE);
nmt_newt_grid_add (NMT_NEWT_GRID (priv->border_grid), priv->border_open_label, 0, 0);
priv->border_closed_label = nmt_newt_label_new (closed_glyph);
nmt_newt_grid_add (NMT_NEWT_GRID (priv->border_grid), priv->border_closed_label, 0, 0);
priv->border_end_label = nmt_newt_label_new (end_glyph);
nmt_newt_widget_set_visible (priv->border_open_label, FALSE);
nmt_newt_grid_add (NMT_NEWT_GRID (priv->border_grid), priv->border_end_label, 0, 1);
priv->border_line_labels = g_ptr_array_new ();
}
static void
nmt_newt_section_finalize (GObject *object)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (object);
g_ptr_array_unref (priv->border_line_labels);
G_OBJECT_CLASS (nmt_newt_section_parent_class)->finalize (object);
}
/**
* nmt_newt_section_set_header:
* @section: an #NmtNewtSection
* @header: the header widget
*
* Sets @section's header widget.
*/
void
nmt_newt_section_set_header (NmtNewtSection *section,
NmtNewtWidget *header)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (section);
NmtNewtContainerClass *parent_class = NMT_NEWT_CONTAINER_CLASS (nmt_newt_section_parent_class);
NmtNewtContainer *container = NMT_NEWT_CONTAINER (section);
if (priv->header)
parent_class->remove (container, priv->header);
priv->header = header;
parent_class->add (container, header);
}
/**
* nmt_newt_section_get_header:
* @section: an #NmtNewtSection
*
* Gets @section's header widget.
*
* Returns: @section's header widget.
*/
NmtNewtWidget *
nmt_newt_section_get_header (NmtNewtSection *section)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (section);
return priv->header;
}
/**
* nmt_newt_section_set_body:
* @section: an #NmtNewtSection
* @body: the body widget
*
* Sets @section's body widget.
*/
void
nmt_newt_section_set_body (NmtNewtSection *section,
NmtNewtWidget *body)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (section);
NmtNewtContainerClass *parent_class = NMT_NEWT_CONTAINER_CLASS (nmt_newt_section_parent_class);
NmtNewtContainer *container = NMT_NEWT_CONTAINER (section);
if (priv->body)
parent_class->remove (container, priv->body);
priv->body = body;
parent_class->add (container, body);
}
/**
* nmt_newt_section_get_body:
* @section: an #NmtNewtSection
*
* Gets @section's body widget.
*
* Returns: @section's body widget.
*/
NmtNewtWidget *
nmt_newt_section_get_body (NmtNewtSection *section)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (section);
return priv->body;
}
static void
nmt_newt_section_remove (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtNewtSection *section = NMT_NEWT_SECTION (container);
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (section);
NmtNewtContainerClass *parent_class = NMT_NEWT_CONTAINER_CLASS (nmt_newt_section_parent_class);
if (widget == priv->header)
priv->header = NULL;
else if (widget == priv->body)
priv->body = NULL;
else if (widget == priv->border_grid)
priv->border_grid = NULL;
parent_class->remove (container, widget);
}
static newtComponent *
nmt_newt_section_get_components (NmtNewtWidget *widget)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (widget);
newtComponent *child_cos;
GPtrArray *cos;
int i;
g_return_val_if_fail (priv->header != NULL && priv->body != NULL, NULL);
cos = g_ptr_array_new ();
child_cos = nmt_newt_widget_get_components (priv->border_grid);
for (i = 0; child_cos[i]; i++)
g_ptr_array_add (cos, child_cos[i]);
g_free (child_cos);
child_cos = nmt_newt_widget_get_components (priv->header);
for (i = 0; child_cos[i]; i++)
g_ptr_array_add (cos, child_cos[i]);
g_free (child_cos);
if (priv->open) {
child_cos = nmt_newt_widget_get_components (priv->body);
for (i = 0; child_cos[i]; i++)
g_ptr_array_add (cos, child_cos[i]);
g_free (child_cos);
}
g_ptr_array_add (cos, NULL);
return (newtComponent *) g_ptr_array_free (cos, FALSE);
}
static void
nmt_newt_section_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (widget);
int border_width, border_height;
g_return_if_fail (priv->header != NULL && priv->body != NULL);
nmt_newt_widget_size_request (priv->border_grid, &border_width, &border_height);
nmt_newt_widget_size_request (priv->header, &priv->hwidth_req, &priv->hheight_req);
nmt_newt_widget_size_request (priv->body, &priv->bwidth_req, &priv->bheight_req);
*width = MAX (priv->hwidth_req, priv->bwidth_req) + 2;
*height = priv->open ? priv->hheight_req + priv->bheight_req + 1 : priv->hheight_req;
}
static void
adjust_border_for_allocation (NmtNewtSectionPrivate *priv,
int height)
{
int i;
/* We have to use a series of one-line labels rather than a multi-line
* textbox, because newt will hide any component that's partially offscreen,
* but we want the on-screen portion of the border to show even if part of
* it is offscreen.
*/
if (height == 1) {
nmt_newt_widget_set_visible (priv->border_closed_label, TRUE);
nmt_newt_widget_set_visible (priv->border_open_label, FALSE);
for (i = 0; i < priv->border_line_labels->len; i++)
nmt_newt_widget_set_visible (priv->border_line_labels->pdata[i], FALSE);
nmt_newt_widget_set_visible (priv->border_end_label, FALSE);
} else {
nmt_newt_widget_set_visible (priv->border_closed_label, FALSE);
nmt_newt_widget_set_visible (priv->border_open_label, TRUE);
for (i = 0; i < height - 2; i++) {
if (i >= priv->border_line_labels->len) {
NmtNewtWidget *label;
label = nmt_newt_label_new (line_glyph);
g_ptr_array_add (priv->border_line_labels, label);
nmt_newt_grid_add (NMT_NEWT_GRID (priv->border_grid), label, 0, i + 1);
} else
nmt_newt_widget_set_visible (priv->border_line_labels->pdata[i], TRUE);
}
nmt_newt_widget_set_visible (priv->border_end_label, TRUE);
nmt_newt_grid_move (NMT_NEWT_GRID (priv->border_grid), priv->border_end_label, 0, height - 1);
}
}
static void
nmt_newt_section_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (widget);
adjust_border_for_allocation (priv, height);
nmt_newt_widget_size_allocate (priv->border_grid, x, y, 1, height);
nmt_newt_widget_size_allocate (priv->header, x + 2, y, width, priv->hheight_req);
if (priv->open) {
nmt_newt_widget_size_allocate (priv->body, x + 2, y + priv->hheight_req,
width, height - priv->hheight_req);
}
}
static void
nmt_newt_section_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (object);
switch (prop_id) {
case PROP_OPEN:
priv->open = g_value_get_boolean (value);
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (object));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_section_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtSectionPrivate *priv = NMT_NEWT_SECTION_GET_PRIVATE (object);
switch (prop_id) {
case PROP_OPEN:
g_value_set_boolean (value, priv->open);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_section_class_init (NmtNewtSectionClass *section_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (section_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (section_class);
NmtNewtContainerClass *container_class = NMT_NEWT_CONTAINER_CLASS (section_class);
g_type_class_add_private (section_class, sizeof (NmtNewtSectionPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_section_set_property;
object_class->get_property = nmt_newt_section_get_property;
object_class->finalize = nmt_newt_section_finalize;
widget_class->get_components = nmt_newt_section_get_components;
widget_class->size_request = nmt_newt_section_size_request;
widget_class->size_allocate = nmt_newt_section_size_allocate;
container_class->remove = nmt_newt_section_remove;
/* properties */
/**
* NmtNewtSection:open:
*
* %TRUE if the section is open (ie, its body is visible), %FALSE
* if not.
*/
g_object_class_install_property (object_class, PROP_OPEN,
g_param_spec_boolean ("open", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/* globals */
closed_glyph = nmt_newt_locale_from_utf8 ("\342\225\220"); /* ═ */
open_glyph = nmt_newt_locale_from_utf8 ("\342\225\244"); /* ╤ */
line_glyph = nmt_newt_locale_from_utf8 ("\342\224\202"); /* │ */
end_glyph = nmt_newt_locale_from_utf8 ("\342\224\224"); /* └ */
if (!closed_glyph || !open_glyph || !line_glyph || !end_glyph) {
g_clear_pointer (&closed_glyph, g_free);
g_clear_pointer (&open_glyph, g_free);
g_clear_pointer (&line_glyph, g_free);
g_clear_pointer (&end_glyph, g_free);
closed_glyph = g_strdup ("-");
open_glyph = g_strdup ("+");
line_glyph = g_strdup ("|");
end_glyph = g_strdup ("\\");
}
}

View File

@@ -0,0 +1,57 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_SECTION_H
#define NMT_NEWT_SECTION_H
#include "nmt-newt-container.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_SECTION (nmt_newt_section_get_type ())
#define NMT_NEWT_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_SECTION, NmtNewtSection))
#define NMT_NEWT_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_SECTION, NmtNewtSectionClass))
#define NMT_IS_NEWT_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_SECTION))
#define NMT_IS_NEWT_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_SECTION))
#define NMT_NEWT_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_SECTION, NmtNewtSectionClass))
struct _NmtNewtSection {
NmtNewtContainer parent;
};
typedef struct {
NmtNewtContainerClass parent;
} NmtNewtSectionClass;
GType nmt_newt_section_get_type (void);
NmtNewtWidget *nmt_newt_section_new (void);
void nmt_newt_section_set_header (NmtNewtSection *section,
NmtNewtWidget *header);
NmtNewtWidget *nmt_newt_section_get_header (NmtNewtSection *section);
void nmt_newt_section_set_body (NmtNewtSection *section,
NmtNewtWidget *body);
NmtNewtWidget *nmt_newt_section_get_body (NmtNewtSection *section);
G_END_DECLS
#endif /* NMT_NEWT_SECTION_H */

View File

@@ -0,0 +1,66 @@
/* -*- 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-newt-separator
* @short_description: Separator
*
* #NmtNewtSeparator is just a blank label, which is used in a few places
* where a widget is needed but none is desired, or to add blank space
* between widgets in containers that don't implement padding.
*/
#include "config.h"
#include "nmt-newt-separator.h"
G_DEFINE_TYPE (NmtNewtSeparator, nmt_newt_separator, NMT_TYPE_NEWT_COMPONENT)
/**
* nmt_newt_separator_new:
*
* Creates a new #NmtNewtSeparator.
*
* Returns: a new #NmtNewtSeparator
*/
NmtNewtWidget *
nmt_newt_separator_new (void)
{
return g_object_new (NMT_TYPE_NEWT_SEPARATOR, NULL);
}
static void
nmt_newt_separator_init (NmtNewtSeparator *separator)
{
}
static newtComponent
nmt_newt_separator_build_component (NmtNewtComponent *component,
gboolean sensitive)
{
return newtLabel (-1, -1, " ");
}
static void
nmt_newt_separator_class_init (NmtNewtSeparatorClass *separator_class)
{
NmtNewtComponentClass *component_class = NMT_NEWT_COMPONENT_CLASS (separator_class);
/* virtual methods */
component_class->build_component = nmt_newt_separator_build_component;
}

View File

@@ -0,0 +1,49 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_SEPARATOR_H
#define NMT_NEWT_SEPARATOR_H
#include "nmt-newt-component.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_SEPARATOR (nmt_newt_separator_get_type ())
#define NMT_NEWT_SEPARATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_SEPARATOR, NmtNewtSeparator))
#define NMT_NEWT_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_SEPARATOR, NmtNewtSeparatorClass))
#define NMT_IS_NEWT_SEPARATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_SEPARATOR))
#define NMT_IS_NEWT_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_SEPARATOR))
#define NMT_NEWT_SEPARATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_SEPARATOR, NmtNewtSeparatorClass))
struct _NmtNewtSeparator {
NmtNewtComponent parent;
};
typedef struct {
NmtNewtComponentClass parent;
} NmtNewtSeparatorClass;
GType nmt_newt_separator_get_type (void);
NmtNewtWidget *nmt_newt_separator_new (void);
G_END_DECLS
#endif /* NMT_NEWT_SEPARATOR_H */

366
tui/newt/nmt-newt-stack.c Normal file
View File

@@ -0,0 +1,366 @@
/* -*- 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-newt-stack
* @short_description: A stack of alternative widgets
*
* #NmtNewtStack implements a stack of widgets, only one of which is
* visible at any time.
*
* The height and width of the widget is determined only by its
* visible child. Likewise, the widget's #NmtNewtWidget:valid is
* determined only by the validity of its visible child, not its other
* children.
*/
#include "config.h"
#include <string.h>
#include "nmt-newt-stack.h"
G_DEFINE_TYPE (NmtNewtStack, nmt_newt_stack, NMT_TYPE_NEWT_CONTAINER)
#define NMT_NEWT_STACK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_STACK, NmtNewtStackPrivate))
typedef struct {
GPtrArray *children;
GPtrArray *ids;
guint active;
} NmtNewtStackPrivate;
enum {
PROP_0,
PROP_ACTIVE,
PROP_ACTIVE_ID,
LAST_PROP
};
/**
* nmt_newt_stack_new:
*
* Creates a new #NmtNewtStack
*
* Returns: a new #NmtNewtStack
*/
NmtNewtWidget *
nmt_newt_stack_new (void)
{
return g_object_new (NMT_TYPE_NEWT_STACK, NULL);
}
static void
nmt_newt_stack_init (NmtNewtStack *stack)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (stack);
priv->children = g_ptr_array_new ();
priv->ids = g_ptr_array_new_with_free_func (g_free);
}
static void
nmt_newt_stack_finalize (GObject *object)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (object);
g_ptr_array_unref (priv->children);
g_ptr_array_unref (priv->ids);
G_OBJECT_CLASS (nmt_newt_stack_parent_class)->finalize (object);
}
static newtComponent *
nmt_newt_stack_get_components (NmtNewtWidget *widget)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (widget);
if (priv->active > priv->children->len)
return NULL;
return nmt_newt_widget_get_components (priv->children->pdata[priv->active]);
}
static void
nmt_newt_stack_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
NmtNewtStack *stack = NMT_NEWT_STACK (widget);
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (stack);
int i, child_width, child_height;
if (priv->active > priv->children->len) {
*width = *height = 0;
return;
}
/* We size-request all pages so that embedded NmtPageGrids will
* participate in their size-grouping (so that switching pages
* won't result in the column widths changing).
*/
for (i = 0; i < priv->children->len; i++) {
nmt_newt_widget_size_request (priv->children->pdata[i], &child_width, &child_height);
if (i == priv->active) {
*width = child_width;
*height = child_height;
}
}
}
static void
nmt_newt_stack_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (widget);
if (priv->active > priv->children->len)
return;
nmt_newt_widget_size_allocate (priv->children->pdata[priv->active], x, y, width, height);
}
/**
* nmt_newt_stack_add:
* @stack: an #NmtNewtStack
* @id: the ID for the new page
* @widget: the widget to add
*
* Adds @widget to @stack with the given @id.
*/
void
nmt_newt_stack_add (NmtNewtStack *stack,
const char *id,
NmtNewtWidget *widget)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (stack);
g_ptr_array_add (priv->children, widget);
g_ptr_array_add (priv->ids, g_strdup (id));
NMT_NEWT_CONTAINER_CLASS (nmt_newt_stack_parent_class)->add (NMT_NEWT_CONTAINER (stack), widget);
}
static void
nmt_newt_stack_remove (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtNewtStack *stack = NMT_NEWT_STACK (container);
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (stack);
int i;
NMT_NEWT_CONTAINER_CLASS (nmt_newt_stack_parent_class)->remove (container, widget);
for (i = 0; i < priv->children->len; i++) {
if (priv->children->pdata[i] == widget) {
g_ptr_array_remove_index (priv->children, i);
g_ptr_array_remove_index (priv->ids, i);
return;
}
}
}
static void
nmt_newt_stack_child_validity_changed (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (container);
if (priv->active > priv->children->len)
return;
if (priv->children->pdata[priv->active] == (gpointer) widget) {
NMT_NEWT_CONTAINER_CLASS (nmt_newt_stack_parent_class)->
child_validity_changed (container, widget);
}
}
/**
* nmt_newt_stack_set_active:
* @stack: an #NmtNewtStack
* @active: the index of the new active page
*
* Sets the active page on @stack to @active.
*/
void
nmt_newt_stack_set_active (NmtNewtStack *stack,
guint active)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (stack);
if (priv->active == active)
return;
priv->active = active;
g_object_notify (G_OBJECT (stack), "active");
g_object_notify (G_OBJECT (stack), "active-id");
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (stack));
}
/**
* nmt_newt_stack_get_active:
* @stack: an #NmtNewtStack
*
* Gets the index of the active page on @stack
*
* Returns: the index of the active page on @stack
*/
guint
nmt_newt_stack_get_active (NmtNewtStack *stack)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (stack);
return priv->active;
}
/**
* nmt_newt_stack_set_active_id:
* @stack: an #NmtNewtStack
* @active_id: the ID of the new active page
*
* Sets the active page on @stack to @active_id.
*/
void
nmt_newt_stack_set_active_id (NmtNewtStack *stack,
const char *id)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (stack);
int i;
if (!g_strcmp0 (priv->ids->pdata[priv->active], id))
return;
for (i = 0; i < priv->ids->len; i++) {
if (!g_strcmp0 (priv->ids->pdata[i], id)) {
priv->active = i;
g_object_notify (G_OBJECT (stack), "active");
g_object_notify (G_OBJECT (stack), "active-id");
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (stack));
return;
}
}
}
/**
* nmt_newt_stack_get_active_id:
* @stack: an #NmtNewtStack
*
* Gets the ID of the active page on @stack
*
* Returns: the ID of the active page on @stack
*/
const char *
nmt_newt_stack_get_active_id (NmtNewtStack *stack)
{
NmtNewtStackPrivate *priv = NMT_NEWT_STACK_GET_PRIVATE (stack);
if (priv->active > priv->children->len)
return NULL;
return priv->ids->pdata[priv->active];
}
static void
nmt_newt_stack_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtStack *stack = NMT_NEWT_STACK (object);
switch (prop_id) {
case PROP_ACTIVE:
nmt_newt_stack_set_active (stack, g_value_get_uint (value));
break;
case PROP_ACTIVE_ID:
nmt_newt_stack_set_active_id (stack, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_stack_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtStack *stack = NMT_NEWT_STACK (object);
switch (prop_id) {
case PROP_ACTIVE:
g_value_set_uint (value, nmt_newt_stack_get_active (stack));
break;
case PROP_ACTIVE_ID:
g_value_set_string (value, nmt_newt_stack_get_active_id (stack));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_stack_class_init (NmtNewtStackClass *stack_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (stack_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (stack_class);
NmtNewtContainerClass *container_class = NMT_NEWT_CONTAINER_CLASS (stack_class);
g_type_class_add_private (stack_class, sizeof (NmtNewtStackPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_stack_set_property;
object_class->get_property = nmt_newt_stack_get_property;
object_class->finalize = nmt_newt_stack_finalize;
widget_class->get_components = nmt_newt_stack_get_components;
widget_class->size_request = nmt_newt_stack_size_request;
widget_class->size_allocate = nmt_newt_stack_size_allocate;
container_class->remove = nmt_newt_stack_remove;
container_class->child_validity_changed = nmt_newt_stack_child_validity_changed;
/**
* NmtNewtStack:active:
*
* The index of the active page
*/
g_object_class_install_property (object_class, PROP_ACTIVE,
g_param_spec_uint ("active", "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtStack:active-id:
*
* The ID of the active page
*/
g_object_class_install_property (object_class, PROP_ACTIVE_ID,
g_param_spec_string ("active-id", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

61
tui/newt/nmt-newt-stack.h Normal file
View File

@@ -0,0 +1,61 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_STACK_H
#define NMT_NEWT_STACK_H
#include "nmt-newt-container.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_STACK (nmt_newt_stack_get_type ())
#define NMT_NEWT_STACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_STACK, NmtNewtStack))
#define NMT_NEWT_STACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_STACK, NmtNewtStackClass))
#define NMT_IS_NEWT_STACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_STACK))
#define NMT_IS_NEWT_STACK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_STACK))
#define NMT_NEWT_STACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_STACK, NmtNewtStackClass))
struct _NmtNewtStack {
NmtNewtContainer parent;
};
typedef struct {
NmtNewtContainerClass parent;
} NmtNewtStackClass;
GType nmt_newt_stack_get_type (void);
NmtNewtWidget *nmt_newt_stack_new (void);
void nmt_newt_stack_add (NmtNewtStack *stack,
const char *id,
NmtNewtWidget *widget);
void nmt_newt_stack_set_active (NmtNewtStack *stack,
guint active);
guint nmt_newt_stack_get_active (NmtNewtStack *stack);
void nmt_newt_stack_set_active_id (NmtNewtStack *stack,
const char *id);
const char * nmt_newt_stack_get_active_id (NmtNewtStack *stack);
G_END_DECLS
#endif /* NMT_NEWT_STACK_H */

292
tui/newt/nmt-newt-textbox.c Normal file
View File

@@ -0,0 +1,292 @@
/* -*- 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-newt-textbox
* @short_description: Multi-line text box
*
* #NmtNewtTextbox implements a multi-line text, optionally with
* word-wrapping.
*/
#include "config.h"
#include <string.h>
#include "nmt-newt-textbox.h"
#include "nmt-newt-utils.h"
G_DEFINE_TYPE (NmtNewtTextbox, nmt_newt_textbox, NMT_TYPE_NEWT_COMPONENT)
#define NMT_NEWT_TEXTBOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_TEXTBOX, NmtNewtTextboxPrivate))
typedef struct {
int wrap_width;
NmtNewtTextboxFlags flags;
char *text;
int width, height;
} NmtNewtTextboxPrivate;
enum {
PROP_0,
PROP_TEXT,
PROP_FLAGS,
PROP_WRAP_WIDTH,
LAST_PROP
};
/**
* NmtNewtTextboxFlags:
* @NMT_NEWT_TEXTBOX_SCROLLABLE: the textbox should be scollable.
* @NMT_NEWT_TEXTBOX_SET_BACKGROUND: the textbox should have a
* white background
*
* Flags for an #NmtNewtTextbox
*/
/**
* nmt_newt_textbox_new:
* @flags: the textbox's flags
* @wrap_width: width in characters at which to word-wrap, or
* 0 to not wrap.
*
* Creates a new #NmtNewtTextbox.
*
* Returns: a new #NmtNewtTextbox
*/
NmtNewtWidget *
nmt_newt_textbox_new (NmtNewtTextboxFlags flags,
int wrap_width)
{
return g_object_new (NMT_TYPE_NEWT_TEXTBOX,
"flags", flags,
"wrap-width", wrap_width,
NULL);
}
/**
* nmt_newt_textbox_get_text:
* @textbox: an #NmtNewtTextbox
*
* Gets @textbox's text
*
* Returns: @textbox's text
*/
void
nmt_newt_textbox_set_text (NmtNewtTextbox *textbox,
const char *text)
{
NmtNewtTextboxPrivate *priv = NMT_NEWT_TEXTBOX_GET_PRIVATE (textbox);
char **lines;
int i, len;
if (!text)
text = "";
if (!strcmp (priv->text, text))
return;
g_free (priv->text);
priv->text = g_strdup (text);
priv->width = priv->height = 0;
lines = g_strsplit (priv->text, "\n", -1);
for (i = 0; lines[i]; i++) {
len = g_utf8_strlen (lines[i], -1);
if (len > priv->width)
priv->width = len;
}
g_free (lines);
priv->height = MIN (i, 1);
g_object_notify (G_OBJECT (textbox), "text");
nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (textbox));
}
/**
* nmt_newt_textbox_get_text:
* @textbox: an #NmtNewtTextbox
*
* Gets @textbox's text
*
* Returns: @textbox's text
*/
const char *
nmt_newt_textbox_get_text (NmtNewtTextbox *textbox)
{
NmtNewtTextboxPrivate *priv = NMT_NEWT_TEXTBOX_GET_PRIVATE (textbox);
return priv->text;
}
static void
nmt_newt_textbox_init (NmtNewtTextbox *textbox)
{
NmtNewtTextboxPrivate *priv = NMT_NEWT_TEXTBOX_GET_PRIVATE (textbox);
priv->text = g_strdup ("");
}
static void
nmt_newt_textbox_finalize (GObject *object)
{
NmtNewtTextboxPrivate *priv = NMT_NEWT_TEXTBOX_GET_PRIVATE (object);
g_free (priv->text);
G_OBJECT_CLASS (nmt_newt_textbox_parent_class)->finalize (object);
}
static guint
convert_flags (NmtNewtTextboxFlags flags)
{
guint newt_flags = 0;
if (flags & NMT_NEWT_TEXTBOX_SCROLLABLE)
newt_flags |= NEWT_FLAG_SCROLL;
return newt_flags;
}
static newtComponent
nmt_newt_textbox_build_component (NmtNewtComponent *component,
gboolean sensitive)
{
NmtNewtTextboxPrivate *priv = NMT_NEWT_TEXTBOX_GET_PRIVATE (component);
newtComponent co;
const char *text;
char *text_lc;
text = priv->text;
if (!*text)
text = "\n";
text_lc = nmt_newt_locale_from_utf8 (text);
if (priv->wrap_width > 0) {
co = newtTextboxReflowed (-1, -1, text_lc, priv->wrap_width, 0, 0, 0);
} else {
co = newtTextbox (-1, -1, priv->width, priv->height, convert_flags (priv->flags));
newtTextboxSetText (co, text_lc);
}
g_free (text_lc);
if (priv->flags & NMT_NEWT_TEXTBOX_SET_BACKGROUND)
newtTextboxSetColors (co, NMT_NEWT_COLORSET_TEXTBOX_WITH_BACKGROUND, NEWT_COLORSET_ACTTEXTBOX);
return co;
}
static void
nmt_newt_textbox_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtTextbox *textbox = NMT_NEWT_TEXTBOX (object);
NmtNewtTextboxPrivate *priv = NMT_NEWT_TEXTBOX_GET_PRIVATE (textbox);
switch (prop_id) {
case PROP_TEXT:
nmt_newt_textbox_set_text (textbox, g_value_get_string (value));
break;
case PROP_FLAGS:
priv->flags = g_value_get_uint (value);
break;
case PROP_WRAP_WIDTH:
priv->wrap_width = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_textbox_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtTextboxPrivate *priv = NMT_NEWT_TEXTBOX_GET_PRIVATE (object);
switch (prop_id) {
case PROP_TEXT:
g_value_set_string (value, priv->text);
break;
case PROP_FLAGS:
g_value_set_uint (value, priv->flags);
break;
case PROP_WRAP_WIDTH:
g_value_set_int (value, priv->wrap_width);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_textbox_class_init (NmtNewtTextboxClass *textbox_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (textbox_class);
NmtNewtComponentClass *component_class = NMT_NEWT_COMPONENT_CLASS (textbox_class);
g_type_class_add_private (textbox_class, sizeof (NmtNewtTextboxPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_textbox_set_property;
object_class->get_property = nmt_newt_textbox_get_property;
object_class->finalize = nmt_newt_textbox_finalize;
component_class->build_component = nmt_newt_textbox_build_component;
/**
* NmtNewtTextbox:text:
*
* The textbox's text
*/
g_object_class_install_property (object_class, PROP_TEXT,
g_param_spec_string ("text", "", "",
"",
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtTextbox:flags:
*
* The textbox's flags
*/
g_object_class_install_property (object_class, PROP_FLAGS,
g_param_spec_uint ("flags", "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtTextbox:wrap-width:
*
* The width in characters at which the textbox's text
* will wrap, or 0 if it does not wrap.
*/
g_object_class_install_property (object_class, PROP_WRAP_WIDTH,
g_param_spec_int ("wrap-width", "", "",
0, G_MAXINT, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -0,0 +1,59 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_TEXTBOX_H
#define NMT_NEWT_TEXTBOX_H
#include "nmt-newt-component.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_TEXTBOX (nmt_newt_textbox_get_type ())
#define NMT_NEWT_TEXTBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_TEXTBOX, NmtNewtTextbox))
#define NMT_NEWT_TEXTBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_TEXTBOX, NmtNewtTextboxClass))
#define NMT_IS_NEWT_TEXTBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_TEXTBOX))
#define NMT_IS_NEWT_TEXTBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_TEXTBOX))
#define NMT_NEWT_TEXTBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_TEXTBOX, NmtNewtTextboxClass))
struct _NmtNewtTextbox {
NmtNewtComponent parent;
};
typedef struct {
NmtNewtComponentClass parent;
} NmtNewtTextboxClass;
GType nmt_newt_textbox_get_type (void);
typedef enum {
NMT_NEWT_TEXTBOX_SCROLLABLE = (1 << 0),
NMT_NEWT_TEXTBOX_SET_BACKGROUND = (1 << 1)
} NmtNewtTextboxFlags;
NmtNewtWidget *nmt_newt_textbox_new (NmtNewtTextboxFlags flags,
int wrap_width);
void nmt_newt_textbox_set_text (NmtNewtTextbox *textbox,
const char *text);
const char *nmt_newt_textbox_get_text (NmtNewtTextbox *textbox);
G_END_DECLS
#endif /* NMT_NEWT_TEXTBOX_H */

View File

@@ -0,0 +1,234 @@
/* -*- 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-newt-toggle-button
* @short_description: Toggle buttons
*
* #NmtNewtToggleButton implements a two-state toggle button.
*/
#include "config.h"
#include "nmt-newt-toggle-button.h"
G_DEFINE_TYPE (NmtNewtToggleButton, nmt_newt_toggle_button, NMT_TYPE_NEWT_BUTTON)
#define NMT_NEWT_TOGGLE_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_TOGGLE_BUTTON, NmtNewtToggleButtonPrivate))
typedef struct {
char *on_label, *off_label;
gboolean active;
} NmtNewtToggleButtonPrivate;
enum {
PROP_0,
PROP_ON_LABEL,
PROP_OFF_LABEL,
PROP_ACTIVE,
LAST_PROP
};
/**
* nmt_newt_toggle_button_new:
* @on_label: the button's label when it is in the "on" state
* @off_label: the button's label when it is in the "off" state
*
* Creates a new #NmtNewtToggleButton
*
* Returns: a new #NmtNewtToggleButton
*/
NmtNewtWidget *
nmt_newt_toggle_button_new (const char *on_label,
const char *off_label)
{
return g_object_new (NMT_TYPE_NEWT_TOGGLE_BUTTON,
"on-label", on_label,
"off-label", off_label,
NULL);
}
/**
* nmt_newt_toggle_button_get_active:
* @button: an #NmtNewtToggleButton
*
* Gets whether @button is currently "on" or "off"
*
* Returns: whether @button is currently "on" (%TRUE) or "off" (%FALSE)
*/
gboolean
nmt_newt_toggle_button_get_active (NmtNewtToggleButton *button)
{
NmtNewtToggleButtonPrivate *priv = NMT_NEWT_TOGGLE_BUTTON_GET_PRIVATE (button);
return priv->active;
}
/**
* nmt_newt_toggle_button_set_active:
* @button: an #NmtNewtToggleButton
* @active: whether @button should be "on" or "off"
*
* Sets whether @button is currently "on" or "off"
*/
void
nmt_newt_toggle_button_set_active (NmtNewtToggleButton *button,
gboolean active)
{
NmtNewtToggleButtonPrivate *priv = NMT_NEWT_TOGGLE_BUTTON_GET_PRIVATE (button);
if (priv->active == active)
return;
priv->active = active;
g_object_set (G_OBJECT (button),
"label", active ? priv->on_label : priv->off_label,
NULL);
g_object_notify (G_OBJECT (button), "active");
}
static void
nmt_newt_toggle_button_init (NmtNewtToggleButton *button)
{
}
static void
nmt_newt_toggle_button_finalize (GObject *object)
{
NmtNewtToggleButtonPrivate *priv = NMT_NEWT_TOGGLE_BUTTON_GET_PRIVATE (object);
g_free (priv->on_label);
g_free (priv->off_label);
G_OBJECT_CLASS (nmt_newt_toggle_button_parent_class)->finalize (object);
}
static void
nmt_newt_toggle_button_activated (NmtNewtWidget *widget)
{
NmtNewtToggleButton *button = NMT_NEWT_TOGGLE_BUTTON (widget);
nmt_newt_toggle_button_set_active (button, !nmt_newt_toggle_button_get_active (button));
NMT_NEWT_WIDGET_CLASS (nmt_newt_toggle_button_parent_class)->activated (widget);
}
static void
nmt_newt_toggle_button_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtToggleButtonPrivate *priv = NMT_NEWT_TOGGLE_BUTTON_GET_PRIVATE (object);
switch (prop_id) {
case PROP_ON_LABEL:
g_free (priv->on_label);
priv->on_label = g_value_dup_string (value);
if (priv->active)
g_object_set (object, "label", priv->on_label, NULL);
break;
case PROP_OFF_LABEL:
g_free (priv->off_label);
priv->off_label = g_value_dup_string (value);
if (!priv->active)
g_object_set (object, "label", priv->off_label, NULL);
break;
case PROP_ACTIVE:
priv->active = g_value_get_boolean (value);
g_object_set (object,
"label", priv->active ? priv->on_label : priv->off_label,
NULL);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_toggle_button_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtToggleButtonPrivate *priv = NMT_NEWT_TOGGLE_BUTTON_GET_PRIVATE (object);
switch (prop_id) {
case PROP_ON_LABEL:
g_value_set_string (value, priv->on_label);
break;
case PROP_OFF_LABEL:
g_value_set_string (value, priv->off_label);
break;
case PROP_ACTIVE:
g_value_set_boolean (value, priv->active);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_toggle_button_class_init (NmtNewtToggleButtonClass *button_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (button_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (button_class);
g_type_class_add_private (button_class, sizeof (NmtNewtToggleButtonPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_toggle_button_set_property;
object_class->get_property = nmt_newt_toggle_button_get_property;
object_class->finalize = nmt_newt_toggle_button_finalize;
widget_class->activated = nmt_newt_toggle_button_activated;
/**
* NmtNewtToggleButton:on-label:
*
* The label the button displays when it is "on".
*/
g_object_class_install_property (object_class, PROP_ON_LABEL,
g_param_spec_string ("on-label", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtToggleButton:off-label:
*
* The label the button displays when it is "off".
*/
g_object_class_install_property (object_class, PROP_OFF_LABEL,
g_param_spec_string ("off-label", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtToggleButton:active:
*
* Whether the button is currently "on" (%TRUE) or "off" (%FALSE)
*/
g_object_class_install_property (object_class, PROP_ACTIVE,
g_param_spec_boolean ("active", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

View File

@@ -0,0 +1,54 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_TOGGLE_BUTTON_H
#define NMT_NEWT_TOGGLE_BUTTON_H
#include "nmt-newt-button.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_TOGGLE_BUTTON (nmt_newt_toggle_button_get_type ())
#define NMT_NEWT_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_TOGGLE_BUTTON, NmtNewtToggleButton))
#define NMT_NEWT_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_TOGGLE_BUTTON, NmtNewtToggleButtonClass))
#define NMT_IS_NEWT_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_TOGGLE_BUTTON))
#define NMT_IS_NEWT_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_TOGGLE_BUTTON))
#define NMT_NEWT_TOGGLE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_TOGGLE_BUTTON, NmtNewtToggleButtonClass))
struct _NmtNewtToggleButton {
NmtNewtButton parent;
};
typedef struct {
NmtNewtButtonClass parent;
} NmtNewtToggleButtonClass;
GType nmt_newt_toggle_button_get_type (void);
NmtNewtWidget *nmt_newt_toggle_button_new (const char *on_label,
const char *off_label);
gboolean nmt_newt_toggle_button_get_active (NmtNewtToggleButton *button);
void nmt_newt_toggle_button_set_active (NmtNewtToggleButton *button,
gboolean active);
G_END_DECLS
#endif /* NMT_NEWT_TOGGLE_BUTTON_H */

49
tui/newt/nmt-newt-types.h Normal file
View File

@@ -0,0 +1,49 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_TYPES_H
#define NMT_NEWT_TYPES_H
#include <glib-object.h>
#include <newt.h>
G_BEGIN_DECLS
typedef struct _NmtNewtButton NmtNewtButton;
typedef struct _NmtNewtButtonBox NmtNewtButtonBox;
typedef struct _NmtNewtCheckbox NmtNewtCheckbox;
typedef struct _NmtNewtComponent NmtNewtComponent;
typedef struct _NmtNewtContainer NmtNewtContainer;
typedef struct _NmtNewtEntry NmtNewtEntry;
typedef struct _NmtNewtEntryNumeric NmtNewtEntryNumeric;
typedef struct _NmtNewtForm NmtNewtForm;
typedef struct _NmtNewtGrid NmtNewtGrid;
typedef struct _NmtNewtLabel NmtNewtLabel;
typedef struct _NmtNewtListbox NmtNewtListbox;
typedef struct _NmtNewtPopup NmtNewtPopup;
typedef struct _NmtNewtSection NmtNewtSection;
typedef struct _NmtNewtSectionBorder NmtNewtSectionBorder;
typedef struct _NmtNewtSeparator NmtNewtSeparator;
typedef struct _NmtNewtStack NmtNewtStack;
typedef struct _NmtNewtTextbox NmtNewtTextbox;
typedef struct _NmtNewtToggleButton NmtNewtToggleButton;
typedef struct _NmtNewtWidget NmtNewtWidget;
G_END_DECLS
#endif /* NMT_NEWT_COMPONENT_H */

333
tui/newt/nmt-newt-utils.c Normal file
View File

@@ -0,0 +1,333 @@
/* -*- 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-newt-utils
* @short_description: Utility functions
*/
#include "config.h"
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#include <glib/gi18n-lib.h>
#include "nmt-newt-utils.h"
static void
nmt_newt_g_log_handler (const char *log_domain,
GLogLevelFlags log_level,
const char *message,
gpointer user_data)
{
const char *level_name;
char *full_message;
int screen_width, screen_height;
newtComponent text, ok, form;
newtGrid grid;
g_assert (!(log_level & G_LOG_FLAG_RECURSION));
if (log_level & G_LOG_LEVEL_DEBUG)
return;
switch (log_level & G_LOG_LEVEL_MASK) {
case G_LOG_LEVEL_ERROR:
level_name = "ERROR";
break;
case G_LOG_LEVEL_CRITICAL:
level_name = "CRITICAL";
break;
case G_LOG_LEVEL_WARNING:
level_name = "WARNING";
break;
case G_LOG_LEVEL_MESSAGE:
level_name = "Message";
break;
default:
level_name = NULL;
}
full_message = g_strdup_printf ("%s%s%s%s%s",
log_domain ? log_domain : "",
log_domain && level_name ? " " : "",
level_name ? level_name : "",
log_domain || level_name ? ": " : "",
message);
/* newtWinMessage() wraps the window too narrowly by default, so
* we don't want to use that. But we intentionally avoid using any
* NmtNewt classes, to avoid possible error recursion.
*/
newtGetScreenSize (&screen_width, &screen_height);
text = newtTextboxReflowed (-1, -1, full_message, MAX (70, screen_width - 10), 0, 0, 0);
g_free (full_message);
ok = newtButton (-1, -1, "OK");
grid = newtCreateGrid (1, 2);
newtGridSetField (grid, 0, 0, NEWT_GRID_COMPONENT, text, 0, 0, 0, 0, 0, 0);
newtGridSetField (grid, 0, 1, NEWT_GRID_COMPONENT, ok, 0, 1, 0, 0,
NEWT_ANCHOR_RIGHT, 0);
newtGridWrappedWindow (grid, (char *) (level_name ? level_name : ""));
newtGridFree (grid, TRUE);
form = newtForm (NULL, NULL, 0);
newtFormAddComponents (form, text, ok, NULL);
newtRunForm (form);
newtFormDestroy (form);
newtPopWindow ();
}
/**
* nmt_newt_init:
*
* Wrapper for newtInit() that also does some nmt-newt-internal setup.
* This should be called once, before any other nmt-newt functions.
*
* FIXME: Currently this also calls g_log_set_default_handler() to set
* up a log handler that displays g_warning()s and the like as pop-up
* windows, but in the long run that should only happen for
* debug/developer builds.
*/
void
nmt_newt_init (void)
{
newtInit ();
newtCls ();
newtSetColor (NEWT_COLORSET_CHECKBOX, "black", "lightgray");
newtSetColor (NMT_NEWT_COLORSET_BAD_LABEL, "red", "lightgray");
newtSetColor (NMT_NEWT_COLORSET_PLAIN_LABEL, "black", "lightgray");
newtSetColor (NMT_NEWT_COLORSET_DISABLED_BUTTON, "blue", "lightgray");
newtSetColor (NMT_NEWT_COLORSET_TEXTBOX_WITH_BACKGROUND, "black", "white");
g_log_set_default_handler (nmt_newt_g_log_handler, NULL);
}
/**
* nmt_newt_finished:
*
* Wrapper for newtFinished(). Should be called at the end of the program.
*/
void
nmt_newt_finished (void)
{
newtFinished ();
g_log_set_default_handler (nmt_newt_g_log_handler, g_log_default_handler);
}
/**
* nmt_newt_error_dialog:
* @message: a printf()-style message format
* @...: arguments
*
* Displays the given message in a dialog box with a single "OK"
* button, and returns after the user clicks "OK".
*
* FIXME: it's not just for errors any more!
*/
void
nmt_newt_error_dialog (const char *message,
...)
{
va_list ap;
char *msg, *msg_lc, *ok_lc;
va_start (ap, message);
msg = g_strdup_vprintf (message, ap);
va_end (ap);
msg_lc = nmt_newt_locale_from_utf8 (msg);
ok_lc = nmt_newt_locale_from_utf8 (_("OK"));
newtWinMessage (NULL, ok_lc, "%s", msg_lc);
g_free (ok_lc);
g_free (msg_lc);
g_free (msg);
}
/**
* nmt_newt_choice_dialog:
* @button1: the label for the first button
* @button2: the label for the second button
* @message: a printf()-style message format
* @...: arguments
*
* Displays the given message in a dialog box with two buttons with
* the indicated labels, and waits for the user to click one.
*
* Returns: which button was clicked: 0 for @button1 or 1 for @button2
*/
int
nmt_newt_choice_dialog (const char *button1,
const char *button2,
const char *message,
...)
{
va_list ap;
char *msg, *msg_lc, *button1_lc, *button2_lc;
int choice;
va_start (ap, message);
msg = g_strdup_vprintf (message, ap);
va_end (ap);
msg_lc = nmt_newt_locale_from_utf8 (msg);
button1_lc = nmt_newt_locale_from_utf8 (button1);
button2_lc = nmt_newt_locale_from_utf8 (button2);
choice = newtWinChoice (NULL, button1_lc, button2_lc, "%s", msg_lc);
g_free (button1_lc);
g_free (button2_lc);
g_free (msg_lc);
g_free (msg);
return choice;
}
/**
* nmt_newt_locale_to_utf8:
* @str_lc: a string in the user's locale encoding
*
* Convenience wrapper around g_locale_to_utf8().
*
* Note that libnewt works in terms of the user's locale character
* set, NOT UTF-8, so all strings received from libnewt must be
* converted back to UTF-8 before being returned to the caller or used
* in other APIs.
*
* Returns: @str_lc, converted to UTF-8.
*/
char *
nmt_newt_locale_to_utf8 (const char *str_lc)
{
char *str_utf8;
str_utf8 = g_locale_to_utf8 (str_lc, -1, NULL, NULL, NULL);
if (!str_utf8)
str_utf8 = g_strdup ("");
return str_utf8;
}
/**
* nmt_newt_locale_from_utf8:
* @str_utf8: a UTF-8 string
*
* Convenience wrapper around g_locale_from_utf8().
*
* Note that libnewt works in terms of the user's locale character
* set, NOT UTF-8, so all strings from nmt-newt must be converted to
* locale encoding before being passed to libnewt.
*
* Returns: @str_utf8, converted to the user's locale encoding.
*/
char *
nmt_newt_locale_from_utf8 (const char *str_utf8)
{
char *str_lc;
str_lc = g_locale_from_utf8 (str_utf8, -1, NULL, NULL, NULL);
if (!str_lc)
str_lc = g_strdup ("");
return str_lc;
}
/**
* nmt_newt_edit_string:
* @data: data to edit
*
* libnewt does not have a multi-line editable text component, so
* nmt-newt provides this function instead, which will open the user's
* editor to edit a file containing the given @data (ensuring that the
* current screen state is saved before starting the editor and
* restored after it returns).
*
* Returns: the edited data, or %NULL if an error occurred.
*/
char *
nmt_newt_edit_string (const char *data)
{
gssize len, nwrote;
char *filename, *argv[3];
GError *error = NULL;
int fd, status;
char *new_data = NULL;
fd = g_file_open_tmp ("XXXXXX.json", &filename, &error);
if (fd == -1) {
nmt_newt_error_dialog (_("Could not create temporary file: %s"), error->message);
g_error_free (error);
return NULL;
}
len = data ? strlen (data) : 0;
while (len) {
do
nwrote = write (fd, data, len);
while (nwrote == -1 && errno == EINTR);
len -= nwrote;
data += nwrote;
}
close (fd);
argv[0] = (char *) g_getenv ("VISUAL");
if (!argv[0])
argv[0] = (char *) g_getenv ("EDITOR");
if (!argv[0])
argv[0] = (char *) "vi";
argv[1] = filename;
argv[2] = NULL;
newtSuspend ();
g_spawn_sync (NULL, argv, NULL,
G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN,
NULL, NULL, NULL, NULL,
&status, &error);
newtResume ();
if (error) {
nmt_newt_error_dialog (_("Could not create temporary file: %s"), error->message);
g_error_free (error);
goto done;
}
if (!g_spawn_check_exit_status (status, &error)) {
nmt_newt_error_dialog (_("Editor failed: %s"), error->message);
g_error_free (error);
goto done;
}
if (!g_file_get_contents (filename, &new_data, NULL, &error)) {
nmt_newt_error_dialog (_("Could not re-read file: %s"), error->message);
g_error_free (error);
goto done;
}
done:
unlink (filename);
g_free (filename);
return new_data;
}

51
tui/newt/nmt-newt-utils.h Normal file
View File

@@ -0,0 +1,51 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_UTILS_H
#define NMT_NEWT_UTILS_H
#include <newt.h>
#include <glib.h>
G_BEGIN_DECLS
void nmt_newt_init (void);
void nmt_newt_finished (void);
typedef enum {
NMT_NEWT_COLORSET_BAD_LABEL = NEWT_COLORSET_CUSTOM (0),
NMT_NEWT_COLORSET_PLAIN_LABEL,
NMT_NEWT_COLORSET_DISABLED_BUTTON,
NMT_NEWT_COLORSET_TEXTBOX_WITH_BACKGROUND
} NmtNewtColorsets;
char *nmt_newt_locale_to_utf8 (const char *str_lc);
char *nmt_newt_locale_from_utf8 (const char *str_utf8);
void nmt_newt_error_dialog (const char *message,
...);
int nmt_newt_choice_dialog (const char *button1,
const char *button2,
const char *message,
...);
char *nmt_newt_edit_string (const char *data);
G_END_DECLS
#endif /* NMT_NEWT_UTILS_H */

648
tui/newt/nmt-newt-widget.c Normal file
View File

@@ -0,0 +1,648 @@
/* -*- 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-newt-widget
* @short_description: Base TUI Widget class
*
* #NmtNewtWidget is the abstract base class for nmt-newt. All widgets
* inherit from one of its two subclasses: #NmtNewtComponent, for
* widgets that wrap a (single) #newtComponent, and #NmtNewtContainer,
* for widgets consisting of multiple components. See those classes
* for more details.
*
* With the exception of #NmtNewtForm, all widgets start out with a
* floating reference, which will be sunk by the container they are
* added to. #NmtNewtForm is the "top-level" widget type, and so does
* not have a floating reference.
*
* FIXME: need RTL support
*/
#include "config.h"
#include "nmt-newt-widget.h"
#include "nmt-newt-form.h"
G_DEFINE_ABSTRACT_TYPE (NmtNewtWidget, nmt_newt_widget, G_TYPE_INITIALLY_UNOWNED)
#define NMT_NEWT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_NEWT_WIDGET, NmtNewtWidgetPrivate))
typedef struct {
NmtNewtWidget *parent;
gboolean visible, realized, valid;
gboolean exit_on_activate;
int pad_left, pad_top, pad_right, pad_bottom;
} NmtNewtWidgetPrivate;
enum {
PROP_0,
PROP_PARENT,
PROP_VISIBLE,
PROP_VALID,
PROP_EXIT_ON_ACTIVATE,
LAST_PROP
};
enum {
NEEDS_REBUILD,
ACTIVATED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static void
nmt_newt_widget_init (NmtNewtWidget *widget)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
priv->visible = TRUE;
priv->valid = TRUE;
}
static void
nmt_newt_widget_finalize (GObject *object)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (object);
nmt_newt_widget_unrealize (NMT_NEWT_WIDGET (object));
g_clear_object (&priv->parent);
G_OBJECT_CLASS (nmt_newt_widget_parent_class)->finalize (object);
}
/**
* nmt_newt_widget_realize:
* @widget: an #NmtNewtWidget
*
* "Realizes" @widget. That is, creates #newtComponents corresponding
* to @widget and its children.
*
* You should not need to call this yourself; an #NmtNewtForm will
* cause its children to be realized and unrealized as needed.
*/
void
nmt_newt_widget_realize (NmtNewtWidget *widget)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
if (!priv->realized) {
NMT_NEWT_WIDGET_GET_CLASS (widget)->realize (widget);
priv->realized = TRUE;
}
}
/**
* nmt_newt_widget_unrealize:
* @widget: an #NmtNewtWidget
*
* "Unrealizes" @widget, destroying its #newtComponents.
*
* You should not need to call this yourself; an #NmtNewtForm will
* cause its children to be realized and unrealized as needed.
*/
void
nmt_newt_widget_unrealize (NmtNewtWidget *widget)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
if (priv->realized) {
NMT_NEWT_WIDGET_GET_CLASS (widget)->unrealize (widget);
priv->realized = FALSE;
}
}
/**
* nmt_newt_widget_get_components:
* @widget: an #NmtNewtWidget
*
* Gets the #newtComponents that make up @widget, if @widget is
* visible. If @widget has not yet been realized, it will be realized
* first.
*
* If this function is called on a widget, then the widget will assume
* that someone else is now responsible for destroying the components,
* and so it will not destroy them itself when the widget is
* destroyed. Normally, components will end up being destroyed by the
* #NmtNewtForm they are added to.
*
* Returns: a %NULL-terminated array of components, in focus-chain
* order. You must free the array with g_free() when you are done
* with it.
*/
newtComponent *
nmt_newt_widget_get_components (NmtNewtWidget *widget)
{
if (nmt_newt_widget_get_visible (widget)) {
nmt_newt_widget_realize (widget);
return NMT_NEWT_WIDGET_GET_CLASS (widget)->get_components (widget);
} else
return NULL;
}
/**
* nmt_newt_widget_find_component:
* @widget: an #NmtNewtWidget
* @co: a #newtComponent
*
* Finds the widget inside @widget that owns @co.
*
* Return value: @co's owner, or %NULL if it was not found.
*/
NmtNewtWidget *
nmt_newt_widget_find_component (NmtNewtWidget *widget,
newtComponent co)
{
return NMT_NEWT_WIDGET_GET_CLASS (widget)->find_component (widget, co);
}
/**
* nmt_newt_widget_set_padding:
* @widget: an #NmtNewtWidget
* @pad_left: padding on the left of @widget
* @pad_top: padding on the top of @widget
* @pad_right: padding on the right of @widget
* @pad_bottom: padding on the bottom of @widget
*
* Sets the padding on @widget.
*/
void
nmt_newt_widget_set_padding (NmtNewtWidget *widget,
int pad_left,
int pad_top,
int pad_right,
int pad_bottom)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
priv->pad_left = pad_left;
priv->pad_top = pad_top;
priv->pad_right = pad_right;
priv->pad_bottom = pad_bottom;
}
/**
* nmt_newt_widget_size_request:
* @widget: an #NmtNewtWidget
* @width: (out): on output, the widget's requested width
* @height: (out): on output, the widget's requested height
*
* Asks @widget for its requested size. If @widget is not visible,
* this will return 0, 0. If @widget has not yet been realized, it
* will be realized first.
*/
void
nmt_newt_widget_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
if (nmt_newt_widget_get_visible (widget)) {
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
nmt_newt_widget_realize (widget);
NMT_NEWT_WIDGET_GET_CLASS (widget)->size_request (widget, width, height);
*width += priv->pad_left + priv->pad_right;
*height += priv->pad_top + priv->pad_bottom;
} else
*width = *height = 0;
}
/**
* nmt_newt_widget_size_allocate:
* @widget: an #NmtNewtWidget
* @x: the widget's (absolute) X coordinate
* @y: the widget's (absolute) Y coordinate
* @width: the widget's allocated width
* @height: the widget's allocated height
*
* Positions @widget at the given coordinates, with the given size. If
* @widget is not visible, this has no effect. If @widget has not yet
* been realized, it will be realized first.
*
* @x and @y are absolute coordinates (ie, relative to the screen /
* terminal window, not relative to @widget's parent).
*
* In general, the results are undefined if @width or @height is less
* than the widget's requested size. If @width or @height is larger
* than the requested size, most #NmtNewtComponents will ignore the
* extra space, but some components and most containers will expand to
* fit.
*/
void
nmt_newt_widget_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
if (nmt_newt_widget_get_visible (widget)) {
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
nmt_newt_widget_realize (widget);
x += priv->pad_left;
y += priv->pad_top;
width -= priv->pad_left + priv->pad_right;
height -= priv->pad_top + priv->pad_bottom;
NMT_NEWT_WIDGET_GET_CLASS (widget)->size_allocate (widget, x, y, width, height);
}
}
/**
* nmt_newt_widget_get_focus_component:
* @widget: an #NmtNewtWidget
*
* Gets the #newtComponent that should be given the keyboard focus when
* @widget is focused.
*
* Returns: the #newtComponent to focus, or %NULL if @widget can't
* take the focus.
*/
newtComponent
nmt_newt_widget_get_focus_component (NmtNewtWidget *widget)
{
if (!NMT_NEWT_WIDGET_GET_CLASS (widget)->get_focus_component)
return NULL;
return NMT_NEWT_WIDGET_GET_CLASS (widget)->get_focus_component (widget);
}
static void
nmt_newt_widget_real_activated (NmtNewtWidget *widget)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
if (priv->exit_on_activate)
nmt_newt_form_quit (nmt_newt_widget_get_form (widget));
}
/**
* nmt_newt_widget_activated:
* @widget: an #NmtNewtWidget
*
* Tells @widget that its #newtComponent has been activated (ie, the
* user hit "Return" on it) and emits #NmtNewtWidget::activated.
*
* If #NmtNewtWidget:exit-on-activate is set on @widget, then this
* will call nmt_newt_form_quit() on the widget's form.
*/
void
nmt_newt_widget_activated (NmtNewtWidget *widget)
{
g_signal_emit (widget, signals[ACTIVATED], 0);
}
/**
* nmt_newt_widget_get_exit_on_activate:
* @widget: an #NmtNewtWidget
*
* Gets @widget's #NmtNewtWidget:exit-on-activate flag, qv.
*
* Returns: @widget's #NmtNewtWidget:exit-on-activate flag
*/
gboolean
nmt_newt_widget_get_exit_on_activate (NmtNewtWidget *widget)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
return priv->exit_on_activate;
}
/**
* nmt_newt_widget_set_exit_on_activate:
* @widget: an #NmtNewtWidget
* @exit_on_activate: whether @widget should exit on activate.
*
* Sets @widget's #NmtNewtWidget:exit-on-activate flag, qv.
*/
void
nmt_newt_widget_set_exit_on_activate (NmtNewtWidget *widget,
gboolean exit_on_activate)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
exit_on_activate = !!exit_on_activate;
if (priv->exit_on_activate != exit_on_activate) {
priv->exit_on_activate = exit_on_activate;
g_object_notify (G_OBJECT (widget), "exit-on-activate");
}
}
/**
* nmt_newt_widget_get_visible:
* @widget: an #NmtNewtWidget
*
* Gets @widget's #NmtNewtWidget:visible flag, qv.
*
* Returns: @widget's #NmtNewtWidget:visible flag
*/
gboolean
nmt_newt_widget_get_visible (NmtNewtWidget *widget)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
return priv->visible;
}
/**
* nmt_newt_widget_set_visible:
* @widget: an #NmtNewtWidget
* @visible: whether @widget should be visible
*
* Sets @widget's #NmtNewtWidget:visible flag, qv.
*/
void
nmt_newt_widget_set_visible (NmtNewtWidget *widget,
gboolean visible)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
visible = !!visible;
if (priv->visible != visible) {
priv->visible = visible;
g_object_notify (G_OBJECT (widget), "visible");
nmt_newt_widget_needs_rebuild (widget);
}
}
/**
* nmt_newt_widget_set_parent:
* @widget: an #NmtNewtWidget
* @parent: @widget's parent
*
* Sets @widget's parent to @parent. This is used internally by
* #NmtNewtContainer implementations; you must use an appropriate
* container-specific method to actually add a widget to a container.
*/
void
nmt_newt_widget_set_parent (NmtNewtWidget *widget,
NmtNewtWidget *parent)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
g_clear_object (&priv->parent);
priv->parent = parent ? g_object_ref (parent) : NULL;
g_object_notify (G_OBJECT (widget), "parent");
}
/**
* nmt_newt_widget_get_parent:
* @widget: an #NmtNewtWidget
*
* Gets @widget's parent
*
* Returns: @widget's parent
*/
NmtNewtWidget *
nmt_newt_widget_get_parent (NmtNewtWidget *widget)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
return priv->parent;
}
/**
* nmt_newt_widget_get_form:
* @widget: an #NmtNewtWidget
*
* Gets @widget's top-level form.
*
* Returns: @widget's #NmtNewtForm
*/
NmtNewtForm *
nmt_newt_widget_get_form (NmtNewtWidget *widget)
{
while (widget) {
if (NMT_IS_NEWT_FORM (widget))
return NMT_NEWT_FORM (widget);
widget = nmt_newt_widget_get_parent (widget);
}
return NULL;
}
/**
* nmt_newt_widget_get_valid:
* @widget: an #NmtNewtWidget
*
* Gets @widget's #NmtNewtWidget:valid flag, indicating whether its
* content is valid.
*
* Returns: @widget's #NmtNewtWidget:valid flag
*/
gboolean
nmt_newt_widget_get_valid (NmtNewtWidget *widget)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
return priv->valid;
}
/**
* nmt_newt_widget_set_valid:
* @widget: an #NmtNewtWidget
* @valid: whether @widget is valid
*
* Sets @widget's #NmtNewtWidget:valid flag, indicating whether its
* content is valid.
*
* This method should be considered "protected"; if you change it, the
* widget implementation will likely just change it back at some
* point.
*/
void
nmt_newt_widget_set_valid (NmtNewtWidget *widget,
gboolean valid)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget);
valid = !!valid;
if (priv->valid == valid)
return;
priv->valid = valid;
g_object_notify (G_OBJECT (widget), "valid");
}
/**
* nmt_newt_widget_needs_rebuilds:
* @widget: an #NmtNewtWidget
*
* Marks @widget as needing to be "rebuilt" (ie, re-realized). This is
* called automatically in some cases (such as when adding a widget to
* or removing it from a container). #NmtNewtComponent implementations
* should also call this if they need to make some change that can
* only be done by destroying their current #newtComponent and
* creating a new one.
*/
void
nmt_newt_widget_needs_rebuild (NmtNewtWidget *widget)
{
g_signal_emit (widget, signals[NEEDS_REBUILD], 0);
}
static void
nmt_newt_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtNewtWidget *widget = NMT_NEWT_WIDGET (object);
switch (prop_id) {
case PROP_PARENT:
nmt_newt_widget_set_parent (widget, g_value_get_object (value));
break;
case PROP_VISIBLE:
nmt_newt_widget_set_visible (widget, g_value_get_boolean (value));
break;
case PROP_EXIT_ON_ACTIVATE:
nmt_newt_widget_set_exit_on_activate (widget, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (object);
switch (prop_id) {
case PROP_PARENT:
g_value_set_object (value, priv->parent);
break;
case PROP_VISIBLE:
g_value_set_boolean (value, priv->visible);
break;
case PROP_VALID:
g_value_set_boolean (value, priv->valid);
break;
case PROP_EXIT_ON_ACTIVATE:
g_value_set_boolean (value, priv->exit_on_activate);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_newt_widget_class_init (NmtNewtWidgetClass *widget_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (widget_class);
g_type_class_add_private (widget_class, sizeof (NmtNewtWidgetPrivate));
/* virtual methods */
object_class->set_property = nmt_newt_widget_set_property;
object_class->get_property = nmt_newt_widget_get_property;
object_class->finalize = nmt_newt_widget_finalize;
widget_class->activated = nmt_newt_widget_real_activated;
/* signals */
/**
* NmtNewtWidget::needs-rebuild:
* @widget: the #NmtNewtWidget
*
* Emitted when nmt_newt_widget_need_rebuild() is called on @widget
* or any of its children. This signal propagates up the container
* hierarchy, eventually reaching the top-level #NmtNewtForm.
*/
signals[NEEDS_REBUILD] =
g_signal_new ("needs-rebuild",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NmtNewtWidgetClass, needs_rebuild),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
/**
* NmtNewtWidget::activated:
* @widget: the #NmtNewtWidget
*
* Emitted when the widget's #newtComponent is activated.
*/
signals[ACTIVATED] =
g_signal_new ("activated",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NmtNewtWidgetClass, activated),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
/* properties */
/**
* NmtNewtWidget:parent:
*
* The widget's parent widget, or %NULL if it has no parent.
*/
g_object_class_install_property (object_class, PROP_PARENT,
g_param_spec_object ("parent", "", "",
NMT_TYPE_NEWT_WIDGET,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtWidget:visible:
*
* Whether the widget is visible. Invisible widgets do not get
* realized or sized.
*/
g_object_class_install_property (object_class, PROP_VISIBLE,
g_param_spec_boolean ("visible", "", "",
TRUE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtWidget:valid:
*
* Whether the widget's content is considered valid. Components
* determine their own validity. A container, by default, is
* considered valid if all of its children are valid.
*/
g_object_class_install_property (object_class, PROP_VALID,
g_param_spec_boolean ("valid", "", "",
TRUE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NmtNewtWidget:exit-on-activate:
*
* If %TRUE, the widget will call nmt_newt_form_quit() on its form
* when it is activated.
*/
g_object_class_install_property (object_class, PROP_EXIT_ON_ACTIVATE,
g_param_spec_boolean ("exit-on-activate", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

117
tui/newt/nmt-newt-widget.h Normal file
View File

@@ -0,0 +1,117 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_WIDGET_H
#define NMT_NEWT_WIDGET_H
#include "nmt-newt-types.h"
G_BEGIN_DECLS
#define NMT_TYPE_NEWT_WIDGET (nmt_newt_widget_get_type ())
#define NMT_NEWT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_NEWT_WIDGET, NmtNewtWidget))
#define NMT_NEWT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_NEWT_WIDGET, NmtNewtWidgetClass))
#define NMT_IS_NEWT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_NEWT_WIDGET))
#define NMT_IS_NEWT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_NEWT_WIDGET))
#define NMT_NEWT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_NEWT_WIDGET, NmtNewtWidgetClass))
struct _NmtNewtWidget {
GInitiallyUnowned parent;
};
typedef struct {
GInitiallyUnownedClass parent;
/* signals */
void (*needs_rebuild) (NmtNewtWidget *widget);
void (*activated) (NmtNewtWidget *widget);
/* methods */
void (*realize) (NmtNewtWidget *widget);
void (*unrealize) (NmtNewtWidget *widget);
newtComponent * (*get_components) (NmtNewtWidget *widget);
NmtNewtWidget * (*find_component) (NmtNewtWidget *widget,
newtComponent co);
void (*size_request) (NmtNewtWidget *widget,
int *width,
int *height);
void (*size_allocate) (NmtNewtWidget *widget,
int x,
int y,
int width,
int height);
newtComponent (*get_focus_component) (NmtNewtWidget *widget);
} NmtNewtWidgetClass;
GType nmt_newt_widget_get_type (void);
void nmt_newt_widget_realize (NmtNewtWidget *widget);
void nmt_newt_widget_unrealize (NmtNewtWidget *widget);
newtComponent *nmt_newt_widget_get_components (NmtNewtWidget *widget);
void nmt_newt_widget_set_padding (NmtNewtWidget *widget,
int pad_left,
int pad_top,
int pad_right,
int pad_bottom);
void nmt_newt_widget_size_request (NmtNewtWidget *widget,
int *width,
int *height);
void nmt_newt_widget_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height);
void nmt_newt_widget_set_parent (NmtNewtWidget *widget,
NmtNewtWidget *parent);
NmtNewtWidget *nmt_newt_widget_get_parent (NmtNewtWidget *widget);
NmtNewtForm *nmt_newt_widget_get_form (NmtNewtWidget *widget);
gboolean nmt_newt_widget_get_visible (NmtNewtWidget *widget);
void nmt_newt_widget_set_visible (NmtNewtWidget *widget,
gboolean visible);
newtComponent nmt_newt_widget_get_focus_component (NmtNewtWidget *widget);
void nmt_newt_widget_activated (NmtNewtWidget *widget);
gboolean nmt_newt_widget_get_exit_on_activate (NmtNewtWidget *widget);
void nmt_newt_widget_set_exit_on_activate (NmtNewtWidget *widget,
gboolean exit_on_activate);
gboolean nmt_newt_widget_get_valid (NmtNewtWidget *widget);
NmtNewtWidget *nmt_newt_widget_find_component (NmtNewtWidget *widget,
newtComponent co);
/* protected */
void nmt_newt_widget_needs_rebuild (NmtNewtWidget *widget);
void nmt_newt_widget_set_valid (NmtNewtWidget *widget,
gboolean valid);
G_END_DECLS
#endif /* NMT_NEWT_WIDGET_H */

39
tui/newt/nmt-newt.h Normal file
View File

@@ -0,0 +1,39 @@
/* -*- 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.
*/
#ifndef NMT_NEWT_H
#define NMT_NEWT_H
#include "nmt-newt-button.h"
#include "nmt-newt-button-box.h"
#include "nmt-newt-checkbox.h"
#include "nmt-newt-entry.h"
#include "nmt-newt-entry-numeric.h"
#include "nmt-newt-form.h"
#include "nmt-newt-grid.h"
#include "nmt-newt-label.h"
#include "nmt-newt-listbox.h"
#include "nmt-newt-popup.h"
#include "nmt-newt-section.h"
#include "nmt-newt-separator.h"
#include "nmt-newt-stack.h"
#include "nmt-newt-textbox.h"
#include "nmt-newt-toggle-button.h"
#include "nmt-newt-utils.h"
#endif /* NMT_NEWT_H */

1666
tui/nm-editor-bindings.c Normal file

File diff suppressed because it is too large Load Diff

99
tui/nm-editor-bindings.h Normal file
View File

@@ -0,0 +1,99 @@
/* -*- 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.
*/
#ifndef NM_EDITOR_BINDINGS_H
#define NM_EDITOR_BINDINGS_H
#include <glib-object.h>
#include <nm-connection.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-vlan.h>
G_BEGIN_DECLS
void nm_editor_bindings_init (void);
void nm_editor_bind_ip4_addresses_with_prefix_to_strv (gpointer source,
const gchar *source_property,
gpointer target,
const gchar *target_property,
GBindingFlags flags);
void nm_editor_bind_ip4_addresses_to_strv (gpointer source,
const gchar *source_property,
gpointer target,
const gchar *target_property,
GBindingFlags flags);
void nm_editor_bind_ip4_gateway_to_string (gpointer source,
const gchar *source_property,
gpointer target,
const gchar *target_property,
GBindingFlags flags);
void nm_editor_bind_ip4_route_to_strings (gpointer source,
const gchar *source_property,
gpointer dest_target,
const gchar *dest_target_property,
gpointer next_hop_target,
const gchar *next_hop_target_property,
gpointer metric_target,
const gchar *metric_target_property,
GBindingFlags flags);
void nm_editor_bind_ip6_addresses_with_prefix_to_strv (gpointer source,
const gchar *source_property,
gpointer target,
const gchar *target_property,
GBindingFlags flags);
void nm_editor_bind_ip6_addresses_to_strv (gpointer source,
const gchar *source_property,
gpointer target,
const gchar *target_property,
GBindingFlags flags);
void nm_editor_bind_ip6_gateway_to_string (gpointer source,
const gchar *source_property,
gpointer target,
const gchar *target_property,
GBindingFlags flags);
void nm_editor_bind_ip6_route_to_strings (gpointer source,
const gchar *source_property,
gpointer dest_target,
const gchar *dest_target_property,
gpointer next_hop_target,
const gchar *next_hop_target_property,
gpointer metric_target,
const gchar *metric_target_property,
GBindingFlags flags);
void nm_editor_bind_wireless_security_method (NMConnection *connection,
NMSettingWirelessSecurity *s_wsec,
gpointer target,
const char *target_property,
GBindingFlags flags);
void nm_editor_bind_wireless_security_wep_key (NMSettingWirelessSecurity *s_wsec,
gpointer entry,
const char *entry_property,
gpointer key_selector,
const char *key_selector_property,
GBindingFlags flags);
void nm_editor_bind_vlan_name (NMSettingVlan *s_vlan);
G_END_DECLS
#endif /* NM_EDITOR_BINDINGS_H */

420
tui/nm-editor-utils.c Normal file
View File

@@ -0,0 +1,420 @@
/* -*- 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 2012, 2013 Red Hat, Inc.
*/
/**
* SECTION:nm-editor-utils
* @short_description: Miscellaneous connection editor utilities
*
* nm-editor-utils contains helper functions for connection editors.
* The goal is that this should eventually be shared between nmtui,
* nm-connection-editor, and gnome-control-center.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <nm-utils.h>
#include <nm-device-bond.h>
#include <nm-device-bridge.h>
#include <nm-device-team.h>
#include <nm-device-ethernet.h>
#include <nm-device-infiniband.h>
#include <nm-device-team.h>
#include <nm-device-vlan.h>
#include <nm-device-wifi.h>
#include "nm-editor-utils.h"
#if 0
#include "vpn-helpers.h"
static GSList *vpn_plugins;
static gint
sort_vpn_plugins (gconstpointer a, gconstpointer b)
{
NMVpnPluginUiInterface *aa = NM_VPN_PLUGIN_UI_INTERFACE (a);
NMVpnPluginUiInterface *bb = NM_VPN_PLUGIN_UI_INTERFACE (b);
char *aa_desc = NULL, *bb_desc = NULL;
int ret;
g_object_get (aa, NM_VPN_PLUGIN_UI_INTERFACE_NAME, &aa_desc, NULL);
g_object_get (bb, NM_VPN_PLUGIN_UI_INTERFACE_NAME, &bb_desc, NULL);
ret = g_strcmp0 (aa_desc, bb_desc);
g_free (aa_desc);
g_free (bb_desc);
return ret;
}
#endif
static void
wifi_connection_setup_func (NMConnection *connection,
NMSettingConnection *s_con,
NMSetting *s_hw)
{
g_object_set (G_OBJECT (s_hw),
NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA,
NULL);
}
static void
bond_connection_setup_func (NMConnection *connection,
NMSettingConnection *s_con,
NMSetting *s_hw)
{
NMSettingBond *s_bond = NM_SETTING_BOND (s_hw);
const char **options, *def, *cur;
int i;
options = nm_setting_bond_get_valid_options (s_bond);
for (i = 0; options[i]; i++) {
def = nm_setting_bond_get_option_default (s_bond, options[i]);
cur = nm_setting_bond_get_option_by_name (s_bond, options[i]);
if (g_strcmp0 (def, cur) != 0)
nm_setting_bond_add_option (s_bond, options[i], def);
}
}
typedef void (*NMEditorNewConnectionSetupFunc) (NMConnection *connection,
NMSettingConnection *s_con,
NMSetting *s_hw);
typedef struct {
NMEditorConnectionTypeData data;
const char *id_format;
NMEditorNewConnectionSetupFunc connection_setup_func;
gboolean no_autoconnect;
} NMEditorConnectionTypeDataReal;
static gint
sort_types (gconstpointer a, gconstpointer b)
{
NMEditorConnectionTypeData *typea = *(NMEditorConnectionTypeData **)a;
NMEditorConnectionTypeData *typeb = *(NMEditorConnectionTypeData **)b;
if (typea->virtual && !typeb->virtual)
return 1;
else if (typeb->virtual && !typea->virtual)
return -1;
if (typea->setting_type == NM_TYPE_SETTING_VPN &&
typeb->setting_type != NM_TYPE_SETTING_VPN)
return 1;
else if (typeb->setting_type == NM_TYPE_SETTING_VPN &&
typea->setting_type != NM_TYPE_SETTING_VPN)
return -1;
return g_utf8_collate (typea->name, typeb->name);
}
/**
* nm_editor_utils_get_connection_type_list:
*
* Gets an array of information about supported connection types. The
* array is sorted in a standard presentation order (hardware types
* first, alphabetized, then virtual types, alphabetized, then VPN
* types, alphabetized).
*
* Returns: the array of connection type information
*/
NMEditorConnectionTypeData **
nm_editor_utils_get_connection_type_list (void)
{
GPtrArray *array;
NMEditorConnectionTypeDataReal *item;
static NMEditorConnectionTypeData **list;
#if 0
GHashTable *vpn_plugins_hash;
gboolean have_vpn_plugins;
#endif
if (list)
return list;
array = g_ptr_array_new ();
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("Ethernet");
item->data.setting_type = NM_TYPE_SETTING_WIRED;
item->data.device_type = NM_TYPE_DEVICE_ETHERNET;
item->data.virtual = FALSE;
item->id_format = _("Ethernet connection %d");
g_ptr_array_add (array, item);
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("Wi-Fi");
item->data.setting_type = NM_TYPE_SETTING_WIRELESS;
item->data.device_type = NM_TYPE_DEVICE_WIFI;
item->data.virtual = FALSE;
item->id_format = _("Wi-Fi connection %d");
item->connection_setup_func = wifi_connection_setup_func;
g_ptr_array_add (array, item);
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("InfiniBand");
item->data.setting_type = NM_TYPE_SETTING_INFINIBAND;
item->data.device_type = NM_TYPE_DEVICE_INFINIBAND;
item->data.virtual = FALSE;
item->id_format = _("InfiniBand connection %d");
g_ptr_array_add (array, item);
#if 0
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("Mobile Broadband");
item->data.setting_type = NM_TYPE_SETTING_GSM;
item->data.virtual = FALSE;
item->id_format = _("Mobile broadband connection %d");
item->no_autoconnect = TRUE;
g_ptr_array_add (array, item);
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("DSL");
item->data.setting_type = NM_TYPE_SETTING_PPPOE;
item->data.device_type = NM_TYPE_DEVICE_ETHERNET;
item->data.virtual = FALSE;
item->id_format = _("DSL connection %d");
item->no_autoconnect = TRUE;
g_ptr_array_add (array, item);
#endif
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("Bond");
item->data.setting_type = NM_TYPE_SETTING_BOND;
item->data.device_type = NM_TYPE_DEVICE_BOND;
item->data.virtual = TRUE;
item->id_format = _("Bond connection %d");
item->connection_setup_func = bond_connection_setup_func;
g_ptr_array_add (array, item);
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("Bridge");
item->data.setting_type = NM_TYPE_SETTING_BRIDGE;
item->data.slave_setting_type = NM_TYPE_SETTING_BRIDGE_PORT;
item->data.device_type = NM_TYPE_DEVICE_BRIDGE;
item->data.virtual = TRUE;
item->id_format = _("Bridge connection %d");
g_ptr_array_add (array, item);
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("Team");
item->data.setting_type = NM_TYPE_SETTING_TEAM;
item->data.slave_setting_type = NM_TYPE_SETTING_TEAM_PORT;
item->data.device_type = NM_TYPE_DEVICE_TEAM;
item->data.virtual = TRUE;
item->id_format = _("Team connection %d");
g_ptr_array_add (array, item);
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("VLAN");
item->data.setting_type = NM_TYPE_SETTING_VLAN;
item->data.device_type = NM_TYPE_DEVICE_VLAN;
item->data.virtual = TRUE;
item->id_format = _("VLAN connection %d");
g_ptr_array_add (array, item);
#if 0
/* Add "VPN" only if there are plugins */
vpn_plugins_hash = vpn_get_plugins (NULL);
have_vpn_plugins = vpn_plugins_hash && g_hash_table_size (vpn_plugins_hash);
if (have_vpn_plugins) {
GHashTableIter iter;
gpointer name, plugin;
item = g_new0 (NMEditorConnectionTypeDataReal, 1);
item->data.name = _("VPN");
item->data.setting_type = NM_TYPE_SETTING_VPN;
item->data.virtual = TRUE;
item->id_format = _("VPN connection %d");
item->no_autoconnect = TRUE;
g_ptr_array_add (array, item);
vpn_plugins = NULL;
g_hash_table_iter_init (&iter, vpn_plugins_hash);
while (g_hash_table_iter_next (&iter, &name, &plugin))
vpn_plugins = g_slist_prepend (vpn_plugins, plugin);
vpn_plugins = g_slist_sort (vpn_plugins, sort_vpn_plugins);
}
#endif
g_ptr_array_sort (array, sort_types);
g_ptr_array_add (array, NULL);
list = (NMEditorConnectionTypeData **)g_ptr_array_free (array, FALSE);
return list;
}
static char *
get_available_connection_name (const char *format,
NMRemoteSettings *settings)
{
GSList *connections, *iter, *names = NULL;
char *cname = NULL;
int i = 0;
connections = nm_remote_settings_list_connections (settings);
for (iter = connections; iter; iter = iter->next) {
const char *id;
id = nm_connection_get_id (NM_CONNECTION (iter->data));
g_assert (id);
names = g_slist_append (names, (gpointer) id);
}
g_slist_free (connections);
/* Find the next available unique connection name */
while (!cname && (i++ < 10000)) {
char *temp;
gboolean found = FALSE;
temp = g_strdup_printf (format, i);
for (iter = names; iter; iter = g_slist_next (iter)) {
if (!strcmp (iter->data, temp)) {
found = TRUE;
break;
}
}
if (!found)
cname = temp;
else
g_free (temp);
}
g_slist_free (names);
return cname;
}
/**
* nm_editor_utils_create_connection:
* @type: the type of the connection's primary #NMSetting
* @master: (allow-none): the connection's master, if any
* @settings: an #NMRemoteSettings
*
* Creates a new #NMConnection of the given type, automatically
* creating a UUID and an appropriate not-currently-in-use connection
* name, setting #NMSettingConnection:autoconnect appropriately for
* the connection type, filling in slave-related information if
* @master is not %NULL, and initializing any other mandatory-to-set
* properties to reasonable initial values.
*
* Returns: a new #NMConnection
*/
NMConnection *
nm_editor_utils_create_connection (GType type,
NMConnection *master,
NMRemoteSettings *settings)
{
NMEditorConnectionTypeData **types;
NMEditorConnectionTypeDataReal *type_data = NULL;
const char *master_setting_type = NULL, *master_uuid = NULL;
GType master_type = G_TYPE_INVALID, slave_setting_type = G_TYPE_INVALID;
NMConnection *connection;
NMSettingConnection *s_con;
NMSetting *s_hw, *s_slave;
char *uuid, *id;
int i;
if (master) {
NMSettingConnection *master_s_con;
master_s_con = nm_connection_get_setting_connection (master);
master_setting_type = nm_setting_connection_get_connection_type (master_s_con);
master_uuid = nm_setting_connection_get_uuid (master_s_con);
master_type = nm_connection_lookup_setting_type (master_setting_type);
}
types = nm_editor_utils_get_connection_type_list ();
for (i = 0; types[i]; i++) {
if (types[i]->setting_type == type)
type_data = (NMEditorConnectionTypeDataReal *)types[i];
if (types[i]->setting_type == master_type)
slave_setting_type = types[i]->slave_setting_type;
}
g_return_val_if_fail (type_data != NULL, NULL);
connection = nm_connection_new ();
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
nm_connection_add_setting (connection, NM_SETTING (s_con));
s_hw = g_object_new (type, NULL);
nm_connection_add_setting (connection, s_hw);
if (slave_setting_type != G_TYPE_INVALID) {
s_slave = g_object_new (slave_setting_type, NULL);
nm_connection_add_setting (connection, s_slave);
}
uuid = nm_utils_uuid_generate ();
id = get_available_connection_name (type_data->id_format, settings);
g_object_set (s_con,
NM_SETTING_CONNECTION_UUID, uuid,
NM_SETTING_CONNECTION_ID, id,
NM_SETTING_CONNECTION_TYPE, nm_setting_get_name (s_hw),
NM_SETTING_CONNECTION_AUTOCONNECT, !type_data->no_autoconnect,
NM_SETTING_CONNECTION_MASTER, master_uuid,
NM_SETTING_CONNECTION_SLAVE_TYPE, master_setting_type,
NULL);
g_free (uuid);
g_free (id);
if (type_data->connection_setup_func)
type_data->connection_setup_func (connection, s_con, s_hw);
return connection;
}
/**
* nm_editor_utils_get_connection_type_data:
* @conn: an #NMConnection
*
* Gets the #NMEditorConnectionTypeData corresponding to
* @conn's connection type.
*
* Returns: the #NMEditorConnectionTypeData
*/
NMEditorConnectionTypeData *
nm_editor_utils_get_connection_type_data (NMConnection *conn)
{
NMSettingConnection *s_con;
const char *conn_type;
GType conn_gtype;
NMEditorConnectionTypeData **types;
int i;
s_con = nm_connection_get_setting_connection (conn);
g_return_val_if_fail (s_con != NULL, NULL);
conn_type = nm_setting_connection_get_connection_type (s_con);
conn_gtype = nm_connection_lookup_setting_type (conn_type);
g_return_val_if_fail (conn_gtype != G_TYPE_INVALID, NULL);
types = nm_editor_utils_get_connection_type_list ();
for (i = 0; types[i]; i++) {
if (types[i]->setting_type == conn_gtype)
return types[i];
}
return NULL;
}

44
tui/nm-editor-utils.h Normal file
View File

@@ -0,0 +1,44 @@
/* -*- 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 2012, 2013 Red Hat, Inc.
*/
#ifndef NM_EDITOR_UTILS_H
#define NM_EDITOR_UTILS_H
#include <glib-object.h>
#include <nm-remote-settings.h>
G_BEGIN_DECLS
typedef struct {
const char *name;
GType setting_type;
GType slave_setting_type;
GType device_type;
gboolean virtual;
} NMEditorConnectionTypeData;
NMEditorConnectionTypeData **nm_editor_utils_get_connection_type_list (void);
NMEditorConnectionTypeData *nm_editor_utils_get_connection_type_data (NMConnection *conn);
NMConnection *nm_editor_utils_create_connection (GType type,
NMConnection *master,
NMRemoteSettings *settings);
G_END_DECLS
#endif /* NM_EDITOR_UTILS_H */

101
tui/nm-gvaluearray-compat.h Normal file
View File

@@ -0,0 +1,101 @@
/* -*- 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.
*/
#ifndef NM_GVALUEARRAY_COMPAT_H
#define NM_GVALUEARRAY_COMPAT_H
#include <glib.h>
#define g_value_array_get_type() \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_get_type (); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_get_nth(value_array, index_) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_get_nth (value_array, index_); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_new(n_prealloced) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_new (n_prealloced); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_free(value_array) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_free (value_array); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_copy(value_array) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_copy (value_array); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_prepend(value_array, value) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_prepend (value_array, value); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_append(value_array, value) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_append (value_array, value); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_insert(value_array, index_, value) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_insert (value_array, index_, value); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_remove(value_array, index_) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_remove (value_array, index_); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_sort(value_array, compare_func) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_sort (value_array, compare_func); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#define g_value_array_sort_with_data(value_array, compare_func, user_data) \
G_GNUC_EXTENSION ({ \
G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
g_value_array_sort_with_data (value_array, compare_func, user_data); \
G_GNUC_END_IGNORE_DEPRECATIONS \
})
#endif /* NM_GVALUEARRAY_COMPAT_H */

587
tui/nm-ui-utils.c Normal file
View File

@@ -0,0 +1,587 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2007 - 2012 Red Hat, Inc.
*/
/**
* SECTION:nm-ui-utils
* @short_description: Applet/Connection editor utilities
*
* This is stolen directly from libnm-gtk and should probably
* eventually migrate into libnm-glib. FIXME.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <glib/gi18n.h>
#include <gudev/gudev.h>
#include <nm-device.h>
#include "nm-ui-utils.h"
static char *ignored_words[] = {
"Semiconductor",
"Components",
"Corporation",
"Communications",
"Company",
"Corp.",
"Corp",
"Co.",
"Inc.",
"Inc",
"Incorporated",
"Ltd.",
"Limited.",
"Intel?",
"chipset",
"adapter",
"[hex]",
"NDIS",
"Module",
NULL
};
static char *ignored_phrases[] = {
"Multiprotocol MAC/baseband processor",
"Wireless LAN Controller",
"Wireless LAN Adapter",
"Wireless Adapter",
"Network Connection",
"Wireless Cardbus Adapter",
"Wireless CardBus Adapter",
"54 Mbps Wireless PC Card",
"Wireless PC Card",
"Wireless PC",
"PC Card with XJACK(r) Antenna",
"Wireless cardbus",
"Wireless LAN PC Card",
"Technology Group Ltd.",
"Communication S.p.A.",
"Business Mobile Networks BV",
"Mobile Broadband Minicard Composite Device",
"Mobile Communications AB",
"(PC-Suite Mode)",
NULL
};
static char *
fixup_desc_string (const char *desc)
{
char *p, *temp;
char **words, **item;
GString *str;
p = temp = g_strdup (desc);
while (*p) {
if (*p == '_' || *p == ',')
*p = ' ';
p++;
}
/* Attempt to shorten ID by ignoring certain phrases */
for (item = ignored_phrases; *item; item++) {
guint32 ignored_len = strlen (*item);
p = strstr (temp, *item);
if (p)
memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */
}
/* Attmept to shorten ID by ignoring certain individual words */
words = g_strsplit (temp, " ", 0);
str = g_string_new_len (NULL, strlen (temp));
g_free (temp);
for (item = words; *item; item++) {
int i = 0;
gboolean ignore = FALSE;
if (g_ascii_isspace (**item) || (**item == '\0'))
continue;
while (ignored_words[i] && !ignore) {
if (!strcmp (*item, ignored_words[i]))
ignore = TRUE;
i++;
}
if (!ignore) {
if (str->len)
g_string_append_c (str, ' ');
g_string_append (str, *item);
}
}
g_strfreev (words);
temp = str->str;
g_string_free (str, FALSE);
return temp;
}
#define VENDOR_TAG "nma_utils_get_device_vendor"
#define PRODUCT_TAG "nma_utils_get_device_product"
#define DESCRIPTION_TAG "nma_utils_get_device_description"
static void
get_description (NMDevice *device)
{
char *description = NULL;
const char *dev_product;
const char *dev_vendor;
char *product, *pdown;
char *vendor, *vdown;
GString *str;
dev_product = nm_device_get_product (device);
dev_vendor = nm_device_get_vendor (device);
if (!dev_product || !dev_vendor) {
g_object_set_data (G_OBJECT (device),
DESCRIPTION_TAG,
(char *) nm_device_get_iface (device));
return;
}
product = fixup_desc_string (dev_product);
vendor = fixup_desc_string (dev_vendor);
str = g_string_new_len (NULL, strlen (vendor) + strlen (product) + 1);
/* Another quick hack; if all of the fixed up vendor string
* is found in product, ignore the vendor.
*/
pdown = g_ascii_strdown (product, -1);
vdown = g_ascii_strdown (vendor, -1);
if (!strstr (pdown, vdown)) {
g_string_append (str, vendor);
g_string_append_c (str, ' ');
}
g_free (pdown);
g_free (vdown);
g_string_append (str, product);
description = g_string_free (str, FALSE);
g_object_set_data_full (G_OBJECT (device),
VENDOR_TAG, vendor,
(GDestroyNotify) g_free);
g_object_set_data_full (G_OBJECT (device),
PRODUCT_TAG, product,
(GDestroyNotify) g_free);
g_object_set_data_full (G_OBJECT (device),
DESCRIPTION_TAG, description,
(GDestroyNotify) g_free);
}
/**
* nma_utils_get_device_vendor:
* @device: an #NMDevice
*
* Gets a cleaned-up version of #NMDevice:vendor for @device. This
* removes strings like "Inc." that would just take up unnecessary
* space in the UI.
*
* Returns: a cleaned-up vendor string, or %NULL if the vendor is
* not known
*/
const char *
nma_utils_get_device_vendor (NMDevice *device)
{
const char *vendor;
g_return_val_if_fail (device != NULL, NULL);
vendor = g_object_get_data (G_OBJECT (device), VENDOR_TAG);
if (!vendor) {
get_description (device);
vendor = g_object_get_data (G_OBJECT (device), VENDOR_TAG);
}
return vendor;
}
/**
* nma_utils_get_device_product:
* @device: an #NMDevice
*
* Gets a cleaned-up version of #NMDevice:product for @device. This
* removes strings like "Wireless LAN Adapter" that would just take up
* unnecessary space in the UI.
*
* Returns: a cleaned-up product string, or %NULL if the product name
* is not known
*/
const char *
nma_utils_get_device_product (NMDevice *device)
{
const char *product;
g_return_val_if_fail (device != NULL, NULL);
product = g_object_get_data (G_OBJECT (device), PRODUCT_TAG);
if (!product) {
get_description (device);
product = g_object_get_data (G_OBJECT (device), PRODUCT_TAG);
}
return product;
}
/**
* nma_utils_get_device_description:
* @device: an #NMDevice
*
* Gets a description of @device, incorporating the results of
* nma_utils_get_device_vendor() and
* nma_utils_get_device_product().
*
* Returns: a description of @device. If either the vendor or the
* product name is unknown, this returns the interface name.
*/
const char *
nma_utils_get_device_description (NMDevice *device)
{
const char *description;
g_return_val_if_fail (device != NULL, NULL);
description = g_object_get_data (G_OBJECT (device), DESCRIPTION_TAG);
if (!description) {
get_description (device);
description = g_object_get_data (G_OBJECT (device), DESCRIPTION_TAG);
}
return description;
}
static gboolean
find_duplicates (char **names,
gboolean *duplicates,
int num_devices)
{
int i, j;
gboolean found_any = FALSE;
memset (duplicates, 0, num_devices * sizeof (gboolean));
for (i = 0; i < num_devices; i++) {
if (duplicates[i])
continue;
for (j = i + 1; j < num_devices; j++) {
if (duplicates[j])
continue;
if (!strcmp (names[i], names[j]))
duplicates[i] = duplicates[j] = found_any = TRUE;
}
}
return found_any;
}
/**
* nma_utils_get_device_generic_type_name:
* @device: an #NMDevice
*
* Gets a "generic" name for the type of @device.
*
* Returns: @device's generic type name
*/
const char *
nma_utils_get_device_generic_type_name (NMDevice *device)
{
switch (nm_device_get_device_type (device)) {
case NM_DEVICE_TYPE_ETHERNET:
case NM_DEVICE_TYPE_INFINIBAND:
return _("Wired");
default:
return nma_utils_get_device_type_name (device);
}
}
/**
* nma_utils_get_device_type_name:
* @device: an #NMDevice
*
* Gets a specific name for the type of @device.
*
* Returns: @device's generic type name
*/
const char *
nma_utils_get_device_type_name (NMDevice *device)
{
switch (nm_device_get_device_type (device)) {
case NM_DEVICE_TYPE_ETHERNET:
return _("Ethernet");
case NM_DEVICE_TYPE_WIFI:
return _("Wi-Fi");
case NM_DEVICE_TYPE_BT:
return _("Bluetooth");
case NM_DEVICE_TYPE_OLPC_MESH:
return _("OLPC Mesh");
case NM_DEVICE_TYPE_WIMAX:
return _("WiMAX");
case NM_DEVICE_TYPE_MODEM:
return _("Mobile Broadband");
case NM_DEVICE_TYPE_INFINIBAND:
return _("InfiniBand");
case NM_DEVICE_TYPE_BOND:
return _("Bond");
case NM_DEVICE_TYPE_TEAM:
return _("Team");
case NM_DEVICE_TYPE_BRIDGE:
return _("Bridge");
case NM_DEVICE_TYPE_VLAN:
return _("VLAN");
case NM_DEVICE_TYPE_ADSL:
return _("ADSL");
default:
return _("Unknown");
}
}
static char *
get_device_type_name_with_iface (NMDevice *device)
{
const char *type_name = nma_utils_get_device_type_name (device);
switch (nm_device_get_device_type (device)) {
case NM_DEVICE_TYPE_BOND:
case NM_DEVICE_TYPE_TEAM:
case NM_DEVICE_TYPE_BRIDGE:
case NM_DEVICE_TYPE_VLAN:
return g_strdup_printf ("%s (%s)", type_name, nm_device_get_iface (device));
default:
return g_strdup (type_name);
}
}
static char *
get_device_generic_type_name_with_iface (NMDevice *device)
{
switch (nm_device_get_device_type (device)) {
case NM_DEVICE_TYPE_ETHERNET:
case NM_DEVICE_TYPE_INFINIBAND:
return g_strdup (_("Wired"));
default:
return get_device_type_name_with_iface (device);
}
}
#define BUS_TAG "nm-ui-utils.c:get_bus_name"
static const char *
get_bus_name (GUdevClient *uclient, NMDevice *device)
{
GUdevDevice *udevice;
const char *ifname, *bus;
char *display_bus;
bus = g_object_get_data (G_OBJECT (device), BUS_TAG);
if (bus) {
if (*bus)
return bus;
else
return NULL;
}
ifname = nm_device_get_iface (device);
if (!ifname)
return NULL;
udevice = g_udev_client_query_by_subsystem_and_name (uclient, "net", ifname);
if (!udevice)
udevice = g_udev_client_query_by_subsystem_and_name (uclient, "tty", ifname);
if (!udevice)
return NULL;
bus = g_udev_device_get_property (udevice, "ID_BUS");
if (!g_strcmp0 (bus, "pci"))
display_bus = g_strdup (_("PCI"));
else if (!g_strcmp0 (bus, "usb"))
display_bus = g_strdup (_("USB"));
else {
/* Use "" instead of NULL so we can tell later that we've
* already tried.
*/
display_bus = g_strdup ("");
}
g_object_set_data_full (G_OBJECT (device),
BUS_TAG, display_bus,
(GDestroyNotify) g_free);
if (*display_bus)
return display_bus;
else
return NULL;
}
/**
* nma_utils_disambiguate_device_names:
* @devices: (array length=num_devices): a set of #NMDevice
* @num_devices: length of @devices
*
* Generates a list of short-ish unique presentation names for the
* devices in @devices.
*
* Returns: (transfer full) (array zero-terminated=1): the device names
*/
char **
nma_utils_disambiguate_device_names (NMDevice **devices,
int num_devices)
{
static const char *subsys[3] = { "net", "tty", NULL };
GUdevClient *uclient;
char **names;
gboolean *duplicates;
int i;
names = g_new (char *, num_devices + 1);
duplicates = g_new (gboolean, num_devices);
/* Generic device name */
for (i = 0; i < num_devices; i++)
names[i] = get_device_generic_type_name_with_iface (devices[i]);
if (!find_duplicates (names, duplicates, num_devices))
goto done;
/* Try specific names (eg, "Ethernet" and "InfiniBand" rather
* than "Wired")
*/
for (i = 0; i < num_devices; i++) {
if (duplicates[i]) {
g_free (names[i]);
names[i] = get_device_type_name_with_iface (devices[i]);
}
}
if (!find_duplicates (names, duplicates, num_devices))
goto done;
/* Try prefixing bus name (eg, "PCI Ethernet" vs "USB Ethernet") */
uclient = g_udev_client_new (subsys);
for (i = 0; i < num_devices; i++) {
if (duplicates[i]) {
const char *bus = get_bus_name (uclient, devices[i]);
char *name;
if (!bus)
continue;
g_free (names[i]);
name = get_device_type_name_with_iface (devices[i]);
/* Translators: the first %s is a bus name (eg, "USB") or
* product name, the second is a device type (eg,
* "Ethernet"). You can change this to something like
* "%2$s (%1$s)" if there's no grammatical way to combine
* the strings otherwise.
*/
names[i] = g_strdup_printf (C_("long device name", "%s %s"),
bus, name);
g_free (name);
}
}
g_object_unref (uclient);
if (!find_duplicates (names, duplicates, num_devices))
goto done;
/* Try prefixing vendor name */
for (i = 0; i < num_devices; i++) {
if (duplicates[i]) {
const char *vendor = nma_utils_get_device_vendor (devices[i]);
char *name;
if (!vendor)
continue;
g_free (names[i]);
name = get_device_type_name_with_iface (devices[i]);
names[i] = g_strdup_printf (C_("long device name", "%s %s"),
vendor,
nma_utils_get_device_type_name (devices[i]));
g_free (name);
}
}
if (!find_duplicates (names, duplicates, num_devices))
goto done;
/* We have multiple identical network cards, so we have to differentiate
* them by interface name.
*/
for (i = 0; i < num_devices; i++) {
if (duplicates[i]) {
const char *interface = nm_device_get_iface (devices[i]);
if (!interface)
continue;
g_free (names[i]);
names[i] = g_strdup_printf ("%s (%s)",
nma_utils_get_device_type_name (devices[i]),
interface);
}
}
done:
g_free (duplicates);
names[num_devices] = NULL;
return names;
}
/**
* nma_utils_get_connection_device_name:
* @connection: an #NMConnection for a virtual device type
*
* Returns the name that nma_utils_disambiguate_device_names() would
* return for the virtual device that would be created for @connection.
* Eg, "VLAN (eth1.1)".
*
* Returns: (transfer full): the name of @connection's device
*/
char *
nma_utils_get_connection_device_name (NMConnection *connection)
{
const char *iface, *type, *display_type;
NMSettingConnection *s_con;
iface = nm_connection_get_virtual_iface_name (connection);
g_return_val_if_fail (iface != NULL, NULL);
s_con = nm_connection_get_setting_connection (connection);
g_return_val_if_fail (s_con != NULL, NULL);
type = nm_setting_connection_get_connection_type (s_con);
if (!strcmp (type, NM_SETTING_BOND_SETTING_NAME))
display_type = _("Bond");
else if (!strcmp (type, NM_SETTING_TEAM_SETTING_NAME))
display_type = _("Team");
else if (!strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME))
display_type = _("Bridge");
else if (!strcmp (type, NM_SETTING_VLAN_SETTING_NAME))
display_type = _("VLAN");
else {
g_warning ("Unrecognized virtual device type '%s'", type);
display_type = type;
}
return g_strdup_printf ("%s (%s)", display_type, iface);
}

41
tui/nm-ui-utils.h Normal file
View File

@@ -0,0 +1,41 @@
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2007 - 2012 Red Hat, Inc.
*/
/* WARNING: this file is private API between nm-applet and various GNOME
* bits; it may change without notice and is not guaranteed to be stable.
*/
#ifndef NMA_UI_UTILS_H
#define NMA_UI_UTILS_H
#include <nm-device.h>
const char *nma_utils_get_device_vendor (NMDevice *device);
const char *nma_utils_get_device_product (NMDevice *device);
const char *nma_utils_get_device_description (NMDevice *device);
const char *nma_utils_get_device_generic_type_name (NMDevice *device);
const char *nma_utils_get_device_type_name (NMDevice *device);
char **nma_utils_disambiguate_device_names (NMDevice **devices,
int num_devices);
char *nma_utils_get_connection_device_name (NMConnection *connection);
#endif /* NMA_UI_UTILS_H */

284
tui/nmt-address-list.c Normal file
View File

@@ -0,0 +1,284 @@
/* -*- 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-address-list
* @short_description: An editable list of IP addresses or hostnames
*
* #NmtAddressList is a subclass of #NmtWidgetList that contains
* entries displaying IP addresses, address/prefix strings, or
* hostnames. This is designed for binding its #NmtAddressList:strings
* property to an appropriate #NMSettingIP4Config or
* #NMSettingIP6Config property via one of the nm-editor-bindings
* functions.
*/
#include "config.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus-glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-address-list.h"
#include "nmt-ip-entry.h"
G_DEFINE_TYPE (NmtAddressList, nmt_address_list, NMT_TYPE_WIDGET_LIST)
#define NMT_ADDRESS_LIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_ADDRESS_LIST, NmtAddressListPrivate))
typedef struct {
NmtAddressListType list_type;
char **strings;
} NmtAddressListPrivate;
enum {
PROP_0,
PROP_LIST_TYPE,
PROP_STRINGS,
LAST_PROP
};
/**
* NmtAddressListType:
* @NMT_ADDRESS_LIST_IP4_WITH_PREFIX: IPv4 address/prefix strings
* @NMT_ADDRESS_LIST_IP4: IPv4 addresses
* @NMT_ADDRESS_LIST_IP6_WITH_PREFIX: IPv6 address/prefix strings
* @NMT_ADDRESS_LIST_IP6: IPv6 addresses
* @NMT_ADDRESS_LIST_HOSTNAME: hostnames
*
* The type of address in an #NmtAddressList
*/
/**
* nmt_address_list_new:
* @list_type: the type of address the list will contain
*
* Creates a new #NmtAddressList
*
* Returns: a new #NmtAddressList
*/
NmtNewtWidget *
nmt_address_list_new (NmtAddressListType list_type)
{
return g_object_new (NMT_TYPE_ADDRESS_LIST,
"list-type", list_type,
NULL);
}
static void
nmt_address_list_init (NmtAddressList *list)
{
}
static gboolean
strings_transform_to_entry (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
int n = GPOINTER_TO_INT (user_data);
char **strings;
strings = g_value_get_boxed (source_value);
if (n >= g_strv_length (strings))
return FALSE;
g_value_set_string (target_value, strings[n]);
return TRUE;
}
static gboolean
strings_transform_from_entry (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
NmtAddressList *list = NMT_ADDRESS_LIST (g_binding_get_source (binding));
NmtAddressListPrivate *priv = NMT_ADDRESS_LIST_GET_PRIVATE (list);
int n = GPOINTER_TO_INT (user_data);
if (n >= g_strv_length (priv->strings))
return FALSE;
g_free (priv->strings[n]);
priv->strings[n] = g_value_dup_string (source_value);
g_value_set_boxed (target_value, priv->strings);
return TRUE;
}
static gboolean
hostname_filter (NmtNewtEntry *entry,
const char *text,
int ch,
int position,
gpointer user_data)
{
return g_ascii_isalnum (ch) || ch == '.' || ch == '-';
}
static NmtNewtWidget *
nmt_address_list_create_widget (NmtWidgetList *list,
int num)
{
NmtAddressListPrivate *priv = NMT_ADDRESS_LIST_GET_PRIVATE (list);
NmtNewtWidget *entry;
if (priv->list_type == NMT_ADDRESS_LIST_IP4_WITH_PREFIX)
entry = nmt_ip_entry_new (25, AF_INET, TRUE, FALSE);
else if (priv->list_type == NMT_ADDRESS_LIST_IP4)
entry = nmt_ip_entry_new (25, AF_INET, FALSE, FALSE);
else if (priv->list_type == NMT_ADDRESS_LIST_IP6_WITH_PREFIX)
entry = nmt_ip_entry_new (25, AF_INET6, TRUE, FALSE);
else if (priv->list_type == NMT_ADDRESS_LIST_IP6)
entry = nmt_ip_entry_new (25, AF_INET6, FALSE, FALSE);
else if (priv->list_type == NMT_ADDRESS_LIST_HOSTNAME) {
entry = nmt_newt_entry_new (25, NMT_NEWT_ENTRY_NONEMPTY);
nmt_newt_entry_set_filter (NMT_NEWT_ENTRY (entry), hostname_filter, list);
} else
g_assert_not_reached ();
g_object_bind_property_full (list, "strings", entry, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
strings_transform_to_entry,
strings_transform_from_entry,
GINT_TO_POINTER (num), NULL);
return entry;
}
static void
nmt_address_list_add_clicked (NmtWidgetList *list)
{
NmtAddressListPrivate *priv = NMT_ADDRESS_LIST_GET_PRIVATE (list);
int len;
len = g_strv_length (priv->strings);
priv->strings = g_renew (char *, priv->strings, len + 2);
priv->strings[len] = g_strdup ("");
priv->strings[len + 1] = NULL;
nmt_widget_list_set_length (list, len + 1);
g_object_notify (G_OBJECT (list), "strings");
}
static void
nmt_address_list_remove_clicked (NmtWidgetList *list,
int num)
{
NmtAddressListPrivate *priv = NMT_ADDRESS_LIST_GET_PRIVATE (list);
int len;
len = g_strv_length (priv->strings);
g_free (priv->strings[num]);
memmove (priv->strings + num, priv->strings + num + 1, (len - num) * sizeof (char *));
nmt_widget_list_set_length (list, len - 1);
g_object_notify (G_OBJECT (list), "strings");
}
static void
nmt_address_list_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtAddressListPrivate *priv = NMT_ADDRESS_LIST_GET_PRIVATE (object);
switch (prop_id) {
case PROP_LIST_TYPE:
priv->list_type = g_value_get_uint (value);
break;
case PROP_STRINGS:
g_strfreev (priv->strings);
priv->strings = g_value_dup_boxed (value);
if (!priv->strings)
priv->strings = g_new0 (char *, 1);
nmt_widget_list_set_length (NMT_WIDGET_LIST (object),
g_strv_length (priv->strings));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_address_list_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtAddressListPrivate *priv = NMT_ADDRESS_LIST_GET_PRIVATE (object);
switch (prop_id) {
case PROP_LIST_TYPE:
g_value_set_uint (value, priv->list_type);
break;
case PROP_STRINGS:
g_value_set_boxed (value, priv->strings);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_address_list_class_init (NmtAddressListClass *list_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (list_class);
NmtWidgetListClass *widget_list_class = NMT_WIDGET_LIST_CLASS (list_class);
g_type_class_add_private (list_class, sizeof (NmtAddressListPrivate));
/* virtual methods */
object_class->set_property = nmt_address_list_set_property;
object_class->get_property = nmt_address_list_get_property;
widget_list_class->create_widget = nmt_address_list_create_widget;
widget_list_class->add_clicked = nmt_address_list_add_clicked;
widget_list_class->remove_clicked = nmt_address_list_remove_clicked;
/**
* NmtAddressList:list-type:
*
* The type of address the list holds.
*/
g_object_class_install_property (object_class, PROP_LIST_TYPE,
g_param_spec_uint ("list-type", "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtAddressList:strings:
*
* The strings in the list's entries.
*/
g_object_class_install_property (object_class, PROP_STRINGS,
g_param_spec_boxed ("strings", "", "",
G_TYPE_STRV,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

57
tui/nmt-address-list.h Normal file
View File

@@ -0,0 +1,57 @@
/* -*- 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.
*/
#ifndef NMT_ADDRESS_LIST_H
#define NMT_ADDRESS_LIST_H
#include "nmt-widget-list.h"
G_BEGIN_DECLS
#define NMT_TYPE_ADDRESS_LIST (nmt_address_list_get_type ())
#define NMT_ADDRESS_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_ADDRESS_LIST, NmtAddressList))
#define NMT_ADDRESS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_ADDRESS_LIST, NmtAddressListClass))
#define NMT_IS_ADDRESS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_ADDRESS_LIST))
#define NMT_IS_ADDRESS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_ADDRESS_LIST))
#define NMT_ADDRESS_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_ADDRESS_LIST, NmtAddressListClass))
typedef struct {
NmtWidgetList parent;
} NmtAddressList;
typedef struct {
NmtWidgetListClass parent;
} NmtAddressListClass;
GType nmt_address_list_get_type (void);
typedef enum {
NMT_ADDRESS_LIST_IP4_WITH_PREFIX,
NMT_ADDRESS_LIST_IP4,
NMT_ADDRESS_LIST_IP6_WITH_PREFIX,
NMT_ADDRESS_LIST_IP6,
NMT_ADDRESS_LIST_HOSTNAME
} NmtAddressListType;
NmtNewtWidget *nmt_address_list_new (NmtAddressListType list_type);
G_END_DECLS
#endif /* NMT_ADDRESS_LIST_H */

View File

@@ -0,0 +1,820 @@
/* -*- 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-connect-connection-list
* @short_description: Connection list for "nmtui connect"
*
* #NmtConnectConnectionList is the list of devices, connections, and
* access points displayed by "nmtui connect".
*/
#include "config.h"
#include <stdlib.h>
#include <glib/gi18n-lib.h>
#include <nm-access-point.h>
#include <nm-device-wifi.h>
#include <nm-utils.h>
#include "nmtui.h"
#include "nmt-connect-connection-list.h"
#include "nmt-utils.h"
#include "nmt-password-dialog.h"
#include "nmt-secret-agent.h"
#include "nm-ui-utils.h"
G_DEFINE_TYPE (NmtConnectConnectionList, nmt_connect_connection_list, NMT_TYPE_NEWT_LISTBOX)
#define NMT_CONNECT_CONNECTION_LIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_CONNECT_CONNECTION_LIST, NmtConnectConnectionListPrivate))
typedef struct {
char *name;
NMDevice *device;
int sort_order;
GSList *conns;
} NmtConnectDevice;
typedef struct {
const char *name;
char *ssid;
NMConnection *conn;
NMAccessPoint *ap;
NMDevice *device;
} NmtConnectConnection;
typedef struct {
GSList *nmt_devices;
} NmtConnectConnectionListPrivate;
/**
* nmt_connect_connection_list_new:
*
* Creates a new #NmtConnectConnectionList
*
* Returns: a new #NmtConnectConnectionList
*/
NmtNewtWidget *
nmt_connect_connection_list_new (void)
{
return g_object_new (NMT_TYPE_CONNECT_CONNECTION_LIST,
"flags", NMT_NEWT_LISTBOX_SCROLL | NMT_NEWT_LISTBOX_BORDER,
"skip-null-keys", TRUE,
NULL);
}
static void
nmt_connect_connection_list_init (NmtConnectConnectionList *list)
{
}
static void
nmt_connect_connection_free (NmtConnectConnection *nmtconn)
{
g_clear_object (&nmtconn->conn);
g_clear_object (&nmtconn->ap);
g_free (nmtconn->ssid);
}
static void
nmt_connect_device_free (NmtConnectDevice *nmtdev)
{
g_clear_pointer (&nmtdev->name, g_free);
g_clear_object (&nmtdev->device);
g_slist_free_full (nmtdev->conns, (GDestroyNotify) nmt_connect_connection_free);
}
static const char *device_sort_order[] = {
"NMDeviceEthernet",
"NMDeviceInfiniband",
"NMDeviceWifi",
NM_SETTING_VLAN_SETTING_NAME,
NM_SETTING_BOND_SETTING_NAME,
NM_SETTING_TEAM_SETTING_NAME,
NM_SETTING_BRIDGE_SETTING_NAME,
"NMDeviceModem",
"NMDeviceBt"
};
static const int device_sort_order_len = G_N_ELEMENTS (device_sort_order);
static int
get_sort_order_for_device (NMDevice *device)
{
const char *type;
int i;
type = G_OBJECT_TYPE_NAME (device);
for (i = 0; i < device_sort_order_len; i++) {
if (!strcmp (type, device_sort_order[i]))
return i;
}
return -1;
}
static int
get_sort_order_for_connection (NMConnection *conn)
{
NMSettingConnection *s_con;
const char *type;
int i;
s_con = nm_connection_get_setting_connection (conn);
type = nm_setting_connection_get_connection_type (s_con);
for (i = 0; i < device_sort_order_len; i++) {
if (!strcmp (type, device_sort_order[i]))
return i;
}
return -1;
}
static int
sort_connections (gconstpointer a,
gconstpointer b)
{
NmtConnectConnection *nmta = (NmtConnectConnection *)a;
NmtConnectConnection *nmtb = (NmtConnectConnection *)b;
/* If nmta and nmtb both have NMConnections, sort them by timestamp */
if (nmta->conn && nmtb->conn) {
NMSettingConnection *s_con_a, *s_con_b;
guint64 time_a, time_b;
s_con_a = nm_connection_get_setting_connection (nmta->conn);
s_con_b = nm_connection_get_setting_connection (nmtb->conn);
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);
}
/* If one is an NMConnection and the other is an NMAccessPoint, the
* connection comes first.
*/
if (nmta->conn)
return -1;
else if (nmtb->conn)
return 1;
g_return_val_if_fail (nmta->ap && nmtb->ap, 0);
/* If both are access points, then sort by strength */
return nm_access_point_get_strength (nmtb->ap) - nm_access_point_get_strength (nmta->ap);
}
static void
add_connections_for_device (NmtConnectDevice *nmtdev,
GSList *connections)
{
GSList *iter;
for (iter = connections; iter; iter = iter->next) {
NMConnection *conn = iter->data;
NMSettingConnection *s_con;
s_con = nm_connection_get_setting_connection (conn);
if (nm_setting_connection_get_master (s_con))
continue;
if (nm_device_connection_valid (nmtdev->device, conn)) {
NmtConnectConnection *nmtconn = g_slice_new0 (NmtConnectConnection);
nmtconn->name = nm_connection_get_id (conn);
nmtconn->device = nmtdev->device;
nmtconn->conn = g_object_ref (conn);
nmtdev->conns = g_slist_prepend (nmtdev->conns, nmtconn);
}
}
}
static void
add_connections_for_aps (NmtConnectDevice *nmtdev,
GSList *connections)
{
NmtConnectConnection *nmtconn;
NMConnection *conn;
NMAccessPoint *ap;
const GPtrArray *aps;
GSList *iter;
int i;
aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nmtdev->device));
if (!aps)
return;
for (i = 0; i < aps->len; i++) {
ap = aps->pdata[i];
if (!nm_access_point_get_ssid (ap))
continue;
nmtconn = g_slice_new0 (NmtConnectConnection);
nmtconn->device = nmtdev->device;
nmtconn->ap = g_object_ref (ap);
nmtconn->ssid = nm_utils_ssid_to_utf8 (nm_access_point_get_ssid (ap));
for (iter = connections; iter; iter = iter->next) {
conn = iter->data;
if ( nm_device_connection_valid (nmtdev->device, conn)
&& nm_access_point_connection_valid (ap, conn)) {
nmtconn->name = nm_connection_get_id (conn);
nmtconn->conn = g_object_ref (conn);
break;
}
}
if (!iter)
nmtconn->name = nmtconn->ssid;
nmtdev->conns = g_slist_prepend (nmtdev->conns, nmtconn);
}
}
static GSList *
append_nmt_devices_for_devices (GSList *nmt_devices,
const GPtrArray *devices,
char **names,
GSList *connections)
{
NmtConnectDevice *nmtdev;
NMDevice *device;
int i, sort_order;
for (i = 0; i < devices->len; i++) {
device = devices->pdata[i];
sort_order = get_sort_order_for_device (device);
if (sort_order == -1)
continue;
nmtdev = g_slice_new0 (NmtConnectDevice);
nmtdev->name = g_strdup (names[i]);
nmtdev->device = g_object_ref (device);
nmtdev->sort_order = sort_order;
if (NM_IS_DEVICE_WIFI (device))
add_connections_for_aps (nmtdev, connections);
else
add_connections_for_device (nmtdev, connections);
nmtdev->conns = g_slist_sort (nmtdev->conns, sort_connections);
nmt_devices = g_slist_prepend (nmt_devices, nmtdev);
}
return nmt_devices;
}
static GSList *
append_nmt_devices_for_virtual_devices (GSList *nmt_devices,
GSList *connections)
{
NmtConnectDevice *nmtdev;
GSList *iter;
GHashTable *devices_by_name;
char *name;
NMConnection *conn;
NmtConnectConnection *nmtconn;
int sort_order;
devices_by_name = g_hash_table_new (g_str_hash, g_str_equal);
for (iter = connections; iter; iter = iter->next) {
conn = iter->data;
sort_order = get_sort_order_for_connection (conn);
if (sort_order == -1)
continue;
name = nma_utils_get_connection_device_name (conn);
nmtdev = g_hash_table_lookup (devices_by_name, name);
if (nmtdev)
g_free (name);
else {
nmtdev = g_slice_new0 (NmtConnectDevice);
nmtdev->name = name;
nmtdev->sort_order = sort_order;
g_hash_table_insert (devices_by_name, nmtdev->name, nmtdev);
nmt_devices = g_slist_prepend (nmt_devices, nmtdev);
}
nmtconn = g_slice_new0 (NmtConnectConnection);
nmtconn->name = nm_connection_get_id (conn);
nmtconn->conn = g_object_ref (conn);
nmtdev->conns = g_slist_insert_sorted (nmtdev->conns, nmtconn, sort_connections);
}
g_hash_table_destroy (devices_by_name);
return nmt_devices;
}
static GSList *
append_nmt_devices_for_vpns (GSList *nmt_devices,
GSList *connections)
{
NmtConnectDevice *nmtdev;
GSList *iter;
NMConnection *conn;
NmtConnectConnection *nmtconn;
nmtdev = g_slice_new0 (NmtConnectDevice);
nmtdev->name = g_strdup (_("VPN"));
nmtdev->sort_order = 100;
for (iter = connections; iter; iter = iter->next) {
conn = iter->data;
if (!nm_connection_is_type (conn, NM_SETTING_VPN_SETTING_NAME))
continue;
nmtconn = g_slice_new0 (NmtConnectConnection);
nmtconn->name = nm_connection_get_id (conn);
nmtconn->conn = g_object_ref (conn);
nmtdev->conns = g_slist_insert_sorted (nmtdev->conns, nmtconn, sort_connections);
}
if (nmtdev->conns)
nmt_devices = g_slist_prepend (nmt_devices, nmtdev);
else
nmt_connect_device_free (nmtdev);
return nmt_devices;
}
static int
sort_nmt_devices (gconstpointer a,
gconstpointer b)
{
NmtConnectDevice *nmta = (NmtConnectDevice *)a;
NmtConnectDevice *nmtb = (NmtConnectDevice *)b;
if (nmta->sort_order != nmtb->sort_order)
return nmta->sort_order - nmtb->sort_order;
return strcmp (nmta->name, nmtb->name);
}
static gboolean
connection_is_active (NMConnection *conn,
const GPtrArray *acs)
{
NMActiveConnection *ac;
const char *path, *ac_path;
int i;
path = nm_connection_get_path (conn);
for (i = 0; acs && i < acs->len; i++) {
ac = acs->pdata[i];
ac_path = nm_active_connection_get_connection (ac);
if (!strcmp (path, ac_path))
return TRUE;
}
return FALSE;
}
static void
nmt_connect_connection_list_rebuild (NmtConnectConnectionList *list)
{
NmtConnectConnectionListPrivate *priv = NMT_CONNECT_CONNECTION_LIST_GET_PRIVATE (list);
NmtNewtListbox *listbox = NMT_NEWT_LISTBOX (list);
const GPtrArray *devices, *acs;
int max_width;
char **names, *row, active_col;
const char *strength_col;
GSList *connections;
GSList *nmt_devices, *diter, *citer;
NmtConnectDevice *nmtdev;
NmtConnectConnection *nmtconn;
g_slist_free_full (priv->nmt_devices, (GDestroyNotify) nmt_connect_device_free);
priv->nmt_devices = NULL;
nmt_newt_listbox_clear (listbox);
devices = nm_client_get_devices (nm_client);
acs = nm_client_get_active_connections (nm_client);
connections = nm_remote_settings_list_connections (nm_settings);
nmt_devices = NULL;
if (devices) {
names = nma_utils_disambiguate_device_names ((NMDevice **) devices->pdata, devices->len);
nmt_devices = append_nmt_devices_for_devices (nmt_devices, devices, names, connections);
g_strfreev (names);
}
nmt_devices = append_nmt_devices_for_virtual_devices (nmt_devices, connections);
nmt_devices = append_nmt_devices_for_vpns (nmt_devices, connections);
nmt_devices = g_slist_sort (nmt_devices, sort_nmt_devices);
g_slist_free (connections);
max_width = 0;
for (diter = nmt_devices; diter; diter = diter->next) {
nmtdev = diter->data;
for (citer = nmtdev->conns; citer; citer = citer->next) {
nmtconn = citer->data;
max_width = MAX (max_width, g_utf8_strlen (nmtconn->name, -1));
}
}
for (diter = nmt_devices; diter; diter = diter->next) {
nmtdev = diter->data;
if (diter != nmt_devices)
nmt_newt_listbox_append (listbox, "", NULL);
nmt_newt_listbox_append (listbox, nmtdev->name, NULL);
for (citer = nmtdev->conns; citer; citer = citer->next) {
nmtconn = citer->data;
if (nmtconn->conn && connection_is_active (nmtconn->conn, acs))
active_col = '*';
else
active_col = ' ';
if (nmtconn->ap) {
guint8 strength = nm_access_point_get_strength (nmtconn->ap);
if (strength > 80)
strength_col = " ▂▄▆█";
else if (strength > 55)
strength_col = " ▂▄▆_";
else if (strength > 30)
strength_col = " ▂▄__";
else if (strength > 5)
strength_col = " ▂___";
else
strength_col = " ____";
} else
strength_col = "";
row = g_strdup_printf ("%c %s%-*s%s",
active_col,
nmtconn->name,
(int)(max_width - g_utf8_strlen (nmtconn->name, -1)), "",
strength_col);
nmt_newt_listbox_append (listbox, row, nmtconn);
g_free (row);
}
}
priv->nmt_devices = nmt_devices;
}
static void
rebuild_on_acs_changed (GObject *object,
GParamSpec *spec,
gpointer list)
{
nmt_connect_connection_list_rebuild (list);
}
static void
rebuild_on_devices_changed (NMClient *client,
NMDevice *device,
gpointer list)
{
nmt_connect_connection_list_rebuild (list);
}
static void
nmt_connect_connection_list_constructed (GObject *object)
{
NmtConnectConnectionList *list = NMT_CONNECT_CONNECTION_LIST (object);
g_signal_connect (nm_client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS,
G_CALLBACK (rebuild_on_acs_changed), list);
g_signal_connect (nm_client, "device-added",
G_CALLBACK (rebuild_on_devices_changed), list);
g_signal_connect (nm_client, "device-removed",
G_CALLBACK (rebuild_on_devices_changed), list);
nmt_connect_connection_list_rebuild (list);
G_OBJECT_CLASS (nmt_connect_connection_list_parent_class)->constructed (object);
}
static void
nmt_connect_connection_list_finalize (GObject *object)
{
NmtConnectConnectionListPrivate *priv = NMT_CONNECT_CONNECTION_LIST_GET_PRIVATE (object);
g_slist_free_full (priv->nmt_devices, (GDestroyNotify) nmt_connect_device_free);
g_signal_handlers_disconnect_by_func (nm_client, G_CALLBACK (rebuild_on_acs_changed), object);
g_signal_handlers_disconnect_by_func (nm_client, G_CALLBACK (rebuild_on_devices_changed), object);
G_OBJECT_CLASS (nmt_connect_connection_list_parent_class)->finalize (object);
}
typedef struct {
NmtNewtForm *form;
NMSecretAgent *agent;
} NmtActivationData;
static void
nmt_activation_data_free (NmtActivationData *data)
{
g_object_unref (data->form);
g_object_unref (data->agent);
g_slice_free (NmtActivationData, data);
}
static void
secrets_requested (NmtSecretAgent *agent,
const char *request_id,
const char *title,
const char *msg,
GPtrArray *secrets,
gpointer user_data)
{
NmtNewtForm *form;
form = nmt_password_dialog_new (request_id, title, msg, secrets);
nmt_newt_form_run_sync (form);
if (nmt_password_dialog_succeeded (NMT_PASSWORD_DIALOG (form)))
nmt_secret_agent_response (agent, request_id, secrets);
else
nmt_secret_agent_response (agent, request_id, NULL);
g_object_unref (form);
}
static gboolean
idle_unref_ac (gpointer ac)
{
g_object_unref (ac);
return FALSE;
}
static void
activation_complete (GSimpleAsyncResult *simple,
GError *error)
{
NmtActivationData *data = g_object_get_data (G_OBJECT (simple), "NmtActivationData");
if (error)
g_simple_async_result_set_from_error (simple, error);
else
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
nmt_newt_form_quit (data->form);
/* If we bail out too soon, the agent won't have completed registering,
* and nm_secret_agent_unregister() would complain.
*/
if (nm_secret_agent_get_registered (data->agent))
nm_secret_agent_unregister (data->agent);
}
static void
activate_ac_state_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
NMActiveConnectionState state;
GError *error = NULL;
state = nm_active_connection_get_state (NM_ACTIVE_CONNECTION (object));
if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING)
return;
if (state != NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
error = g_error_new_literal (NM_CLIENT_ERROR, NM_CLIENT_ERROR_UNKNOWN,
_("Activation failed"));
}
g_signal_handlers_disconnect_by_func (object, G_CALLBACK (activate_ac_state_changed), simple);
/* Work around NMObject bug for now: fix is 1981323b */
g_idle_add (idle_unref_ac, object);
activation_complete (simple, error);
g_clear_error (&error);
}
static void
activation_callback (NMClient *client,
NMActiveConnection *ac,
GError *error,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
if (error || nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
activation_complete (simple, error);
return;
}
g_object_ref (ac);
g_signal_connect (ac, "notify::" NM_ACTIVE_CONNECTION_STATE,
G_CALLBACK (activate_ac_state_changed), simple);
}
static void
activate_nmt_connection_async (NmtConnectConnectionList *list,
NmtConnectConnection *nmtconn,
GAsyncReadyCallback callback,
gpointer user_data)
{
NmtActivationData *data;
NmtNewtWidget *label;
GSimpleAsyncResult *simple;
data = g_slice_new (NmtActivationData);
data->form = g_object_new (NMT_TYPE_NEWT_FORM, NULL);
label = nmt_newt_label_new (_("Connecting..."));
nmt_newt_form_set_content (data->form, label);
data->agent = nmt_secret_agent_new ();
nm_secret_agent_register (data->agent);
g_signal_connect (data->agent, "request-secrets",
G_CALLBACK (secrets_requested), NULL);
simple = g_simple_async_result_new (G_OBJECT (list), callback, user_data,
activate_nmt_connection_async);
g_object_set_data_full (G_OBJECT (simple), "NmtActivationData", data,
(GDestroyNotify)nmt_activation_data_free);
/* FIXME: cancel button */
nm_client_activate_connection (nm_client,
nmtconn->conn, nmtconn->device,
nmtconn->ap ? nm_object_get_path (NM_OBJECT (nmtconn->ap)) : NULL,
activation_callback, simple);
nmt_newt_form_show (data->form);
}
static gboolean
activate_nmt_connection_finish (NmtConnectConnectionList *list,
GAsyncResult *result,
GError **error)
{
return g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
}
static void
activate_complete (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
NmtSyncOp *op = user_data;
GError *error = NULL;
if (activate_nmt_connection_finish (NMT_CONNECT_CONNECTION_LIST (object), result, &error))
nmt_sync_op_complete_boolean (op, TRUE, NULL);
else
nmt_sync_op_complete_boolean (op, FALSE, error);
g_clear_error (&error);
}
static void
nmt_connect_connection_list_activated (NmtNewtWidget *widget)
{
NmtConnectConnection *nmtconn;
NmtSyncOp op;
GError *error = NULL;
nmtconn = nmt_newt_listbox_get_active_key (NMT_NEWT_LISTBOX (widget));
g_return_if_fail (nmtconn != NULL);
nmt_sync_op_init (&op);
activate_nmt_connection_async (NMT_CONNECT_CONNECTION_LIST (widget), nmtconn,
activate_complete, &op);
if (!nmt_sync_op_wait_boolean (&op, &error)) {
nmt_newt_error_dialog (_("Could not activate connection: %s"), error->message);
g_error_free (error);
}
}
static void
nmt_connect_connection_list_class_init (NmtConnectConnectionListClass *list_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (list_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (list_class);
g_type_class_add_private (list_class, sizeof (NmtConnectConnectionListPrivate));
/* virtual methods */
object_class->constructed = nmt_connect_connection_list_constructed;
object_class->finalize = nmt_connect_connection_list_finalize;
widget_class->activated = nmt_connect_connection_list_activated;
}
/**
* nmt_connect_connection_list_activate_async:
* @list: an #NmtConnectConnectionList
* @identifier: a connection ID or UUID
* @callback: #GAsyncReadyCallback
* @user_data: data for @callback
*
* Asynchronously begins to activate the connection identified by
* @identifier, and invokes @callback when it completes.
*/
void
nmt_connect_connection_list_activate_async (NmtConnectConnectionList *list,
const char *identifier,
GAsyncReadyCallback callback,
gpointer user_data)
{
NmtConnectConnectionListPrivate *priv = NMT_CONNECT_CONNECTION_LIST_GET_PRIVATE (list);
GSList *diter, *citer;
NmtConnectDevice *nmtdev;
NmtConnectConnection *nmtconn = NULL;
NMConnection *conn = NULL;
if (nm_utils_is_uuid (identifier))
conn = NM_CONNECTION (nm_remote_settings_get_connection_by_uuid (nm_settings, identifier));
else {
GSList *conns, *iter;
conns = nm_remote_settings_list_connections (nm_settings);
for (iter = conns; iter; iter = iter->next) {
NMConnection *candidate = iter->data;
if (!strcmp (identifier, nm_connection_get_id (candidate))) {
conn = candidate;
break;
}
}
g_slist_free (conns);
}
for (diter = priv->nmt_devices; diter; diter = diter->next) {
nmtdev = diter->data;
if (!nmtdev->conns)
continue;
for (citer = nmtdev->conns; citer; citer = citer->next) {
nmtconn = citer->data;
if (conn) {
if (conn == nmtconn->conn)
goto activate;
else
continue;
}
if (nmtconn->ssid && !strcmp (identifier, nmtconn->ssid))
goto activate;
}
if (!conn && !nmtdev->device && !strcmp (identifier, nm_device_get_ip_iface (nmtdev->device))) {
nmtconn = nmtdev->conns->data;
goto activate;
}
}
g_printerr ("%s: no such connection '%s'\n", g_get_prgname (), identifier);
exit (1);
activate:
activate_nmt_connection_async (list, nmtconn, callback, user_data);
}
/**
* nmt_connect_connection_list_activate_finish:
* @list: an #NmtConnectConnectionList
* @result: the #GAsyncResult passed to the callback
* @error: return location for a #GError
*
* Gets the result of an nmt_connect_connection_list_activate_async() call.
*
* Returns: success or failure
*/
gboolean
nmt_connect_connection_list_activate_finish (NmtConnectConnectionList *list,
GAsyncResult *result,
GError **error)
{
return g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
}

View File

@@ -0,0 +1,58 @@
/* -*- 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.
*/
#ifndef NMT_CONNECT_CONNECTION_LIST_H
#define NMT_CONNECT_CONNECTION_LIST_H
#include "nmt-newt.h"
G_BEGIN_DECLS
#define NMT_TYPE_CONNECT_CONNECTION_LIST (nmt_connect_connection_list_get_type ())
#define NMT_CONNECT_CONNECTION_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_CONNECT_CONNECTION_LIST, NmtConnectConnectionList))
#define NMT_CONNECT_CONNECTION_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_CONNECT_CONNECTION_LIST, NmtConnectConnectionListClass))
#define NMT_IS_CONNECT_CONNECTION_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_CONNECT_CONNECTION_LIST))
#define NMT_IS_CONNECT_CONNECTION_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_CONNECT_CONNECTION_LIST))
#define NMT_CONNECT_CONNECTION_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_CONNECT_CONNECTION_LIST, NmtConnectConnectionListClass))
typedef struct {
NmtNewtListbox parent;
} NmtConnectConnectionList;
typedef struct {
NmtNewtListboxClass parent;
} NmtConnectConnectionListClass;
GType nmt_connect_connection_list_get_type (void);
NmtNewtWidget *nmt_connect_connection_list_new (void);
void nmt_connect_connection_list_activate_async (NmtConnectConnectionList *list,
const char *identifier,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean nmt_connect_connection_list_activate_finish (NmtConnectConnectionList *list,
GAsyncResult *result,
GError **error);
G_END_DECLS
#endif /* NMT_CONNECT_CONNECTION_LIST_H */

589
tui/nmt-device-entry.c Normal file
View File

@@ -0,0 +1,589 @@
/* -*- 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-device-entry
* @short_description: #NmtNewtEntry for identifying a device
*
* #NmtDeviceEntry provides a widget for identifying a device, either
* by interface name or by hardware address. The user can enter either
* value, and the entry's #NmtDeviceEntry:interface-name or
* #NmtDeviceEntry:mac-address property will be set accordingly. If
* the entry recognizes the interface name or mac address typed in as
* matching a known #NMDevice, then it will also display the other
* property in parentheses.
*
* FIXME: #NmtDeviceEntry is currently an #NmtPageGrid object, so that
* we can possibly eventually add a button to its "extra" field, that
* would pop up a form for selecting a device. But if we're not going
* to implement that then we should make it just an #NmtNewtEntry.
*/
#include "config.h"
#include <string.h>
#include <sys/socket.h>
#include <linux/if_arp.h>
#include <glib/gi18n-lib.h>
#include <nm-device.h>
#include <nm-device-infiniband.h>
#include <nm-utils.h>
#include "nmtui.h"
#include "nmt-device-entry.h"
G_DEFINE_TYPE (NmtDeviceEntry, nmt_device_entry, NMT_TYPE_PAGE_GRID)
#define NMT_DEVICE_ENTRY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_DEVICE_ENTRY, NmtDeviceEntryPrivate))
typedef struct {
GType hardware_type;
NmtDeviceEntryDeviceFilter device_filter;
gpointer device_filter_data;
int arptype;
char *interface_name;
GByteArray *mac_address;
char *label;
NmtNewtEntry *entry;
NmtNewtWidget *button;
gboolean updating;
} NmtDeviceEntryPrivate;
enum {
PROP_0,
PROP_LABEL,
PROP_WIDTH,
PROP_HARDWARE_TYPE,
PROP_INTERFACE_NAME,
PROP_MAC_ADDRESS,
LAST_PROP
};
/**
* nmt_device_entry_new:
* @label: the label for the entry
* @width: the width of the entry
* @hardware_type: the type of #NMDevice to be selected, or
* %G_TYPE_NONE if this is for a virtual device type.
*
* Creates a new #NmtDeviceEntry, for identifying a device of type
* @hardware_type. If @hardware_type is %G_TYPE_NONE (and you do not
* set a #NmtDeviceEntryDeviceFilter), then this will only allow
* specifying an interface name, not a hardware address.
*
* Returns: a new #NmtDeviceEntry.
*/
NmtNewtWidget *
nmt_device_entry_new (const char *label,
int width,
GType hardware_type)
{
return g_object_new (NMT_TYPE_DEVICE_ENTRY,
"label", label,
"width", width,
"hardware-type", hardware_type,
NULL);
}
static gboolean
device_entry_parse (NmtDeviceEntry *deventry,
const char *text,
char **interface_name,
char **mac_address)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
char **words;
int len;
*interface_name = *mac_address = NULL;
if (!*text)
return TRUE;
if (priv->hardware_type == G_TYPE_NONE && !priv->device_filter) {
if (nm_utils_iface_valid_name (text)) {
*interface_name = g_strdup (text);
return TRUE;
} else
return FALSE;
}
words = g_strsplit (text, " ", -1);
if (g_strv_length (words) > 2) {
g_strfreev (words);
return FALSE;
}
if (words[1]) {
len = strlen (words[1]);
if (len < 3 || words[1][0] != '(' || words[1][len - 1] != ')')
goto fail;
memmove (words[1], words[1] + 1, len - 2);
words[1][len - 2] = '\0';
}
if ( nm_utils_hwaddr_aton (words[0], priv->arptype, buf)
&& (!words[1] || nm_utils_iface_valid_name (words[1]))) {
*mac_address = words[0];
*interface_name = NULL;
g_free (words);
return TRUE;
} else if ( nm_utils_iface_valid_name (words[0])
&& (!words[1] || nm_utils_hwaddr_aton (words[1], priv->arptype, buf))) {
*interface_name = words[0];
*mac_address = NULL;
g_free (words);
return TRUE;
}
fail:
g_strfreev (words);
return FALSE;
}
static gboolean
device_entry_validate (NmtNewtEntry *entry,
const char *text,
gpointer user_data)
{
NmtDeviceEntry *deventry = user_data;
char *ifname, *mac;
if (!device_entry_parse (deventry, text, &ifname, &mac))
return FALSE;
g_free (ifname);
g_free (mac);
return TRUE;
}
static NMDevice *
find_device_by_interface_name (NmtDeviceEntry *deventry,
const char *interface_name)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
const GPtrArray *devices;
NMDevice *device = NULL;
int i;
devices = nm_client_get_devices (nm_client);
if (!devices)
return NULL;
for (i = 0; i < devices->len && !device; i++) {
NMDevice *candidate = devices->pdata[i];
if ( priv->hardware_type != G_TYPE_NONE
&& !G_TYPE_CHECK_INSTANCE_TYPE (candidate, priv->hardware_type))
continue;
if ( priv->device_filter
&& !priv->device_filter (deventry, candidate, priv->device_filter_data))
continue;
if (!g_strcmp0 (interface_name, nm_device_get_iface (candidate)))
device = candidate;
}
return device;
}
static NMDevice *
find_device_by_mac_address (NmtDeviceEntry *deventry,
const char *mac_address)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
const GPtrArray *devices;
NMDevice *device = NULL;
int i;
devices = nm_client_get_devices (nm_client);
if (!devices)
return NULL;
for (i = 0; i < devices->len && !device; i++) {
NMDevice *candidate = devices->pdata[i];
char *hwaddr;
if ( priv->hardware_type != G_TYPE_NONE
&& !G_TYPE_CHECK_INSTANCE_TYPE (candidate, priv->hardware_type))
continue;
if ( priv->device_filter
&& !priv->device_filter (deventry, candidate, priv->device_filter_data))
continue;
g_object_get (G_OBJECT (candidate), "hw-address", &hwaddr, NULL);
if (hwaddr && !g_ascii_strcasecmp (mac_address, hwaddr))
device = candidate;
g_free (hwaddr);
}
return device;
}
static void
update_entry (NmtDeviceEntry *deventry)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
const char *ifname;
char *mac, *text;
NMDevice *ifname_device, *mac_device;
if (priv->interface_name) {
ifname = priv->interface_name;
ifname_device = find_device_by_interface_name (deventry, priv->interface_name);
} else {
ifname = NULL;
ifname_device = NULL;
}
if (priv->mac_address) {
mac = nm_utils_hwaddr_ntoa (priv->mac_address->data, priv->arptype);
mac_device = find_device_by_mac_address (deventry, mac);
} else {
mac = NULL;
mac_device = NULL;
}
if (!ifname && mac_device)
ifname = nm_device_get_iface (mac_device);
if (!mac && ifname_device)
g_object_get (G_OBJECT (ifname_device), "hw-address", &mac, NULL);
if (ifname_device && mac_device && ifname_device != mac_device) {
/* Mismatch! */
text = g_strdup_printf ("%s != %s", priv->interface_name, mac);
} else if (ifname && mac) {
if (ifname_device)
text = g_strdup_printf ("%s (%s)", ifname, mac);
else
text = g_strdup_printf ("%s (%s)", mac, ifname);
} else if (ifname)
text = g_strdup (ifname);
else if (mac)
text = g_strdup (mac);
else
text = g_strdup ("");
priv->updating = TRUE;
g_object_set (G_OBJECT (priv->entry), "text", text, NULL);
priv->updating = FALSE;
g_free (text);
g_free (mac);
}
static gboolean
nmt_device_entry_set_interface_name (NmtDeviceEntry *deventry,
const char *interface_name)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
if (g_strcmp0 (interface_name, priv->interface_name) != 0) {
g_free (priv->interface_name);
priv->interface_name = g_strdup (interface_name);
g_object_notify (G_OBJECT (deventry), "interface-name");
return TRUE;
} else
return FALSE;
}
static gboolean
nmt_device_entry_set_mac_address (NmtDeviceEntry *deventry,
GByteArray *mac_address)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
gboolean changed;
if (mac_address)
g_return_val_if_fail (mac_address->len == nm_utils_hwaddr_len (priv->arptype), FALSE);
if (mac_address && !priv->mac_address) {
priv->mac_address = g_boxed_copy (DBUS_TYPE_G_UCHAR_ARRAY, mac_address);
changed = TRUE;
} else if (!mac_address && priv->mac_address) {
g_clear_pointer (&priv->mac_address, g_byte_array_unref);
changed = TRUE;
} else if ( mac_address && priv->mac_address
&& memcmp (mac_address->data, priv->mac_address->data, mac_address->len) != 0) {
g_byte_array_unref (priv->mac_address);
priv->mac_address = g_boxed_copy (DBUS_TYPE_G_UCHAR_ARRAY, mac_address);
changed = TRUE;
} else
changed = FALSE;
if (changed)
g_object_notify (G_OBJECT (deventry), "mac-address");
return changed;
}
static void
entry_text_changed (GObject *object,
GParamSpec *pspec,
gpointer deventry)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
const char *text;
char *ifname, *mac;
if (priv->updating)
return;
text = nmt_newt_entry_get_text (priv->entry);
if (!device_entry_parse (deventry, text, &ifname, &mac))
return;
if (ifname) {
nmt_device_entry_set_interface_name (deventry, ifname);
g_free (ifname);
} else
nmt_device_entry_set_interface_name (deventry, NULL);
if (mac) {
GByteArray *mac_address;
mac_address = nm_utils_hwaddr_atoba (mac, priv->arptype);
nmt_device_entry_set_mac_address (deventry, mac_address);
g_byte_array_unref (mac_address);
g_free (mac);
} else
nmt_device_entry_set_mac_address (deventry, NULL);
}
static void
nmt_device_entry_init (NmtDeviceEntry *deventry)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
NmtNewtWidget *entry;
priv->hardware_type = G_TYPE_NONE;
entry = nmt_newt_entry_new (-1, 0);
priv->entry = NMT_NEWT_ENTRY (entry);
nmt_newt_entry_set_validator (priv->entry, device_entry_validate, deventry);
g_signal_connect (priv->entry, "notify::text",
G_CALLBACK (entry_text_changed), deventry);
#if 0
priv->button = nmt_newt_button_new (_("Select..."));
g_signal_connect (priv->button, "clicked",
G_CALLBACK (do_select_dialog), deventry);
#endif
}
static void
nmt_device_entry_constructed (GObject *object)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (object);
nmt_page_grid_append (NMT_PAGE_GRID (object), priv->label, NMT_NEWT_WIDGET (priv->entry), NULL);
G_OBJECT_CLASS (nmt_device_entry_parent_class)->constructed (object);
}
static void
nmt_device_entry_finalize (GObject *object)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (object);
g_free (priv->interface_name);
if (priv->mac_address)
g_byte_array_unref (priv->mac_address);
G_OBJECT_CLASS (nmt_device_entry_parent_class)->finalize (object);
}
/**
* NmtDeviceEntryDeviceFilter:
* @deventry: the #NmtDeviceEntry
* @device: an #NMDevice
* @user_data: user data
*
* Filter function for determining which devices can be specified
* on an entry.
*
* Returns: %TRUE if @device is acceptable for @deventry
*/
/**
* nmt_device_entry_set_device_filter:
* @deventry: the #NmtDeviceEntry
* @filter: the filter
* @user_data: data for @filter
*
* Sets a device filter on @deventry. Only devices that pass @filter
* will be recognized by @deventry.
*
* If the entry's #NmtDeviceEntry:hardware-type is not %G_TYPE_NONE,
* then only devices that both match the hardware type and are
* accepted by the filter will be allowed.
*/
void
nmt_device_entry_set_device_filter (NmtDeviceEntry *deventry,
NmtDeviceEntryDeviceFilter filter,
gpointer user_data)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
priv->device_filter = filter;
priv->device_filter_data = user_data;
}
static void
nmt_device_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtDeviceEntry *deventry = NMT_DEVICE_ENTRY (object);
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
const char *interface_name;
GByteArray *mac_address;
switch (prop_id) {
case PROP_LABEL:
priv->label = g_value_dup_string (value);
break;
case PROP_WIDTH:
nmt_newt_entry_set_width (priv->entry, g_value_get_int (value));
break;
case PROP_HARDWARE_TYPE:
priv->hardware_type = g_value_get_gtype (value);
priv->arptype = (priv->hardware_type == NM_TYPE_DEVICE_INFINIBAND) ? ARPHRD_INFINIBAND : ARPHRD_ETHER;
break;
case PROP_INTERFACE_NAME:
interface_name = g_value_get_string (value);
if (nmt_device_entry_set_interface_name (deventry, interface_name))
update_entry (deventry);
break;
case PROP_MAC_ADDRESS:
mac_address = g_value_get_boxed (value);
if (nmt_device_entry_set_mac_address (deventry, mac_address))
update_entry (deventry);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_device_entry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (object);
switch (prop_id) {
case PROP_LABEL:
g_value_set_string (value, priv->label);
break;
case PROP_WIDTH:
g_value_set_int (value, nmt_newt_entry_get_width (priv->entry));
break;
case PROP_HARDWARE_TYPE:
g_value_set_gtype (value, priv->hardware_type);
break;
case PROP_INTERFACE_NAME:
g_value_set_string (value, priv->interface_name);
break;
case PROP_MAC_ADDRESS:
g_value_set_boxed (value, priv->mac_address);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_device_entry_class_init (NmtDeviceEntryClass *deventry_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (deventry_class);
g_type_class_add_private (deventry_class, sizeof (NmtDeviceEntryPrivate));
/* virtual methods */
object_class->constructed = nmt_device_entry_constructed;
object_class->set_property = nmt_device_entry_set_property;
object_class->get_property = nmt_device_entry_get_property;
object_class->finalize = nmt_device_entry_finalize;
/**
* NmtDeviceEntry:label:
*
* The entry's label
*/
g_object_class_install_property (object_class, PROP_LABEL,
g_param_spec_string ("label", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtDeviceEntry:width:
*
* The entry's width in characters
*/
g_object_class_install_property (object_class, PROP_WIDTH,
g_param_spec_int ("width", "", "",
-1, 80, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtDeviceEntry:hardware-type:
*
* The type of #NMDevice to limit the entry to, or %G_TYPE_NONE
* if the entry is for a virtual device and should not accept
* hardware addresses.
*/
g_object_class_install_property (object_class, PROP_HARDWARE_TYPE,
g_param_spec_gtype ("hardware-type", "", "",
G_TYPE_NONE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtDeviceEntry:interface-name:
*
* The interface name of the device identified by the entry.
*/
g_object_class_install_property (object_class, PROP_INTERFACE_NAME,
g_param_spec_string ("interface-name", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtDeviceEntry:mac-address:
*
* The hardware address of the device identified by the entry.
*/
g_object_class_install_property (object_class, PROP_MAC_ADDRESS,
g_param_spec_boxed ("mac-address", "", "",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

61
tui/nmt-device-entry.h Normal file
View File

@@ -0,0 +1,61 @@
/* -*- 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.
*/
#ifndef NMT_DEVICE_ENTRY_H
#define NMT_DEVICE_ENTRY_H
#include "nmt-page-grid.h"
#include <nm-connection.h>
#include <nm-device.h>
G_BEGIN_DECLS
#define NMT_TYPE_DEVICE_ENTRY (nmt_device_entry_get_type ())
#define NMT_DEVICE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_DEVICE_ENTRY, NmtDeviceEntry))
#define NMT_DEVICE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_DEVICE_ENTRY, NmtDeviceEntryClass))
#define NMT_IS_DEVICE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_DEVICE_ENTRY))
#define NMT_IS_DEVICE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_DEVICE_ENTRY))
#define NMT_DEVICE_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_DEVICE_ENTRY, NmtDeviceEntryClass))
typedef struct {
NmtPageGrid parent;
} NmtDeviceEntry;
typedef struct {
NmtPageGridClass parent;
} NmtDeviceEntryClass;
GType nmt_device_entry_get_type (void);
NmtNewtWidget *nmt_device_entry_new (const char *label,
int width,
GType hardware_type);
typedef gboolean (*NmtDeviceEntryDeviceFilter) (NmtDeviceEntry *deventry,
NMDevice *device,
gpointer user_data);
void nmt_device_entry_set_device_filter (NmtDeviceEntry *deventry,
NmtDeviceEntryDeviceFilter filter,
gpointer user_data);
G_END_DECLS
#endif /* NMT_DEVICE_ENTRY_H */

View File

@@ -0,0 +1,550 @@
/* -*- 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);
NmtNewtListbox *listbox;
GSList *iter, *next;
gboolean did_header = FALSE, did_vpn = FALSE;
NMEditorConnectionTypeData **types;
NMConnection *conn;
int i;
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);
listbox = NMT_NEWT_LISTBOX (priv->listbox);
nmt_newt_listbox_clear (listbox);
if (!priv->grouped) {
/* Just add the connections in order */
for (iter = priv->connections; iter; iter = iter->next) {
conn = iter->data;
nmt_newt_listbox_append (listbox, nm_connection_get_id (conn), conn);
}
return;
}
types = nm_editor_utils_get_connection_type_list ();
for (i = 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 (listbox, types[i]->name, NULL);
did_header = TRUE;
}
indented = g_strdup_printf (" %s", nm_connection_get_id (conn));
nmt_newt_listbox_append (listbox, indented, conn);
g_free (indented);
}
}
}
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_LAST,
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_LAST,
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_LAST,
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));
}

View File

@@ -0,0 +1,61 @@
/* -*- 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.
*/
#ifndef NMT_EDIT_CONNECTION_LIST_H
#define NMT_EDIT_CONNECTION_LIST_H
#include "nmt-newt.h"
#include <nm-remote-connection.h>
G_BEGIN_DECLS
#define NMT_TYPE_EDIT_CONNECTION_LIST (nmt_edit_connection_list_get_type ())
#define NMT_EDIT_CONNECTION_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_EDIT_CONNECTION_LIST, NmtEditConnectionList))
#define NMT_EDIT_CONNECTION_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_EDIT_CONNECTION_LIST, NmtEditConnectionListClass))
#define NMT_IS_EDIT_CONNECTION_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_EDIT_CONNECTION_LIST))
#define NMT_IS_EDIT_CONNECTION_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_EDIT_CONNECTION_LIST))
#define NMT_EDIT_CONNECTION_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_EDIT_CONNECTION_LIST, NmtEditConnectionListClass))
typedef struct {
NmtNewtGrid parent;
} NmtEditConnectionList;
typedef struct {
NmtNewtGridClass parent;
/* signals */
void (*add_connection) (NmtEditConnectionList *list);
void (*edit_connection) (NmtEditConnectionList *list,
NMConnection *connection);
void (*remove_connection) (NmtEditConnectionList *list,
NMRemoteConnection *connection);
} NmtEditConnectionListClass;
GType nmt_edit_connection_list_get_type (void);
typedef gboolean (*NmtEditConnectionListFilter) (NmtEditConnectionList *list,
NMConnection *connection,
gpointer user_data);
GSList *nmt_edit_connection_list_get_connections (NmtEditConnectionList *list);
G_END_DECLS
#endif /* NMT_EDIT_CONNECTION_LIST_H */

227
tui/nmt-editor-page.c Normal file
View File

@@ -0,0 +1,227 @@
/* -*- 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-editor-page:
* @short_description: An #NmtEditor "page"
*
* #NmtEditorPage is the abstract base class for #NmtEditor "pages".
* Note that despite the name, currently all "page" types except
* #NmtPageMain are actually displayed as collapsible sections, not
* separate tabs/forms.
*/
#include "config.h"
#include <glib/gi18n-lib.h>
#include "nmt-editor-page.h"
G_DEFINE_ABSTRACT_TYPE (NmtEditorPage, nmt_editor_page, NMT_TYPE_PAGE_GRID)
#define NMT_EDITOR_PAGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_EDITOR_PAGE, NmtEditorPagePrivate))
typedef struct {
char *title;
NmtNewtWidget *header_widget;
NMConnection *connection;
} NmtEditorPagePrivate;
enum {
PROP_0,
PROP_CONNECTION,
PROP_TITLE,
LAST_PROP
};
static void
nmt_editor_page_init (NmtEditorPage *page)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (page);
priv->header_widget = g_object_ref_sink (nmt_newt_separator_new ());
}
static void
nmt_editor_page_finalize (GObject *object)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (object);
g_free (priv->title);
g_clear_object (&priv->header_widget);
g_clear_object (&priv->connection);
G_OBJECT_CLASS (nmt_editor_page_parent_class)->finalize (object);
}
/**
* nmt_editor_page_get_connection:
* @page: the #NmtEditorPage
*
* Gets the page's #NMConnection.
*
* Returns: (transfer none): the page's #NMConnection.
*/
NMConnection *
nmt_editor_page_get_connection (NmtEditorPage *page)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (page);
return priv->connection;
}
/**
* nmt_editor_page_set_header_widget:
* @page: the #NmtEditorPage
* @widget: an #NmtNewtWidget
*
* Sets the page's header widget. When displayed as a subpage of
* #NmtPageMain, this widget will be put into the corresponding
* #NmtNewtSection's header.
*
* FIXME: for consistency, this should be a property as well.
*/
void
nmt_editor_page_set_header_widget (NmtEditorPage *page,
NmtNewtWidget *widget)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (page);
g_clear_object (&priv->header_widget);
if (!widget)
widget = nmt_newt_separator_new ();
priv->header_widget = g_object_ref_sink (widget);
}
/**
* nmt_editor_page_get_header_widget:
* @page: the #NmtEditorPage
*
* Gets the page's header widget. When displayed as a subpage of
* #NmtPageMain, this widget will be put into the corresponding
* #NmtNewtSection's header.
*
* Returns: (transfer none): the page's header widget.
*/
NmtNewtWidget *
nmt_editor_page_get_header_widget (NmtEditorPage *page)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (page);
return priv->header_widget;
}
/**
* nmt_editor_page_get_title:
* @page: the #NmtEditorPage
*
* Gets the page's title.
*
* Returns: the page's title
*/
const char *
nmt_editor_page_get_title (NmtEditorPage *page)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (page);
return priv->title;
}
static void
nmt_editor_page_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (object);
switch (prop_id) {
case PROP_CONNECTION:
priv->connection = g_value_dup_object (value);
break;
case PROP_TITLE:
priv->title = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_editor_page_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (object);
switch (prop_id) {
case PROP_CONNECTION:
g_value_set_object (value, priv->connection);
break;
case PROP_TITLE:
g_value_set_string (value, priv->title);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_editor_page_class_init (NmtEditorPageClass *page_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (page_class);
g_type_class_add_private (page_class, sizeof (NmtEditorPagePrivate));
/* virtual methods */
object_class->set_property = nmt_editor_page_set_property;
object_class->get_property = nmt_editor_page_get_property;
object_class->finalize = nmt_editor_page_finalize;
/* properties */
/**
* NmtEditorPage:connection:
*
* The page's #NMConnection.
*/
g_object_class_install_property (object_class, PROP_CONNECTION,
g_param_spec_object ("connection", "", "",
NM_TYPE_CONNECTION,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtEditorPage:title:
*
* The page's title.
*/
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title", "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

57
tui/nmt-editor-page.h Normal file
View File

@@ -0,0 +1,57 @@
/* -*- 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.
*/
#ifndef NMT_EDITOR_PAGE_H
#define NMT_EDITOR_PAGE_H
#include <nm-connection.h>
#include "nmt-page-grid.h"
G_BEGIN_DECLS
#define NMT_TYPE_EDITOR_PAGE (nmt_editor_page_get_type ())
#define NMT_EDITOR_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_EDITOR_PAGE, NmtEditorPage))
#define NMT_EDITOR_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_EDITOR_PAGE, NmtEditorPageClass))
#define NMT_IS_EDITOR_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_EDITOR_PAGE))
#define NMT_IS_EDITOR_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_EDITOR_PAGE))
#define NMT_EDITOR_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_EDITOR_PAGE, NmtEditorPageClass))
typedef struct {
NmtPageGrid parent;
} NmtEditorPage;
typedef struct {
NmtPageGridClass parent;
} NmtEditorPageClass;
GType nmt_editor_page_get_type (void);
NMConnection *nmt_editor_page_get_connection (NmtEditorPage *page);
void nmt_editor_page_set_header_widget (NmtEditorPage *page,
NmtNewtWidget *widget);
NmtNewtWidget *nmt_editor_page_get_header_widget (NmtEditorPage *page);
const char *nmt_editor_page_get_title (NmtEditorPage *page);
G_END_DECLS
#endif /* NMT_EDITOR_PAGE_H */

330
tui/nmt-editor.c Normal file
View File

@@ -0,0 +1,330 @@
/* -*- 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-editor
* @short_description: Connection editing form
*
* #NmtEditor is the top-level form for editing a connection.
*/
#include "config.h"
#include "nmt-editor.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <nm-utils.h>
#include "nmtui.h"
#include "nm-editor-utils.h"
#include "nmt-page-main.h"
#include "nmt-utils.h"
G_DEFINE_TYPE (NmtEditor, nmt_editor, NMT_TYPE_NEWT_FORM)
#define NMT_EDITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_EDITOR, NmtEditorPrivate))
typedef struct {
NMConnection *orig_connection;
NMConnection *edit_connection;
NMEditorConnectionTypeData *type_data;
NmtNewtWidget *ok, *cancel;
gboolean running;
} NmtEditorPrivate;
enum {
PROP_0,
PROP_CONNECTION,
PROP_TYPE_DATA,
LAST_PROP
};
/**
* nmt_editor_new:
* @connection: the #NMConnection to edit
*
* Creates a new #NmtEditor to edit @connection.
*
* Returns: a new #NmtEditor
*/
NmtNewtForm *
nmt_editor_new (NMConnection *connection)
{
NMEditorConnectionTypeData *type_data;
type_data = nm_editor_utils_get_connection_type_data (connection);
if (!type_data) {
NMSettingConnection *s_con;
s_con = nm_connection_get_setting_connection (connection);
if (s_con) {
nmt_newt_error_dialog (_("Could not create editor for connection '%s' of type '%s'."),
nm_connection_get_id (connection),
nm_setting_connection_get_connection_type (s_con));
} else {
nmt_newt_error_dialog (_("Could not create editor for invalid connection '%s'."),
nm_connection_get_id (connection));
}
return NULL;
}
return g_object_new (NMT_TYPE_EDITOR,
"connection", connection,
"type-data", type_data,
"title", _("Edit connection"),
"fullscreen", TRUE,
NULL);
}
static void
nmt_editor_init (NmtEditor *entry)
{
}
static void
connection_updated (NMRemoteConnection *connection,
GError *error,
gpointer op)
{
nmt_sync_op_complete_boolean (op, error == NULL, error);
}
static void
connection_added (NMRemoteSettings *settings,
NMRemoteConnection *connection,
GError *error,
gpointer op)
{
nmt_sync_op_complete_boolean (op, error == NULL, error);
}
static void
save_connection_and_exit (NmtNewtButton *button,
gpointer user_data)
{
NmtEditor *editor = user_data;
NmtEditorPrivate *priv = NMT_EDITOR_GET_PRIVATE (editor);
NmtSyncOp op;
GError *error = NULL;
if (!nm_connection_replace_settings_from_connection (priv->orig_connection,
priv->edit_connection,
&error)) {
nmt_newt_error_dialog (_("Error saving connection: %s"), error->message);
g_error_free (error);
return;
}
nmt_sync_op_init (&op);
if (NM_IS_REMOTE_CONNECTION (priv->orig_connection)) {
nm_remote_connection_commit_changes (NM_REMOTE_CONNECTION (priv->orig_connection),
connection_updated, &op);
if (!nmt_sync_op_wait_boolean (&op, &error)) {
nmt_newt_error_dialog (_("Unable to save connection: %s"),
error->message);
g_error_free (error);
return;
}
/* Clear secrets so they don't lay around in memory; they'll get
* requested again anyway next time the connection is edited.
*/
nm_connection_clear_secrets (priv->orig_connection);
} else {
nm_remote_settings_add_connection (nm_settings, priv->orig_connection,
connection_added, &op);
if (!nmt_sync_op_wait_boolean (&op, &error)) {
nmt_newt_error_dialog (_("Unable to add new connection: %s"),
error->message);
g_error_free (error);
return;
}
}
nmt_newt_form_quit (NMT_NEWT_FORM (editor));
}
static void
got_secrets (NMRemoteConnection *connection,
GHashTable *secrets,
GError *error,
gpointer op)
{
nmt_sync_op_complete_pointer (op, secrets, error);
}
static NMConnection *
build_edit_connection (NMConnection *orig_connection)
{
NMConnection *edit_connection;
GHashTable *settings, *secrets;
GHashTableIter iter;
const char *setting_name;
NmtSyncOp op;
edit_connection = nm_connection_duplicate (orig_connection);
if (!NM_IS_REMOTE_CONNECTION (orig_connection))
return edit_connection;
settings = nm_connection_to_hash (orig_connection, NM_SETTING_HASH_FLAG_NO_SECRETS);
g_hash_table_iter_init (&iter, settings);
while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, NULL)) {
nmt_sync_op_init (&op);
nm_remote_connection_get_secrets (NM_REMOTE_CONNECTION (orig_connection),
setting_name, got_secrets, &op);
/* FIXME: error handling */
secrets = nmt_sync_op_wait_pointer (&op, NULL);
if (secrets)
nm_connection_update_secrets (edit_connection, setting_name, secrets, NULL);
}
g_hash_table_unref (settings);
return edit_connection;
}
static void
nmt_editor_constructed (GObject *object)
{
NmtEditor *editor = NMT_EDITOR (object);
NmtEditorPrivate *priv = NMT_EDITOR_GET_PRIVATE (editor);
NmtNewtWidget *vbox, *buttons, *page;
if (G_OBJECT_CLASS (nmt_editor_parent_class)->constructed)
G_OBJECT_CLASS (nmt_editor_parent_class)->constructed (object);
priv->edit_connection = build_edit_connection (priv->orig_connection);
vbox = nmt_newt_grid_new ();
page = nmt_page_main_new (priv->edit_connection, priv->type_data);
nmt_newt_grid_add (NMT_NEWT_GRID (vbox), page, 0, 0);
buttons = nmt_newt_button_box_new (NMT_NEWT_BUTTON_BOX_HORIZONTAL);
nmt_newt_grid_add (NMT_NEWT_GRID (vbox), buttons, 0, 1);
nmt_newt_widget_set_padding (buttons, 0, 1, 0, 0);
priv->cancel = nmt_newt_button_box_add_end (NMT_NEWT_BUTTON_BOX (buttons), _("Cancel"));
nmt_newt_widget_set_exit_on_activate (priv->cancel, TRUE);
priv->ok = nmt_newt_button_box_add_end (NMT_NEWT_BUTTON_BOX (buttons), _("OK"));
g_signal_connect (priv->ok, "clicked", G_CALLBACK (save_connection_and_exit), editor);
g_object_bind_property (page, "valid",
priv->ok, "sensitive",
G_BINDING_SYNC_CREATE);
nmt_newt_form_set_content (NMT_NEWT_FORM (editor), vbox);
}
static void
nmt_editor_finalize (GObject *object)
{
NmtEditorPrivate *priv = NMT_EDITOR_GET_PRIVATE (object);
g_clear_object (&priv->orig_connection);
g_clear_object (&priv->edit_connection);
g_clear_object (&priv->ok);
g_clear_object (&priv->cancel);
G_OBJECT_CLASS (nmt_editor_parent_class)->finalize (object);
}
static void
nmt_editor_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtEditorPrivate *priv = NMT_EDITOR_GET_PRIVATE (object);
switch (prop_id) {
case PROP_CONNECTION:
priv->orig_connection = g_value_dup_object (value);
break;
case PROP_TYPE_DATA:
priv->type_data = g_value_get_pointer (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_editor_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtEditorPrivate *priv = NMT_EDITOR_GET_PRIVATE (object);
switch (prop_id) {
case PROP_CONNECTION:
g_value_set_object (value, priv->orig_connection);
break;
case PROP_TYPE_DATA:
g_value_set_pointer (value, priv->type_data);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_editor_class_init (NmtEditorClass *entry_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (entry_class);
g_type_class_add_private (entry_class, sizeof (NmtEditorPrivate));
/* virtual methods */
object_class->constructed = nmt_editor_constructed;
object_class->set_property = nmt_editor_set_property;
object_class->get_property = nmt_editor_get_property;
object_class->finalize = nmt_editor_finalize;
/**
* NmtEditor:connection:
*
* The connection being edited.
*/
g_object_class_install_property (object_class, PROP_CONNECTION,
g_param_spec_object ("connection", "", "",
NM_TYPE_CONNECTION,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtEditor:type-data:
*
* The #NmEditorConnectionTypeData for #NmtEditor:connection.
*/
g_object_class_install_property (object_class, PROP_TYPE_DATA,
g_param_spec_pointer ("type-data", "", "",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

51
tui/nmt-editor.h Normal file
View File

@@ -0,0 +1,51 @@
/* -*- 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.
*/
#ifndef NMT_EDITOR_H
#define NMT_EDITOR_H
#include <nm-connection.h>
#include "nmt-newt.h"
G_BEGIN_DECLS
#define NMT_TYPE_EDITOR (nmt_editor_get_type ())
#define NMT_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_EDITOR, NmtEditor))
#define NMT_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_EDITOR, NmtEditorClass))
#define NMT_IS_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_EDITOR))
#define NMT_IS_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_EDITOR))
#define NMT_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_EDITOR, NmtEditorClass))
typedef struct {
NmtNewtForm parent;
} NmtEditor;
typedef struct {
NmtNewtFormClass parent;
} NmtEditorClass;
GType nmt_editor_get_type (void);
NmtNewtForm *nmt_editor_new (NMConnection *connection);
G_END_DECLS
#endif /* NMT_EDITOR_H */

265
tui/nmt-ip-entry.c Normal file
View File

@@ -0,0 +1,265 @@
/* -*- 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-ip-entry
* @short_description: #NmtNewtEntry for IP address entry
*
* #NmtIPEntry is an #NmtNewtEntry for entering IP addresses, or IP
* address/prefix combination. It will only allow typing characters
* that are valid in an IP address, and will set its
* #NmtNewtWidget:valid property depending on whether it currently
* contains a valid IP address.
*/
#include "config.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <glib/gi18n-lib.h>
#include "nmt-ip-entry.h"
G_DEFINE_TYPE (NmtIPEntry, nmt_ip_entry, NMT_TYPE_NEWT_ENTRY)
#define NMT_IP_ENTRY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_IP_ENTRY, NmtIPEntryPrivate))
typedef struct {
int family;
gboolean prefix;
gboolean optional;
} NmtIPEntryPrivate;
enum {
PROP_0,
PROP_FAMILY,
PROP_PREFIX,
PROP_OPTIONAL,
LAST_PROP
};
/**
* nmt_ip_entry_new:
* @width: the width of the entry
* @family: the IP address family. Eg, %AF_INET
* @prefix: whether to require a trailing "/prefix"
* @optional: whether the address is optional
*
* Creates a new #NmtIPEntry, to accept IP addresses in the indicated
* @family, or (if @prefix is %TRUE), to accept IP address/prefix combos.
*
* If @optional is %TRUE then the address is considered optional, and
* so will still be #NmtNewtWidget:valid even when it is empty. If
* @optional is %FALSE, the entry will be invalid when it is empty.
*/
NmtNewtWidget *
nmt_ip_entry_new (int width,
int family,
gboolean prefix,
gboolean optional)
{
return g_object_new (NMT_TYPE_IP_ENTRY,
"width", width,
"family", family,
"prefix", prefix,
"optional", optional,
NULL);
}
static gboolean
ip_entry_filter (NmtNewtEntry *entry,
const char *text,
int ch,
int position,
gpointer user_data)
{
NmtIPEntryPrivate *priv = NMT_IP_ENTRY_GET_PRIVATE (entry);
const char *slash;
gboolean inaddr;
if (g_ascii_isdigit (ch))
return TRUE;
slash = strchr (text, '/');
if (ch == '/')
return priv->prefix && slash == NULL;
inaddr = !slash || (position <= (slash - text));
if (priv->family == AF_INET) {
if (ch == '.')
return inaddr;
else
return FALSE;
} else if (priv->family == AF_INET6) {
if (g_ascii_isxdigit (ch) || ch == ':')
return inaddr;
else
return FALSE;
} else
g_return_val_if_reached (FALSE);
}
static gboolean
ip_entry_validate (NmtNewtEntry *entry,
const char *text,
gpointer user_data)
{
NmtIPEntryPrivate *priv = NMT_IP_ENTRY_GET_PRIVATE (entry);
guchar buf[16];
guint32 prefix;
const char *slash;
char *addrstr, *end;
gboolean valid;
if (!*text)
return priv->optional;
slash = strchr (text, '/');
if (slash) {
if (!priv->prefix)
return FALSE;
addrstr = g_strndup (text, slash - text);
} else
addrstr = g_strdup (text);
valid = (inet_pton (priv->family, addrstr, buf) == 1);
g_free (addrstr);
if (!valid)
return FALSE;
if (slash) {
prefix = strtoul (slash + 1, &end, 10);
if ( *end
|| prefix == 0
|| (priv->family == AF_INET && prefix > 32)
|| (priv->family == AF_INET6 && prefix > 128))
valid = FALSE;
}
return valid;
}
static void
nmt_ip_entry_init (NmtIPEntry *entry)
{
nmt_newt_entry_set_filter (NMT_NEWT_ENTRY (entry), ip_entry_filter, NULL);
nmt_newt_entry_set_validator (NMT_NEWT_ENTRY (entry), ip_entry_validate, NULL);
}
static void
nmt_ip_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtIPEntryPrivate *priv = NMT_IP_ENTRY_GET_PRIVATE (object);
switch (prop_id) {
case PROP_FAMILY:
priv->family = g_value_get_int (value);
break;
case PROP_PREFIX:
priv->prefix = g_value_get_boolean (value);
break;
case PROP_OPTIONAL:
priv->optional = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_ip_entry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtIPEntryPrivate *priv = NMT_IP_ENTRY_GET_PRIVATE (object);
switch (prop_id) {
case PROP_FAMILY:
g_value_set_int (value, priv->family);
break;
case PROP_PREFIX:
g_value_set_boolean (value, priv->prefix);
break;
case PROP_OPTIONAL:
g_value_set_boolean (value, priv->optional);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_ip_entry_class_init (NmtIPEntryClass *entry_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (entry_class);
g_type_class_add_private (entry_class, sizeof (NmtIPEntryPrivate));
/* virtual methods */
object_class->set_property = nmt_ip_entry_set_property;
object_class->get_property = nmt_ip_entry_get_property;
/**
* NmtIPEntry:family:
*
* The address family. Eg, %AF_INET
*/
g_object_class_install_property (object_class, PROP_FAMILY,
g_param_spec_int ("family", "", "",
0, G_MAXINT, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtIPEntry:prefix:
*
* If %TRUE, the entry accepts address/prefix combinations. If
* %FALSE it accepts just addresses.
*/
g_object_class_install_property (object_class, PROP_PREFIX,
g_param_spec_boolean ("prefix", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* NmtIPEntry:optional:
*
* If %TRUE, the entry will be #NmtNewtWidget:valid when it is
* empty. If %FALSE, it will only be valid when it contains a
* valid address or address/prefix.
*/
g_object_class_install_property (object_class, PROP_OPTIONAL,
g_param_spec_boolean ("optional", "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

52
tui/nmt-ip-entry.h Normal file
View File

@@ -0,0 +1,52 @@
/* -*- 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.
*/
#ifndef NMT_IP_ENTRY_H
#define NMT_IP_ENTRY_H
#include "nmt-newt.h"
G_BEGIN_DECLS
#define NMT_TYPE_IP_ENTRY (nmt_ip_entry_get_type ())
#define NMT_IP_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_IP_ENTRY, NmtIPEntry))
#define NMT_IP_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_IP_ENTRY, NmtIPEntryClass))
#define NMT_IS_IP_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_IP_ENTRY))
#define NMT_IS_IP_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_IP_ENTRY))
#define NMT_IP_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_IP_ENTRY, NmtIPEntryClass))
typedef struct {
NmtNewtEntry parent;
} NmtIPEntry;
typedef struct {
NmtNewtEntryClass parent;
} NmtIPEntryClass;
GType nmt_ip_entry_get_type (void);
NmtNewtWidget *nmt_ip_entry_new (int width,
int family,
gboolean prefix,
gboolean optional);
G_END_DECLS
#endif /* NMT_IP_ENTRY_H */

217
tui/nmt-mac-entry.c Normal file
View File

@@ -0,0 +1,217 @@
/* -*- 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-mac-entry
* @short_description: #NmtNewtEntry for hardware address entry
*
* #NmtMacEntry is an #NmtNewtEntry for entering hardware addresses.
* It will only allow typing characters that are valid in a hardware
* address, and will set its #NmtNewtWidget:valid property depending
* on whether it currently contains a valid hardware address.
*/
#include "config.h"
#include <dbus/dbus-glib.h>
#include <nm-utils.h>
#include "nmt-mac-entry.h"
G_DEFINE_TYPE (NmtMacEntry, nmt_mac_entry, NMT_TYPE_NEWT_ENTRY)
#define NMT_MAC_ENTRY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_MAC_ENTRY, NmtMacEntryPrivate))
typedef struct {
int mac_length;
int mac_str_length;
} NmtMacEntryPrivate;
enum {
PROP_0,
PROP_MAC_LENGTH,
PROP_MAC_ADDRESS,
LAST_PROP
};
/**
* nmt_mac_entry_new:
* @width: the width in characters of the entry
* @mac_length: the length in bytes of the hardware address
* (either %ETH_ALEN or %INFINIBAND_ALEN)
*
* Creates a new #NmtMacEntry.
*
* Returns: a new #NmtMacEntry.
*/
NmtNewtWidget *
nmt_mac_entry_new (int width,
int mac_length)
{
return g_object_new (NMT_TYPE_MAC_ENTRY,
"width", width,
"mac-length", mac_length,
NULL);
}
static gboolean
mac_filter (NmtNewtEntry *entry,
const char *text,
int ch,
int position,
gpointer user_data)
{
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE (entry);
if (position > priv->mac_str_length)
return FALSE;
return g_ascii_isxdigit (ch) || ch == ':';
}
static gboolean
mac_validator (NmtNewtEntry *entry,
const char *text,
gpointer user_data)
{
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE (entry);
const char *p;
if (!*text)
return TRUE;
p = text;
while ( g_ascii_isxdigit (p[0])
&& g_ascii_isxdigit (p[1])
&& p[2] == ':')
p += 3;
if ( !g_ascii_isxdigit (p[0])
|| !g_ascii_isxdigit (p[1]))
return FALSE;
p += 2;
if (!*p)
return (p - text == priv->mac_str_length);
if (g_ascii_isxdigit (p[0]) && !p[1]) {
char *fixed = g_strdup_printf ("%.*s:%c", (int)(p - text), text, *p);
g_object_set (G_OBJECT (entry), "text", fixed, NULL);
return TRUE;
}
return FALSE;
}
static void
nmt_mac_entry_init (NmtMacEntry *entry)
{
nmt_newt_entry_set_filter (NMT_NEWT_ENTRY (entry), mac_filter, NULL);
nmt_newt_entry_set_validator (NMT_NEWT_ENTRY (entry), mac_validator, NULL);
}
static void
nmt_mac_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE (object);
GByteArray *addr;
char *addr_str;
switch (prop_id) {
case PROP_MAC_LENGTH:
priv->mac_length = g_value_get_int (value);
priv->mac_str_length = priv->mac_length * 3 - 1;
break;
case PROP_MAC_ADDRESS:
addr = g_value_get_boxed (value);
if (addr) {
addr_str = nm_utils_hwaddr_ntoa_len (addr->data, addr->len);
nmt_newt_entry_set_text (NMT_NEWT_ENTRY (object), addr_str);
g_free (addr_str);
} else
nmt_newt_entry_set_text (NMT_NEWT_ENTRY (object), "");
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_mac_entry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE (object);
GByteArray *addr;
switch (prop_id) {
case PROP_MAC_LENGTH:
g_value_set_int (value, priv->mac_length);
break;
case PROP_MAC_ADDRESS:
addr = nm_utils_hwaddr_atoba (nmt_newt_entry_get_text (NMT_NEWT_ENTRY (object)), ARPHRD_ETHER);
g_value_take_boxed (value, addr);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_mac_entry_class_init (NmtMacEntryClass *entry_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (entry_class);
g_type_class_add_private (entry_class, sizeof (NmtMacEntryPrivate));
/* virtual methods */
object_class->set_property = nmt_mac_entry_set_property;
object_class->get_property = nmt_mac_entry_get_property;
/**
* NmtMacEntry:mac-length:
*
* The length in bytes of the hardware address type the entry
* accepts: either %ETH_ALEN or %INFINIBAND_ALEN.
*/
g_object_class_install_property (object_class, PROP_MAC_LENGTH,
g_param_spec_int ("mac-length", "", "",
0, INFINIBAND_ALEN, ETH_ALEN,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtMacEntry:mac-address:
*
* The MAC address, in binary (in the same format used by the various
* #NMSetting "mac-address" properties).
*/
g_object_class_install_property (object_class, PROP_MAC_ADDRESS,
g_param_spec_boxed ("mac-address", "", "",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

54
tui/nmt-mac-entry.h Normal file
View File

@@ -0,0 +1,54 @@
/* -*- 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.
*/
#ifndef NMT_MAC_ENTRY_H
#define NMT_MAC_ENTRY_H
#include <linux/if_ether.h>
#include <linux/if_infiniband.h>
#include <linux/if_arp.h>
#include "nmt-newt.h"
G_BEGIN_DECLS
#define NMT_TYPE_MAC_ENTRY (nmt_mac_entry_get_type ())
#define NMT_MAC_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_MAC_ENTRY, NmtMacEntry))
#define NMT_MAC_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_MAC_ENTRY, NmtMacEntryClass))
#define NMT_IS_MAC_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_MAC_ENTRY))
#define NMT_IS_MAC_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_MAC_ENTRY))
#define NMT_MAC_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_MAC_ENTRY, NmtMacEntryClass))
typedef struct {
NmtNewtEntry parent;
} NmtMacEntry;
typedef struct {
NmtNewtEntryClass parent;
} NmtMacEntryClass;
GType nmt_mac_entry_get_type (void);
NmtNewtWidget *nmt_mac_entry_new (int width,
int mac_length);
G_END_DECLS
#endif /* NMT_MAC_ENTRY_H */

191
tui/nmt-mtu-entry.c Normal file
View File

@@ -0,0 +1,191 @@
/* -*- 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-mtu-entry
* @short_description: #NmtNewtEntry for MTU entry
*
* #NmtMtuEntry is an #NmtNewtEntry for entering MTU values. It will
* only allow typing numeric characters, and will set its
* #NmtNewtWidget:valid property depending on whether it currently
* contains a valid MTU.
*
* The entry also has an attached #NmtNewtLabel. When the entry value
* is "0", the label will read "(default)". Otherwise it reads "bytes",
* indicating the units used by the entry.
*/
#include "config.h"
#include <stdlib.h>
#include <glib/gi18n-lib.h>
#include "nmt-mtu-entry.h"
G_DEFINE_TYPE (NmtMtuEntry, nmt_mtu_entry, NMT_TYPE_NEWT_GRID)
#define NMT_MTU_ENTRY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_MTU_ENTRY, NmtMtuEntryPrivate))
typedef struct {
int mtu;
NmtNewtEntry *entry;
NmtNewtLabel *label;
} NmtMtuEntryPrivate;
enum {
PROP_0,
PROP_MTU,
LAST_PROP
};
/**
* nmt_mtu_entry_new:
*
* Creates a new #NmtMtuEntry
*
* Returns: a new #NmtMtuEntry
*/
NmtNewtWidget *
nmt_mtu_entry_new (void)
{
return g_object_new (NMT_TYPE_MTU_ENTRY, NULL);
}
static gboolean
mtu_validator (NmtNewtEntry *entry,
const char *text,
gpointer user_data)
{
NmtMtuEntryPrivate *priv = NMT_MTU_ENTRY_GET_PRIVATE (user_data);
if (*text && !atoi (text)) {
nmt_newt_entry_set_text (entry, "");
text = "";
}
if (!*text)
nmt_newt_label_set_text (priv->label, _("(default)"));
else
nmt_newt_label_set_text (priv->label, _("bytes"));
return TRUE;
}
static gboolean
mtu_transform_to_text (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
int mtu = g_value_get_int (source_value);
if (mtu)
g_value_transform (source_value, target_value);
else
g_value_set_string (target_value, "");
return TRUE;
}
static void
nmt_mtu_entry_init (NmtMtuEntry *entry)
{
NmtMtuEntryPrivate *priv = NMT_MTU_ENTRY_GET_PRIVATE (entry);
NmtNewtGrid *grid = NMT_NEWT_GRID (entry);
NmtNewtWidget *real_entry, *label;
real_entry = nmt_newt_entry_numeric_new (10, 0, 65535);
priv->entry = NMT_NEWT_ENTRY (real_entry);
label = nmt_newt_label_new (_("bytes"));
priv->label = NMT_NEWT_LABEL (label);
nmt_newt_grid_add (grid, real_entry, 0, 0);
nmt_newt_grid_add (grid, label, 1, 0);
nmt_newt_widget_set_padding (label, 1, 0, 0, 0);
nmt_newt_entry_set_validator (priv->entry, mtu_validator, entry);
g_object_bind_property_full (entry, "mtu", real_entry, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
mtu_transform_to_text,
NULL,
NULL, NULL);
}
static void
nmt_mtu_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtMtuEntryPrivate *priv = NMT_MTU_ENTRY_GET_PRIVATE (object);
switch (prop_id) {
case PROP_MTU:
priv->mtu = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_mtu_entry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtMtuEntryPrivate *priv = NMT_MTU_ENTRY_GET_PRIVATE (object);
switch (prop_id) {
case PROP_MTU:
g_value_set_int (value, priv->mtu);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_mtu_entry_class_init (NmtMtuEntryClass *entry_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (entry_class);
g_type_class_add_private (entry_class, sizeof (NmtMtuEntryPrivate));
/* virtual methods */
object_class->set_property = nmt_mtu_entry_set_property;
object_class->get_property = nmt_mtu_entry_get_property;
/**
* NmtMtuEntry:mtu:
*
* The contents of the entry, as a number.
*/
g_object_class_install_property (object_class, PROP_MTU,
g_param_spec_int ("mtu", "", "",
0, G_MAXINT, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

49
tui/nmt-mtu-entry.h Normal file
View File

@@ -0,0 +1,49 @@
/* -*- 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.
*/
#ifndef NMT_MTU_ENTRY_H
#define NMT_MTU_ENTRY_H
#include "nmt-newt.h"
G_BEGIN_DECLS
#define NMT_TYPE_MTU_ENTRY (nmt_mtu_entry_get_type ())
#define NMT_MTU_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_MTU_ENTRY, NmtMtuEntry))
#define NMT_MTU_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_MTU_ENTRY, NmtMtuEntryClass))
#define NMT_IS_MTU_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_MTU_ENTRY))
#define NMT_IS_MTU_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_MTU_ENTRY))
#define NMT_MTU_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_MTU_ENTRY, NmtMtuEntryClass))
typedef struct {
NmtNewtGrid parent;
} NmtMtuEntry;
typedef struct {
NmtNewtGridClass parent;
} NmtMtuEntryClass;
GType nmt_mtu_entry_get_type (void);
NmtNewtWidget *nmt_mtu_entry_new (void);
G_END_DECLS
#endif /* NMT_MTU_ENTRY_H */

436
tui/nmt-page-bond.c Normal file
View File

@@ -0,0 +1,436 @@
/* -*- 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-page-bond
* @short_description: The editor page for Bond connections
*
* Note that this is fairly different from most of the other editor
* pages, because #NMSettingBond doesn't have properties, so we
* can't just use #GBinding.
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-bond.h"
#include "nmt-address-list.h"
#include "nmt-slave-list.h"
G_DEFINE_TYPE (NmtPageBond, nmt_page_bond, NMT_TYPE_PAGE_DEVICE)
#define NMT_PAGE_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_BOND, NmtPageBondPrivate))
typedef enum {
NMT_PAGE_BOND_MONITORING_UNKNOWN = -1,
NMT_PAGE_BOND_MONITORING_MII = 0,
NMT_PAGE_BOND_MONITORING_ARP = 1,
} NmtPageBondMonitoringMode;
typedef struct {
NmtSlaveList *slaves;
NmtNewtPopup *mode;
NmtNewtEntry *primary;
NmtNewtPopup *monitoring;
NmtNewtEntry *miimon;
NmtNewtEntry *updelay;
NmtNewtEntry *downdelay;
NmtNewtEntry *arp_interval;
NmtAddressList *arp_ip_target;
NmtPageBondMonitoringMode monitoring_mode;
NMSettingBond *s_bond;
GType slave_type;
gboolean updating;
} NmtPageBondPrivate;
NmtNewtWidget *
nmt_page_bond_new (NMConnection *conn,
NmtDeviceEntry *deventry)
{
return g_object_new (NMT_TYPE_PAGE_BOND,
"connection", conn,
"title", _("BOND"),
"device-entry", deventry,
NULL);
}
static void
nmt_page_bond_init (NmtPageBond *bond)
{
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
priv->monitoring_mode = NMT_PAGE_BOND_MONITORING_UNKNOWN;
priv->slave_type = G_TYPE_NONE;
}
static NmtNewtPopupEntry bond_mode[] = {
{ N_("Round-robin"), "balance-rr" },
{ N_("Active Backup"), "active-backup" },
{ N_("XOR"), "balance-xor" },
{ N_("Broadcast"), "broadcast" },
{ N_("802.3ad"), "802.3ad" },
{ N_("Adaptive Transmit Load Balancing (tlb)"), "balance-tlb" },
{ N_("Adaptive Load Balancing (alb)"), "balance-alb" },
{ NULL, NULL }
};
/* NB: the ordering/numbering here corresponds to NmtPageBondMonitoringMode */
static NmtNewtPopupEntry bond_monitoring[] = {
{ N_("MII (recommended)"), "mii" },
{ N_("ARP"), "arp" },
{ NULL, NULL }
};
static void
bond_options_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
NMSettingBond *s_bond = NM_SETTING_BOND (object);
NmtPageBond *bond = NMT_PAGE_BOND (user_data);
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
const char *val;
char **ips;
if (priv->updating)
return;
priv->updating = TRUE;
val = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE);
nmt_newt_popup_set_active_id (priv->mode, val);
if (!strcmp (val, "active-backup")) {
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->primary), TRUE);
val = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
nmt_newt_entry_set_text (priv->primary, val);
} else
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->primary), FALSE);
if (priv->monitoring_mode == NMT_PAGE_BOND_MONITORING_UNKNOWN) {
val = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
if (val && strcmp (val, "0") != 0)
priv->monitoring_mode = NMT_PAGE_BOND_MONITORING_ARP;
else
priv->monitoring_mode = NMT_PAGE_BOND_MONITORING_MII;
}
nmt_newt_popup_set_active (priv->monitoring, priv->monitoring_mode);
if (priv->monitoring_mode == NMT_PAGE_BOND_MONITORING_MII) {
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->miimon), TRUE);
val = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON);
nmt_newt_entry_set_text (priv->miimon, val);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->updelay), TRUE);
val = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_UPDELAY);
nmt_newt_entry_set_text (priv->updelay, val);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->downdelay), TRUE);
val = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY);
nmt_newt_entry_set_text (priv->downdelay, val);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->arp_interval), FALSE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->arp_ip_target), FALSE);
} else {
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->arp_interval), TRUE);
val = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
nmt_newt_entry_set_text (priv->arp_interval, val);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->arp_ip_target), TRUE);
val = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
ips = g_strsplit (val, ",", -1);
g_object_set (G_OBJECT (priv->arp_ip_target),
"string", ips,
NULL);
g_strfreev (ips);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->miimon), FALSE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->updelay), FALSE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->downdelay), FALSE);
}
priv->updating = FALSE;
}
static void
slaves_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
NmtPageBond *bond = NMT_PAGE_BOND (user_data);
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
GPtrArray *slaves;
g_object_get (object, "connections", &slaves, NULL);
if (slaves->len == 0) {
if (priv->slave_type == G_TYPE_NONE)
return;
priv->slave_type = G_TYPE_NONE;
} else {
NMConnection *slave = slaves->pdata[0];
if (priv->slave_type != G_TYPE_NONE)
return;
if (nm_connection_is_type (slave, NM_SETTING_INFINIBAND_SETTING_NAME))
priv->slave_type = NM_TYPE_SETTING_INFINIBAND;
else
priv->slave_type = NM_TYPE_SETTING_WIRED;
}
if (priv->slave_type == NM_TYPE_SETTING_INFINIBAND) {
nmt_newt_popup_set_active_id (priv->mode, "active-backup");
nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->mode), FALSE);
} else
nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->mode), TRUE);
}
#define WIDGET_CHANGED_FUNC(widget, func, option) \
static void \
widget ## _widget_changed (GObject *object, \
GParamSpec *pspec, \
gpointer user_data) \
{ \
NmtPageBond *bond = NMT_PAGE_BOND (user_data); \
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond); \
\
if (priv->updating) \
return; \
\
priv->updating = TRUE; \
nm_setting_bond_add_option (priv->s_bond, option, func (priv->widget)); \
priv->updating = FALSE; \
}
WIDGET_CHANGED_FUNC (primary, nmt_newt_entry_get_text, NM_SETTING_BOND_OPTION_PRIMARY)
WIDGET_CHANGED_FUNC (miimon, nmt_newt_entry_get_text, NM_SETTING_BOND_OPTION_MIIMON)
WIDGET_CHANGED_FUNC (updelay, nmt_newt_entry_get_text, NM_SETTING_BOND_OPTION_UPDELAY)
WIDGET_CHANGED_FUNC (downdelay, nmt_newt_entry_get_text, NM_SETTING_BOND_OPTION_DOWNDELAY)
WIDGET_CHANGED_FUNC (arp_interval, nmt_newt_entry_get_text, NM_SETTING_BOND_OPTION_ARP_INTERVAL)
static void
mode_widget_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
NmtPageBond *bond = NMT_PAGE_BOND (user_data);
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
const char *mode;
if (priv->updating)
return;
mode = nmt_newt_popup_get_active_id (priv->mode);
priv->updating = TRUE;
nm_setting_bond_add_option (priv->s_bond, NM_SETTING_BOND_OPTION_MODE, mode);
priv->updating = FALSE;
if (!strcmp (mode, "balance-tlb") || !strcmp (mode, "balance-alb")) {
nmt_newt_popup_set_active (priv->monitoring, NMT_PAGE_BOND_MONITORING_MII);
nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->monitoring), FALSE);
} else
nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->monitoring), TRUE);
if (!strcmp (mode, "active-backup"))
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->primary), TRUE);
else
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->primary), FALSE);
}
static void
monitoring_widget_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
NmtPageBond *bond = NMT_PAGE_BOND (user_data);
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
if (priv->updating)
return;
priv->monitoring_mode = nmt_newt_popup_get_active (priv->monitoring);
if (priv->monitoring_mode == NMT_PAGE_BOND_MONITORING_MII) {
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->miimon), TRUE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->updelay), TRUE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->downdelay), TRUE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->arp_interval), FALSE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->arp_ip_target), FALSE);
} else {
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->arp_interval), TRUE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->arp_ip_target), TRUE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->miimon), FALSE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->updelay), FALSE);
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->downdelay), FALSE);
}
}
static void
arp_ip_target_widget_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
NmtPageBond *bond = NMT_PAGE_BOND (user_data);
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
char **ips, *target;
if (priv->updating)
return;
g_object_get (G_OBJECT (priv->arp_ip_target),
"strings", &ips,
NULL);
target = g_strjoinv (",", ips);
priv->updating = TRUE;
nm_setting_bond_add_option (priv->s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, target);
priv->updating = FALSE;
g_free (target);
g_strfreev (ips);
}
static gboolean
bond_connection_type_filter (GType connection_type,
gpointer user_data)
{
NmtPageBond *bond = user_data;
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
if ( priv->slave_type != NM_TYPE_SETTING_WIRED
&& connection_type == NM_TYPE_SETTING_INFINIBAND)
return TRUE;
if ( priv->slave_type != NM_TYPE_SETTING_INFINIBAND
&& connection_type == NM_TYPE_SETTING_WIRED)
return TRUE;
return FALSE;
}
static void
nmt_page_bond_constructed (GObject *object)
{
NmtPageBond *bond = NMT_PAGE_BOND (object);
NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
NmtDeviceEntry *deventry;
NmtPageGrid *grid;
NMSettingBond *s_bond;
NmtNewtWidget *widget, *label;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (bond));
s_bond = nm_connection_get_setting_bond (conn);
if (!s_bond) {
nm_connection_add_setting (conn, nm_setting_bond_new ());
s_bond = nm_connection_get_setting_bond (conn);
}
priv->s_bond = s_bond;
deventry = nmt_page_device_get_device_entry (NMT_PAGE_DEVICE (object));
g_object_bind_property (s_bond, NM_SETTING_BOND_INTERFACE_NAME,
deventry, "interface-name",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
grid = NMT_PAGE_GRID (bond);
widget = nmt_newt_separator_new ();
nmt_page_grid_append (grid, _("Slaves"), widget, NULL);
nmt_page_grid_set_row_flags (grid, widget, NMT_PAGE_GRID_ROW_LABEL_ALIGN_LEFT);
widget = nmt_slave_list_new (conn, bond_connection_type_filter, bond);
g_signal_connect (widget, "notify::connections",
G_CALLBACK (slaves_changed), bond);
nmt_page_grid_append (grid, NULL, widget, NULL);
priv->slaves = NMT_SLAVE_LIST (widget);
widget = nmt_newt_popup_new (bond_mode);
g_signal_connect (widget, "notify::active-id",
G_CALLBACK (mode_widget_changed), bond);
nmt_page_grid_append (grid, _("Mode"), widget, NULL);
priv->mode = NMT_NEWT_POPUP (widget);
widget = nmt_newt_entry_new (40, 0);
g_signal_connect (widget, "notify::text",
G_CALLBACK (primary_widget_changed), bond);
nmt_page_grid_append (grid, _("Primary"), widget, NULL);
priv->primary = NMT_NEWT_ENTRY (widget);
widget = nmt_newt_popup_new (bond_monitoring);
g_signal_connect (widget, "notify::active",
G_CALLBACK (monitoring_widget_changed), bond);
nmt_page_grid_append (grid, _("Link monitoring"), widget, NULL);
priv->monitoring = NMT_NEWT_POPUP (widget);
widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
g_signal_connect (widget, "notify::text",
G_CALLBACK (miimon_widget_changed), bond);
label = nmt_newt_label_new (C_("milliseconds", "ms"));
nmt_page_grid_append (grid, _("Monitoring frequency"), widget, label);
priv->miimon = NMT_NEWT_ENTRY (widget);
widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
g_signal_connect (widget, "notify::text",
G_CALLBACK (updelay_widget_changed), bond);
label = nmt_newt_label_new (C_("milliseconds", "ms"));
nmt_page_grid_append (grid, _("Link up delay"), widget, label);
priv->updelay = NMT_NEWT_ENTRY (widget);
widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
g_signal_connect (widget, "notify::text",
G_CALLBACK (downdelay_widget_changed), bond);
label = nmt_newt_label_new (C_("milliseconds", "ms"));
nmt_page_grid_append (grid, _("Link down delay"), widget, label);
priv->downdelay = NMT_NEWT_ENTRY (widget);
widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
g_signal_connect (widget, "notify::text",
G_CALLBACK (arp_interval_widget_changed), bond);
label = nmt_newt_label_new (C_("milliseconds", "ms"));
nmt_page_grid_append (grid, _("Monitoring frequency"), widget, label);
priv->arp_interval = NMT_NEWT_ENTRY (widget);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_IP4);
g_signal_connect (widget, "notify::strings",
G_CALLBACK (arp_ip_target_widget_changed), bond);
nmt_page_grid_append (grid, _("ARP targets"), widget, NULL);
priv->arp_ip_target = NMT_ADDRESS_LIST (widget);
g_signal_connect (s_bond, "notify::" NM_SETTING_BOND_OPTIONS,
G_CALLBACK (bond_options_changed), bond);
bond_options_changed (G_OBJECT (s_bond), NULL, bond);
slaves_changed (G_OBJECT (priv->slaves), NULL, bond);
G_OBJECT_CLASS (nmt_page_bond_parent_class)->constructed (object);
}
static void
nmt_page_bond_class_init (NmtPageBondClass *bond_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (bond_class);
g_type_class_add_private (bond_class, sizeof (NmtPageBondPrivate));
object_class->constructed = nmt_page_bond_constructed;
}

50
tui/nmt-page-bond.h Normal file
View File

@@ -0,0 +1,50 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_BOND_H
#define NMT_PAGE_BOND_H
#include "nmt-page-device.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_BOND (nmt_page_bond_get_type ())
#define NMT_PAGE_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_BOND, NmtPageBond))
#define NMT_PAGE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_BOND, NmtPageBondClass))
#define NMT_IS_PAGE_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_BOND))
#define NMT_IS_PAGE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_BOND))
#define NMT_PAGE_BOND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_BOND, NmtPageBondClass))
typedef struct {
NmtPageDevice parent;
} NmtPageBond;
typedef struct {
NmtPageDeviceClass parent;
} NmtPageBondClass;
GType nmt_page_bond_get_type (void);
NmtNewtWidget *nmt_page_bond_new (NMConnection *conn,
NmtDeviceEntry *deventry);
G_END_DECLS
#endif /* NMT_PAGE_BOND_H */

View File

@@ -0,0 +1,92 @@
/* -*- 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-page-bridge-port
* @short_description: The editor page for Bridge ports
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-bridge-port.h"
G_DEFINE_TYPE (NmtPageBridgePort, nmt_page_bridge_port, NMT_TYPE_EDITOR_PAGE)
NmtNewtWidget *
nmt_page_bridge_port_new (NMConnection *conn)
{
return g_object_new (NMT_TYPE_PAGE_BRIDGE_PORT,
"connection", conn,
"title", _("BRIDGE PORT"),
NULL);
}
static void
nmt_page_bridge_port_init (NmtPageBridgePort *bridge)
{
}
static void
nmt_page_bridge_port_constructed (GObject *object)
{
NmtPageBridgePort *bridge = NMT_PAGE_BRIDGE_PORT (object);
NmtPageGrid *grid;
NMSettingBridgePort *s_port;
NmtNewtWidget *widget;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (bridge));
s_port = nm_connection_get_setting_bridge_port (conn);
if (!s_port) {
nm_connection_add_setting (conn, nm_setting_bridge_port_new ());
s_port = nm_connection_get_setting_bridge_port (conn);
}
grid = NMT_PAGE_GRID (bridge);
widget = nmt_newt_entry_numeric_new (10, 0, 63);
g_object_bind_property (s_port, NM_SETTING_BRIDGE_PORT_PRIORITY,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Priority"), widget, NULL);
widget = nmt_newt_entry_numeric_new (10, 1, 65535);
g_object_bind_property (s_port, NM_SETTING_BRIDGE_PORT_PATH_COST,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Path cost"), widget, NULL);
widget = nmt_newt_checkbox_new (_("Hairpin mode"));
g_object_bind_property (s_port, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE,
widget, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, NULL, widget, NULL);
G_OBJECT_CLASS (nmt_page_bridge_port_parent_class)->constructed (object);
}
static void
nmt_page_bridge_port_class_init (NmtPageBridgePortClass *bridge_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (bridge_class);
object_class->constructed = nmt_page_bridge_port_constructed;
}

View File

@@ -0,0 +1,49 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_BRIDGE_PORT_H
#define NMT_PAGE_BRIDGE_PORT_H
#include "nmt-editor-page.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_BRIDGE_PORT (nmt_page_bridge_port_get_type ())
#define NMT_PAGE_BRIDGE_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_BRIDGE_PORT, NmtPageBridgePort))
#define NMT_PAGE_BRIDGE_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_BRIDGE_PORT, NmtPageBridgePortClass))
#define NMT_IS_PAGE_BRIDGE_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_BRIDGE_PORT))
#define NMT_IS_PAGE_BRIDGE_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_BRIDGE_PORT))
#define NMT_PAGE_BRIDGE_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_BRIDGE_PORT, NmtPageBridgePortClass))
typedef struct {
NmtEditorPage parent;
} NmtPageBridgePort;
typedef struct {
NmtEditorPageClass parent;
} NmtPageBridgePortClass;
GType nmt_page_bridge_port_get_type (void);
NmtNewtWidget *nmt_page_bridge_port_new (NMConnection *conn);
G_END_DECLS
#endif /* NMT_PAGE_BRIDGE_PORT_H */

153
tui/nmt-page-bridge.c Normal file
View File

@@ -0,0 +1,153 @@
/* -*- 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-page-bridge
* @short_description: The editor page for Bridge connections
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-bridge.h"
#include "nmt-address-list.h"
#include "nmt-slave-list.h"
G_DEFINE_TYPE (NmtPageBridge, nmt_page_bridge, NMT_TYPE_PAGE_DEVICE)
NmtNewtWidget *
nmt_page_bridge_new (NMConnection *conn,
NmtDeviceEntry *deventry)
{
return g_object_new (NMT_TYPE_PAGE_BRIDGE,
"connection", conn,
"title", _("BRIDGE"),
"device-entry", deventry,
NULL);
}
static void
nmt_page_bridge_init (NmtPageBridge *bridge)
{
}
static gboolean
bridge_connection_type_filter (GType connection_type,
gpointer user_data)
{
return ( connection_type == NM_TYPE_SETTING_WIRED
|| connection_type == NM_TYPE_SETTING_WIRELESS
|| connection_type == NM_TYPE_SETTING_VLAN);
}
static void
nmt_page_bridge_constructed (GObject *object)
{
NmtPageBridge *bridge = NMT_PAGE_BRIDGE (object);
NmtDeviceEntry *deventry;
NmtPageGrid *grid;
NMSettingBridge *s_bridge;
NmtNewtWidget *widget, *label, *stp;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (bridge));
s_bridge = nm_connection_get_setting_bridge (conn);
if (!s_bridge) {
nm_connection_add_setting (conn, nm_setting_bridge_new ());
s_bridge = nm_connection_get_setting_bridge (conn);
}
deventry = nmt_page_device_get_device_entry (NMT_PAGE_DEVICE (object));
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME,
deventry, "interface-name",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
grid = NMT_PAGE_GRID (bridge);
widget = nmt_newt_separator_new ();
nmt_page_grid_append (grid, _("Slaves"), widget, NULL);
nmt_page_grid_set_row_flags (grid, widget, NMT_PAGE_GRID_ROW_LABEL_ALIGN_LEFT);
widget = nmt_slave_list_new (conn, bridge_connection_type_filter, bridge);
nmt_page_grid_append (grid, NULL, widget, NULL);
widget = nmt_newt_entry_numeric_new (10, 0, 1000000);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_AGEING_TIME,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
label = nmt_newt_label_new (_("seconds"));
nmt_page_grid_append (grid, _("Aging time"), widget, label);
widget = stp = nmt_newt_checkbox_new (_("Enable STP (Spanning Tree Protocol)"));
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_STP,
widget, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, NULL, widget, NULL);
widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_PRIORITY,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_STP,
widget, "sensitive",
G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Priority"), widget, NULL);
widget = nmt_newt_entry_numeric_new (10, 2, 30);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_FORWARD_DELAY,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_STP,
widget, "sensitive",
G_BINDING_SYNC_CREATE);
label = nmt_newt_label_new (_("seconds"));
nmt_page_grid_append (grid, _("Forward delay"), widget, label);
widget = nmt_newt_entry_numeric_new (10, 1, 10);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_HELLO_TIME,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_STP,
widget, "sensitive",
G_BINDING_SYNC_CREATE);
label = nmt_newt_label_new (_("seconds"));
nmt_page_grid_append (grid, _("Hello time"), widget, label);
widget = nmt_newt_entry_numeric_new (10, 6, 40);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_MAX_AGE,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_STP,
widget, "sensitive",
G_BINDING_SYNC_CREATE);
label = nmt_newt_label_new (_("seconds"));
nmt_page_grid_append (grid, _("Max age"), widget, label);
G_OBJECT_CLASS (nmt_page_bridge_parent_class)->constructed (object);
}
static void
nmt_page_bridge_class_init (NmtPageBridgeClass *bridge_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (bridge_class);
object_class->constructed = nmt_page_bridge_constructed;
}

50
tui/nmt-page-bridge.h Normal file
View File

@@ -0,0 +1,50 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_BRIDGE_H
#define NMT_PAGE_BRIDGE_H
#include "nmt-page-device.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_BRIDGE (nmt_page_bridge_get_type ())
#define NMT_PAGE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_BRIDGE, NmtPageBridge))
#define NMT_PAGE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_BRIDGE, NmtPageBridgeClass))
#define NMT_IS_PAGE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_BRIDGE))
#define NMT_IS_PAGE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_BRIDGE))
#define NMT_PAGE_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_BRIDGE, NmtPageBridgeClass))
typedef struct {
NmtPageDevice parent;
} NmtPageBridge;
typedef struct {
NmtPageDeviceClass parent;
} NmtPageBridgeClass;
GType nmt_page_bridge_get_type (void);
NmtNewtWidget *nmt_page_bridge_new (NMConnection *conn,
NmtDeviceEntry *deventry);
G_END_DECLS
#endif /* NMT_PAGE_BRIDGE_H */

151
tui/nmt-page-device.c Normal file
View File

@@ -0,0 +1,151 @@
/* -*- 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-page-device
* @short_description: Abstract base class for "device" editor pages
*
* #NmtPageDevice is the base class for #NmtEditorPage subclasses
* representing device-type-specific data. (Eg, #NmtPageEthernet,
* #NmtPageVlan, etc).
*
* FIXME: rename to NmtEditorPageDevice, so it doesn't sound like it's
* an actual page type.
*/
#include "config.h"
#include "nmt-page-device.h"
G_DEFINE_TYPE (NmtPageDevice, nmt_page_device, NMT_TYPE_EDITOR_PAGE)
#define NMT_PAGE_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_DEVICE, NmtPageDevicePrivate))
typedef struct {
NmtDeviceEntry *device_entry;
gboolean show_by_default;
} NmtPageDevicePrivate;
enum {
PROP_0,
PROP_DEVICE_ENTRY,
PROP_SHOW_BY_DEFAULT,
LAST_PROP
};
static void
nmt_page_device_init (NmtPageDevice *device)
{
}
static void
nmt_page_device_finalize (GObject *object)
{
NmtPageDevicePrivate *priv = NMT_PAGE_DEVICE_GET_PRIVATE (object);
g_clear_object (&priv->device_entry);
G_OBJECT_CLASS (nmt_page_device_parent_class)->finalize (object);
}
NmtDeviceEntry *
nmt_page_device_get_device_entry (NmtPageDevice *page)
{
NmtPageDevicePrivate *priv = NMT_PAGE_DEVICE_GET_PRIVATE (page);
return priv->device_entry;
}
gboolean
nmt_page_device_get_show_by_default (NmtPageDevice *page)
{
NmtPageDevicePrivate *priv = NMT_PAGE_DEVICE_GET_PRIVATE (page);
return priv->show_by_default;
}
static void
nmt_page_device_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtPageDevicePrivate *priv = NMT_PAGE_DEVICE_GET_PRIVATE (object);
switch (prop_id) {
case PROP_DEVICE_ENTRY:
priv->device_entry = g_value_dup_object (value);
break;
case PROP_SHOW_BY_DEFAULT:
priv->show_by_default = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_page_device_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtPageDevicePrivate *priv = NMT_PAGE_DEVICE_GET_PRIVATE (object);
switch (prop_id) {
case PROP_DEVICE_ENTRY:
g_value_set_object (value, priv->device_entry);
break;
case PROP_SHOW_BY_DEFAULT:
g_value_set_boolean (value, priv->show_by_default);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_page_device_class_init (NmtPageDeviceClass *page_device_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (page_device_class);
g_type_class_add_private (page_device_class, sizeof (NmtPageDevicePrivate));
/* virtual methods */
object_class->set_property = nmt_page_device_set_property;
object_class->get_property = nmt_page_device_get_property;
object_class->finalize = nmt_page_device_finalize;
/* properties */
g_object_class_install_property (object_class, PROP_DEVICE_ENTRY,
g_param_spec_object ("device-entry", "", "",
NMT_TYPE_DEVICE_ENTRY,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_SHOW_BY_DEFAULT,
g_param_spec_boolean ("show-by-default", "", "",
TRUE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

51
tui/nmt-page-device.h Normal file
View File

@@ -0,0 +1,51 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_DEVICE_H
#define NMT_PAGE_DEVICE_H
#include "nmt-editor-page.h"
#include "nmt-device-entry.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_DEVICE (nmt_page_device_get_type ())
#define NMT_PAGE_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_DEVICE, NmtPageDevice))
#define NMT_PAGE_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_DEVICE, NmtPageDeviceClass))
#define NMT_IS_PAGE_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_DEVICE))
#define NMT_IS_PAGE_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_DEVICE))
#define NMT_PAGE_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_DEVICE, NmtPageDeviceClass))
typedef struct {
NmtEditorPage parent;
} NmtPageDevice;
typedef struct {
NmtEditorPageClass parent;
} NmtPageDeviceClass;
GType nmt_page_device_get_type (void);
NmtDeviceEntry *nmt_page_device_get_device_entry (NmtPageDevice *page);
gboolean nmt_page_device_get_show_by_default (NmtPageDevice *page);
G_END_DECLS
#endif /* NMT_PAGE_DEVICE_H */

97
tui/nmt-page-ethernet.c Normal file
View File

@@ -0,0 +1,97 @@
/* -*- 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-page-ethernet
* @short_description: The editor page for Ethernet connections
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-ethernet.h"
#include "nmt-mac-entry.h"
#include "nmt-mtu-entry.h"
G_DEFINE_TYPE (NmtPageEthernet, nmt_page_ethernet, NMT_TYPE_PAGE_DEVICE)
NmtNewtWidget *
nmt_page_ethernet_new (NMConnection *conn,
NmtDeviceEntry *deventry)
{
return g_object_new (NMT_TYPE_PAGE_ETHERNET,
"connection", conn,
"title", _("ETHERNET"),
"device-entry", deventry,
"show-by-default", FALSE,
NULL);
}
static void
nmt_page_ethernet_init (NmtPageEthernet *ethernet)
{
}
static void
nmt_page_ethernet_constructed (GObject *object)
{
NmtPageEthernet *ethernet = NMT_PAGE_ETHERNET (object);
NmtDeviceEntry *deventry;
NmtPageGrid *grid;
NMSettingWired *s_wired;
NmtNewtWidget *widget;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (ethernet));
s_wired = nm_connection_get_setting_wired (conn);
if (!s_wired) {
nm_connection_add_setting (conn, nm_setting_wired_new ());
s_wired = nm_connection_get_setting_wired (conn);
}
deventry = nmt_page_device_get_device_entry (NMT_PAGE_DEVICE (object));
g_object_bind_property (s_wired, NM_SETTING_WIRED_MAC_ADDRESS,
deventry, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
grid = NMT_PAGE_GRID (ethernet);
widget = nmt_mac_entry_new (40, ETH_ALEN);
g_object_bind_property (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Cloned MAC address"), widget, NULL);
widget = nmt_mtu_entry_new ();
g_object_bind_property (s_wired, NM_SETTING_WIRED_MTU,
widget, "mtu",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("MTU"), widget, NULL);
G_OBJECT_CLASS (nmt_page_ethernet_parent_class)->constructed (object);
}
static void
nmt_page_ethernet_class_init (NmtPageEthernetClass *ethernet_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ethernet_class);
object_class->constructed = nmt_page_ethernet_constructed;
}

50
tui/nmt-page-ethernet.h Normal file
View File

@@ -0,0 +1,50 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_ETHERNET_H
#define NMT_PAGE_ETHERNET_H
#include "nmt-page-device.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_ETHERNET (nmt_page_ethernet_get_type ())
#define NMT_PAGE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_ETHERNET, NmtPageEthernet))
#define NMT_PAGE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_ETHERNET, NmtPageEthernetClass))
#define NMT_IS_PAGE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_ETHERNET))
#define NMT_IS_PAGE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_ETHERNET))
#define NMT_PAGE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_ETHERNET, NmtPageEthernetClass))
typedef struct {
NmtPageDevice parent;
} NmtPageEthernet;
typedef struct {
NmtPageDeviceClass parent;
} NmtPageEthernetClass;
GType nmt_page_ethernet_get_type (void);
NmtNewtWidget *nmt_page_ethernet_new (NMConnection *conn,
NmtDeviceEntry *deventry);
G_END_DECLS
#endif /* NMT_PAGE_ETHERNET_H */

458
tui/nmt-page-grid.c Normal file
View File

@@ -0,0 +1,458 @@
/* -*- 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-page-grid
* @short_description: Grid widget for #NmtEditorPages
*
* #NmtPageGrid is the layout grid used by #NmtEditorPages. It
* consists of a number of rows, each containing either a single
* widget that spans the entire width of the row, or else containing a
* label, a widget, and an optional extra widget.
*
* Each row of the grid can take up multiple on-screen rows, if
* its main widget is multiple rows high. The label and extra widgets
* will be top-aligned if the row is taller than they are.
*
* The #NmtPageGrids in a form behave as though they are all in a
* "size group" together; they will all use the same column widths,
* which will be wide enough for the widest labels/widgets in any of
* the grids. #NmtPageGrid is also specially aware of #NmtNewtSection,
* and grids inside sections will automatically take the size of the
* section border into account as well.
*/
#include "config.h"
#include <string.h>
#include "nmt-page-grid.h"
G_DEFINE_TYPE (NmtPageGrid, nmt_page_grid, NMT_TYPE_NEWT_CONTAINER)
#define NMT_PAGE_GRID_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_GRID, NmtPageGridPrivate))
typedef struct {
GArray *rows;
int *row_heights;
int indent;
} NmtPageGridPrivate;
typedef struct {
NmtNewtWidget *label;
NmtNewtWidget *widget;
NmtNewtWidget *extra;
NmtPageGridRowFlags flags;
} NmtPageGridRow;
typedef struct {
int col_widths[3];
} NmtPageGridFormState;
/**
* nmt_page_grid_new:
*
* Creates a new #NmtPageGrid
*
* Returns: a new #NmtPageGrid
*/
NmtNewtWidget *
nmt_page_grid_new (void)
{
return g_object_new (NMT_TYPE_PAGE_GRID,
NULL);
}
static void
nmt_page_grid_init (NmtPageGrid *grid)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (grid);
priv->rows = g_array_new (FALSE, TRUE, sizeof (NmtPageGridRow));
}
static void
nmt_page_grid_finalize (GObject *object)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (object);
g_array_unref (priv->rows);
g_clear_pointer (&priv->row_heights, g_free);
G_OBJECT_CLASS (nmt_page_grid_parent_class)->finalize (object);
}
/**
* nmt_page_grid_append:
* @grid: the #NmtPageGrid
* @label: (allow-none): the label text for @widget, or %NULL
* @widget: the (main) widget
* @extra: (allow-none): optional extra widget
*
* Adds a row to @grid.
*
* If @label is non-%NULL, this will add a three-column row,
* containing a right-aligned #NmtNewtLabel in the first column,
* @widget in the second column, and @extra (if non-%NULL) in
* the third column.
*
* If @label is %NULL, then this will add a row with a single
* grid-spanning column, containing @widget.
*
* FIXME: That's sort of weird.
*
* See also nmt_page_grid_set_row_flags().
*/
void
nmt_page_grid_append (NmtPageGrid *grid,
const char *label,
NmtNewtWidget *widget,
NmtNewtWidget *extra)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (grid);
NmtNewtContainerClass *parent_class = NMT_NEWT_CONTAINER_CLASS (nmt_page_grid_parent_class);
NmtNewtContainer *container = NMT_NEWT_CONTAINER (grid);
NmtPageGridRow row;
memset (&row, 0, sizeof (row));
if (label) {
row.label = nmt_newt_label_new (label);
parent_class->add (container, row.label);
}
row.widget = widget;
parent_class->add (container, widget);
if (row.label) {
g_object_bind_property (row.widget, "valid",
row.label, "highlight",
G_BINDING_INVERT_BOOLEAN | G_BINDING_SYNC_CREATE);
}
if (extra) {
row.extra = extra;
parent_class->add (container, extra);
}
g_array_append_val (priv->rows, row);
}
static int
nmt_page_grid_find_widget (NmtPageGrid *grid,
NmtNewtWidget *widget)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (grid);
NmtPageGridRow *rows = (NmtPageGridRow *) priv->rows->data;
int i;
for (i = 0; i < priv->rows->len; i++) {
if (rows[i].label == widget || rows[i].widget == widget || rows[i].extra == widget)
return i;
}
return -1;
}
/**
* NmtPageGridRowFlags:
* @NMT_PAGE_GRID_ROW_LABEL_ALIGN_LEFT: the row's label should be
* aligned left instead of right.
* @NMT_PAGE_GRID_ROW_EXTRA_ALIGN_RIGHT: the row's extra widget
* should be aligned right instead of left.
*
* Flags to alter an #NmtPageGrid row's layout.
*/
/**
* nmt_page_grid_set_row_flags:
* @grid: an #NmtPageGrid
* @widget: the widget whose row you want to adjust
* @flags: the flags to set
*
* Sets flags to adjust the layout of @widget's row in @grid.
*/
void
nmt_page_grid_set_row_flags (NmtPageGrid *grid,
NmtNewtWidget *widget,
NmtPageGridRowFlags flags)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (grid);
NmtPageGridRow *rows = (NmtPageGridRow *) priv->rows->data;
int i;
i = nmt_page_grid_find_widget (grid, widget);
if (i != -1)
rows[i].flags = flags;
}
static void
nmt_page_grid_remove (NmtNewtContainer *container,
NmtNewtWidget *widget)
{
NmtPageGrid *grid = NMT_PAGE_GRID (container);
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (grid);
NmtNewtContainerClass *parent_class = NMT_NEWT_CONTAINER_CLASS (nmt_page_grid_parent_class);
NmtPageGridRow *rows = (NmtPageGridRow *) priv->rows->data;
int i;
i = nmt_page_grid_find_widget (grid, widget);
if (i != -1) {
if (rows[i].label)
parent_class->remove (container, rows[i].label);
parent_class->remove (container, rows[i].widget);
if (rows[i].extra)
parent_class->remove (container, rows[i].extra);
g_array_remove_index (priv->rows, i);
return;
}
// FIXME: shouldn't happen
parent_class->remove (container, widget);
}
static newtComponent *
nmt_page_grid_get_components (NmtNewtWidget *widget)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (widget);
NmtPageGridRow *rows = (NmtPageGridRow *) priv->rows->data;
newtComponent *child_cos;
GPtrArray *cos;
int i, c;
cos = g_ptr_array_new ();
for (i = 0; i < priv->rows->len; i++) {
if (!nmt_newt_widget_get_visible (rows[i].widget))
continue;
if (rows[i].label) {
child_cos = nmt_newt_widget_get_components (rows[i].label);
g_assert (child_cos[0] && !child_cos[1]);
g_ptr_array_add (cos, child_cos[0]);
g_free (child_cos);
}
child_cos = nmt_newt_widget_get_components (rows[i].widget);
for (c = 0; child_cos[c]; c++)
g_ptr_array_add (cos, child_cos[c]);
g_free (child_cos);
if (rows[i].extra) {
child_cos = nmt_newt_widget_get_components (rows[i].extra);
for (c = 0; child_cos[c]; c++)
g_ptr_array_add (cos, child_cos[c]);
g_free (child_cos);
}
}
g_ptr_array_add (cos, NULL);
return (newtComponent *) g_ptr_array_free (cos, FALSE);
}
static NmtPageGridFormState *
get_form_state (NmtNewtWidget *widget)
{
NmtNewtForm *form = nmt_newt_widget_get_form (widget);
NmtPageGridFormState *state;
if (!form)
return NULL;
state = g_object_get_data (G_OBJECT (form), "NmtPageGridFormState");
if (state)
return state;
state = g_new0 (NmtPageGridFormState, 1);
g_object_set_data_full (G_OBJECT (form), "NmtPageGridFormState", state, g_free);
return state;
}
static void
nmt_page_grid_realize (NmtNewtWidget *widget)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (widget);
NmtNewtWidget *parent;
NMT_NEWT_WIDGET_CLASS (nmt_page_grid_parent_class)->realize (widget);
/* This is a hack, but it's the simplest way to make it work... */
priv->indent = 0;
parent = nmt_newt_widget_get_parent (widget);
while (parent) {
if (NMT_IS_NEWT_SECTION (parent)) {
priv->indent = 2;
break;
}
parent = nmt_newt_widget_get_parent (parent);
}
}
static void
nmt_page_grid_unrealize (NmtNewtWidget *widget)
{
NmtPageGridFormState *state = get_form_state (widget);
if (state)
memset (state->col_widths, 0, sizeof (state->col_widths));
NMT_NEWT_WIDGET_CLASS (nmt_page_grid_parent_class)->unrealize (widget);
}
static void
nmt_page_grid_size_request (NmtNewtWidget *widget,
int *width,
int *height)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (widget);
NmtPageGridRow *rows = (NmtPageGridRow *) priv->rows->data;
NmtPageGridFormState *state = get_form_state (widget);
gboolean add_padding = FALSE;
int i;
g_free (priv->row_heights);
priv->row_heights = g_new0 (int, priv->rows->len);
*height = 0;
for (i = 0; i < priv->rows->len; i++) {
int lwidth, lheight, wwidth, wheight, ewidth, eheight;
if (!nmt_newt_widget_get_visible (rows[i].widget))
continue;
if (rows[i].label) {
nmt_newt_widget_size_request (rows[i].label, &lwidth, &lheight);
lwidth += priv->indent;
state->col_widths[0] = MAX (state->col_widths[0], lwidth);
nmt_newt_widget_size_request (rows[i].widget, &wwidth, &wheight);
state->col_widths[1] = MAX (state->col_widths[1], wwidth);
priv->row_heights[i] = wheight;
add_padding = TRUE;
} else {
nmt_newt_widget_size_request (rows[i].widget, &wwidth, &wheight);
priv->row_heights[i] = wheight;
}
if (rows[i].extra) {
nmt_newt_widget_size_request (rows[i].extra, &ewidth, &eheight);
state->col_widths[2] = MAX (state->col_widths[2], ewidth);
priv->row_heights[i] = MAX (priv->row_heights[i], eheight);
}
*height += priv->row_heights[i];
}
*width = state->col_widths[0] + state->col_widths[1] + state->col_widths[2];
if (add_padding)
*width += 2;
}
static void
nmt_page_grid_size_allocate (NmtNewtWidget *widget,
int x,
int y,
int width,
int height)
{
NmtPageGridPrivate *priv = NMT_PAGE_GRID_GET_PRIVATE (widget);
NmtPageGridRow *rows = (NmtPageGridRow *) priv->rows->data;
NmtPageGridFormState *state = get_form_state (widget);
int col0_width, col1_width, col2_width;
int i, row;
col0_width = state->col_widths[0] - priv->indent;
col1_width = state->col_widths[1];
col2_width = state->col_widths[2];
for (i = row = 0; i < priv->rows->len; i++) {
if (!nmt_newt_widget_get_visible (rows[i].widget))
continue;
if (rows[i].label) {
int lwidth, lheight, lx;
if (rows[i].flags & NMT_PAGE_GRID_ROW_LABEL_ALIGN_LEFT)
lx = x;
else {
nmt_newt_widget_size_request (rows[i].label, &lwidth, &lheight);
lx = x + col0_width - lwidth;
}
nmt_newt_widget_size_allocate (rows[i].label,
lx,
y + row,
col0_width,
priv->row_heights[i]);
nmt_newt_widget_size_allocate (rows[i].widget,
x + col0_width + 1,
y + row,
col1_width,
priv->row_heights[i]);
if (rows[i].extra) {
int wwidth, wheight, ex;
if (rows[i].flags & NMT_PAGE_GRID_ROW_EXTRA_ALIGN_RIGHT)
ex = x + col0_width + col1_width + 2;
else {
nmt_newt_widget_size_request (rows[i].widget, &wwidth, &wheight);
ex = x + col0_width + wwidth + 2;
}
nmt_newt_widget_size_allocate (rows[i].extra,
ex,
y + row,
col2_width,
priv->row_heights[i]);
}
} else {
nmt_newt_widget_size_allocate (rows[i].widget,
x,
y + row,
col0_width + col1_width + col2_width + 2,
priv->row_heights[i]);
}
row += priv->row_heights[i];
}
}
static void
nmt_page_grid_class_init (NmtPageGridClass *grid_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (grid_class);
NmtNewtWidgetClass *widget_class = NMT_NEWT_WIDGET_CLASS (grid_class);
NmtNewtContainerClass *container_class = NMT_NEWT_CONTAINER_CLASS (grid_class);
g_type_class_add_private (grid_class, sizeof (NmtPageGridPrivate));
/* virtual methods */
object_class->finalize = nmt_page_grid_finalize;
widget_class->realize = nmt_page_grid_realize;
widget_class->unrealize = nmt_page_grid_unrealize;
widget_class->get_components = nmt_page_grid_get_components;
widget_class->size_request = nmt_page_grid_size_request;
widget_class->size_allocate = nmt_page_grid_size_allocate;
container_class->remove = nmt_page_grid_remove;
}

62
tui/nmt-page-grid.h Normal file
View File

@@ -0,0 +1,62 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_GRID_H
#define NMT_PAGE_GRID_H
#include "nmt-newt.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_GRID (nmt_page_grid_get_type ())
#define NMT_PAGE_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_GRID, NmtPageGrid))
#define NMT_PAGE_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_GRID, NmtPageGridClass))
#define NMT_IS_PAGE_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_GRID))
#define NMT_IS_PAGE_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_GRID))
#define NMT_PAGE_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_GRID, NmtPageGridClass))
typedef struct {
NmtNewtContainer parent;
} NmtPageGrid;
typedef struct {
NmtNewtContainerClass parent;
} NmtPageGridClass;
GType nmt_page_grid_get_type (void);
typedef enum {
NMT_PAGE_GRID_ROW_LABEL_ALIGN_LEFT = (1 << 0),
NMT_PAGE_GRID_ROW_EXTRA_ALIGN_RIGHT = (1 << 1)
} NmtPageGridRowFlags;
NmtNewtWidget *nmt_page_grid_new (void);
void nmt_page_grid_append (NmtPageGrid *grid,
const char *label,
NmtNewtWidget *widget,
NmtNewtWidget *extra);
void nmt_page_grid_set_row_flags (NmtPageGrid *grid,
NmtNewtWidget *widget,
NmtPageGridRowFlags flags);
G_END_DECLS
#endif /* NMT_PAGE_GRID_H */

101
tui/nmt-page-infiniband.c Normal file
View File

@@ -0,0 +1,101 @@
/* -*- 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-page-infiniband
* @short_description: The editor page for InfiniBand connections
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-infiniband.h"
#include "nmt-mtu-entry.h"
G_DEFINE_TYPE (NmtPageInfiniband, nmt_page_infiniband, NMT_TYPE_PAGE_DEVICE)
NmtNewtWidget *
nmt_page_infiniband_new (NMConnection *conn,
NmtDeviceEntry *deventry)
{
return g_object_new (NMT_TYPE_PAGE_INFINIBAND,
"connection", conn,
"title", _("INFINIBAND"),
"device-entry", deventry,
NULL);
}
static void
nmt_page_infiniband_init (NmtPageInfiniband *infiniband)
{
}
static NmtNewtPopupEntry transport_mode[] = {
{ N_("Datagram"), "datagram" },
{ N_("Connected"), "connected" },
{ NULL, NULL }
};
static void
nmt_page_infiniband_constructed (GObject *object)
{
NmtPageInfiniband *infiniband = NMT_PAGE_INFINIBAND (object);
NmtDeviceEntry *deventry;
NmtPageGrid *grid;
NMSettingInfiniband *s_ib;
NmtNewtWidget *widget;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (infiniband));
s_ib = nm_connection_get_setting_infiniband (conn);
if (!s_ib) {
nm_connection_add_setting (conn, nm_setting_infiniband_new ());
s_ib = nm_connection_get_setting_infiniband (conn);
}
deventry = nmt_page_device_get_device_entry (NMT_PAGE_DEVICE (object));
g_object_bind_property (s_ib, NM_SETTING_INFINIBAND_MAC_ADDRESS,
deventry, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
grid = NMT_PAGE_GRID (infiniband);
widget = nmt_newt_popup_new (transport_mode);
g_object_bind_property (s_ib, NM_SETTING_INFINIBAND_TRANSPORT_MODE,
widget, "active-id",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Transport mode"), widget, NULL);
widget = nmt_mtu_entry_new ();
g_object_bind_property (s_ib, NM_SETTING_INFINIBAND_MTU,
widget, "mtu",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("MTU"), widget, NULL);
G_OBJECT_CLASS (nmt_page_infiniband_parent_class)->constructed (object);
}
static void
nmt_page_infiniband_class_init (NmtPageInfinibandClass *infiniband_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (infiniband_class);
object_class->constructed = nmt_page_infiniband_constructed;
}

50
tui/nmt-page-infiniband.h Normal file
View File

@@ -0,0 +1,50 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_INFINIBAND_H
#define NMT_PAGE_INFINIBAND_H
#include "nmt-page-device.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_INFINIBAND (nmt_page_infiniband_get_type ())
#define NMT_PAGE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_INFINIBAND, NmtPageInfiniband))
#define NMT_PAGE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_INFINIBAND, NmtPageInfinibandClass))
#define NMT_IS_PAGE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_INFINIBAND))
#define NMT_IS_PAGE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_INFINIBAND))
#define NMT_PAGE_INFINIBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_INFINIBAND, NmtPageInfinibandClass))
typedef struct {
NmtPageDevice parent;
} NmtPageInfiniband;
typedef struct {
NmtPageDeviceClass parent;
} NmtPageInfinibandClass;
GType nmt_page_infiniband_get_type (void);
NmtNewtWidget *nmt_page_infiniband_new (NMConnection *conn,
NmtDeviceEntry *deventry);
G_END_DECLS
#endif /* NMT_PAGE_INFINIBAND_H */

199
tui/nmt-page-ip4.c Normal file
View File

@@ -0,0 +1,199 @@
/* -*- 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-page-ip4
* @short_description: The editor page for IP4 configuration
*/
#include "config.h"
#include <stdlib.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-ip4.h"
#include "nmt-ip-entry.h"
#include "nmt-address-list.h"
#include "nmt-route-editor.h"
#include "nm-editor-bindings.h"
G_DEFINE_TYPE (NmtPageIP4, nmt_page_ip4, NMT_TYPE_EDITOR_PAGE)
static NmtNewtPopupEntry ip4methods[] = {
{ N_("Disabled"), NM_SETTING_IP4_CONFIG_METHOD_DISABLED },
{ N_("Automatic"), NM_SETTING_IP4_CONFIG_METHOD_AUTO },
{ N_("Link-Local"), NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL },
{ N_("Manual"), NM_SETTING_IP4_CONFIG_METHOD_MANUAL },
{ N_("Shared"), NM_SETTING_IP4_CONFIG_METHOD_SHARED },
{ NULL, NULL }
};
NmtNewtWidget *
nmt_page_ip4_new (NMConnection *conn)
{
return g_object_new (NMT_TYPE_PAGE_IP4,
"connection", conn,
"title", _("IPv4 CONFIGURATION"),
NULL);
}
gboolean
nmt_page_ip4_is_non_empty (NmtPageIP4 *ip4)
{
NMConnection *conn;
NMSettingIP4Config *s_ip4;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (ip4));
s_ip4 = nm_connection_get_setting_ip4_config (conn);
if ( !g_strcmp0 (nm_setting_ip4_config_get_method (s_ip4), NM_SETTING_IP4_CONFIG_METHOD_MANUAL)
|| nm_setting_ip4_config_get_num_addresses (s_ip4))
return TRUE;
return FALSE;
}
static void
nmt_page_ip4_init (NmtPageIP4 *ip4)
{
}
static void
edit_routes (NmtNewtButton *button,
gpointer user_data)
{
NMSetting *s_ip4 = user_data;
NmtNewtForm *form;
form = nmt_route_editor_new (s_ip4);
nmt_newt_form_run_sync (form);
g_object_unref (form);
}
static gboolean
ip4_routes_transform_to_description (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
GPtrArray *routes;
char *text;
routes = g_value_get_boxed (source_value);
if (!routes || !routes->len)
text = g_strdup (_("(No custom routes)"));
else {
text = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
"One custom route",
"%d custom routes",
routes->len),
routes->len);
}
g_value_take_string (target_value, text);
return TRUE;
}
static void
nmt_page_ip4_constructed (GObject *object)
{
NmtPageIP4 *ip4 = NMT_PAGE_IP4 (object);
NmtPageGrid *grid;
NMSettingIP4Config *s_ip4;
NmtNewtWidget *widget, *button;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (ip4));
s_ip4 = nm_connection_get_setting_ip4_config (conn);
if (!s_ip4) {
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
nm_connection_add_setting (conn, (NMSetting *) s_ip4);
}
widget = nmt_newt_popup_new (ip4methods);
g_object_bind_property (s_ip4, NM_SETTING_IP4_CONFIG_METHOD,
widget, "active-id",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_editor_page_set_header_widget (NMT_EDITOR_PAGE (ip4), widget);
grid = NMT_PAGE_GRID (ip4);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_IP4_WITH_PREFIX);
nm_editor_bind_ip4_addresses_with_prefix_to_strv (s_ip4, NM_SETTING_IP4_CONFIG_ADDRESSES,
widget, "strings",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Addresses"), widget, NULL);
widget = nmt_ip_entry_new (25, AF_INET, FALSE, TRUE);
nm_editor_bind_ip4_gateway_to_string (s_ip4, NM_SETTING_IP4_CONFIG_ADDRESSES,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Gateway"), widget, NULL);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_IP4);
nm_editor_bind_ip4_addresses_to_strv (s_ip4, NM_SETTING_IP4_CONFIG_DNS,
widget, "strings",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("DNS servers"), widget, NULL);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_HOSTNAME);
g_object_bind_property (s_ip4, NM_SETTING_IP4_CONFIG_DNS_SEARCH,
widget, "strings",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Search domains"), widget, NULL);
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
widget = g_object_new (NMT_TYPE_NEWT_LABEL,
"text", "",
"style", NMT_NEWT_LABEL_PLAIN,
NULL);
g_object_bind_property_full (s_ip4, NM_SETTING_IP4_CONFIG_ROUTES,
widget, "text",
G_BINDING_SYNC_CREATE,
ip4_routes_transform_to_description,
NULL, NULL, NULL);
button = nmt_newt_button_new (_("Edit..."));
g_signal_connect (button, "clicked", G_CALLBACK (edit_routes), s_ip4);
nmt_page_grid_append (grid, _("Routing"), widget, button);
widget = nmt_newt_checkbox_new (_("Never use this network for default route"));
g_object_bind_property (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT,
widget, "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
nmt_page_grid_append (grid, NULL, widget, NULL);
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
widget = nmt_newt_checkbox_new (_("Require IPv4 addressing for this connection"));
g_object_bind_property (s_ip4, NM_SETTING_IP4_CONFIG_MAY_FAIL,
widget, "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
nmt_page_grid_append (grid, NULL, widget, NULL);
G_OBJECT_CLASS (nmt_page_ip4_parent_class)->constructed (object);
}
static void
nmt_page_ip4_class_init (NmtPageIP4Class *ip4_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ip4_class);
object_class->constructed = nmt_page_ip4_constructed;
}

51
tui/nmt-page-ip4.h Normal file
View File

@@ -0,0 +1,51 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_IP4_H
#define NMT_PAGE_IP4_H
#include "nmt-editor-page.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_IP4 (nmt_page_ip4_get_type ())
#define NMT_PAGE_IP4(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_IP4, NmtPageIP4))
#define NMT_PAGE_IP4_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_IP4, NmtPageIP4Class))
#define NMT_IS_PAGE_IP4(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_IP4))
#define NMT_IS_PAGE_IP4_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_IP4))
#define NMT_PAGE_IP4_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_IP4, NmtPageIP4Class))
typedef struct {
NmtEditorPage parent;
} NmtPageIP4;
typedef struct {
NmtEditorPageClass parent;
} NmtPageIP4Class;
GType nmt_page_ip4_get_type (void);
NmtNewtWidget *nmt_page_ip4_new (NMConnection *conn);
gboolean nmt_page_ip4_is_non_empty (NmtPageIP4 *ip4);
G_END_DECLS
#endif /* NMT_PAGE_IP4_H */

197
tui/nmt-page-ip6.c Normal file
View File

@@ -0,0 +1,197 @@
/* -*- 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-page-ip6
* @short_description: The editor page for IP6 configuration
*/
#include "config.h"
#include <stdlib.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-ip6.h"
#include "nmt-ip-entry.h"
#include "nmt-address-list.h"
#include "nmt-route-editor.h"
#include "nm-editor-bindings.h"
G_DEFINE_TYPE (NmtPageIP6, nmt_page_ip6, NMT_TYPE_EDITOR_PAGE)
static NmtNewtPopupEntry ip6methods[] = {
{ N_("Ignore"), NM_SETTING_IP6_CONFIG_METHOD_IGNORE },
{ N_("Automatic"), NM_SETTING_IP6_CONFIG_METHOD_AUTO },
{ N_("Automatic (DHCP-only)"), NM_SETTING_IP6_CONFIG_METHOD_DHCP },
{ N_("Link-Local"), NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL },
{ N_("Manual"), NM_SETTING_IP6_CONFIG_METHOD_MANUAL },
{ NULL, NULL }
};
NmtNewtWidget *
nmt_page_ip6_new (NMConnection *conn)
{
return g_object_new (NMT_TYPE_PAGE_IP6,
"connection", conn,
"title", _("IPv6 CONFIGURATION"),
NULL);
}
gboolean
nmt_page_ip6_is_non_empty (NmtPageIP6 *ip6)
{
NMConnection *conn;
NMSettingIP6Config *s_ip6;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (ip6));
s_ip6 = nm_connection_get_setting_ip6_config (conn);
if ( !g_strcmp0 (nm_setting_ip6_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_MANUAL)
|| nm_setting_ip6_config_get_num_addresses (s_ip6))
return TRUE;
return FALSE;
}
static void
nmt_page_ip6_init (NmtPageIP6 *ip6)
{
}
static void
edit_routes (NmtNewtButton *button,
gpointer user_data)
{
NMSetting *s_ip6 = user_data;
NmtNewtForm *form;
form = nmt_route_editor_new (s_ip6);
nmt_newt_form_run_sync (form);
g_object_unref (form);
}
static gboolean
ip6_routes_transform_to_description (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
GPtrArray *routes;
char *text;
routes = g_value_get_boxed (source_value);
if (!routes || !routes->len)
text = g_strdup (_("(No custom routes)"));
else {
text = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
"One custom route",
"%d custom routes",
routes->len),
routes->len);
}
g_value_take_string (target_value, text);
return TRUE;
}
static void
nmt_page_ip6_constructed (GObject *object)
{
NmtPageIP6 *ip6 = NMT_PAGE_IP6 (object);
NmtPageGrid *grid;
NMSettingIP6Config *s_ip6;
NmtNewtWidget *widget, *button;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (ip6));
s_ip6 = nm_connection_get_setting_ip6_config (conn);
if (!s_ip6) {
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
nm_connection_add_setting (conn, (NMSetting *) s_ip6);
}
widget = nmt_newt_popup_new (ip6methods);
g_object_bind_property (s_ip6, NM_SETTING_IP6_CONFIG_METHOD,
widget, "active-id",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_editor_page_set_header_widget (NMT_EDITOR_PAGE (ip6), widget);
grid = NMT_PAGE_GRID (ip6);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_IP6_WITH_PREFIX);
nm_editor_bind_ip6_addresses_with_prefix_to_strv (s_ip6, NM_SETTING_IP6_CONFIG_ADDRESSES,
widget, "strings",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Addresses"), widget, NULL);
widget = nmt_ip_entry_new (25, AF_INET6, FALSE, TRUE);
nm_editor_bind_ip6_gateway_to_string (s_ip6, NM_SETTING_IP6_CONFIG_ADDRESSES,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Gateway"), widget, NULL);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_IP6);
nm_editor_bind_ip6_addresses_to_strv (s_ip6, NM_SETTING_IP6_CONFIG_DNS,
widget, "strings",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("DNS servers"), widget, NULL);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_HOSTNAME);
g_object_bind_property (s_ip6, NM_SETTING_IP6_CONFIG_DNS_SEARCH,
widget, "strings",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Search domains"), widget, NULL);
widget = g_object_new (NMT_TYPE_NEWT_LABEL,
"text", "",
"style", NMT_NEWT_LABEL_PLAIN,
NULL);
g_object_bind_property_full (s_ip6, NM_SETTING_IP6_CONFIG_ROUTES,
widget, "text",
G_BINDING_SYNC_CREATE,
ip6_routes_transform_to_description,
NULL, NULL, NULL);
button = nmt_newt_button_new (_("Edit..."));
g_signal_connect (button, "clicked", G_CALLBACK (edit_routes), s_ip6);
nmt_page_grid_append (grid, _("Routing"), widget, button);
widget = nmt_newt_checkbox_new (_("Never use this network for default route"));
g_object_bind_property (s_ip6, NM_SETTING_IP6_CONFIG_NEVER_DEFAULT,
widget, "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
nmt_page_grid_append (grid, NULL, widget, NULL);
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
widget = nmt_newt_checkbox_new (_("Require IPv6 addressing for this connection"));
g_object_bind_property (s_ip6, NM_SETTING_IP6_CONFIG_MAY_FAIL,
widget, "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
nmt_page_grid_append (grid, NULL, widget, NULL);
G_OBJECT_CLASS (nmt_page_ip6_parent_class)->constructed (object);
}
static void
nmt_page_ip6_class_init (NmtPageIP6Class *ip6_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ip6_class);
object_class->constructed = nmt_page_ip6_constructed;
}

51
tui/nmt-page-ip6.h Normal file
View File

@@ -0,0 +1,51 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_IP6_H
#define NMT_PAGE_IP6_H
#include "nmt-editor-page.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_IP6 (nmt_page_ip6_get_type ())
#define NMT_PAGE_IP6(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_IP6, NmtPageIP6))
#define NMT_PAGE_IP6_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_IP6, NmtPageIP6Class))
#define NMT_IS_PAGE_IP6(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_IP6))
#define NMT_IS_PAGE_IP6_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_IP6))
#define NMT_PAGE_IP6_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_IP6, NmtPageIP6Class))
typedef struct {
NmtEditorPage parent;
} NmtPageIP6;
typedef struct {
NmtEditorPageClass parent;
} NmtPageIP6Class;
GType nmt_page_ip6_get_type (void);
NmtNewtWidget *nmt_page_ip6_new (NMConnection *conn);
gboolean nmt_page_ip6_is_non_empty (NmtPageIP6 *ip6);
G_END_DECLS
#endif /* NMT_PAGE_IP6_H */

327
tui/nmt-page-main.c Normal file
View File

@@ -0,0 +1,327 @@
/* -*- 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-page-main
* @short_description: The top-level #NmtEditorPage for a connection
*
* #NmtPageMain is the top-level #NmtEditorPage for a connection. It
* handles #NMSettingConnection properties, and embeds the other pages
* within itself.
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <nm-device.h>
#include <nm-utils.h>
#include "nmt-page-main.h"
#include "nmt-device-entry.h"
#include "nmt-mac-entry.h"
#include "nmt-mtu-entry.h"
#include "nmtui.h"
#include "nmt-page-bond.h"
#include "nmt-page-bridge.h"
#include "nmt-page-bridge-port.h"
#include "nmt-page-ethernet.h"
#include "nmt-page-infiniband.h"
#include "nmt-page-ip4.h"
#include "nmt-page-ip6.h"
#include "nmt-page-team.h"
#include "nmt-page-team-port.h"
#include "nmt-page-vlan.h"
#include "nmt-page-wifi.h"
G_DEFINE_TYPE (NmtPageMain, nmt_page_main, NMT_TYPE_EDITOR_PAGE)
#define NMT_PAGE_MAIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_MAIN, NmtPageMainPrivate))
typedef struct {
NMEditorConnectionTypeData *type_data;
} NmtPageMainPrivate;
enum {
PROP_0,
PROP_TYPE_DATA,
LAST_PROP
};
/**
* nmt_page_main_new:
* @conn: the #NMConnection to display
* @type_data: @conn's #NMEditorConnectionTypeData
*
* Creates a new #NmtPageMain
*
* Returns: a new #NmtPageMain
*/
NmtNewtWidget *
nmt_page_main_new (NMConnection *conn,
NMEditorConnectionTypeData *type_data)
{
return g_object_new (NMT_TYPE_PAGE_MAIN,
"connection", conn,
"type-data", type_data,
NULL);
}
static void
nmt_page_main_init (NmtPageMain *page)
{
}
static gboolean
permissions_transform_to_allusers (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
GSList *perms = g_value_get_boxed (source_value);
g_value_set_boolean (target_value, perms == NULL);
return TRUE;
}
static gboolean
permissions_transform_from_allusers (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
gboolean allusers = g_value_get_boolean (source_value);
GSList *perms = NULL;
if (allusers) {
char *perm = g_strdup_printf ("user:%s:", g_get_user_name ());
perms = g_slist_prepend (perms, perm);
}
g_value_take_boxed (target_value, perms);
return TRUE;
}
static NmtNewtWidget *
build_section_for_page (NmtEditorPage *page,
gboolean open)
{
NmtNewtWidget *section, *header, *toggle;
g_return_val_if_fail (nmt_newt_widget_get_parent (NMT_NEWT_WIDGET (page)) == NULL, NULL);
section = nmt_newt_section_new ();
toggle = nmt_newt_toggle_button_new (_("Hide"), _("Show"));
header = nmt_page_grid_new ();
nmt_page_grid_append (NMT_PAGE_GRID (header),
nmt_editor_page_get_title (page),
nmt_editor_page_get_header_widget (page),
toggle);
nmt_page_grid_set_row_flags (NMT_PAGE_GRID (header),
nmt_editor_page_get_header_widget (page),
NMT_PAGE_GRID_ROW_LABEL_ALIGN_LEFT |
NMT_PAGE_GRID_ROW_EXTRA_ALIGN_RIGHT);
nmt_newt_section_set_header (NMT_NEWT_SECTION (section), header);
nmt_newt_section_set_body (NMT_NEWT_SECTION (section), NMT_NEWT_WIDGET (page));
g_object_bind_property (toggle, "active",
section, "open",
G_BINDING_SYNC_CREATE);
if (open || !nmt_newt_widget_get_valid (section))
nmt_newt_toggle_button_set_active (NMT_NEWT_TOGGLE_BUTTON (toggle), TRUE);
return section;
}
static void
nmt_page_main_constructed (GObject *object)
{
NmtPageMain *page_main = NMT_PAGE_MAIN (object);
NmtPageMainPrivate *priv = NMT_PAGE_MAIN_GET_PRIVATE (page_main);
NmtPageGrid *grid;
NMConnection *conn;
NMSettingConnection *s_con;
NmtNewtWidget *widget, *section, *page, *separator;
NmtDeviceEntry *deventry;
GType hardware_type;
const char *slave_type;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (page_main));
s_con = nm_connection_get_setting_connection (conn);
grid = NMT_PAGE_GRID (page_main);
widget = nmt_newt_entry_new (40, NMT_NEWT_ENTRY_NONEMPTY);
g_object_bind_property (s_con, NM_SETTING_CONNECTION_ID,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Profile name"), widget, NULL);
if (priv->type_data->virtual)
hardware_type = G_TYPE_NONE;
else
hardware_type = priv->type_data->device_type;
widget = nmt_device_entry_new (_("Device"), 40, hardware_type);
nmt_page_grid_append (grid, NULL, widget, NULL);
deventry = NMT_DEVICE_ENTRY (widget);
g_object_bind_property (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME,
deventry, "interface-name",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
if (nm_connection_is_type (conn, NM_SETTING_BOND_SETTING_NAME))
page = nmt_page_bond_new (conn, deventry);
else if (nm_connection_is_type (conn, NM_SETTING_BRIDGE_SETTING_NAME))
page = nmt_page_bridge_new (conn, deventry);
else if (nm_connection_is_type (conn, NM_SETTING_INFINIBAND_SETTING_NAME))
page = nmt_page_infiniband_new (conn, deventry);
else if (nm_connection_is_type (conn, NM_SETTING_TEAM_SETTING_NAME))
page = nmt_page_team_new (conn, deventry);
else if (nm_connection_is_type (conn, NM_SETTING_VLAN_SETTING_NAME))
page = nmt_page_vlan_new (conn, deventry);
else if (nm_connection_is_type (conn, NM_SETTING_WIRED_SETTING_NAME))
page = nmt_page_ethernet_new (conn, deventry);
else if (nm_connection_is_type (conn, NM_SETTING_WIRELESS_SETTING_NAME))
page = nmt_page_wifi_new (conn, deventry);
else
page = NULL;
if (page) {
gboolean show_by_default = nmt_page_device_get_show_by_default (NMT_PAGE_DEVICE (page));
section = build_section_for_page (NMT_EDITOR_PAGE (page), show_by_default);
nmt_page_grid_append (grid, NULL, section, NULL);
}
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
slave_type = nm_setting_connection_get_slave_type (s_con);
if (slave_type) {
if (!strcmp (slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) {
page = nmt_page_bridge_port_new (conn);
section = build_section_for_page (NMT_EDITOR_PAGE (page), TRUE);
nmt_page_grid_append (grid, NULL, section, NULL);
} else if (!strcmp (slave_type, NM_SETTING_TEAM_SETTING_NAME)) {
page = nmt_page_team_port_new (conn);
section = build_section_for_page (NMT_EDITOR_PAGE (page), TRUE);
nmt_page_grid_append (grid, NULL, section, NULL);
}
} else {
page = nmt_page_ip4_new (conn);
section = build_section_for_page (NMT_EDITOR_PAGE (page),
nmt_page_ip4_is_non_empty (NMT_PAGE_IP4 (page)));
nmt_page_grid_append (grid, NULL, section, NULL);
/* Add a separator between ip4 and ip6 that's only visible if ip4 is open */
separator = nmt_newt_separator_new ();
g_object_bind_property (section, "open", separator, "visible", G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, NULL, separator, NULL);
page = nmt_page_ip6_new (conn);
section = build_section_for_page (NMT_EDITOR_PAGE (page),
nmt_page_ip6_is_non_empty (NMT_PAGE_IP6 (page)));
nmt_page_grid_append (grid, NULL, section, NULL);
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
}
widget = nmt_newt_checkbox_new (_("Automatically connect"));
g_object_bind_property (s_con, NM_SETTING_CONNECTION_AUTOCONNECT,
widget, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, NULL, widget, NULL);
widget = nmt_newt_checkbox_new (_("Available to all users"));
g_object_bind_property_full (s_con, NM_SETTING_CONNECTION_PERMISSIONS,
widget, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
permissions_transform_to_allusers,
permissions_transform_from_allusers,
NULL, NULL);
nmt_page_grid_append (grid, NULL, widget, NULL);
G_OBJECT_CLASS (nmt_page_main_parent_class)->constructed (object);
}
static void
nmt_page_main_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtPageMainPrivate *priv = NMT_PAGE_MAIN_GET_PRIVATE (object);
switch (prop_id) {
case PROP_TYPE_DATA:
priv->type_data = g_value_get_pointer (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_page_main_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtPageMainPrivate *priv = NMT_PAGE_MAIN_GET_PRIVATE (object);
switch (prop_id) {
case PROP_TYPE_DATA:
g_value_set_pointer (value, priv->type_data);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_page_main_class_init (NmtPageMainClass *main_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (main_class);
g_type_class_add_private (main_class, sizeof (NmtPageMainPrivate));
object_class->constructed = nmt_page_main_constructed;
object_class->set_property = nmt_page_main_set_property;
object_class->get_property = nmt_page_main_get_property;
/**
* NmtPageMain:type-data:
*
* The page's connection's #NMEditorConnectionTypeData
*/
g_object_class_install_property (object_class, PROP_TYPE_DATA,
g_param_spec_pointer ("type-data", "", "",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}

51
tui/nmt-page-main.h Normal file
View File

@@ -0,0 +1,51 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_MAIN_H
#define NMT_PAGE_MAIN_H
#include "nmt-editor-page.h"
#include "nm-editor-utils.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_MAIN (nmt_page_main_get_type ())
#define NMT_PAGE_MAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_MAIN, NmtPageMain))
#define NMT_PAGE_MAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_MAIN, NmtPageMainClass))
#define NMT_IS_PAGE_MAIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_MAIN))
#define NMT_IS_PAGE_MAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_MAIN))
#define NMT_PAGE_MAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_MAIN, NmtPageMainClass))
typedef struct {
NmtEditorPage parent;
} NmtPageMain;
typedef struct {
NmtEditorPageClass parent;
} NmtPageMainClass;
GType nmt_page_main_get_type (void);
NmtNewtWidget *nmt_page_main_new (NMConnection *conn,
NMEditorConnectionTypeData *type_data);
G_END_DECLS
#endif /* NMT_PAGE_MAIN_H */

125
tui/nmt-page-team-port.c Normal file
View File

@@ -0,0 +1,125 @@
/* -*- 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-page-team-port
* @short_description: The editor page for Team ports.
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-team-port.h"
G_DEFINE_TYPE (NmtPageTeamPort, nmt_page_team_port, NMT_TYPE_EDITOR_PAGE)
#define NMT_PAGE_TEAM_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_TEAM_PORT, NmtPageTeamPortPrivate))
typedef struct {
NMSettingTeamPort *s_port;
} NmtPageTeamPortPrivate;
NmtNewtWidget *
nmt_page_team_port_new (NMConnection *conn)
{
return g_object_new (NMT_TYPE_PAGE_TEAM_PORT,
"connection", conn,
"title", _("TEAM PORT"),
NULL);
}
static void
nmt_page_team_port_init (NmtPageTeamPort *team)
{
}
static void
edit_clicked (NmtNewtButton *button,
gpointer user_data)
{
NmtPageTeamPort *team = user_data;
NmtPageTeamPortPrivate *priv = NMT_PAGE_TEAM_PORT_GET_PRIVATE (team);
const char *config;
char *new_config;
config = nm_setting_team_port_get_config (priv->s_port);
if (!config)
config = "";
new_config = nmt_newt_edit_string (config);
if (new_config && !*new_config)
g_clear_pointer (&new_config, g_free);
g_object_set (G_OBJECT (priv->s_port),
NM_SETTING_TEAM_PORT_CONFIG, new_config,
NULL);
g_free (new_config);
}
static void
nmt_page_team_port_constructed (GObject *object)
{
NmtPageTeamPort *team = NMT_PAGE_TEAM_PORT (object);
NmtPageTeamPortPrivate *priv = NMT_PAGE_TEAM_PORT_GET_PRIVATE (team);
NmtNewtGrid *grid;
NMSettingTeamPort *s_port;
NmtNewtWidget *widget;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (team));
s_port = nm_connection_get_setting_team_port (conn);
if (!s_port) {
nm_connection_add_setting (conn, nm_setting_team_port_new ());
s_port = nm_connection_get_setting_team_port (conn);
}
priv->s_port = s_port;
widget = nmt_newt_grid_new ();
nmt_page_grid_append (NMT_PAGE_GRID (team), NULL, widget, NULL);
grid = NMT_NEWT_GRID (widget);
widget = nmt_newt_label_new (_("JSON configuration"));
nmt_newt_grid_add (grid, widget, 0, 2);
widget = nmt_newt_textbox_new (NMT_NEWT_TEXTBOX_SCROLLABLE | NMT_NEWT_TEXTBOX_SET_BACKGROUND, 60);
g_object_bind_property (s_port, NM_SETTING_TEAM_PORT_CONFIG,
widget, "text",
G_BINDING_SYNC_CREATE);
nmt_newt_grid_add (grid, widget, 0, 3);
nmt_newt_widget_set_padding (widget, 2, 0, 2, 1);
widget = nmt_newt_button_new (_("Edit..."));
g_signal_connect (widget, "clicked", G_CALLBACK (edit_clicked), team);
nmt_newt_grid_add (grid, widget, 0, 4);
G_OBJECT_CLASS (nmt_page_team_port_parent_class)->constructed (object);
}
static void
nmt_page_team_port_class_init (NmtPageTeamPortClass *team_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (team_class);
g_type_class_add_private (team_class, sizeof (NmtPageTeamPortPrivate));
object_class->constructed = nmt_page_team_port_constructed;
}

49
tui/nmt-page-team-port.h Normal file
View File

@@ -0,0 +1,49 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_TEAM_PORT_H
#define NMT_PAGE_TEAM_PORT_H
#include "nmt-page-device.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_TEAM_PORT (nmt_page_team_port_get_type ())
#define NMT_PAGE_TEAM_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_TEAM_PORT, NmtPageTeamPort))
#define NMT_PAGE_TEAM_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_TEAM_PORT, NmtPageTeamPortClass))
#define NMT_IS_PAGE_TEAM_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_TEAM_PORT))
#define NMT_IS_PAGE_TEAM_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_TEAM_PORT))
#define NMT_PAGE_TEAM_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_TEAM_PORT, NmtPageTeamPortClass))
typedef struct {
NmtEditorPage parent;
} NmtPageTeamPort;
typedef struct {
NmtEditorPageClass parent;
} NmtPageTeamPortClass;
GType nmt_page_team_port_get_type (void);
NmtNewtWidget *nmt_page_team_port_new (NMConnection *conn);
G_END_DECLS
#endif /* NMT_PAGE_TEAM_PORT_H */

195
tui/nmt-page-team.c Normal file
View File

@@ -0,0 +1,195 @@
/* -*- 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-page-team
* @short_description: The editor page for Team connections
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "nmt-page-team.h"
#include "nmt-slave-list.h"
G_DEFINE_TYPE (NmtPageTeam, nmt_page_team, NMT_TYPE_PAGE_DEVICE)
#define NMT_PAGE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_TEAM, NmtPageTeamPrivate))
typedef struct {
NmtSlaveList *slaves;
NMSettingTeam *s_team;
GType slave_type;
} NmtPageTeamPrivate;
NmtNewtWidget *
nmt_page_team_new (NMConnection *conn,
NmtDeviceEntry *deventry)
{
return g_object_new (NMT_TYPE_PAGE_TEAM,
"connection", conn,
"title", _("TEAM"),
"device-entry", deventry,
NULL);
}
static void
nmt_page_team_init (NmtPageTeam *team)
{
NmtPageTeamPrivate *priv = NMT_PAGE_TEAM_GET_PRIVATE (team);
priv->slave_type = G_TYPE_NONE;
}
static void
slaves_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
NmtPageTeam *team = NMT_PAGE_TEAM (user_data);
NmtPageTeamPrivate *priv = NMT_PAGE_TEAM_GET_PRIVATE (team);
GPtrArray *slaves;
g_object_get (object, "connections", &slaves, NULL);
if (slaves->len == 0) {
priv->slave_type = G_TYPE_NONE;
} else if (priv->slave_type == G_TYPE_NONE) {
NMConnection *slave = slaves->pdata[0];
if (nm_connection_is_type (slave, NM_SETTING_INFINIBAND_SETTING_NAME))
priv->slave_type = NM_TYPE_SETTING_INFINIBAND;
else
priv->slave_type = NM_TYPE_SETTING_WIRED;
}
}
static gboolean
team_connection_type_filter (GType connection_type,
gpointer user_data)
{
NmtPageTeam *team = user_data;
NmtPageTeamPrivate *priv = NMT_PAGE_TEAM_GET_PRIVATE (team);
if (priv->slave_type != NM_TYPE_SETTING_WIRED) {
if (connection_type == NM_TYPE_SETTING_INFINIBAND)
return TRUE;
}
if (priv->slave_type != NM_TYPE_SETTING_INFINIBAND) {
if ( connection_type == NM_TYPE_SETTING_WIRED
|| connection_type == NM_TYPE_SETTING_WIRELESS
|| connection_type == NM_TYPE_SETTING_VLAN)
return TRUE;
}
return FALSE;
}
static void
edit_clicked (NmtNewtButton *button,
gpointer user_data)
{
NmtPageTeam *team = user_data;
NmtPageTeamPrivate *priv = NMT_PAGE_TEAM_GET_PRIVATE (team);
const char *config;
char *new_config;
config = nm_setting_team_get_config (priv->s_team);
if (!config)
config = "";
new_config = nmt_newt_edit_string (config);
if (new_config && !*new_config)
g_clear_pointer (&new_config, g_free);
g_object_set (G_OBJECT (priv->s_team),
NM_SETTING_TEAM_CONFIG, new_config,
NULL);
g_free (new_config);
}
static void
nmt_page_team_constructed (GObject *object)
{
NmtPageTeam *team = NMT_PAGE_TEAM (object);
NmtPageTeamPrivate *priv = NMT_PAGE_TEAM_GET_PRIVATE (team);
NmtDeviceEntry *deventry;
NmtNewtGrid *grid;
NMSettingTeam *s_team;
NmtNewtWidget *widget;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (team));
s_team = nm_connection_get_setting_team (conn);
if (!s_team) {
nm_connection_add_setting (conn, nm_setting_team_new ());
s_team = nm_connection_get_setting_team (conn);
}
priv->s_team = s_team;
deventry = nmt_page_device_get_device_entry (NMT_PAGE_DEVICE (object));
g_object_bind_property (s_team, NM_SETTING_TEAM_INTERFACE_NAME,
deventry, "interface-name",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
widget = nmt_newt_grid_new ();
nmt_page_grid_append (NMT_PAGE_GRID (team), NULL, widget, NULL);
grid = NMT_NEWT_GRID (widget);
widget = nmt_newt_label_new (_("Slaves"));
nmt_newt_grid_add (grid, widget, 0, 0);
widget = nmt_slave_list_new (conn, team_connection_type_filter, team);
g_signal_connect (widget, "notify::connections",
G_CALLBACK (slaves_changed), team);
nmt_newt_grid_add (grid, widget, 0, 1);
nmt_newt_widget_set_padding (widget, 0, 0, 0, 1);
priv->slaves = NMT_SLAVE_LIST (widget);
slaves_changed (G_OBJECT (priv->slaves), NULL, team);
widget = nmt_newt_label_new (_("JSON configuration"));
nmt_newt_grid_add (grid, widget, 0, 2);
widget = nmt_newt_textbox_new (NMT_NEWT_TEXTBOX_SCROLLABLE | NMT_NEWT_TEXTBOX_SET_BACKGROUND, 60);
g_object_bind_property (s_team, NM_SETTING_TEAM_CONFIG,
widget, "text",
G_BINDING_SYNC_CREATE);
nmt_newt_grid_add (grid, widget, 0, 3);
nmt_newt_widget_set_padding (widget, 2, 0, 2, 1);
widget = nmt_newt_button_new (_("Edit..."));
g_signal_connect (widget, "clicked", G_CALLBACK (edit_clicked), team);
nmt_newt_grid_add (grid, widget, 0, 4);
G_OBJECT_CLASS (nmt_page_team_parent_class)->constructed (object);
}
static void
nmt_page_team_class_init (NmtPageTeamClass *team_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (team_class);
g_type_class_add_private (team_class, sizeof (NmtPageTeamPrivate));
object_class->constructed = nmt_page_team_constructed;
}

50
tui/nmt-page-team.h Normal file
View File

@@ -0,0 +1,50 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_TEAM_H
#define NMT_PAGE_TEAM_H
#include "nmt-page-device.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_TEAM (nmt_page_team_get_type ())
#define NMT_PAGE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_TEAM, NmtPageTeam))
#define NMT_PAGE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_TEAM, NmtPageTeamClass))
#define NMT_IS_PAGE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_TEAM))
#define NMT_IS_PAGE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_TEAM))
#define NMT_PAGE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_TEAM, NmtPageTeamClass))
typedef struct {
NmtPageDevice parent;
} NmtPageTeam;
typedef struct {
NmtPageDeviceClass parent;
} NmtPageTeamClass;
GType nmt_page_team_get_type (void);
NmtNewtWidget *nmt_page_team_new (NMConnection *conn,
NmtDeviceEntry *deventry);
G_END_DECLS
#endif /* NMT_PAGE_TEAM_H */

163
tui/nmt-page-vlan.c Normal file
View File

@@ -0,0 +1,163 @@
/* -*- 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-page-vlan
* @short_description: The editor page for VLAN connections
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <nm-device-ethernet.h>
#include "nm-editor-bindings.h"
#include "nmt-page-vlan.h"
#include "nmt-device-entry.h"
#include "nmt-mac-entry.h"
#include "nmt-mtu-entry.h"
G_DEFINE_TYPE (NmtPageVlan, nmt_page_vlan, NMT_TYPE_PAGE_DEVICE)
#define NMT_PAGE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_VLAN, NmtPageVlanPrivate))
typedef struct {
NMSettingWired *s_wired;
} NmtPageVlanPrivate;
NmtNewtWidget *
nmt_page_vlan_new (NMConnection *conn,
NmtDeviceEntry *deventry)
{
return g_object_new (NMT_TYPE_PAGE_VLAN,
"connection", conn,
"title", _("VLAN"),
"device-entry", deventry,
NULL);
}
static void
nmt_page_vlan_init (NmtPageVlan *vlan)
{
}
static gboolean
vlan_device_filter (NmtDeviceEntry *deventry,
NMDevice *device,
gpointer user_data)
{
// FIXME
return NM_IS_DEVICE_ETHERNET (device);
}
static void
nmt_page_vlan_constructed (GObject *object)
{
NmtPageVlan *vlan = NMT_PAGE_VLAN (object);
NmtPageVlanPrivate *priv = NMT_PAGE_VLAN_GET_PRIVATE (vlan);
NmtDeviceEntry *deventry;
NmtPageGrid *grid;
NMSettingWired *s_wired;
NMSettingVlan *s_vlan;
NmtNewtWidget *widget, *parent, *id_entry;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (vlan));
s_vlan = nm_connection_get_setting_vlan (conn);
if (!s_vlan) {
nm_connection_add_setting (conn, nm_setting_vlan_new ());
s_vlan = nm_connection_get_setting_vlan (conn);
}
s_wired = nm_connection_get_setting_wired (conn);
if (!s_wired) {
/* It makes things simpler if we always have a NMSettingWired;
* we'll hold a ref on one, and add it to and remove it from
* the connection as needed.
*/
s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
}
priv->s_wired = g_object_ref_sink (s_wired);
deventry = nmt_page_device_get_device_entry (NMT_PAGE_DEVICE (object));
g_object_bind_property (s_vlan, NM_SETTING_VLAN_INTERFACE_NAME,
deventry, "interface-name",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
grid = NMT_PAGE_GRID (vlan);
nm_editor_bind_vlan_name (s_vlan);
widget = parent = nmt_device_entry_new (_("Parent"), 40, G_TYPE_NONE);
nmt_device_entry_set_device_filter (NMT_DEVICE_ENTRY (widget),
vlan_device_filter, vlan);
g_object_bind_property (s_vlan, NM_SETTING_VLAN_PARENT,
widget, "interface-name",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (s_wired, NM_SETTING_WIRED_MAC_ADDRESS,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, NULL, widget, NULL);
widget = id_entry = nmt_newt_entry_numeric_new (8, 0, 4095);
g_object_bind_property (s_vlan, NM_SETTING_VLAN_ID,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("VLAN id"), widget, NULL);
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
widget = nmt_mac_entry_new (40, ETH_ALEN);
g_object_bind_property (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Cloned MAC address"), widget, NULL);
widget = nmt_mtu_entry_new ();
g_object_bind_property (s_wired, NM_SETTING_WIRED_MTU,
widget, "mtu",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("MTU"), widget, NULL);
G_OBJECT_CLASS (nmt_page_vlan_parent_class)->constructed (object);
}
static void
nmt_page_vlan_finalize (GObject *object)
{
NmtPageVlanPrivate *priv = NMT_PAGE_VLAN_GET_PRIVATE (object);
g_clear_object (&priv->s_wired);
G_OBJECT_CLASS (nmt_page_vlan_parent_class)->finalize (object);
}
static void
nmt_page_vlan_class_init (NmtPageVlanClass *vlan_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (vlan_class);
g_type_class_add_private (vlan_class, sizeof (NmtPageVlanPrivate));
/* virtual methods */
object_class->constructed = nmt_page_vlan_constructed;
object_class->finalize = nmt_page_vlan_finalize;
}

50
tui/nmt-page-vlan.h Normal file
View File

@@ -0,0 +1,50 @@
/* -*- 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.
*/
#ifndef NMT_PAGE_VLAN_H
#define NMT_PAGE_VLAN_H
#include "nmt-page-device.h"
G_BEGIN_DECLS
#define NMT_TYPE_PAGE_VLAN (nmt_page_vlan_get_type ())
#define NMT_PAGE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_PAGE_VLAN, NmtPageVlan))
#define NMT_PAGE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_PAGE_VLAN, NmtPageVlanClass))
#define NMT_IS_PAGE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_PAGE_VLAN))
#define NMT_IS_PAGE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_PAGE_VLAN))
#define NMT_PAGE_VLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_PAGE_VLAN, NmtPageVlanClass))
typedef struct {
NmtPageDevice parent;
} NmtPageVlan;
typedef struct {
NmtPageDeviceClass parent;
} NmtPageVlanClass;
GType nmt_page_vlan_get_type (void);
NmtNewtWidget *nmt_page_vlan_new (NMConnection *conn,
NmtDeviceEntry *deventry);
G_END_DECLS
#endif /* NMT_PAGE_VLAN_H */

389
tui/nmt-page-wifi.c Normal file
View File

@@ -0,0 +1,389 @@
/* -*- 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-page-wifi
* @short_description: The editor page for Wi-Fi connections
*
* #NmtPageWifi is the editor page for Wi-Fi connections, which
* includes both #NMSettingWireless and #NMSettingWirelessSecurity
* properties.
*/
#include "config.h"
#include <stdlib.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <nm-utils.h>
#include "nmt-page-wifi.h"
#include "nmt-mac-entry.h"
#include "nmt-mtu-entry.h"
#include "nmt-password-fields.h"
#include "nm-editor-bindings.h"
G_DEFINE_TYPE (NmtPageWifi, nmt_page_wifi, NMT_TYPE_PAGE_DEVICE)
#define NMT_PAGE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_WIFI, NmtPageWifiPrivate))
typedef struct {
NMSettingWirelessSecurity *s_wsec;
} NmtPageWifiPrivate;
NmtNewtWidget *
nmt_page_wifi_new (NMConnection *conn,
NmtDeviceEntry *deventry)
{
return g_object_new (NMT_TYPE_PAGE_WIFI,
"connection", conn,
"title", _("WI-FI"),
"device-entry", deventry,
NULL);
}
static void
nmt_page_wifi_init (NmtPageWifi *wifi)
{
}
static NmtNewtPopupEntry wifi_mode[] = {
{ NC_("Wi-Fi", "Client"), NM_SETTING_WIRELESS_MODE_INFRA },
{ N_("Access Point"), NM_SETTING_WIRELESS_MODE_AP },
{ N_("Ad-Hoc Network"), NM_SETTING_WIRELESS_MODE_ADHOC },
{ NULL, NULL }
};
static NmtNewtPopupEntry wifi_band[] = {
{ NC_("Wi-Fi", "Automatic"), NULL },
/* 802.11a Wi-Fi network */
{ N_("A (5 GHz)"), "a" },
/* 802.11b / 802.11g Wi-Fi network */
{ N_("B/G (2.4 GHz)"), "bg" },
{ NULL, NULL }
};
static NmtNewtPopupEntry wifi_security[] = {
{ NC_("Wi-Fi security", "None"), "none" },
{ N_("WPA & WPA2 Personal"), "wpa-personal" },
{ N_("WPA & WPA2 Enterprise"), "wpa-enterprise" },
{ N_("WEP 40/128-bit Key (Hex or ASCII)"), "wep-key" },
{ N_("WEP 128-bit Passphrase"), "wep-passphrase" },
{ N_("Dynamic WEP (802.1x)"), "dynamic-wep" },
{ N_("LEAP"), "leap" },
{ NULL, NULL }
};
static NmtNewtPopupEntry wep_index[] = {
{ NC_("WEP key index", "1 (Default)"), "1" },
{ NC_("WEP key index", "2"), "2" },
{ NC_("WEP key index", "3"), "3" },
{ NC_("WEP key index", "4"), "4" },
{ NULL, NULL }
};
static NmtNewtPopupEntry wep_auth[] = {
{ N_("Open System"), "open" },
{ N_("Shared Key"), "shared" },
{ NULL, NULL }
};
static gboolean
mode_transform_to_band_visibility (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
if (!g_strcmp0 (g_value_get_string (source_value), NM_SETTING_WIRELESS_MODE_INFRA))
g_value_set_boolean (target_value, FALSE);
else
g_value_set_boolean (target_value, TRUE);
return TRUE;
}
static gboolean
band_transform_to_channel_visibility (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
g_value_set_boolean (target_value, g_value_get_string (source_value) != NULL);
return TRUE;
}
static gboolean
ssid_transform_to_entry (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
GByteArray *ssid;
char *utf8;
ssid = g_value_get_boxed (source_value);
utf8 = nm_utils_ssid_to_utf8 (ssid);
g_value_take_string (target_value, utf8);
return TRUE;
}
static gboolean
ssid_transform_from_entry (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
NMSettingWireless *s_wireless = user_data;
const char *text;
const GByteArray *old_ssid;
GByteArray *ssid;
char *utf8;
text = g_value_get_string (source_value);
old_ssid = nm_setting_wireless_get_ssid (s_wireless);
utf8 = nm_utils_ssid_to_utf8 (old_ssid);
if (!g_strcmp0 (text, utf8)) {
g_free (utf8);
return FALSE;
}
g_free (utf8);
ssid = g_byte_array_new ();
g_byte_array_append (ssid, (guint8 *)text, strlen (text));
g_value_take_boxed (target_value, ssid);
return TRUE;
}
static void
nmt_page_wifi_constructed (GObject *object)
{
NmtPageWifiPrivate *priv = NMT_PAGE_WIFI_GET_PRIVATE (object);
NmtPageWifi *wifi = NMT_PAGE_WIFI (object);
NmtDeviceEntry *deventry;
NmtPageGrid *grid;
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wsec;
NmtNewtWidget *widget, *hbox, *subgrid;
NmtNewtWidget *mode, *band, *security, *entry;
NmtNewtStack *stack;
NMConnection *conn;
conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (wifi));
s_wireless = nm_connection_get_setting_wireless (conn);
if (!s_wireless) {
nm_connection_add_setting (conn, nm_setting_wireless_new ());
s_wireless = nm_connection_get_setting_wireless (conn);
}
s_wsec = nm_connection_get_setting_wireless_security (conn);
if (!s_wsec) {
/* It makes things simpler if we always have a
* NMSettingWirelessSecurity; we'll hold a ref on one, and add
* it to and remove it from the connection as needed.
*/
s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
}
priv->s_wsec = g_object_ref_sink (s_wsec);
deventry = nmt_page_device_get_device_entry (NMT_PAGE_DEVICE (object));
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS,
deventry, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
grid = NMT_PAGE_GRID (wifi);
widget = nmt_newt_entry_new (40, NMT_NEWT_ENTRY_NONEMPTY);
g_object_bind_property_full (s_wireless, NM_SETTING_WIRELESS_SSID,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
ssid_transform_to_entry,
ssid_transform_from_entry,
s_wireless, NULL);
nmt_page_grid_append (grid, _("SSID"), widget, NULL);
widget = nmt_newt_popup_new (wifi_mode);
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_MODE,
widget, "active-id",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Mode"), widget, NULL);
mode = widget;
hbox = nmt_newt_grid_new ();
widget = nmt_newt_popup_new (wifi_band);
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_BAND,
widget, "active-id",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_newt_grid_add (NMT_NEWT_GRID (hbox), widget, 0, 0);
band = widget;
widget = nmt_newt_entry_numeric_new (10, 0, 255);
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_CHANNEL,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_newt_grid_add (NMT_NEWT_GRID (hbox), widget, 1, 0);
nmt_newt_widget_set_padding (widget, 1, 0, 0, 0);
g_object_bind_property_full (band, "active-id", widget, "visible",
G_BINDING_SYNC_CREATE,
band_transform_to_channel_visibility,
NULL, NULL, NULL);
g_object_bind_property_full (mode, "active-id", hbox, "visible",
G_BINDING_SYNC_CREATE,
mode_transform_to_band_visibility,
NULL, NULL, NULL);
nmt_page_grid_append (grid, _("Channel"), hbox, NULL);
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
widget = nmt_newt_popup_new (wifi_security);
nmt_page_grid_append (grid, _("Security"), widget, NULL);
security = widget;
widget = nmt_newt_stack_new ();
stack = NMT_NEWT_STACK (widget);
/* none */
subgrid = nmt_page_grid_new ();
nmt_newt_stack_add (stack, "none", subgrid);
/* wpa-personal */
subgrid = nmt_page_grid_new ();
widget = nmt_password_fields_new (40, NMT_PASSWORD_FIELDS_SHOW_PASSWORD);
g_object_bind_property (s_wsec, NM_SETTING_WIRELESS_SECURITY_PSK,
widget, "password",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("Password"), widget, NULL);
nmt_newt_stack_add (stack, "wpa-personal", subgrid);
/* "wpa-enterprise" */
// FIXME
widget = nmt_newt_label_new (_("(No support for wpa-enterprise yet...)"));
nmt_newt_stack_add (stack, "wpa-enterprise", widget);
/* wep-key */
subgrid = nmt_page_grid_new ();
widget = entry = nmt_password_fields_new (40, NMT_PASSWORD_FIELDS_SHOW_PASSWORD);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("Key"), widget, NULL);
widget = nmt_newt_popup_new (wep_index);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("WEP index"), widget, NULL);
nm_editor_bind_wireless_security_wep_key (s_wsec,
entry, "password",
widget, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
widget = nmt_newt_popup_new (wep_auth);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("Authentication"), widget, NULL);
nmt_newt_stack_add (stack, "wep-key", subgrid);
/* wep-passphrase */
subgrid = nmt_page_grid_new ();
widget = entry = nmt_password_fields_new (40, NMT_PASSWORD_FIELDS_SHOW_PASSWORD);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("Password"), widget, NULL);
widget = nmt_newt_popup_new (wep_index);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("WEP index"), widget, NULL);
nm_editor_bind_wireless_security_wep_key (s_wsec,
entry, "password",
widget, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
widget = nmt_newt_popup_new (wep_auth);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("Authentication"), widget, NULL);
nmt_newt_stack_add (stack, "wep-passphrase", subgrid);
/* "dynamic-wep" */
// FIXME
widget = nmt_newt_label_new (_("(No support for dynamic-wep yet...)"));
nmt_newt_stack_add (stack, "dynamic-wep", widget);
/* leap */
subgrid = nmt_page_grid_new ();
widget = nmt_newt_entry_new (40, NMT_NEWT_ENTRY_NONEMPTY);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("Username"), widget, NULL);
widget = nmt_password_fields_new (40, NMT_PASSWORD_FIELDS_SHOW_PASSWORD);
g_object_bind_property (s_wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
widget, "password",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
nmt_page_grid_append (NMT_PAGE_GRID (subgrid), _("Password"), widget, NULL);
nmt_newt_stack_add (stack, "leap", subgrid);
nmt_page_grid_append (grid, NULL, NMT_NEWT_WIDGET (stack), NULL);
g_object_bind_property (security, "active-id",
stack, "active-id",
G_BINDING_SYNC_CREATE);
nm_editor_bind_wireless_security_method (conn, s_wsec, security, "active-id",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
widget = nmt_mac_entry_new (40, ETH_ALEN);
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_BSSID,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("BSSID"), widget, NULL);
widget = nmt_mac_entry_new (40, ETH_ALEN);
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Cloned MAC address"), widget, NULL);
widget = nmt_mtu_entry_new ();
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_MTU,
widget, "mtu",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("MTU"), widget, NULL);
G_OBJECT_CLASS (nmt_page_wifi_parent_class)->constructed (object);
}
static void
nmt_page_wifi_finalize (GObject *object)
{
NmtPageWifiPrivate *priv = NMT_PAGE_WIFI_GET_PRIVATE (object);
g_clear_object (&priv->s_wsec);
G_OBJECT_CLASS (nmt_page_wifi_parent_class)->constructed (object);
}
static void
nmt_page_wifi_class_init (NmtPageWifiClass *wifi_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (wifi_class);
g_type_class_add_private (wifi_class, sizeof (NmtPageWifiPrivate));
object_class->constructed = nmt_page_wifi_constructed;
object_class->finalize = nmt_page_wifi_finalize;
}

Some files were not shown because too many files have changed in this diff Show More