## ThunarxPropertyPage

ThunarxPropertyPage — The base class for pages added to the properties dialog

## Stability Level

Stable, unless otherwise indicated

## Synopsis

    #include <thunarx/thunarx.h>

                        ThunarxPropertyPage;
    GtkWidget*          thunarx_property_page_new           (const gchar *label);
    GtkWidget*          thunarx_property_page_new_with_label_widget
                                                            (GtkWidget *label_widget);
    const gchar*        thunarx_property_page_get_label     (ThunarxPropertyPage *property_page);
    void                thunarx_property_page_set_label     (ThunarxPropertyPage *property_page,
                                                             const gchar *label);
    GtkWidget*          thunarx_property_page_get_label_widget
                                                            (ThunarxPropertyPage *property_page);
    void                thunarx_property_page_set_label_widget
                                                            (ThunarxPropertyPage *property_page,
                                                             GtkWidget *label_widget);

## Object Hierarchy

      GObject
       +----GInitiallyUnowned
             +----GtkObject
                   +----GtkWidget
                         +----GtkContainer
                               +----GtkBin
                                     +----ThunarxPropertyPage

## Implemented Interfaces

ThunarxPropertyPage implements AtkImplementorIface and GtkBuildable.

## Properties

      "label"                    gchar*                : Read / Write
      "label-widget"             GtkWidget*            : Read / Write

## Description

The class for pages that can be added to Thunar's file properties dialog by extensions implementing the ThunarxPropertyPageProvider interface. The pages returned by extensions from `thunarx_property_page_provider_get_pages()` method are instances of this class or a derived class. Note that extensions do not need to subclass ThunarxPropertyPage, but may also instantiate it directly and add widgets to it, but I strongly suggest to create a subclass as it usually leads to better modularization and thereby better maintainability in the code.

To pick up the TagPage example from the `thunarx_property_page_provider_get_pages()` description again, you'd create a new class TagPage, that inherits ThunarxPropertyPage (using the THUNARX_DEFINE_TYPE macro), which provides several user interface elements in the property, and defines atleast one property named `"file"`, which is the ThunarxFileInfo whose tags are displayed in the property page. For example, the `tag-page.h` header file would look like this (this is really just an example of the suggested way to implement property pages, you may of course choose a different way):

    ##ifndef __TAG_PAGE_H__
    ##define __TAG_PAGE_H__

    ##include <thunarx/thunarx.h>

    G_BEGIN_DECLS;

    typedef struct _TagPageClass TagPageClass;
    typedef struct _TagPage      TagPage;

    #define TAG_TYPE_PAGE            (tag_page_get_type ())
    #define TAG_PAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TAG_TYPE_PAGE, TagPage))
    #define TAG_PAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TAG_TYPE_PAGE, TagPageClass))
    #define TAG_IS_PAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TAG_TYPE_PAGE))
    #define TAG_IS_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TAG_TYPE_PAGE))
    #define TAG_PAGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TAG_TYPE_PAGE, TagPageClass))

    /* these two functions are implemented automatically by the THUNARX_DEFINE_TYPE macro */
    GType            tag_page_get_type      (void) G_GNUC_CONST G_GNUC_INTERNAL;
    void             tag_page_register_type (ThunarxProviderPlugin *plugin) G_GNUC_INTERNAL;

    GtkWidget       *tag_page_new           (ThunarxFileInfo       *file) G_GNUC_INTERNAL G_GNUC_MALLOC;

    ThunarxFileInfo *tag_page_get_file      (TagPage               *tag_page) G_GNUC_INTERNAL;
    void             tag_page_set_file      (TagPage               *tag_page,
                                             ThunarxFileInfo       *file) G_GNUC_INTERNAL;

    G_END_DECLS;

    ##endif /* !__TAG_PAGE_H__ */

