Thunar Extensions Reference Manual: ThunarxPropertyPage

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

## Stability Level

Stable, unless otherwise indicated

## Functions

GtkWidget * | thunarx_property_page_new ()
GtkWidget * | thunarx_property_page_new_with_label_widget ()
const gchar * | thunarx_property_page_get_label ()
void | thunarx_property_page_set_label ()
GtkWidget * | thunarx_property_page_get_label_widget ()
void | thunarx_property_page_set_label_widget ()

## Properties

gchar * | label | Read / Write
GtkWidget * | label-widget | Read / Write

## Types and Values

struct | ThunarxPropertyPage

## Object Hierarchy

        GObject
        ╰── GInitiallyUnowned
            ╰── GtkObject
                ╰── GtkWidget
                    ╰── GtkContainer
                        ╰── GtkBin
                            ╰── ThunarxPropertyPage

## Implemented Interfaces

ThunarxPropertyPage implements AtkImplementorIface and GtkBuildable.

## Includes

    #include <thunarx/thunarx.h>

## 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):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ##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;
    void             tag_page_register_type (ThunarxProviderPlugin *plugin);
    GtkWidget       *tag_page_new           (ThunarxFileInfo       *file) G_GNUC_MALLOC;
    ThunarxFileInfo *tag_page_get_file      (TagPage               *tag_page);
    void             tag_page_set_file      (TagPage               *tag_page,
                                             ThunarxFileInfo       *file);
    G_END_DECLS;
    ##endif /* !__TAG_PAGE_H__ */

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    ##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 <a class="link" href="ThunarxFileInfo.html" title="ThunarxFileInfo">ThunarxFileInfo</a> displayed by this <GTKDOCLINK HREF="TagPage">TagPage</GTKDOCLINK>.
       **/
      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.

## Functions

### 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.

#### Parameters

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` .

#### Parameters

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()`).

#### Parameters

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.

#### Parameters

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()`.

#### Parameters

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` .

#### Parameters

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

## Types and Values

### struct ThunarxPropertyPage

    struct ThunarxPropertyPage;

Base instance type for property pages.

## Property Details

### The `“label”` property

      “label”                    gchar *

Text of the page's label.

Flags: Read / Write

Default value: NULL

### The `“label-widget”` property

      “label-widget”             GtkWidget *

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

Flags: Read / Write

## See Also

The description of the ThunarxPropertyPageProvider interface.