/**
 * nmt_connect_connection_list_get_connection:
 * @list: an #NmtConnectConnectionList
 * @identifier: a connection ID or UUID, or device name
 * @connection: (out) (transfer none): the #NMConnection to be activated
 * @device: (out) (transfer none): the #NMDevice to activate @connection on
 * @specific_object: (out) (transfer none): the "specific object" to connect to
 * @active: (out) (transfer none): the #NMActiveConnection corresponding
 *   to the selection, if any.
 *
 * Gets information about the indicated connection.
 *
 * Returns: %TRUE if there was a match, %FALSE if not.
 */
gboolean
nmt_connect_connection_list_get_connection (NmtConnectConnectionList  *list,
                                            const char                *identifier,
                                            NMConnection             **connection,
                                            NMDevice                 **device,
                                            NMObject                 **specific_object,
                                            NMActiveConnection       **active)
{
	NmtConnectConnectionListPrivate *priv = NMT_CONNECT_CONNECTION_LIST_GET_PRIVATE (list);
	GSList *diter, *citer;
	NmtConnectDevice *nmtdev;
	NmtConnectConnection *nmtconn = NULL;
	NMConnection *conn = NULL;

	g_return_val_if_fail (identifier, FALSE);

	if (nm_utils_is_uuid (identifier))
		conn = NM_CONNECTION (nm_remote_settings_get_connection_by_uuid (nm_settings, identifier));
	if (!conn)
		conn = NM_CONNECTION (nm_remote_settings_get_connection_by_id (nm_settings, identifier));

	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 found;
			} else if (nmtconn->ssid && !strcmp (identifier, nmtconn->ssid))
				goto found;
		}

		if (!conn && nmtdev->device && !strcmp (identifier, nm_device_get_ip_iface (nmtdev->device))) {
			nmtconn = nmtdev->conns->data;
			goto found;
		}
	}

	return FALSE;

 found:
	if (connection)
		*connection = nmtconn->conn;
	if (device)
		*device = nmtconn->device;
	if (specific_object)
		*specific_object = NM_OBJECT (nmtconn->ap);
	if (active)
		*active = nmtconn->active;

	return TRUE;
}
static gboolean
tree_model_visible_func (GtkTreeModel *model,
                         GtkTreeIter *iter,
                         gpointer user_data)
{
	NMConnectionList *self = user_data;
	NMConnection *connection;
	NMSettingConnection *s_con;
	const char *master;
	const char *slave_type;

	gtk_tree_model_get (model, iter, COL_CONNECTION, &connection, -1);
	if (!connection) {
		/* Top-level type nodes are visible iff they have children */
		return gtk_tree_model_iter_has_child  (model, iter);
	}

	/* A connection node is visible unless it is a slave to a known
	 * bond or bridge.
	 */
	s_con = nm_connection_get_setting_connection (connection);
	g_object_unref (connection);
	g_return_val_if_fail (s_con != NULL, FALSE);

	master = nm_setting_connection_get_master (s_con);
	if (!master)
		return TRUE;
	slave_type = nm_setting_connection_get_slave_type (s_con);
	if (   g_strcmp0 (slave_type, NM_SETTING_BOND_SETTING_NAME) != 0
	    && g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME) != 0)
		return TRUE;

	if (nm_remote_settings_get_connection_by_uuid (self->settings, master))
		return FALSE;
	if (nm_connection_editor_get_master (connection))
		return FALSE;

	/* FIXME: what if master is an interface name */

	return TRUE;
}
static void
populate_ui (CEPageVlan *self)
{
    CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
    GSList *devices, *d_iter;
    NMConnection *parent_connection = NULL;
    NMDevice *device, *parent_device = NULL;
    const char *parent, *iface, *current_parent;
    int i, mtu_def, mtu_val;

    devices = get_vlan_devices (self);

    /* Parent */
    build_vlan_parent_list (self, devices);

    parent = nm_setting_vlan_get_parent (priv->setting);
    if (parent) {
        /* UUID? */
        parent_connection = (NMConnection *)nm_remote_settings_get_connection_by_uuid (CE_PAGE (self)->settings, parent);
        if (!parent_connection) {
            /* Interface name? */
            for (d_iter = devices; d_iter; d_iter = d_iter->next) {
                device = d_iter->data;

                if (!g_strcmp0 (parent, nm_device_get_iface (device))) {
                    parent_device = device;
                    break;
                }
            }
        }
    }

    /* If NMSettingVlan:parent didn't indicate a device, but we have a
     * wired setting, figure out the device from that.
     */
    if (priv->s_hw && !parent_device) {
        const GByteArray *mac;
        const char *device_mac_str;
        char *mac_str;

        if (NM_IS_SETTING_WIRED (priv->s_hw))
            mac = nm_setting_wired_get_mac_address (NM_SETTING_WIRED (priv->s_hw));
        else
            mac = NULL;

        if (mac) {
            mac_str = nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER);

            for (d_iter = devices; d_iter; d_iter = d_iter->next) {
                device = d_iter->data;

                if (NM_IS_DEVICE_ETHERNET (device))
                    device_mac_str = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
                else
                    device_mac_str = NULL;

                if (!g_strcmp0 (mac_str, device_mac_str)) {
                    parent_device = device;
                    break;
                }
            }
        }
    }

    current_parent = parent;
    if (parent_device || parent_connection) {
        for (i = 0; priv->parents[i]; i++) {
            if (parent_device && parent_device != priv->parents[i]->device)
                continue;
            if (parent_connection != priv->parents[i]->connection)
                continue;

            current_parent = priv->parents[i]->label;
            break;
        }
    }
    ce_page_setup_mac_combo (CE_PAGE (self), priv->parent, current_parent, priv->parent_labels);
    g_signal_connect (priv->parent, "changed", G_CALLBACK (parent_changed), self);

    if (current_parent)
        priv->last_parent = g_strndup (current_parent, strcspn (current_parent, " "));

    /* Name */
    iface = nm_setting_vlan_get_interface_name (priv->setting);
    if (iface)
        gtk_entry_set_text (priv->name_entry, iface);
    g_signal_connect (priv->name_entry, "changed", G_CALLBACK (name_changed), self);

    /* ID */
    priv->last_id = nm_setting_vlan_get_id (priv->setting);
    gtk_spin_button_set_value (priv->id_entry, priv->last_id);
    g_signal_connect (priv->id_entry, "value-changed", G_CALLBACK (id_changed), self);

    /* Cloned MAC address */
    if (NM_IS_SETTING_WIRED (priv->s_hw)) {
        ce_page_mac_to_entry (nm_setting_wired_get_cloned_mac_address (NM_SETTING_WIRED (priv->s_hw)),
                              ARPHRD_ETHER, priv->cloned_mac);
    }
    g_signal_connect (priv->cloned_mac, "changed", G_CALLBACK (stuff_changed), self);

    /* MTU */
    if (NM_IS_SETTING_WIRED (priv->s_hw)) {
        mtu_def = ce_get_property_default (priv->s_hw, NM_SETTING_WIRED_MTU);
        mtu_val = nm_setting_wired_get_mtu (NM_SETTING_WIRED (priv->s_hw));
    } else {
        mtu_def = mtu_val = 1500;
    }
    g_signal_connect (priv->mtu, "output",
                      G_CALLBACK (ce_spin_output_with_default),
                      GINT_TO_POINTER (mtu_def));

    gtk_spin_button_set_value (priv->mtu, (gdouble) mtu_val);
    g_signal_connect (priv->mtu, "value-changed", G_CALLBACK (stuff_changed), self);

    g_slist_free (devices);
}