And the `tag-page.c` source file could look like this:

    ##include "tag-page.h"

    /* Property identifiers */
    enum
    {
      PROP_0,
      PROP_FILE,
    };

    static void tag_page_class_init   (TagPageClass *klass);
    static void tag_page_init         (TagPage          *tag_page);
    static void tag_page_finalize     (GObject          *object);
    static void tag_page_get_property (GObject          *object,
                                       guint             prop_id,
                                       GValue           *value,
                                       GParamSpec       *pspec);
    static void tag_page_set_property (GObject          *object,
                                       guint             prop_id,
                                       const GValue     *value,
                                       GParamSpec       *pspec);
    static void tag_page_file_changed (ThunarxFileInfo  *file,
                                       TagPage          *tag_page);

    struct _TagPageClass
    {
      ThunarxPropertyPageClass __parent__;
    };

    struct _TagPage
    {
      ThunarxPropertyPage __parent__;
      ThunarxFileInfo    *file;

      /* your widgets... */
    };

    /* implements the tag_page_get_type() and tag_page_register_type() functions */
    THUNARX_DEFINE_TYPE (TagPage, tag_page, THUNARX_TYPE_PROPERTY_PAGE);

    static void
    tag_page_class_init (TagPageClass *klass)
    {
      GObjectClass *gobject_class;

      gobject_class = G_OBJECT_CLASS (klass);
      gobject_class->finalize = tag_page_finalize;
      gobject_class->get_property = tag_page_get_property;
      gobject_class->set_property = tag_page_set_property;

      /**
       * TagPage:file:
       *
       * The ThunarxFileInfo displayed by this TagPage.
       **/
      g_object_class_install_property (gobject_class,
                                       PROP_FILE,
                                       g_param_spec_object ("file", "file", "file,
                                                            THUNARX_TYPE_FILE_INFO,
                                                            G_PARAM_READWRITE));
    }

    static void
    tag_page_init (TagPage *tag_page)
    {
      GtkWidget *table;

      /* you can of course also use a GtkVBox here, or whatever */
      table = gtk_table_new (2, 2, FALSE);
      gtk_container_add (GTK_CONTAINER (tag_page), table);
      gtk_widget_show (table);

      /* add your widgets to the table... */
    }

    static void
    tag_page_finalize (GObject *object)
    {
      TagPage *tag_page = TAG_PAGE (object);

      /* disconnect from the file */
      tag_page_set_file (tag_page, NULL);

      /* release any additional resources... */

      (*G_OBJECT_CLASS (tag_page_parent_class)->finalize) (object);
    }

    static void
    tag_page_get_property (GObject    *object,
                           guint       prop_id,
                           GValue     *value,
                           GParamSpec *pspec)
    {
      TagPage *tag_page = TAG_PAGE (object);

      switch (prop_id)
        {
        case PROP_FILE:
          g_value_set_object (value, tag_page_get_file (tag_page));
          break;

        default:
          G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
          break;
        }
    }

    static void
    tag_page_set_property (GObject      *object,
                           guint         prop_id,
                           const GValue *value,
                           GParamSpec   *pspec)
    {
      TagPage *tag_page = TAG_PAGE (object);

      switch (prop_id)
        {
        case PROP_FILE:
          tag_page_set_file (tag_page, g_value_get_object (value));
          break;

        default:
          G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
          break;
        }
    }

    static void
    tag_page_file_changed (ThunarxFileInfo *file,
                           TagPage         *tag_page)
    {
      /* update your user interface elements in the tag_page
       * to display the new state of the file...
       */
    }

    GtkWidget*
    tag_page_new (ThunarxFileInfo *file)
    {
      return g_object_new (TAG_TYPE_PAGE, "file", file, NULL);
    }

    ThunarxFileInfo*
    tag_page_get_file (TagPage *tag_page)
    {
      g_return_val_if_fail (TAG_IS_PAGE (tag_page), NULL);
      return tag_page->file;
    }

    void
    tag_page_set_file (TagPage         *tag_page,
                       ThunarxFileInfo *file)
    {
      g_return_if_fail (TAG_IS_PAGE (tag_page));
      g_return_if_fail (file == NULL || THUNARX_IS_FILE_INFO (file));

      if (tag_page->file != NULL)
        {
          g_signal_handlers_disconnect_by_func (tag_page->file, tag_page_file_changed, tag_page);
          g_object_unref (G_OBJECT (tag_page->file));
        }

      tag_page->file = file;

      if (file != NULL)
        {
          g_object_ref (file);
          tag_page_file_changed (file, tag_page);
          g_signal_connect (file, "changed", G_CALLBACK (tag_page_file_changed), tag_page);
        }

      g_object_notify (G_OBJECT (tag_page), "file");
    }

