MooEditWindowCheckActionFunc stuff
parent
87825a8f45
commit
8e0827e704
|
@ -39,6 +39,16 @@
|
||||||
#define LANG_ACTION_ID "LanguageMenu"
|
#define LANG_ACTION_ID "LanguageMenu"
|
||||||
#define STOP_ACTION_ID "StopJob"
|
#define STOP_ACTION_ID "StopJob"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *property;
|
||||||
|
MooEditWindowCheckActionFunc func;
|
||||||
|
gpointer data;
|
||||||
|
GDestroyNotify notify;
|
||||||
|
} ActionCheck;
|
||||||
|
|
||||||
|
static GHashTable *action_checks; /* char* -> GSList* */
|
||||||
|
static GSList *windows;
|
||||||
|
|
||||||
struct _MooEditWindowPrivate {
|
struct _MooEditWindowPrivate {
|
||||||
MooEditor *editor;
|
MooEditor *editor;
|
||||||
|
|
||||||
|
@ -72,95 +82,103 @@ static GtkTargetEntry dest_targets[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GObject *moo_edit_window_constructor (GType type,
|
static ActionCheck *action_check_new (const char *action_prop,
|
||||||
guint n_props,
|
MooEditWindowCheckActionFunc func,
|
||||||
GObjectConstructParam *props);
|
gpointer data,
|
||||||
static void moo_edit_window_finalize (GObject *object);
|
GDestroyNotify notify);
|
||||||
static void moo_edit_window_destroy (GtkObject *object);
|
static void action_check_free (ActionCheck *check);
|
||||||
|
static void action_checks_init (void);
|
||||||
|
static void moo_edit_window_check_actions (MooEditWindow *window);
|
||||||
|
|
||||||
static void moo_edit_window_set_property(GObject *object,
|
GObject *moo_edit_window_constructor (GType type,
|
||||||
guint prop_id,
|
guint n_props,
|
||||||
const GValue *value,
|
GObjectConstructParam *props);
|
||||||
GParamSpec *pspec);
|
static void moo_edit_window_finalize (GObject *object);
|
||||||
static void moo_edit_window_get_property(GObject *object,
|
static void moo_edit_window_destroy (GtkObject *object);
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
static void moo_edit_window_set_property (GObject *object,
|
||||||
GParamSpec *pspec);
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
static void moo_edit_window_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
|
||||||
static gboolean moo_edit_window_close (MooEditWindow *window);
|
static gboolean moo_edit_window_close (MooEditWindow *window);
|
||||||
|
|
||||||
static void setup_notebook (MooEditWindow *window);
|
static void setup_notebook (MooEditWindow *window);
|
||||||
static void update_window_title (MooEditWindow *window);
|
static void update_window_title (MooEditWindow *window);
|
||||||
|
|
||||||
static void notebook_switch_page (MooNotebook *notebook,
|
static void notebook_switch_page (MooNotebook *notebook,
|
||||||
guint page_num,
|
guint page_num,
|
||||||
MooEditWindow *window);
|
MooEditWindow *window);
|
||||||
static gboolean notebook_populate_popup (MooNotebook *notebook,
|
static gboolean notebook_populate_popup (MooNotebook *notebook,
|
||||||
GtkWidget *child,
|
GtkWidget *child,
|
||||||
GtkMenu *menu,
|
GtkMenu *menu,
|
||||||
MooEditWindow *window);
|
MooEditWindow *window);
|
||||||
|
|
||||||
static void proxy_boolean_property (MooEditWindow *window,
|
static void proxy_boolean_property (MooEditWindow *window,
|
||||||
GParamSpec *prop,
|
GParamSpec *prop,
|
||||||
MooEdit *doc);
|
MooEdit *doc);
|
||||||
static void edit_changed (MooEditWindow *window,
|
static void edit_changed (MooEditWindow *window,
|
||||||
MooEdit *doc);
|
MooEdit *doc);
|
||||||
static void edit_filename_changed (MooEditWindow *window,
|
static void edit_filename_changed (MooEditWindow *window,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
MooEdit *doc);
|
MooEdit *doc);
|
||||||
static void edit_lang_changed (MooEditWindow *window,
|
static void edit_lang_changed (MooEditWindow *window,
|
||||||
guint var_id,
|
guint var_id,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
MooEdit *doc);
|
MooEdit *doc);
|
||||||
static GtkWidget *create_tab_label (MooEditWindow *window,
|
static GtkWidget *create_tab_label (MooEditWindow *window,
|
||||||
MooEdit *edit);
|
MooEdit *edit);
|
||||||
static void update_tab_label (MooEditWindow *window,
|
static void update_tab_label (MooEditWindow *window,
|
||||||
MooEdit *doc);
|
MooEdit *doc);
|
||||||
static void edit_cursor_moved (MooEditWindow *window,
|
static void edit_cursor_moved (MooEditWindow *window,
|
||||||
GtkTextIter *iter,
|
GtkTextIter *iter,
|
||||||
MooEdit *edit);
|
MooEdit *edit);
|
||||||
static void update_lang_menu (MooEditWindow *window);
|
static void update_lang_menu (MooEditWindow *window);
|
||||||
|
|
||||||
static void create_statusbar (MooEditWindow *window);
|
static void create_statusbar (MooEditWindow *window);
|
||||||
static void update_statusbar (MooEditWindow *window);
|
static void update_statusbar (MooEditWindow *window);
|
||||||
static MooEdit *get_nth_tab (MooEditWindow *window,
|
static MooEdit *get_nth_tab (MooEditWindow *window,
|
||||||
guint n);
|
guint n);
|
||||||
static int get_page_num (MooEditWindow *window,
|
static int get_page_num (MooEditWindow *window,
|
||||||
MooEdit *doc);
|
MooEdit *doc);
|
||||||
|
|
||||||
static MooAction *create_lang_action (MooEditWindow *window);
|
static MooAction *create_lang_action (MooEditWindow *window);
|
||||||
|
|
||||||
static void create_paned (MooEditWindow *window);
|
static void create_paned (MooEditWindow *window);
|
||||||
static MooPaneParams *load_pane_params (const char *pane_id);
|
static MooPaneParams *load_pane_params (const char *pane_id);
|
||||||
static gboolean save_pane_params (const char *pane_id,
|
static gboolean save_pane_params (const char *pane_id,
|
||||||
MooPaneParams *params);
|
MooPaneParams *params);
|
||||||
static void pane_params_changed (MooEditWindow *window,
|
static void pane_params_changed (MooEditWindow *window,
|
||||||
MooPanePosition position,
|
MooPanePosition position,
|
||||||
guint index);
|
guint index);
|
||||||
static void pane_size_changed (MooEditWindow *window,
|
static void pane_size_changed (MooEditWindow *window,
|
||||||
MooPanePosition position);
|
MooPanePosition position);
|
||||||
|
|
||||||
static void notebook_drag_data_recv (GtkWidget *widget,
|
static void notebook_drag_data_recv (GtkWidget *widget,
|
||||||
GdkDragContext *context,
|
GdkDragContext *context,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
GtkSelectionData *data,
|
GtkSelectionData *data,
|
||||||
guint info,
|
guint info,
|
||||||
guint time,
|
guint time,
|
||||||
MooEditWindow *window);
|
MooEditWindow *window);
|
||||||
static gboolean notebook_drag_drop (GtkWidget *widget,
|
static gboolean notebook_drag_drop (GtkWidget *widget,
|
||||||
GdkDragContext *context,
|
GdkDragContext *context,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
guint time,
|
guint time,
|
||||||
MooEditWindow *window);
|
MooEditWindow *window);
|
||||||
static gboolean notebook_drag_motion (GtkWidget *widget,
|
static gboolean notebook_drag_motion (GtkWidget *widget,
|
||||||
GdkDragContext *context,
|
GdkDragContext *context,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
guint time,
|
guint time,
|
||||||
MooEditWindow *window);
|
MooEditWindow *window);
|
||||||
|
|
||||||
|
|
||||||
/* actions */
|
/* actions */
|
||||||
|
@ -218,12 +236,15 @@ static guint signals[NUM_SIGNALS];
|
||||||
g_param_spec_boolean (name, name, name, FALSE, G_PARAM_READABLE))
|
g_param_spec_boolean (name, name, name, FALSE, G_PARAM_READABLE))
|
||||||
|
|
||||||
|
|
||||||
static void moo_edit_window_class_init (MooEditWindowClass *klass)
|
static void
|
||||||
|
moo_edit_window_class_init (MooEditWindowClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
|
GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
|
||||||
MooWindowClass *window_class = MOO_WINDOW_CLASS (klass);
|
MooWindowClass *window_class = MOO_WINDOW_CLASS (klass);
|
||||||
|
|
||||||
|
action_checks_init ();
|
||||||
|
|
||||||
gobject_class->constructor = moo_edit_window_constructor;
|
gobject_class->constructor = moo_edit_window_constructor;
|
||||||
gobject_class->finalize = moo_edit_window_finalize;
|
gobject_class->finalize = moo_edit_window_finalize;
|
||||||
gobject_class->set_property = moo_edit_window_set_property;
|
gobject_class->set_property = moo_edit_window_set_property;
|
||||||
|
@ -634,6 +655,8 @@ moo_edit_window_init (MooEditWindow *window)
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
window->priv->use_fullname = TRUE;
|
window->priv->use_fullname = TRUE;
|
||||||
|
|
||||||
|
windows = g_slist_prepend (windows, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -665,6 +688,8 @@ moo_edit_window_destroy (GtkObject *object)
|
||||||
g_slist_free (list);
|
g_slist_free (list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
windows = g_slist_remove (windows, window);
|
||||||
|
|
||||||
GTK_OBJECT_CLASS(moo_edit_window_parent_class)->destroy (object);
|
GTK_OBJECT_CLASS(moo_edit_window_parent_class)->destroy (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,6 +1115,7 @@ static void notebook_switch_page (G_GNUC_UNUSED MooNotebook *notebook,
|
||||||
MooEditWindow *window)
|
MooEditWindow *window)
|
||||||
{
|
{
|
||||||
edit_changed (window, get_nth_tab (window, page_num));
|
edit_changed (window, get_nth_tab (window, page_num));
|
||||||
|
moo_edit_window_check_actions (window);
|
||||||
g_object_notify (G_OBJECT (window), "active-doc");
|
g_object_notify (G_OBJECT (window), "active-doc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2249,7 +2275,200 @@ edit_lang_changed (MooEditWindow *window,
|
||||||
MooEdit *doc)
|
MooEdit *doc)
|
||||||
{
|
{
|
||||||
if (doc == ACTIVE_DOC (window))
|
if (doc == ACTIVE_DOC (window))
|
||||||
|
{
|
||||||
update_lang_menu (window);
|
update_lang_menu (window);
|
||||||
|
moo_edit_window_check_actions (window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Action properties checks
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
moo_edit_window_check_action (MooEditWindow *window,
|
||||||
|
MooEdit *doc,
|
||||||
|
MooAction *action,
|
||||||
|
ActionCheck *check)
|
||||||
|
{
|
||||||
|
gpointer klass;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GValue value;
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (action);
|
||||||
|
pspec = g_object_class_find_property (klass, check->property);
|
||||||
|
g_return_if_fail (pspec != NULL);
|
||||||
|
|
||||||
|
value.g_type = 0;
|
||||||
|
g_value_init (&value, pspec->value_type);
|
||||||
|
|
||||||
|
check->func (action, doc, pspec, &value, check->data);
|
||||||
|
g_object_set_property (G_OBJECT (action), check->property, &value);
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_check_actions (const char *action_id,
|
||||||
|
GSList *checks,
|
||||||
|
MooEditWindow *window)
|
||||||
|
{
|
||||||
|
MooAction *action;
|
||||||
|
MooEdit *doc;
|
||||||
|
|
||||||
|
action = moo_window_get_action_by_id (MOO_WINDOW (window), action_id);
|
||||||
|
|
||||||
|
if (!action)
|
||||||
|
return;
|
||||||
|
|
||||||
|
doc = ACTIVE_DOC (window);
|
||||||
|
|
||||||
|
while (checks)
|
||||||
|
{
|
||||||
|
moo_edit_window_check_action (window, doc, action, checks->data);
|
||||||
|
checks = checks->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
moo_edit_window_check_actions (MooEditWindow *window)
|
||||||
|
{
|
||||||
|
g_message ("checking actions");
|
||||||
|
g_hash_table_foreach (action_checks,
|
||||||
|
(GHFunc) window_check_actions,
|
||||||
|
window);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_action (const char *action_id,
|
||||||
|
ActionCheck *check)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
for (l = windows; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
MooEditWindow *window = l->data;
|
||||||
|
MooEdit *doc = ACTIVE_DOC (window);
|
||||||
|
MooAction *action = moo_window_get_action_by_id (MOO_WINDOW (window), action_id);
|
||||||
|
if (action)
|
||||||
|
moo_edit_window_check_action (window, doc, action, check);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_and_prop_cmp (ActionCheck *check,
|
||||||
|
const char *prop)
|
||||||
|
{
|
||||||
|
return strcmp (check->property, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
moo_edit_window_add_action_check (const char *action_id,
|
||||||
|
const char *action_prop,
|
||||||
|
MooEditWindowCheckActionFunc func,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
ActionCheck *check;
|
||||||
|
GSList *list;
|
||||||
|
|
||||||
|
g_return_if_fail (action_id != NULL);
|
||||||
|
g_return_if_fail (action_prop != NULL);
|
||||||
|
g_return_if_fail (func != NULL);
|
||||||
|
|
||||||
|
action_checks_init ();
|
||||||
|
|
||||||
|
list = g_hash_table_lookup (action_checks, action_id);
|
||||||
|
|
||||||
|
if (list)
|
||||||
|
{
|
||||||
|
GSList *old = g_slist_find_custom (list, action_prop,
|
||||||
|
(GCompareFunc) check_and_prop_cmp);
|
||||||
|
|
||||||
|
if (old)
|
||||||
|
{
|
||||||
|
action_check_free (old->data);
|
||||||
|
list = g_slist_delete_link (list, old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check = action_check_new (action_prop, func, data, notify);
|
||||||
|
list = g_slist_prepend (list, check);
|
||||||
|
g_hash_table_insert (action_checks, g_strdup (action_id), list);
|
||||||
|
|
||||||
|
check_action (action_id, check);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
moo_edit_window_remove_action_check (const char *action_id,
|
||||||
|
const char *action_prop)
|
||||||
|
{
|
||||||
|
GSList *list;
|
||||||
|
|
||||||
|
g_return_if_fail (action_id != NULL);
|
||||||
|
g_return_if_fail (action_prop != NULL);
|
||||||
|
|
||||||
|
action_checks_init ();
|
||||||
|
|
||||||
|
list = g_hash_table_lookup (action_checks, action_id);
|
||||||
|
|
||||||
|
if (list)
|
||||||
|
{
|
||||||
|
GSList *old = g_slist_find_custom (list, action_prop,
|
||||||
|
(GCompareFunc) check_and_prop_cmp);
|
||||||
|
|
||||||
|
if (old)
|
||||||
|
{
|
||||||
|
action_check_free (old->data);
|
||||||
|
list = g_slist_delete_link (list, old);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!list)
|
||||||
|
g_hash_table_remove (action_checks, action_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ActionCheck *
|
||||||
|
action_check_new (const char *action_prop,
|
||||||
|
MooEditWindowCheckActionFunc func,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
ActionCheck *check = g_new0 (ActionCheck, 1);
|
||||||
|
check->property = g_strdup (action_prop);
|
||||||
|
check->func = func;
|
||||||
|
check->data = data;
|
||||||
|
check->notify = notify;
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
action_check_free (ActionCheck *check)
|
||||||
|
{
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
if (check->notify)
|
||||||
|
check->notify (check->data);
|
||||||
|
g_free (check->property);
|
||||||
|
g_free (check);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
action_checks_init (void)
|
||||||
|
{
|
||||||
|
if (!action_checks)
|
||||||
|
action_checks =
|
||||||
|
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,51 +55,65 @@ struct _MooEditWindowClass
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GType moo_edit_window_get_type (void) G_GNUC_CONST;
|
GType moo_edit_window_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
MooEdit *moo_edit_window_get_active_doc (MooEditWindow *window);
|
typedef void (*MooEditWindowCheckActionFunc) (MooAction *action,
|
||||||
void moo_edit_window_set_active_doc (MooEditWindow *window,
|
MooEdit *doc,
|
||||||
MooEdit *edit);
|
GParamSpec *pspec,
|
||||||
|
GValue *prop_value,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
GSList *moo_edit_window_list_docs (MooEditWindow *window);
|
void moo_edit_window_add_action_check (const char *action_id,
|
||||||
guint moo_edit_window_num_docs (MooEditWindow *window);
|
const char *action_prop,
|
||||||
|
MooEditWindowCheckActionFunc func,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
void moo_edit_window_remove_action_check (const char *action_id,
|
||||||
|
const char *action_prop);
|
||||||
|
|
||||||
void moo_edit_window_set_title_prefix (MooEditWindow *window,
|
MooEdit *moo_edit_window_get_active_doc (MooEditWindow *window);
|
||||||
const char *prefix);
|
void moo_edit_window_set_active_doc (MooEditWindow *window,
|
||||||
|
MooEdit *edit);
|
||||||
|
|
||||||
|
GSList *moo_edit_window_list_docs (MooEditWindow *window);
|
||||||
|
guint moo_edit_window_num_docs (MooEditWindow *window);
|
||||||
|
|
||||||
|
void moo_edit_window_set_title_prefix (MooEditWindow *window,
|
||||||
|
const char *prefix);
|
||||||
|
|
||||||
/* sinks widget */
|
/* sinks widget */
|
||||||
gboolean moo_edit_window_add_pane (MooEditWindow *window,
|
gboolean moo_edit_window_add_pane (MooEditWindow *window,
|
||||||
const char *user_id,
|
const char *user_id,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
MooPaneLabel *label,
|
MooPaneLabel *label,
|
||||||
MooPanePosition position);
|
MooPanePosition position);
|
||||||
gboolean moo_edit_window_remove_pane (MooEditWindow *window,
|
gboolean moo_edit_window_remove_pane (MooEditWindow *window,
|
||||||
const char *user_id);
|
const char *user_id);
|
||||||
GtkWidget *moo_edit_window_get_pane (MooEditWindow *window,
|
GtkWidget *moo_edit_window_get_pane (MooEditWindow *window,
|
||||||
const char *user_id);
|
const char *user_id);
|
||||||
|
|
||||||
|
|
||||||
typedef void (*MooAbortJobFunc) (gpointer job);
|
typedef void (*MooAbortJobFunc) (gpointer job);
|
||||||
|
|
||||||
void moo_edit_window_add_stop_client (MooEditWindow *window,
|
void moo_edit_window_add_stop_client (MooEditWindow *window,
|
||||||
gpointer client);
|
gpointer client);
|
||||||
void moo_edit_window_remove_stop_client (MooEditWindow *window,
|
void moo_edit_window_remove_stop_client (MooEditWindow *window,
|
||||||
gpointer client);
|
gpointer client);
|
||||||
void moo_edit_window_abort_jobs (MooEditWindow *window);
|
void moo_edit_window_abort_jobs (MooEditWindow *window);
|
||||||
void moo_edit_window_job_started (MooEditWindow *window,
|
void moo_edit_window_job_started (MooEditWindow *window,
|
||||||
const char *name,
|
const char *name,
|
||||||
MooAbortJobFunc func,
|
MooAbortJobFunc func,
|
||||||
gpointer job);
|
gpointer job);
|
||||||
void moo_edit_window_job_finished (MooEditWindow *window,
|
void moo_edit_window_job_finished (MooEditWindow *window,
|
||||||
gpointer job);
|
gpointer job);
|
||||||
|
|
||||||
void moo_edit_window_message (MooEditWindow *window,
|
void moo_edit_window_message (MooEditWindow *window,
|
||||||
const char *message);
|
const char *message);
|
||||||
guint moo_edit_window_push_message (MooEditWindow *window,
|
guint moo_edit_window_push_message (MooEditWindow *window,
|
||||||
const char *message,
|
const char *message,
|
||||||
const char *id);
|
const char *id);
|
||||||
void moo_edit_window_pop_message (MooEditWindow *window,
|
void moo_edit_window_pop_message (MooEditWindow *window,
|
||||||
const char *id);
|
const char *id);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
Loading…
Reference in New Issue