Commit 2afb1acb authored by Dan Winship's avatar Dan Winship Committed by Dan Winship

tui: rework how editor pages work

Instead of having NmtEditorPage be a widget itself, have it just be an
object that returns a list of NmtEditorSections, where
NmtEditorSection is a subclass of NmtNewtSection.

(This will be important when adding VPN pages, which will be split up
into multiple sections, but with the different sections needing to
cooperate on updating the NMSettingVpn. This reorganization lets us
have an NMPageVpn containing multiple sections, with the NMPageVpn
object handling the coordination between the sections.)
parent 84d87554
......@@ -61,6 +61,8 @@ nmtui_SOURCES = \
nmt-editor-page.h \
nmt-editor-page-device.c \
nmt-editor-page-device.h \
nmt-editor-section.c \
nmt-editor-section.h \
nmt-editor.c \
nmt-editor.h \
nmt-ip-entry.c \
......
......@@ -45,7 +45,6 @@ enum {
PROP_0,
PROP_DEVICE_ENTRY,
PROP_SHOW_BY_DEFAULT,
LAST_PROP
};
......@@ -73,14 +72,6 @@ nmt_editor_page_device_get_device_entry (NmtEditorPageDevice *page)
return priv->device_entry;
}
static gboolean
nmt_editor_page_device_show_by_default (NmtEditorPage *page)
{
NmtEditorPageDevicePrivate *priv = NMT_EDITOR_PAGE_DEVICE_GET_PRIVATE (page);
return priv->show_by_default;
}
static void
nmt_editor_page_device_set_property (GObject *object,
guint prop_id,
......@@ -93,9 +84,6 @@ nmt_editor_page_device_set_property (GObject *object,
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;
......@@ -114,9 +102,6 @@ nmt_editor_page_device_get_property (GObject *object,
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;
......@@ -127,7 +112,6 @@ static void
nmt_editor_page_device_class_init (NmtEditorPageDeviceClass *page_device_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (page_device_class);
NmtEditorPageClass *page_class = NMT_EDITOR_PAGE_CLASS (page_device_class);
g_type_class_add_private (page_device_class, sizeof (NmtEditorPageDevicePrivate));
......@@ -136,8 +120,6 @@ nmt_editor_page_device_class_init (NmtEditorPageDeviceClass *page_device_class)
object_class->get_property = nmt_editor_page_device_get_property;
object_class->finalize = nmt_editor_page_device_finalize;
page_class->show_by_default = nmt_editor_page_device_show_by_default;
/* properties */
g_object_class_install_property
(object_class, PROP_DEVICE_ENTRY,
......@@ -146,11 +128,4 @@ nmt_editor_page_device_class_init (NmtEditorPageDeviceClass *page_device_class)
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));
}
......@@ -21,9 +21,7 @@
* @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.
* A "page" is a set of related #NmtEditorSections.
*/
#include "config.h"
......@@ -32,14 +30,13 @@
#include "nmt-editor-page.h"
G_DEFINE_ABSTRACT_TYPE (NmtEditorPage, nmt_editor_page, NMT_TYPE_EDITOR_GRID)
G_DEFINE_ABSTRACT_TYPE (NmtEditorPage, nmt_editor_page, G_TYPE_OBJECT)
#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;
GSList *sections;
} NmtEditorPagePrivate;
......@@ -47,7 +44,6 @@ enum {
PROP_0,
PROP_CONNECTION,
PROP_TITLE,
LAST_PROP
};
......@@ -55,9 +51,6 @@ enum {
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
......@@ -65,9 +58,8 @@ 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_slist_free_full (priv->sections, g_object_unref);
G_OBJECT_CLASS (nmt_editor_page_parent_class)->finalize (object);
}
......@@ -89,81 +81,37 @@ nmt_editor_page_get_connection (NmtEditorPage *page)
}
/**
* nmt_editor_page_set_header_widget:
* nmt_editor_page_get_sections:
* @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.
* Gets the page's list of sections to display.
*
* FIXME: for consistency, this should be a property as well.
* Returns: (transfer none): the list of sections; this is the internal list
* used by the page and must not be modified or freed.
*/
void
nmt_editor_page_set_header_widget (NmtEditorPage *page,
NmtNewtWidget *widget)
GSList *
nmt_editor_page_get_sections (NmtEditorPage *page)
{
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);
return priv->sections;
}
/**
* nmt_editor_page_get_header_widget:
* nmt_editor_page_add_section:
* @page: the #NmtEditorPage
* @section: the #NmtEditorSection
*
* 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.
* Adds a section to the page. This should only be called by #NmtEditorPage
* subclasses.
*/
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)
void
nmt_editor_page_add_section (NmtEditorPage *page,
NmtEditorSection *section)
{
NmtEditorPagePrivate *priv = NMT_EDITOR_PAGE_GET_PRIVATE (page);
return priv->title;
}
static gboolean
nmt_editor_page_real_show_by_default (NmtEditorPage *page)
{
return TRUE;
}
/**
* nmt_editor_page_show_by_default:
* @page: the #NmtEditorPage
*
* Checks if @page should be shown expanded by default
*
* Returns: %TRUE or %FALSE
*/
gboolean
nmt_editor_page_show_by_default (NmtEditorPage *page)
{
return NMT_EDITOR_PAGE_GET_CLASS (page)->show_by_default (page);
priv->sections = g_slist_append (priv->sections, g_object_ref_sink (section));
}
static void
......@@ -178,9 +126,6 @@ nmt_editor_page_set_property (GObject *object,
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;
......@@ -199,9 +144,6 @@ nmt_editor_page_get_property (GObject *object,
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;
......@@ -220,8 +162,6 @@ nmt_editor_page_class_init (NmtEditorPageClass *page_class)
object_class->get_property = nmt_editor_page_get_property;
object_class->finalize = nmt_editor_page_finalize;
page_class->show_by_default = nmt_editor_page_real_show_by_default;
/* properties */
/**
......@@ -236,16 +176,4 @@ nmt_editor_page_class_init (NmtEditorPageClass *page_class)
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));
}
......@@ -13,7 +13,7 @@
* 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.
* Copyright 2013-2014 Red Hat, Inc.
*/
#ifndef NMT_EDITOR_PAGE_H
......@@ -22,6 +22,7 @@
#include <NetworkManager.h>
#include "nmt-editor-grid.h"
#include "nmt-editor-section.h"
G_BEGIN_DECLS
......@@ -33,27 +34,24 @@ G_BEGIN_DECLS
#define NMT_EDITOR_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_EDITOR_PAGE, NmtEditorPageClass))
typedef struct {
NmtEditorGrid parent;
GObject parent;
} NmtEditorPage;
typedef struct {
NmtEditorGridClass parent;
GObjectClass parent;
gboolean (*show_by_default) (NmtEditorPage *);
} 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);
GSList *nmt_editor_page_get_sections (NmtEditorPage *page);
const char *nmt_editor_page_get_title (NmtEditorPage *page);
gboolean nmt_editor_page_show_by_default (NmtEditorPage *page);
/*< protected >*/
void nmt_editor_page_add_section (NmtEditorPage *page,
NmtEditorSection *section);
G_END_DECLS
......
/* -*- 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-section:
* @short_description: A section of the #NmtEditor
*
* #NmtEditorSection is the abstract base class for #NmtEditor sections.
*/
#include "config.h"
#include <glib/gi18n-lib.h>
#include "nmt-editor-section.h"
#include "nmt-newt-toggle-button.h"
G_DEFINE_TYPE (NmtEditorSection, nmt_editor_section, NMT_TYPE_NEWT_SECTION)
#define NMT_EDITOR_SECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_EDITOR_SECTION, NmtEditorSectionPrivate))
typedef struct {
NmtEditorGrid *header, *body;
char *title;
NmtNewtWidget *header_widget;
NmtNewtWidget *toggle;
gboolean show_by_default;
} NmtEditorSectionPrivate;
enum {
PROP_0,
PROP_TITLE,
PROP_SHOW_BY_DEFAULT,
PROP_HEADER_WIDGET,
LAST_PROP
};
/**
* nmt_editor_section_new:
* @title: the section title
* @header_widget: (allow-none): the widget to show next to the title
* @show_by_default: whether the section should be open by default
*
* Creates a new #NmtEditorSection.
*
* Returns: a new #NmtEditorSection
*/
NmtEditorSection *
nmt_editor_section_new (const char *title,
NmtNewtWidget *header_widget,
gboolean show_by_default)
{
return g_object_new (NMT_TYPE_EDITOR_SECTION,
"title", title,
"header-widget", header_widget,
"show-by-default", show_by_default,
NULL);
}
static void
rebuild_header (NmtEditorSection *section)
{
NmtEditorSectionPrivate *priv = NMT_EDITOR_SECTION_GET_PRIVATE (section);
/* Removing any widget in an NmtEditorGrid removes its whole row, so we can
* remove the existing title/widget/toggle by asking to remove toggle.
*/
nmt_newt_container_remove (NMT_NEWT_CONTAINER (priv->header), priv->toggle);
nmt_editor_grid_append (priv->header,
priv->title,
priv->header_widget ? priv->header_widget : nmt_newt_separator_new (),
priv->toggle);
nmt_editor_grid_set_row_flags (priv->header,
priv->toggle,
NMT_EDITOR_GRID_ROW_LABEL_ALIGN_LEFT |
NMT_EDITOR_GRID_ROW_EXTRA_ALIGN_RIGHT);
}
static void
nmt_editor_section_init (NmtEditorSection *section)
{
NmtEditorSectionPrivate *priv = NMT_EDITOR_SECTION_GET_PRIVATE (section);
priv->header = NMT_EDITOR_GRID (nmt_editor_grid_new ());
priv->body = NMT_EDITOR_GRID (nmt_editor_grid_new ());
priv->toggle = nmt_newt_toggle_button_new (_("Hide"), _("Show"));
g_object_ref_sink (priv->toggle);
nmt_newt_section_set_header (NMT_NEWT_SECTION (section), NMT_NEWT_WIDGET (priv->header));
nmt_newt_section_set_body (NMT_NEWT_SECTION (section), NMT_NEWT_WIDGET (priv->body));
g_object_bind_property (priv->toggle, "active",
section, "open",
G_BINDING_SYNC_CREATE);
}
static void
nmt_editor_section_finalize (GObject *object)
{
NmtEditorSectionPrivate *priv = NMT_EDITOR_SECTION_GET_PRIVATE (object);
g_free (priv->title);
g_clear_object (&priv->header_widget);
g_clear_object (&priv->toggle);
G_OBJECT_CLASS (nmt_editor_section_parent_class)->finalize (object);
}
/**
* nmt_editor_section_get_header_widget:
* @section: the #NmtEditorSection
*
* Gets the section's header widget.
*
* Returns: the section's header widget.
*/
NmtNewtWidget *
nmt_editor_section_get_header_widget (NmtEditorSection *section)
{
NmtEditorSectionPrivate *priv = NMT_EDITOR_SECTION_GET_PRIVATE (section);
return priv->header_widget;
}
/**
* nmt_editor_section_get_body:
* @section: the #NmtEditorSection
*
* Gets the section's body grid, so that you can add things to it.
*
* Returns: the #NmtEditorGrid used for the section body
*/
NmtEditorGrid *
nmt_editor_section_get_body (NmtEditorSection *section)
{
NmtEditorSectionPrivate *priv = NMT_EDITOR_SECTION_GET_PRIVATE (section);
return priv->body;
}
/**
* nmt_editor_section_get_title:
* @section: the #NmtEditorSection
*
* Gets the section's title.
*
* Returns: the section's title
*/
const char *
nmt_editor_section_get_title (NmtEditorSection *section)
{
NmtEditorSectionPrivate *priv = NMT_EDITOR_SECTION_GET_PRIVATE (section);
return priv->title;
}
static void
nmt_editor_section_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NmtEditorSection *section = NMT_EDITOR_SECTION (object);
NmtEditorSectionPrivate *priv = NMT_EDITOR_SECTION_GET_PRIVATE (section);
switch (prop_id) {
case PROP_TITLE:
priv->title = g_value_dup_string (value);
rebuild_header (section);
break;
case PROP_SHOW_BY_DEFAULT:
priv->show_by_default = g_value_get_boolean (value);
nmt_newt_toggle_button_set_active (NMT_NEWT_TOGGLE_BUTTON (priv->toggle),
priv->show_by_default);
break;
case PROP_HEADER_WIDGET:
priv->header_widget = g_value_get_object (value);
if (priv->header_widget)
g_object_ref_sink (priv->header_widget);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_editor_section_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NmtEditorSectionPrivate *priv = NMT_EDITOR_SECTION_GET_PRIVATE (object);
switch (prop_id) {
case PROP_TITLE:
g_value_set_string (value, priv->title);
break;
case PROP_SHOW_BY_DEFAULT:
g_value_set_boolean (value, priv->show_by_default);
break;
case PROP_HEADER_WIDGET:
g_value_set_object (value, priv->header_widget);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nmt_editor_section_class_init (NmtEditorSectionClass *section_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (section_class);
g_type_class_add_private (section_class, sizeof (NmtEditorSectionPrivate));
/* virtual methods */
object_class->set_property = nmt_editor_section_set_property;
object_class->get_property = nmt_editor_section_get_property;
object_class->finalize = nmt_editor_section_finalize;
/* properties */
/**
* NmtEditorSection:title:
*
* The section'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));
/**
* NmtEditorSection:show-by-default:
*
* Whether the section should be expanded by default.
*/
g_object_class_install_property
(object_class, PROP_SHOW_BY_DEFAULT,
g_param_spec_boolean ("show-by-default", "", "",
TRUE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NmtEditorSection:header-widget:
*
* The widget (if any) that appears between the section title and its toggle
* button.
*/
g_object_class_install_property
(object_class, PROP_HEADER_WIDGET,
g_param_spec_object ("header-widget", "", "",
NMT_TYPE_NEWT_WIDGET,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}
/* -*- 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_SECTION_H
#define NMT_EDITOR_SECTION_H
#include "nmt-newt-section.h"
#include "nmt-editor-grid.h"
G_BEGIN_DECLS
#define NMT_TYPE_EDITOR_SECTION (nmt_editor_section_get_type ())
#define NMT_EDITOR_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_EDITOR_SECTION, NmtEditorSection))
#define NMT_EDITOR_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_EDITOR_SECTION, NmtEditorSectionClass))
#define NMT_IS_EDITOR_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_EDITOR_SECTION))
#define NMT_IS_EDITOR_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_EDITOR_SECTION))
#define NMT_EDITOR_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_EDITOR_SECTION, NmtEditorSectionClass))
typedef struct {
NmtNewtSection parent;
} NmtEditorSection;
typedef struct {
NmtNewtSectionClass parent;
} NmtEditorSectionClass;
GType nmt_editor_section_get_type (void);
NmtEditorSection *nmt_editor_section_new (const char *title,
NmtNewtWidget *header_widget,
gboolean show_by_default);
const char *nmt_editor_section_get_title (NmtEditorSection *section);
NmtNewtWidget *nmt_editor_section_get_header_widget (NmtEditorSection *section);
NmtEditorGrid *nmt_editor_section_get_body (NmtEditorSection *section);
G_END_DECLS
#endif /* NMT_EDITOR_SECTION_H */
......@@ -64,6 +64,7 @@ typedef struct {
NMEditorConnectionTypeData *type_data;
GSList *pages;
NmtNewtWidget *ok, *cancel;
gboolean running;
} NmtEditorPrivate;
......@@ -266,42 +267,24 @@ permissions_transform_from_allusers (GBinding *binding,
}
static NmtNewtWidget *
add_section_for_page (NmtEditorGrid *grid, NmtNewtWidget *widget)
add_sections_for_page (NmtEditor *editor, NmtEditorGrid *grid, NmtEditorPage *page)
{
NmtEditorPage *page;
NmtNewtWidget *section, *header, *toggle;
g_return_val_if_fail (NMT_IS_EDITOR_PAGE (widget), NULL);
g_return_val_if_fail (nmt_newt_widget_get_parent (widget) == NULL, NULL);
page = NMT_EDITOR_PAGE (widget);
section = nmt_newt_section_new (TRUE);
toggle = nmt_newt_toggle_button_new (_("Hide"), _("Show"));