If this seems to be too complicated to you, just don't follow the suggestion. But keep in mind, that while the above solution is a little longer than a less structured solution, it yields great flexbility and maintainability. For example the TagPage class described above, once filled with user interface elements, may be used for a standalone MP3-Tag editor out of the box (i.e. as an action returned from the `thunarx_renamer_get_actions()` method).

What is important to remember is that you should connect to the `"changed"` signal of the ThunarxFileInfos you are displaying, and update the user interface whenever the file changes.

## Details

### ThunarxPropertyPage

    typedef struct _ThunarxPropertyPage ThunarxPropertyPage;

Base instance type for property pages.

### thunarx_property_page_new ()

    GtkWidget*          thunarx_property_page_new           (const gchar *label);

Allocates a new ThunarxPropertyPage widget and sets its label to the specified `label`. If `label` is `NULL`, the label is omitted.

`label` : | the text to use as the label of the page.
Returns : | the newly allocated ThunarxPropertyPage widget.

### thunarx_property_page_new_with_label_widget ()

    GtkWidget*          thunarx_property_page_new_with_label_widget
                                                            (GtkWidget *label_widget);

Allocates a new ThunarxPropertyPage widget and sets its label to the specified `label_widget`.

`label_widget` : | a GtkWidget, which should be used as label.
Returns : | the newly allocated ThunarxPropertyPage widget.

### thunarx_property_page_get_label ()

    const gchar*        thunarx_property_page_get_label     (ThunarxPropertyPage *property_page);

If the `property_page`'s label widget is a GtkLabel, returns the text in the label widget (the `property_page` will have a GtkLabel for the label widget if a non-`NULL` argument was passed to `thunarx_property_page_new()`).

`property_page` : | a ThunarxPropertyPage.
Returns : | the text in the label or `NULL` if there was no label widget or the label widget was not a GtkLabel. The returned string is owned by the `property_page` and must not be modified or freed.

### thunarx_property_page_set_label ()

    void                thunarx_property_page_set_label     (ThunarxPropertyPage *property_page,
                                                             const gchar *label);

Sets the text of the label. If `label` is `NULL`, the current label is removed.

`property_page` : | a ThunarxPropertyPage.
`label` : | the text to use as the label of the page.

### thunarx_property_page_get_label_widget ()

    GtkWidget*          thunarx_property_page_get_label_widget
                                                            (ThunarxPropertyPage *property_page);

Returns the label widget for the `property_page`. See `thunarx_property_page_set_label_widget()`.

`property_page` : | a ThunarxPropertyPage.
Returns : | the label widget or `NULL` if there is none.

### thunarx_property_page_set_label_widget ()

    void                thunarx_property_page_set_label_widget
                                                            (ThunarxPropertyPage *property_page,
                                                             GtkWidget *label_widget);

Sets the label widget for the `property_page`. This is the widget that will appear in the notebook header for the `property_page`.

`property_page` : | a ThunarxPropertyPage.
`label_widget` : | the new label widget.

## Property Details

### The `"label"` property

      "label"                    gchar*                : Read / Write

Text of the page's label.

Default value: NULL

### The `"label-widget"` property

      "label-widget"             GtkWidget*            : Read / Write

A widget to display in place of the usual page label.

## See Also

The description of the ThunarxPropertyPageProvider interface.