[dia/dia-next: 34/59] Use a seperate custom widget to pick sheets
- From: Zander <zbrown src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia/dia-next: 34/59] Use a seperate custom widget to pick sheets
- Date: Wed, 9 Jan 2019 18:37:09 +0000 (UTC)
commit c0f46e1d9ee86b1da36412b1f1f4f597883debbb
Author: Zander Brown <zbrown gnome org>
Date: Fri Dec 28 23:01:30 2018 +0000
Use a seperate custom widget to pick sheets
Sheet is now DiaSheet and is a GObject
app/Makefile.am | 8 +-
app/menus.c | 19 ---
app/sheets.h | 2 +-
app/sheets_dialog.c | 4 +-
app/sheets_dialog_callbacks.c | 4 +-
app/toolbox.c | 237 ++++++++++------------------------
app/toolbox.h | 5 +-
app/widgets/dia-sheet-chooser.c | 226 ++++++++++++++++++++++++++++++++
app/widgets/dia-sheet-chooser.h | 35 +++++
data/dia-sheet-chooser-popover.ui | 68 ++++++++++
lib/dia-line-style-selector-popover.c | 17 ---
lib/dia_dirs.c | 17 +++
lib/dia_dirs.h | 2 +
lib/diatypes.h | 1 -
lib/sheet.c | 46 ++++---
lib/sheet.h | 20 ++-
lib/widgets/dialist.c | 4 +-
plug-ins/python/pydia-sheet.c | 2 +-
plug-ins/python/pydia-sheet.h | 2 +-
19 files changed, 473 insertions(+), 246 deletions(-)
---
diff --git a/app/Makefile.am b/app/Makefile.am
index 8b474176..4d8f74c7 100644
--- a/app/Makefile.am
+++ b/app/Makefile.am
@@ -141,6 +141,8 @@ dia_core_files = \
handle_ops.h \
interface.c \
interface.h \
+ widgets/dia-sheet-chooser.c \
+ widgets/dia-sheet-chooser.h \
toolbox.c \
toolbox.h \
dia-app-icons.h \
@@ -172,12 +174,6 @@ dia_core_files = \
plugin-manager.h \
dia-props.c \
dia-props.h \
- gtkwrapbox.h \
- gtkwrapbox.c \
- gtkhwrapbox.h \
- gtkhwrapbox.c \
- gtkvwrapbox.h \
- gtkvwrapbox.c \
cursor.c \
cursor.h \
splash.c \
diff --git a/app/menus.c b/app/menus.c
index 01d1eb0b..cdf63f87 100644
--- a/app/menus.c
+++ b/app/menus.c
@@ -60,8 +60,6 @@ create_integrated_ui_toolbar (void);
static void add_plugin_actions (GtkUIManager *ui_manager, const char *base_path);
-gchar *build_ui_filename (const gchar* name);
-
/* Active/inactive state is set in diagram_update_menu_sensitivity()
* in diagram.c */
@@ -742,23 +740,6 @@ add_plugin_actions (GtkUIManager *ui_manager, const gchar *base_path)
}
}
-gchar*
-build_ui_filename (const gchar* name)
-{
- gchar* uifile;
-
- if (g_getenv ("DIA_BASE_PATH") != NULL) {
- /* a small hack cause the final destination and the local path differ */
- const gchar* p = strrchr (name, '/');
- if (p != NULL)
- name = p+1;
- uifile = g_build_filename (g_getenv ("DIA_BASE_PATH"), "data", name, NULL);
- } else
- uifile = dia_get_data_directory (name);
-
- return uifile;
-}
-
/*!
* Not sure why this service is not provided by GTK+.
* We are passing tooltips into the actions (especially recent file menu).
diff --git a/app/sheets.h b/app/sheets.h
index d0fc3b5b..d3d0b914 100644
--- a/app/sheets.h
+++ b/app/sheets.h
@@ -55,7 +55,7 @@ struct _SheetObjectMod
struct _SheetMod
{
- Sheet sheet;
+ DiaSheet sheet;
enum { SHEETMOD_TYPE_NORMAL,
SHEETMOD_TYPE_UNASSIGNED } type; /* reserved for future use */
diff --git a/app/sheets_dialog.c b/app/sheets_dialog.c
index e67378a5..865ecfee 100644
--- a/app/sheets_dialog.c
+++ b/app/sheets_dialog.c
@@ -47,6 +47,7 @@
#include "intl.h"
#include "persistence.h"
+#include "dia_dirs.h"
static void
sheets_dialog_destroyed (GtkWidget *widget, gpointer user_data)
@@ -57,9 +58,6 @@ sheets_dialog_destroyed (GtkWidget *widget, gpointer user_data)
g_object_set_data (G_OBJECT(widget), "_sheet_dialogs_builder", NULL);
}
-/* FIXME: header? */
-gchar *build_ui_filename (const gchar* name);
-
static GtkBuilder *
builder_new_from_file (const char *filename)
{
diff --git a/app/sheets_dialog_callbacks.c b/app/sheets_dialog_callbacks.c
index d079fbb2..a8f07b7a 100644
--- a/app/sheets_dialog_callbacks.c
+++ b/app/sheets_dialog_callbacks.c
@@ -865,7 +865,7 @@ on_sheets_new_dialog_button_ok_clicked (GtkButton *button,
entry = lookup_widget(sheets_new_dialog, "entry_sheet_description");
sheet_descrip = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
- sheet = g_new0(Sheet, 1);
+ sheet = g_object_new (DIA_TYPE_SHEET, NULL);
sheet->name = sheet_name;
sheet->filename = "";
sheet->description = sheet_descrip;
@@ -1797,7 +1797,7 @@ on_sheets_dialog_button_apply_clicked (GtkButton *button,
sheet_object_mods_list = sm->sheet.objects;
sm->sheet.objects = NULL;
/* we have to transfer 'permanent' memory */
- new_sheet = g_new0 (Sheet, 1);
+ new_sheet = g_object_new (DIA_TYPE_SHEET, NULL);
*new_sheet = sm->sheet;
register_sheet(new_sheet);
diff --git a/app/toolbox.c b/app/toolbox.c
index 2657aa09..50ab4df3 100644
--- a/app/toolbox.c
+++ b/app/toolbox.c
@@ -26,6 +26,7 @@
#include "sheet.h"
#include "dia-colour-area.h"
#include "dia-line-width-area.h"
+#include "widgets/dia-sheet-chooser.h"
#include "intl.h"
#include "message.h"
#include "object.h"
@@ -60,9 +61,6 @@ static GtkTargetEntry toolbox_target_table[] =
static guint toolbox_n_targets = (sizeof (toolbox_target_table) /
sizeof (toolbox_target_table[0]));
-static GtkWidget *sheet_option_menu;
-static GtkWidget *sheet_wbox;
-
GtkWidget *modify_tool_button;
gchar *interface_current_sheet_name;
static GSList *tool_group = NULL;
@@ -245,20 +243,15 @@ static void
fill_sheet_wbox (DiaToolbox *self, DiaSheet *sheet)
{
int i = 0;
- int rows;
GSList *tmp;
GtkWidget *first_button = NULL;
-
- gtk_container_foreach(GTK_CONTAINER(sheet_wbox),
- (GtkCallback)gtk_widget_destroy, NULL);
- tool_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(tool_widgets[0]));
+ gtk_container_foreach (GTK_CONTAINER (self->items),
+ (GtkCallback) gtk_widget_destroy, NULL);
+ tool_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (tool_widgets[0]));
/* Remember sheet 'name' for 'Sheets and Objects' dialog */
interface_current_sheet_name = sheet->name;
- /* set the aspect ratio on the wbox */
- rows = ceil(g_slist_length(sheet->objects) / (double)COLUMNS);
- if (rows<1) rows = 1;
for (tmp = sheet->objects; tmp != NULL; tmp = tmp->next) {
SheetObject *sheet_obj = tmp->data;
GdkPixbuf *pixbuf = NULL;
@@ -273,22 +266,22 @@ fill_sheet_wbox (DiaToolbox *self, DiaSheet *sheet)
pixbuf = gdk_pixbuf_new_from_file(sheet_obj->pixmap_file, &gerror);
if (pixbuf != NULL) {
- int width = gdk_pixbuf_get_width (pixbuf);
- int height = gdk_pixbuf_get_height (pixbuf);
- if (width > 22 && prefs.fixed_icon_size) {
- GdkPixbuf *cropped;
- g_warning ("Shape icon '%s' size wrong, cropped.", sheet_obj->pixmap_file);
- cropped = gdk_pixbuf_new_subpixbuf (pixbuf,
- (width - 22) / 2, height > 22 ? (height - 22) / 2 : 0,
- 22, height > 22 ? 22 : height);
- g_object_unref (pixbuf);
- pixbuf = cropped;
- }
+ int width = gdk_pixbuf_get_width (pixbuf);
+ int height = gdk_pixbuf_get_height (pixbuf);
+ if (width > 22 && prefs.fixed_icon_size) {
+ GdkPixbuf *cropped;
+ g_warning ("Shape icon '%s' size wrong, cropped.", sheet_obj->pixmap_file);
+ cropped = gdk_pixbuf_new_subpixbuf (pixbuf,
+ (width - 22) / 2, height > 22 ? (height - 22) / 2 : 0,
+ 22, height > 22 ? 22 : height);
+ g_object_unref (pixbuf);
+ pixbuf = cropped;
+ }
} else {
- pixbuf = gdk_pixbuf_new_from_xpm_data (missing);
+ pixbuf = gdk_pixbuf_new_from_xpm_data (missing);
- message_warning("failed to load icon for file\n %s\n cause=%s",
- sheet_obj->pixmap_file,gerror?gerror->message:"[NULL]");
+ message_warning("failed to load icon for file\n %s\n cause=%s",
+ sheet_obj->pixmap_file,gerror?gerror->message:"[NULL]");
}
} else {
DiaObjectType *type;
@@ -307,15 +300,13 @@ fill_sheet_wbox (DiaToolbox *self, DiaSheet *sheet)
tool_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
gtk_container_add (GTK_CONTAINER (button), image);
- gtk_widget_show(image);
-
- gtk_grid_attach (GTK_GRID (self->items), button, i % COLUMNS, i / COLUMNS, 1, 1);
- gtk_widget_show(button);
+ gtk_widget_show (image);
if (sheet_obj->line_break) {
- g_message ("Got a line break!");
- i += i % COLUMNS;
+ i += COLUMNS - (i % COLUMNS);
}
+ gtk_grid_attach (GTK_GRID (self->items), button, i % COLUMNS, i / COLUMNS, 1, 1);
+ gtk_widget_show (button);
data = g_new(ToolButtonData, 1);
data->type = CREATE_OBJECT_TOOL;
@@ -346,148 +337,59 @@ fill_sheet_wbox (DiaToolbox *self, DiaSheet *sheet)
}
static void
-sheet_option_menu_changed (GtkListBox *box,
- GtkListBoxRow *row,
- DiaToolbox *self)
-{
- char *string;
- DiaSheet *sheet;
-
- g_return_if_fail (DIA_IS_LIST_ITEM (row));
-
- string = dia_list_item_get_value (DIA_LIST_ITEM (row));
- sheet = get_sheet_by_name (string);
-
- if (sheet == NULL) {
- message_warning (_("No sheet named %s"), string);
- } else {
- persistence_set_string ("last-sheet-selected", string);
- fill_sheet_wbox (self, sheet);
- }
- g_free (string);
-}
-
-static int
-cmp_names (const void *a, const void *b)
-{
- return g_utf8_collate(gettext( (gchar *)a ), gettext( (gchar *)b ));
-}
-
-static GList *
-get_sheet_names()
-{
- GSList *tmp;
- GList *names = NULL;
- for (tmp = get_sheets_list(); tmp != NULL; tmp = tmp->next) {
- DiaSheet *sheet = tmp->data;
- names = g_list_append(names, sheet->name);
- }
- /* Already sorted in lib/ but here we sort by the localized (display-)name */
- return g_list_sort (names, cmp_names);
-}
-
-#define DIA_TYPE_SHEET_META (dia_sheet_meta_get_type ())
-G_DECLARE_FINAL_TYPE (DiaSheetMeta, dia_sheet_meta, DIA, SHEET_META, GObject)
-
-struct _DiaSheetMeta {
- GObject parent;
- gchar *name;
-};
-
-G_DEFINE_TYPE (DiaSheetMeta, dia_sheet_meta, G_TYPE_OBJECT)
-
-static void
-dia_sheet_meta_class_init (DiaSheetMetaClass *klass)
-{
-
-}
-
-static void
-dia_sheet_meta_init (DiaSheetMeta *self)
-{
-
-}
-
-static GtkWidget *
-render_row (gpointer item, gpointer user_data)
+sheet_selected (DiaSheetChooser *chooser,
+ DiaSheet *sheet,
+ DiaToolbox *self)
{
- GtkWidget *tmp = dia_list_item_new_with_label (DIA_SHEET_META (item)->name);
- gtk_widget_show_all (tmp);
- return tmp;
+ persistence_set_string ("last-sheet-selected", DIA_SHEET (sheet)->name);
+ fill_sheet_wbox (self, sheet);
}
static void
create_sheet_dropdown_menu (DiaToolbox *self)
{
- GListStore *sheets = g_list_store_new (DIA_TYPE_SHEET_META);
- GList *sheet_names = get_sheet_names();
- DiaSheetMeta *meta;
- GList *l;
- GtkWidget *popover;
- GtkWidget *frame;
- GtkWidget *wrap;
- GtkWidget *list;
-
- if (sheet_option_menu != NULL) {
- gtk_container_remove (GTK_CONTAINER (self), sheet_option_menu);
- sheet_option_menu = NULL;
- }
-
- meta = g_object_new (DIA_TYPE_SHEET_META, NULL);
- meta->name = "Assorted";
- g_list_store_append (sheets, meta);
-
- meta = g_object_new (DIA_TYPE_SHEET_META, NULL);
- meta->name = "Flowchart";
- g_list_store_append (sheets, meta);
-
- meta = g_object_new (DIA_TYPE_SHEET_META, NULL);
- meta->name = "UML";
- g_list_store_append (sheets, meta);
-
- for (l = sheet_names; l != NULL; l = l->next) {
- meta = g_object_new (DIA_TYPE_SHEET_META, NULL);
- meta->name = l->data;
- g_list_store_append (sheets, meta);
+ GSList *sheets = get_sheets_list();
+ GSList *l;
+ GtkWidget *button;
+ DiaSheet *tmp;
+
+ self->sheets = g_list_store_new (DIA_TYPE_SHEET);
+
+ /* TODO: Handle this & translations better */
+ tmp = get_sheet_by_name ("Assorted");
+ g_object_set_data (G_OBJECT (tmp), "dia-list-top", GINT_TO_POINTER (TRUE));
+ g_list_store_append (self->sheets, tmp);
+ tmp = get_sheet_by_name ("Flowchart");
+ g_object_set_data (G_OBJECT (tmp), "dia-list-top", GINT_TO_POINTER (TRUE));
+ g_list_store_append (self->sheets, tmp);
+ tmp = get_sheet_by_name ("UML");
+ g_object_set_data (G_OBJECT (tmp), "dia-list-top", GINT_TO_POINTER (TRUE));
+ g_list_store_append (self->sheets, tmp);
+
+ for (l = sheets; l != NULL; l = l->next) {
+ if (g_strcmp0 (DIA_SHEET (l->data)->name, "Assorted") == 0 ||
+ g_strcmp0 (DIA_SHEET (l->data)->name, "Flowchart") == 0 ||
+ g_strcmp0 (DIA_SHEET (l->data)->name, "UML") == 0) {
+ continue;
+ }
+ g_list_store_append (self->sheets, DIA_SHEET (l->data));
}
- popover = gtk_popover_new (NULL);
- frame = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (popover), frame);
- wrap = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
- "min-content-width", 200,
- "min-content-height", 200,
- NULL);
- gtk_container_add (GTK_CONTAINER (frame), wrap);
- list = gtk_list_box_new ();
- gtk_container_add (GTK_CONTAINER (wrap), list);
- gtk_widget_show_all (frame);
-
- gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_SINGLE);
- gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (sheets), render_row, NULL, NULL);
-
- // TODO: Display selected, Show recent on top, Persistance
- sheet_option_menu = gtk_menu_button_new ();
- gtk_menu_button_set_popover (GTK_MENU_BUTTON (sheet_option_menu), popover);
-
- g_signal_connect (G_OBJECT (list), "row-selected",
- G_CALLBACK(sheet_option_menu_changed), self);
- gtk_box_pack_start (GTK_BOX (self), sheet_option_menu, FALSE, FALSE, 0);
- gtk_widget_show(sheet_option_menu);
+ button = dia_sheet_chooser_new ();
+ g_signal_connect (G_OBJECT (button), "sheet-selected",
+ G_CALLBACK (sheet_selected), self);
+ dia_sheet_chooser_set_model (DIA_SHEET_CHOOSER (button), G_LIST_MODEL (self->sheets));
+ gtk_box_pack_start (GTK_BOX (self), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
}
static void
create_sheets (DiaToolbox *self)
{
- GtkWidget *separator;
GtkWidget *swin;
gchar *sheetname;
DiaSheet *sheet;
- separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_start (GTK_BOX (self), separator, FALSE, FALSE, 0);
- gtk_widget_show (separator);
-
create_sheet_dropdown_menu (self);
swin = gtk_scrolled_window_new (NULL, NULL);
@@ -498,24 +400,20 @@ create_sheets (DiaToolbox *self)
gtk_box_pack_start (GTK_BOX (self), swin, FALSE, FALSE, 0);
gtk_widget_show (swin);
- self->items = gtk_grid_new ();
+ self->items = g_object_new (GTK_TYPE_GRID,
+ "column-homogeneous", TRUE,
+ "column-spacing", 4,
+ "row-spacing", 4,
+ NULL);
gtk_container_add (GTK_CONTAINER (swin), self->items);
gtk_widget_show (self->items);
sheetname = persistence_register_string ("last-sheet-selected", _("Flowchart"));
sheet = get_sheet_by_name (sheetname);
- if (sheet == NULL) {
- /* Couldn't find it */
- } else {
+ if (sheet != NULL) {
fill_sheet_wbox (self, sheet);
- /* TODO: dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
- sheetname); */
}
g_free (sheetname);
-
- separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_end (GTK_BOX (self), separator, FALSE, FALSE, 0);
- gtk_widget_show (separator);
}
static void
@@ -789,8 +687,11 @@ dia_toolbox_class_init (DiaToolboxClass *class)
static void
dia_toolbox_init (DiaToolbox *self)
{
- gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
- gtk_box_set_spacing (GTK_BOX (self), 9);
+ g_object_set (G_OBJECT (self),
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "spacing", 8,
+ "margin", 8,
+ NULL);
gtk_widget_show (GTK_WIDGET (self));
create_tools (self);
diff --git a/app/toolbox.h b/app/toolbox.h
index 1b6bf966..60c1f600 100644
--- a/app/toolbox.h
+++ b/app/toolbox.h
@@ -8,8 +8,9 @@ G_DECLARE_FINAL_TYPE (DiaToolbox, dia_toolbox, DIA, TOOLBOX, GtkBox)
struct _DiaToolbox {
GtkBox parent;
- GtkWidget *tools;
- GtkWidget *items;
+ GtkWidget *tools;
+ GtkWidget *items;
+ GListStore *sheets;
};
typedef struct _ToolButton ToolButton;
diff --git a/app/widgets/dia-sheet-chooser.c b/app/widgets/dia-sheet-chooser.c
new file mode 100644
index 00000000..d28739b9
--- /dev/null
+++ b/app/widgets/dia-sheet-chooser.c
@@ -0,0 +1,226 @@
+#include <gtk/gtk.h>
+
+#include "dia-sheet-chooser.h"
+#include "dia_dirs.h"
+
+G_DEFINE_TYPE (DiaSheetChooserPopover, dia_sheet_chooser_popover, GTK_TYPE_POPOVER)
+
+enum {
+ SHEET_SELECTED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+static guint popover_signals[LAST_SIGNAL] = { 0 };
+
+static void
+dia_sheet_chooser_popover_class_init (DiaSheetChooserPopoverClass *klass)
+{
+ GFile *template_file;
+ GBytes *template;
+ GError *err = NULL;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ popover_signals[SHEET_SELECTED] = g_signal_new ("sheet-selected",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ DIA_TYPE_SHEET);
+
+ /* TODO: Use GResource */
+ template_file = g_file_new_for_path (build_ui_filename ("ui/dia-sheet-chooser-popover.ui"));
+ template = g_file_load_bytes (template_file, NULL, NULL, &err);
+
+ if (err)
+ g_critical ("Failed to load template: %s", err->message);
+
+ gtk_widget_class_set_template (widget_class, template);
+ gtk_widget_class_bind_template_child (widget_class, DiaSheetChooserPopover, list);
+ gtk_widget_class_bind_template_child (widget_class, DiaSheetChooserPopover, filter);
+
+ g_object_unref (template_file);
+}
+
+static GtkWidget *
+render_row (gpointer item, gpointer user_data)
+{
+ GtkWidget *row;
+ GtkWidget *box;
+ GtkWidget *name;
+ GtkWidget *desc;
+
+ row = gtk_list_box_row_new ();
+ /* TODO: Let's avoid the trap of set_data */
+ g_object_set_data (G_OBJECT (row), "dia-sheet", item);
+ g_object_set_data (G_OBJECT (row),
+ "dia-list-top",
+ g_object_get_data (G_OBJECT (item), "dia-list-top"));
+ gtk_widget_set_tooltip_markup (row,
+ g_strdup_printf ("<b>%s</b>\n%s",
+ DIA_SHEET (item)->name,
+ DIA_SHEET (item)->description));
+ gtk_widget_show (row);
+
+ box = g_object_new (GTK_TYPE_BOX,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "spacing", 2,
+ "margin", 4,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (row), box);
+ gtk_widget_show (box);
+
+ name = g_object_new (GTK_TYPE_LABEL,
+ "label", DIA_SHEET (item)->name,
+ "xalign", 0.0,
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ "max-width-chars", 25,
+ NULL);
+ gtk_widget_show (name);
+ gtk_box_pack_start (GTK_BOX (box), name, FALSE, FALSE, 0);
+
+ desc = g_object_new (GTK_TYPE_LABEL,
+ "label", DIA_SHEET (item)->description,
+ "xalign", 0.0,
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ "max-width-chars", 25,
+ NULL);
+ gtk_style_context_add_class (gtk_widget_get_style_context (desc),
+ GTK_STYLE_CLASS_DIM_LABEL);
+ gtk_widget_show (desc);
+ gtk_box_pack_start (GTK_BOX (box), desc, FALSE, FALSE, 0);
+
+ return row;
+}
+
+static void
+header_func (GtkListBoxRow *row,
+ GtkListBoxRow *before,
+ gpointer user_data)
+{
+ gboolean last = FALSE;
+ gboolean this = FALSE;
+
+ if (before)
+ last = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (before), "dia-list-top"));
+ this = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "dia-list-top"));
+
+ if (last && !this) {
+ GtkWidget *sep = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_widget_show (sep);
+ gtk_list_box_row_set_header (row, sep);
+ }
+}
+
+static void
+sheet_selected (GtkListBox *box,
+ GtkListBoxRow *row,
+ DiaSheetChooserPopover *self)
+{
+ DiaSheet *sheet = g_object_get_data (G_OBJECT (row), "dia-sheet");
+
+ g_signal_emit_by_name (G_OBJECT (self), "sheet-selected", sheet);
+}
+
+static void
+sheet_activated (GtkListBox *box,
+ GtkListBoxRow *row,
+ DiaSheetChooserPopover *self)
+{
+ gtk_popover_popdown (GTK_POPOVER (self));
+}
+
+static void
+dia_sheet_chooser_popover_init (DiaSheetChooserPopover *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ gtk_list_box_set_header_func (GTK_LIST_BOX (self->list),
+ header_func, NULL, NULL);
+
+ g_signal_connect (G_OBJECT (self->list), "row-selected",
+ G_CALLBACK (sheet_selected), self);
+ g_signal_connect (G_OBJECT (self->list), "row-activated",
+ G_CALLBACK (sheet_activated), self);
+}
+
+void
+dia_sheet_chooser_popover_set_model (DiaSheetChooserPopover *self,
+ GListModel *model)
+{
+ gtk_list_box_bind_model (GTK_LIST_BOX (self->list),
+ G_LIST_MODEL (model),
+ render_row, NULL, NULL);
+}
+
+GtkWidget *
+dia_sheet_chooser_popover_new ()
+{
+ return g_object_new (DIA_TYPE_SHEET_CHOOSER_POPOVER, NULL);
+}
+
+G_DEFINE_TYPE (DiaSheetChooser, dia_sheet_chooser, GTK_TYPE_MENU_BUTTON)
+
+static void
+propagate (DiaSheetChooserPopover *chooser,
+ DiaSheet *sheet,
+ DiaSheetChooser *self)
+{
+ gtk_label_set_label (GTK_LABEL (self->label), sheet->name);
+
+ g_signal_emit_by_name (G_OBJECT (self), "sheet-selected", sheet);
+}
+
+static void
+dia_sheet_chooser_class_init (DiaSheetChooserClass *klass)
+{
+ signals[SHEET_SELECTED] = g_signal_new ("sheet-selected",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ DIA_TYPE_SHEET);
+}
+
+static void
+dia_sheet_chooser_init (DiaSheetChooser *self)
+{
+ GtkWidget *box;
+ GtkWidget *arrow;
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 16);
+ gtk_widget_show (box);
+ gtk_container_add (GTK_CONTAINER (self), box);
+
+ self->label = g_object_new (GTK_TYPE_LABEL,
+ "label", "[NONE]",
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ "max-width-chars", 14,
+ "xalign", 0.0,
+ NULL);
+ gtk_widget_show (self->label);
+ gtk_box_pack_start (GTK_BOX (box), self->label, TRUE, TRUE, 0);
+
+ arrow = gtk_image_new_from_icon_name ("pan-down-symbolic", GTK_ICON_SIZE_BUTTON);
+ gtk_widget_show (arrow);
+ gtk_box_pack_end (GTK_BOX (box), arrow, FALSE, FALSE, 0);
+
+ self->popover = dia_sheet_chooser_popover_new ();
+ g_signal_connect (G_OBJECT (self->popover), "sheet-selected",
+ G_CALLBACK (propagate), self);
+ gtk_menu_button_set_popover (GTK_MENU_BUTTON (self), self->popover);
+}
+
+void
+dia_sheet_chooser_set_model (DiaSheetChooser *self,
+ GListModel *model)
+{
+ dia_sheet_chooser_popover_set_model (DIA_SHEET_CHOOSER_POPOVER (self->popover),
+ model);
+}
+
+GtkWidget *
+dia_sheet_chooser_new ()
+{
+ return g_object_new (DIA_TYPE_SHEET_CHOOSER, NULL);
+}
diff --git a/app/widgets/dia-sheet-chooser.h b/app/widgets/dia-sheet-chooser.h
new file mode 100644
index 00000000..a37c0116
--- /dev/null
+++ b/app/widgets/dia-sheet-chooser.h
@@ -0,0 +1,35 @@
+#include <gtk/gtk.h>
+
+#include "sheet.h"
+
+G_BEGIN_DECLS
+
+#define DIA_TYPE_SHEET_CHOOSER_POPOVER (dia_sheet_chooser_popover_get_type ())
+G_DECLARE_FINAL_TYPE (DiaSheetChooserPopover, dia_sheet_chooser_popover, DIA, SHEET_CHOOSER_POPOVER,
GtkPopover)
+
+struct _DiaSheetChooserPopover {
+ GtkPopover parent;
+
+ GtkWidget *filter;
+ GtkWidget *list;
+};
+
+void dia_sheet_chooser_popover_set_model (DiaSheetChooserPopover *self,
+ GListModel *model);
+
+
+#define DIA_TYPE_SHEET_CHOOSER (dia_sheet_chooser_get_type ())
+G_DECLARE_FINAL_TYPE (DiaSheetChooser, dia_sheet_chooser, DIA, SHEET_CHOOSER, GtkMenuButton)
+
+struct _DiaSheetChooser {
+ GtkMenuButton parent;
+
+ GtkWidget *label;
+ GtkWidget *popover;
+};
+
+GtkWidget *dia_sheet_chooser_new ();
+void dia_sheet_chooser_set_model (DiaSheetChooser *self,
+ GListModel *model);
+
+G_END_DECLS
\ No newline at end of file
diff --git a/data/dia-sheet-chooser-popover.ui b/data/dia-sheet-chooser-popover.ui
new file mode 100644
index 00000000..0317086b
--- /dev/null
+++ b/data/dia-sheet-chooser-popover.ui
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+ <template class="DiaSheetChooserPopover" parent="GtkPopover">
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">8</property>
+ <property name="margin_right">8</property>
+ <property name="margin_top">8</property>
+ <property name="margin_bottom">8</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkSearchEntry" id="filter">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="primary_icon_name">edit-find-symbolic</property>
+ <property name="primary_icon_activatable">False</property>
+ <property name="primary_icon_sensitive">False</property>
+ <property name="secondary_icon_tooltip_text" translatable="yes">TODO: Add filter</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">etched-in</property>
+ <property name="min_content_width">200</property>
+ <property name="min_content_height">200</property>
+ <property name="max_content_width">300</property>
+ <property name="max_content_height">300</property>
+ <property name="propagate_natural_width">True</property>
+ <property name="propagate_natural_height">True</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkListBox" id="list">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/lib/dia-line-style-selector-popover.c b/lib/dia-line-style-selector-popover.c
index a04cb049..3e0d153c 100644
--- a/lib/dia-line-style-selector-popover.c
+++ b/lib/dia-line-style-selector-popover.c
@@ -23,23 +23,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-static gchar*
-build_ui_filename (const gchar* name)
-{
- gchar* uifile;
-
- if (g_getenv ("DIA_BASE_PATH") != NULL) {
- /* a small hack cause the final destination and the local path differ */
- const gchar* p = strrchr (name, '/');
- if (p != NULL)
- name = p+1;
- uifile = g_build_filename (g_getenv ("DIA_BASE_PATH"), "data", name, NULL);
- } else
- uifile = dia_get_data_directory (name);
-
- return uifile;
-}
-
GtkWidget *
dia_line_style_selector_popover_new ()
{
diff --git a/lib/dia_dirs.c b/lib/dia_dirs.c
index 99e8590c..65abe8ef 100644
--- a/lib/dia_dirs.c
+++ b/lib/dia_dirs.c
@@ -367,3 +367,20 @@ dia_absolutize_filename (const gchar *master, const gchar *slave)
g_free (path);
return result;
}
+
+gchar*
+build_ui_filename (const gchar* name)
+{
+ gchar* uifile;
+
+ if (g_getenv ("DIA_BASE_PATH") != NULL) {
+ /* a small hack cause the final destination and the local path differ */
+ const gchar* p = strrchr (name, '/');
+ if (p != NULL)
+ name = p+1;
+ uifile = g_build_filename (g_getenv ("DIA_BASE_PATH"), "data", name, NULL);
+ } else
+ uifile = dia_get_data_directory (name);
+
+ return uifile;
+}
diff --git a/lib/dia_dirs.h b/lib/dia_dirs.h
index c0cbff05..52c01bd4 100644
--- a/lib/dia_dirs.h
+++ b/lib/dia_dirs.h
@@ -38,4 +38,6 @@ gchar *dia_absolutize_filename (const gchar *master, const gchar *slave);
gchar *dia_get_canonical_path (const gchar *path);
const gchar *dia_message_filename (const gchar *filename);
+gchar *build_ui_filename (const gchar* name);
+
#endif /* DIA_DIRS_H */
diff --git a/lib/diatypes.h b/lib/diatypes.h
index 64ed4f80..4ae01b69 100644
--- a/lib/diatypes.h
+++ b/lib/diatypes.h
@@ -157,7 +157,6 @@ typedef struct _PropDescSArrayExtra PropDescSArrayExtra;
typedef struct _PropOffset PropOffset;
/* In sheet.h: */
-typedef struct _Sheet Sheet;
typedef struct _SheetObject SheetObject;
/* In text.h: */
diff --git a/lib/sheet.c b/lib/sheet.c
index 698b750f..378c535c 100644
--- a/lib/sheet.c
+++ b/lib/sheet.c
@@ -41,15 +41,29 @@
#include "object-alias.h"
#include "dia_dirs.h"
+G_DEFINE_TYPE (DiaSheet, dia_sheet, G_TYPE_OBJECT)
+
static GSList *sheets = NULL;
-Sheet *
-new_sheet(char *name, gchar *description, char *filename, SheetScope scope,
- Sheet *shadowing)
+static void
+dia_sheet_class_init (DiaSheetClass *klass)
+{
+
+}
+
+static void
+dia_sheet_init (DiaSheet *self)
+{
+
+}
+
+DiaSheet *
+dia_sheet_new (char *name, gchar *description, char *filename, SheetScope scope,
+ DiaSheet *shadowing)
{
- Sheet *sheet;
+ DiaSheet *sheet;
- sheet = g_new(Sheet, 1);
+ sheet = g_object_new (DIA_TYPE_SHEET, NULL);
sheet->name = g_strdup(name);
sheet->description = g_strdup(description);
@@ -62,7 +76,7 @@ new_sheet(char *name, gchar *description, char *filename, SheetScope scope,
}
void
-sheet_prepend_sheet_obj(Sheet *sheet, SheetObject *obj)
+sheet_prepend_sheet_obj(DiaSheet *sheet, SheetObject *obj)
{
DiaObjectType *type;
@@ -77,7 +91,7 @@ sheet_prepend_sheet_obj(Sheet *sheet, SheetObject *obj)
}
void
-sheet_append_sheet_obj(Sheet *sheet, SheetObject *obj)
+sheet_append_sheet_obj(DiaSheet *sheet, SheetObject *obj)
{
DiaObjectType *type;
@@ -92,7 +106,7 @@ sheet_append_sheet_obj(Sheet *sheet, SheetObject *obj)
}
void
-register_sheet(Sheet *sheet)
+register_sheet(DiaSheet *sheet)
{
sheets = g_slist_append(sheets, (gpointer) sheet);
}
@@ -114,8 +128,8 @@ static void load_register_sheet(const gchar *directory,const gchar *filename,
static gint
dia_sheet_sort_callback(gconstpointer a, gconstpointer b)
{
- return g_utf8_collate(gettext( ((Sheet *)(a))->name ),
- gettext( ((Sheet *)(b))->name ));
+ return g_utf8_collate(gettext( ((DiaSheet *)(a))->name ),
+ gettext( ((DiaSheet *)(b))->name ));
}
void
@@ -205,12 +219,12 @@ load_register_sheet(const gchar *dirname, const gchar *filename,
gchar *name = NULL, *description = NULL;
int name_score = -1;
int descr_score = -1;
- Sheet *sheet = NULL;
+ DiaSheet *sheet = NULL;
GSList *sheetp;
gboolean set_line_break = FALSE;
gboolean name_is_gmalloced = FALSE;
- Sheet *shadowing = NULL;
- Sheet *shadowing_sheet = NULL;
+ DiaSheet *shadowing = NULL;
+ DiaSheet *shadowing_sheet = NULL;
/* the XML fun begins here. */
@@ -302,12 +316,12 @@ load_register_sheet(const gchar *dirname, const gchar *filename,
sheetp = get_sheets_list();
while (sheetp)
{
- if (sheetp->data && !strcmp(((Sheet *)(sheetp->data))->name, name))
+ if (sheetp->data && !strcmp(((DiaSheet *)(sheetp->data))->name, name))
{
struct stat first_file, this_file;
int stat_ret;
- stat_ret = g_stat(((Sheet *)(sheetp->data))->filename, &first_file);
+ stat_ret = g_stat(((DiaSheet *)(sheetp->data))->filename, &first_file);
g_assert(!stat_ret);
stat_ret = g_stat(filename, &this_file);
@@ -340,7 +354,7 @@ load_register_sheet(const gchar *dirname, const gchar *filename,
sheetp = g_slist_next(sheetp);
}
- sheet = new_sheet(name, description, g_strdup(filename), scope, shadowing);
+ sheet = dia_sheet_new(name, description, g_strdup(filename), scope, shadowing);
if (shadowing_sheet)
shadowing_sheet->shadowing = sheet; /* Hilarious :-) */
diff --git a/lib/sheet.h b/lib/sheet.h
index 2c47aed0..8b9b2405 100644
--- a/lib/sheet.h
+++ b/lib/sheet.h
@@ -19,6 +19,7 @@
#define SHEET_H
#include <glib.h>
+#include <glib-object.h>
#include "diatypes.h"
@@ -43,13 +44,18 @@ typedef enum
}
SheetScope;
-struct _Sheet {
+#define DIA_TYPE_SHEET (dia_sheet_get_type ())
+G_DECLARE_FINAL_TYPE (DiaSheet, dia_sheet, DIA, SHEET, GObject)
+
+struct _DiaSheet {
+ GObject parent;
+
char *name;
char *description;
char *filename;
SheetScope scope;
- Sheet *shadowing; /* If (scope == USER), the system sheet that this
+ DiaSheet *shadowing; /* If (scope == USER), the system sheet that this
user sheet is shadowing.
If (scope == SYSTEM), there has been a name
collision between a system sheet and a user
@@ -60,11 +66,11 @@ struct _Sheet {
GSList *objects; /* list of SheetObject */
};
-Sheet *new_sheet(char *name, char *description, char *filename,
- SheetScope scope, Sheet *shadowing);
-void sheet_prepend_sheet_obj(Sheet *sheet, SheetObject *type);
-void sheet_append_sheet_obj(Sheet *sheet, SheetObject *type);
-void register_sheet(Sheet *sheet);
+DiaSheet *dia_sheet_new (char *name, char *description, char *filename,
+ SheetScope scope, DiaSheet *shadowing);
+void sheet_prepend_sheet_obj(DiaSheet *sheet, SheetObject *type);
+void sheet_append_sheet_obj(DiaSheet *sheet, SheetObject *type);
+void register_sheet(DiaSheet *sheet);
GSList *get_sheets_list(void);
void load_all_sheets(void);
diff --git a/lib/widgets/dialist.c b/lib/widgets/dialist.c
index 6383ec68..05396893 100644
--- a/lib/widgets/dialist.c
+++ b/lib/widgets/dialist.c
@@ -514,7 +514,7 @@ dia_list_item_get_value (DiaListItem* self)
g_return_val_if_fail (self != NULL, NULL);
label = ((DiaListItemPrivate *) dia_list_item_get_instance_private (self))->label;
- result = gtk_label_get_label (GTK_LABEL (label));
+ result = g_strdup (gtk_label_get_label (GTK_LABEL (label)));
return result;
}
@@ -528,7 +528,7 @@ dia_list_item_set_value (DiaListItem* self,
g_return_if_fail (self != NULL);
label = ((DiaListItemPrivate *) dia_list_item_get_instance_private (self))->label;
- gtk_label_set_label (GTK_LABEL (label), value);
+ gtk_label_set_label (GTK_LABEL (label), g_strdup (value));
g_object_notify_by_pspec ((GObject *) self, dia_list_item_properties[DIA_LIST_ITEM_VALUE_PROPERTY]);
}
diff --git a/plug-ins/python/pydia-sheet.c b/plug-ins/python/pydia-sheet.c
index 91f3414a..ef877ecc 100644
--- a/plug-ins/python/pydia-sheet.c
+++ b/plug-ins/python/pydia-sheet.c
@@ -25,7 +25,7 @@
#include <structmember.h> /* PyMemberDef */
PyObject *
-PyDiaSheet_New(Sheet *sheet)
+PyDiaSheet_New(DiaSheet *sheet)
{
PyDiaSheet *self;
diff --git a/plug-ins/python/pydia-sheet.h b/plug-ins/python/pydia-sheet.h
index 84addc76..5b811605 100644
--- a/plug-ins/python/pydia-sheet.h
+++ b/plug-ins/python/pydia-sheet.h
@@ -6,7 +6,7 @@
typedef struct {
PyObject_HEAD
- Sheet *sheet;
+ DiaSheet *sheet;
} PyDiaSheet;
extern PyTypeObject PyDiaSheet_Type;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]