## InfdDirectory InfdDirectory — Directory of published documents |

## Stability Level

Unstable, unless otherwise indicated

## Synopsis

    #include <libinfinity/server/infd-directory.h>

    struct              InfdDirectoryIter;
                        InfdDirectory;
    struct              InfdDirectoryClass;
    void                (*InfdDirectoryForeachConnectionFunc)
                                                            (InfXmlConnection *Param1,
                                                             gpointer Param2);
    InfdDirectoryIter * infd_directory_iter_copy            (InfdDirectoryIter *iter);
    void                infd_directory_iter_free            (InfdDirectoryIter *iter);
    InfdDirectory *     infd_directory_new                  (InfIo *io,
                                                             InfdStorage *storage,
                                                             InfCommunicationManager *comm_manager);
    InfIo *             infd_directory_get_io               (InfdDirectory *directory);
    InfdStorage *       infd_directory_get_storage          (InfdDirectory *directory);
    InfCommunicationManager * infd_directory_get_communication_manager
                                                            (InfdDirectory *directory);
    gboolean            infd_directory_add_plugin           (InfdDirectory *directory,
                                                             const InfdNotePlugin *plugin);
    const InfdNotePlugin * infd_directory_lookup_plugin     (InfdDirectory *directory,
                                                             const gchar *note_type);
    gboolean            infd_directory_add_connection       (InfdDirectory *directory,
                                                             InfXmlConnection *connection);
    void                infd_directory_foreach_connection   (InfdDirectory *directory,
                                                             InfdDirectoryForeachConnectionFunc func,
                                                             gpointer user_data);
    const gchar *       infd_directory_iter_get_name        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    gchar *             infd_directory_iter_get_path        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    void                infd_directory_iter_get_root        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    gboolean            infd_directory_iter_get_next        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    gboolean            infd_directory_iter_get_prev        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    gboolean            infd_directory_iter_get_parent      (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    gboolean            infd_directory_iter_get_child       (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);
    gboolean            infd_directory_iter_get_explored    (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    gboolean            infd_directory_add_subdirectory     (InfdDirectory *directory,
                                                             InfdDirectoryIter *parent,
                                                             const gchar *name,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);
    gboolean            infd_directory_add_note             (InfdDirectory *directory,
                                                             InfdDirectoryIter *parent,
                                                             const gchar *name,
                                                             const InfdNotePlugin *plugin,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);
    gboolean            infd_directory_remove_node          (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);
    InfdStorageNodeType infd_directory_iter_get_node_type   (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    const InfdNotePlugin * infd_directory_iter_get_plugin   (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    InfdSessionProxy *  infd_directory_iter_get_session     (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);
    InfdSessionProxy *  infd_directory_iter_peek_session    (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);
    gboolean            infd_directory_iter_save_session    (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);
    void                infd_directory_enable_chat          (InfdDirectory *directory,
                                                             gboolean enable);
    InfdSessionProxy *  infd_directory_get_chat_session     (InfdDirectory *directory);

## Object Hierarchy

      GBoxed
       +----InfdDirectoryIter

      GObject
       +----InfdDirectory

## Implemented Interfaces

InfdDirectory implements InfCommunicationObject.

## Properties

      "chat-session"             InfdSessionProxy*     : Read
      "communication-manager"    InfCommunicationManager*  : Read / Write / Construct Only
      "io"                       InfIo*                : Read / Write / Construct Only
      "storage"                  InfdStorage*          : Read / Write / Construct

## Signals

      "add-session"                                    : Run Last
      "node-added"                                     : Run Last
      "node-removed"                                   : Run Last
      "remove-session"                                 : Run Last

## Description

The InfdDirectory manages a directory of documents. An item in the directory is also called "node". A node may either be a subdirectory or a document (also called "note"). Notes may be of different type - there may be plain text notes, rich text notes, graphics notes, etc.

InfdStorage defines where the directory structure and the notes are read from and how there are permanently stored.

## Details

### struct InfdDirectoryIter

    struct InfdDirectoryIter {
      guint node_id;
      gpointer node;
    };

### InfdDirectory

    typedef struct _InfdDirectory InfdDirectory;

### struct InfdDirectoryClass

    struct InfdDirectoryClass {
      GObjectClass parent_class;

      /* Signals */
      void (*node_added)(InfdDirectory* directory,
                         InfdDirectoryIter* iter);

      void (*node_removed)(InfdDirectory* directory,
                           InfdDirectoryIter* iter);

      void (*add_session)(InfdDirectory* directory,
                          InfdDirectoryIter* iter,
                          InfdSessionProxy* session);

      void (*remove_session)(InfdDirectory* directory,
                             InfdDirectoryIter* iter,
                             InfdSessionProxy* session);
    };

### InfdDirectoryForeachConnectionFunc ()

    void                (*InfdDirectoryForeachConnectionFunc)
                                                            (InfXmlConnection *Param1,
                                                             gpointer Param2);

### infd_directory_iter_copy ()

    InfdDirectoryIter * infd_directory_iter_copy            (InfdDirectoryIter *iter);

Makes a dynamically-allocated copy of `iter`. This should not be used by applications because you can copy the structs by value.

`iter` : | A InfdDirectoryIter.
Returns : | A newly-allocated copy of `iter`.

### infd_directory_iter_free ()

    void                infd_directory_iter_free            (InfdDirectoryIter *iter);

Frees a InfdDirectoryIter allocated with `infd_directory_iter_copy()`.

`iter` : | A InfdDirectoryIter.

### infd_directory_new ()

    InfdDirectory *     infd_directory_new                  (InfIo *io,
                                                             InfdStorage *storage,
                                                             InfCommunicationManager *comm_manager);

Creates a new InfdDirectory. If `storage` is `NULL` then the directory keeps all content in memory. This can make sense for ad-hoc sessions where no central document storage is required.

`io` : | IO object to watch connections and schedule timeouts.
`storage` : | Storage backend that is used to read/write notes from permanent memory into InfBuffer objects, or `NULL`.
`comm_manager` : | A InfCommunicationManager to register added connections to and which forwards incoming data to the directory or running sessions.
Returns : | A new InfdDirectory.

### infd_directory_get_io ()

    InfIo *             infd_directory_get_io               (InfdDirectory *directory);

Returns the IO object in use by the directory.

`directory` : | A InfdDirectory.
Returns : | A InfIo.

### infd_directory_get_storage ()

    InfdStorage *       infd_directory_get_storage          (InfdDirectory *directory);

Returns the storage backend in use by the directory.

`directory` : | A InfdDirectory:
Returns : | An InfdStorage.

### infd_directory_get_communication_manager ()

    InfCommunicationManager * infd_directory_get_communication_manager
                                                            (InfdDirectory *directory);

Returns the connection manager of the directory.

`directory` : | A InfdDirectory.
Returns : | An InfCommunicationManager.

### infd_directory_add_plugin ()

    gboolean            infd_directory_add_plugin           (InfdDirectory *directory,
                                                             const InfdNotePlugin *plugin);

Adds `plugin` to `directory`. This allows the directory to create sessions of the plugin's type. Only one plugin of each type can be added to the directory. The plugin's storage_type must match the storage of `directory`. If the directory's storage is `NULL`, then the plugin's storage type does not matter, and the plugin's `session_read` and `session_write` functions will not be used (and can therefore be `NULL`).

`directory` : | A InfdDirectory.
`plugin` : | A InfdNotePlugin.
Returns : | Whether the plugin was added successfully.

### infd_directory_lookup_plugin ()

    const InfdNotePlugin * infd_directory_lookup_plugin     (InfdDirectory *directory,
                                                             const gchar *note_type);

Returns the InfdNotePlugin that handles the given note type, or `NULL` in case no corresponding plugin was added.

`directory` : | A InfdDirectory.
`note_type` : | A note type for which to lookup the plugin.
Returns : | A InfdNotePlugin, or `NULL`.

### infd_directory_add_connection ()

    gboolean            infd_directory_add_connection       (InfdDirectory *directory,
                                                             InfXmlConnection *connection);

Adds `connection` to the connections of `directory`. The directory will then receive requests from `connection`. If the directory's method manager does not contain a "central" method for connection's network, then the connection will not be added and the function returns `FALSE`.

The connection is removed again automatically if it is closed.

`directory` : | A InfdDirectory.
`connection` : | A InfConnection.
Returns : | Whether the connection was added to the directory.

### infd_directory_foreach_connection ()

    void                infd_directory_foreach_connection   (InfdDirectory *directory,
                                                             InfdDirectoryForeachConnectionFunc func,
                                                             gpointer user_data);

Calls `func` for each connection in `directory` that has previously been added to the directory.

`directory` : | A InfdDirectory.
`func` : | The function to call for each connection in `directory`.
`user_data` : | Additional data to pass to the callback function.

### infd_directory_iter_get_name ()

    const gchar *       infd_directory_iter_get_name        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Returns the name of the node `iter` points to.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to a node in `directory`.
Returns : | The node's name. The returned string must not be freed.

### infd_directory_iter_get_path ()

    gchar *             infd_directory_iter_get_path        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Returns the complete path to the node `iter` points to. The path to a node is the name of the node and the name of all parent nodes separated by '/', as a filesystem path on Unix.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to a node in `directory`.
Returns : | The node's path. Free with `g_free()` when no longer in use.

### infd_directory_iter_get_root ()

    void                infd_directory_iter_get_root        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Sets `iter` to point to the root node of the directory.

`directory` : | A InfdDirectory
`iter` : | An uninitalized InfdDirectoryIter.

### infd_directory_iter_get_next ()

    gboolean            infd_directory_iter_get_next        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Sets `iter` to point to the next node within the same subdirectory. If there is no next node, `iter` is left untouched and the function returns `FALSE`.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to some node in `directory`.
Returns : | `TRUE`, if `iter` was set.

### infd_directory_iter_get_prev ()

    gboolean            infd_directory_iter_get_prev        (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Sets `iter` to point to the previous node within the same subdirectory. If there is no such node, `iter` is left untouched and the function returns `FALSE`.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to some node in `directory`.
Returns : | `TRUE`, if `iter` was set.

### infd_directory_iter_get_parent ()

    gboolean            infd_directory_iter_get_parent      (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Sets `iter` to point to the parent node of `iter`. This node is guaranteed to be a subdirectory node. If there is no such node (i.e. `iter` points to the root node), `iter` is left untouched and the function returns `FALSE`.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to some node in `directory`.
Returns : | `TRUE`, if `iter` was set.

### infd_directory_iter_get_child ()

    gboolean            infd_directory_iter_get_child       (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);

Sets `iter` to point to first child node of `iter`. This requires that `iter` points to a subdirectory node. If the subdirectory `iter` points to has no children, the function returns `FALSE` and `iter` is left untouched.

The function might fail if this node's children have not yet been read from the background storage and an error occurs while reading them. In this case, `FALSE` is returned and `error` is set.

The function guarantees not to set `error` if the node is already explored, i.e. `infd_directory_iter_get_explored()` returns `TRUE` for `directory` and `iter`.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to a subdirectory node in `directory`.
`error` : | Location to store error information.
Returns : | `TRUE`, if `iter` was set.

### infd_directory_iter_get_explored ()

    gboolean            infd_directory_iter_get_explored    (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Returns whether the subdirectory node pointed to by `iter` has already been read from the background storage. If not, then no connections can be subscribed to any child nodes.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to a subdirectory node in `directory`.
Returns : | Whether the node `iter` points to has been explored.

### infd_directory_add_subdirectory ()

    gboolean            infd_directory_add_subdirectory     (InfdDirectory *directory,
                                                             InfdDirectoryIter *parent,
                                                             const gchar *name,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);

Adds a subdirectory to the directory tree. The new subdirectory will be a child the subdirectory `parent` points to. `iter` is modified to point to the new subdirectory. If creation fails, the function returns FALSE and `error` is set.

`directory` : | A InfdDirectory.
`parent` : | A InfdDirectoryIter pointing to a subdirectory node in `directory`.
`name` : | The name of the new node.
`iter` : | An uninitalized InfdDirectoryIter.
`error` : | Location to store error information.
Returns : | `TRUE` if the subdirectory was created successfully.

### infd_directory_add_note ()

    gboolean            infd_directory_add_note             (InfdDirectory *directory,
                                                             InfdDirectoryIter *parent,
                                                             const gchar *name,
                                                             const InfdNotePlugin *plugin,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);

Creates a new note in `directory`. It will be child of the subdirectory node `parent` points to. `iter` is set to point to the new node. If an error occurs, the function returns `FALSE` and `error` is set.

`directory` : | A InfdDirectory.
`parent` : | A InfdDirectoryIter pointing to a subdirectory node in `directory`.
`name` : | The name of the new node.
`plugin` : | The plugin to use for the node. Must have been added with `infd_directory_add_plugin()`.
`iter` : | An uninitialized InfdDirectoryIter.
`error` : | Location to store error information.
Returns : | `TRUE` on success.

### infd_directory_remove_node ()

    gboolean            infd_directory_remove_node          (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);

Removes the node `iter` points to. If it is a subdirectory node, every node it contains will also be removed. If the function fails, `FALSE` is returned and `error` is set.

`directory` : | A InfdDirectory
`iter` : | A InfdDirectoryIter pointing to some node in `directory`.
`error` : | Location to store error information.
Returns : | `TRUE` on success.

### infd_directory_iter_get_node_type ()

    InfdStorageNodeType infd_directory_iter_get_node_type   (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Returns the type of the node `iter` points to.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to some node in `directory`.
Returns : | A InfdStorageNodeType.

### infd_directory_iter_get_plugin ()

    const InfdNotePlugin * infd_directory_iter_get_plugin   (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Returns the plugin that is used to create a session for the note `iter` points to.

`directory` : | A InfdDirectory.
`iter` : | a InfdDirectoryIter pointing to a note in `directory`.
Returns : | The plugin for the note `iter` points to.

### infd_directory_iter_get_session ()

    InfdSessionProxy *  infd_directory_iter_get_session     (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);

Returns the running session in which the note `iter` points to is currently edited. If the session does not exist, it is created. However, this might fail if the loading from the background storage fails. In this case, `NULL` is returned and `error` is set.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to a note in `directory`.
`error` : | Location to store error information.
Returns : | A InfdSessionProxy for the note `iter` points to.

### infd_directory_iter_peek_session ()

    InfdSessionProxy *  infd_directory_iter_peek_session    (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter);

Returns the running session in which the note `iter` points to is currently edited. If the session does not exist because nobody is editing it at the moment, the function returns `NULL`.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to a note in `directory`.
Returns : | A InfdSessionProxy for the note `iter` points to, or `NULL`.

### infd_directory_iter_save_session ()

    gboolean            infd_directory_iter_save_session    (InfdDirectory *directory,
                                                             InfdDirectoryIter *iter,
                                                             GError **error);

Attempts to store the session the node `iter` points to represents into the background storage.

`directory` : | A InfdDirectory.
`iter` : | A InfdDirectoryIter pointing to a note in `directory`.
`error` : | Location to store error information.
Returns : | `TRUE` if the operation succeeded, `FALSE` otherwise.

### infd_directory_enable_chat ()

    void                infd_directory_enable_chat          (InfdDirectory *directory,
                                                             gboolean enable);

If `enable` is `TRUE`, this enables the chat on the server. This allows clients subscribing to the chat via `infc_browser_subscribe_chat()`. If `enable` is `FALSE` the chat is disabled which means closing an existing chat session if any and no longer allowing subscription to the chat. The chat is initially disabled.

`directory` : | A InfdDirectory.
`enable` : | Whether to enable or disable the chat.

### infd_directory_get_chat_session ()

    InfdSessionProxy *  infd_directory_get_chat_session     (InfdDirectory *directory);

Returns a InfdSessionProxy for the chat session, if any. If the chat is enabled (see `infd_directory_enable_chat()`) this returns a InfdSessionProxy that can be used to join local users to the chat, or to get chat contents (by getting the InfChatBuffer from the proxy's InfChatSession). If the chat is disabled the function returns `NULL`.

`directory` : | A InfdDirectory.
Returns : | A InfdSessionProxy, or `NULL` if the chat is disabled.

## Property Details

### The `"chat-session"` property

      "chat-session"             InfdSessionProxy*     : Read

The server's chat session.

### The `"communication-manager"` property

      "communication-manager"    InfCommunicationManager*  : Read / Write / Construct Only

The communication manager for the directory.

### The `"io"` property

      "io"                       InfIo*                : Read / Write / Construct Only

IO object to watch sockets and schedule timeouts.

### The `"storage"` property

      "storage"                  InfdStorage*          : Read / Write / Construct

The storage backend to use.

## Signal Details

### The `"add-session"` signal

    void                user_function                      (InfdDirectory     *directory,
                                                            InfdDirectoryIter *iter,
                                                            InfdSessionProxy  *session,
                                                            gpointer           user_data)      : Run Last

This signal is emitted, when a session has been associated with a node. This happens when `infd_directory_iter_get_session()` is called on a node, when a remote client subscribes to a session or a new node was created.

When a session has been created for a node, the session is kept until it is idle for some time. Then, it is removed again after having been stored into the background storage.

`directory` : | The InfdDirectory emitting the signal.
`iter` : | A InfdDirectoryIter pointing to the affected node.
`session` : | The InfdSessionProxy proxying the added session.
`user_data` : | user data set when the signal handler was connected.

### The `"node-added"` signal

    void                user_function                      (InfdDirectory     *directory,
                                                            InfdDirectoryIter *iter,
                                                            gpointer           user_data)      : Run Last

This signal is emitted when a new node has been created. It can either be created by API calls such as `infd_directory_add_note()` and `infd_directory_add_subdirectory()` or by a client making a corresponding request.

`directory` : | The InfdDirectory emitting the signal.
`iter` : | A InfdDirectoryIter pointing to the added node.
`user_data` : | user data set when the signal handler was connected.

### The `"node-removed"` signal

    void                user_function                      (InfdDirectory     *directory,
                                                            InfdDirectoryIter *iter,
                                                            gpointer           user_data)      : Run Last

This signal is emitted when a node has been removed. If a subdirectory node is removed, all contained nodes are removed as well. Node removal can either happen through a call to `infd_directory_remove_node()`, or by a client making a corresponding request.

`directory` : | The InfdDirectory emitting the signal.
`iter` : | A InfdDirectoryIter pointing to the removed node.
`user_data` : | user data set when the signal handler was connected.

### The `"remove-session"` signal

    void                user_function                      (InfdDirectory     *directory,
                                                            InfdDirectoryIter *iter,
                                                            InfdSessionProxy  *session,
                                                            gpointer           user_data)      : Run Last

This signal is emitted when a previously added session was removed. This happens when a session is idle for some time, or when the corresponding node has been removed.

`directory` : | The InfdDirectory emitting the signal.
`iter` : | A InfdDirectoryIter pointing to the affected node.
`session` : | The InfdSessionProxy proxying the removed session.
`user_data` : | user data set when the signal handler was connected.

## See Also

InfcBrowser, InfdStorage