From 981e8dcdfe704169b2c4a7b86c1dacdaafeee5df Mon Sep 17 00:00:00 2001 From: Ell Date: Mon, 18 Dec 2017 18:54:17 -0500 Subject: [PATCH] app, menus, icons: add dashboard dockable The dashboard dockable shows the current GEGL cache and swap sizes, and their recent history. It has options to control the update rate and history duration of the data, and an option to warn (by raising/blinking the dialog) when the swap size approaches its limit. --- app/actions/Makefile.am | 4 + app/actions/actions.c | 4 + app/actions/dashboard-actions.c | 193 +++++ app/actions/dashboard-actions.h | 27 + app/actions/dashboard-commands.c | 74 ++ app/actions/dashboard-commands.h | 33 + app/actions/dialogs-actions.c | 6 + app/dialogs/dialogs-constructors.c | 11 + app/dialogs/dialogs-constructors.h | 4 + app/dialogs/dialogs.c | 4 + app/menus/menus.c | 8 + app/widgets/Makefile.am | 2 + app/widgets/gimpdashboard.c | 818 +++++++++++++++++++++ app/widgets/gimpdashboard.h | 90 +++ app/widgets/gimphelp-ids.h | 5 + app/widgets/widgets-enums.h | 18 + app/widgets/widgets-types.h | 1 + icons/Color/16/gimp-dashboard.png | Bin 0 -> 603 bytes icons/Color/24/gimp-dashboard.png | Bin 0 -> 833 bytes icons/Color/color-scalable.svg | 48 +- icons/Color/scalable/gimp-dashboard.svg | 155 ++++ icons/Symbolic/16/gimp-dashboard.png | Bin 0 -> 513 bytes icons/Symbolic/24/gimp-dashboard.png | Bin 0 -> 641 bytes icons/Symbolic/scalable/gimp-dashboard.svg | 102 +++ icons/Symbolic/symbolic-scalable.svg | 462 ++++++------ icons/icon-list.mk | 3 + libgimpwidgets/gimpicons.h | 1 + menus/Makefile.am | 1 + menus/dashboard-menu.xml | 23 + menus/dialogs-menuitems.xml | 1 + po/POTFILES.in | 2 + 31 files changed, 1874 insertions(+), 226 deletions(-) create mode 100644 app/actions/dashboard-actions.c create mode 100644 app/actions/dashboard-actions.h create mode 100644 app/actions/dashboard-commands.c create mode 100644 app/actions/dashboard-commands.h create mode 100644 app/widgets/gimpdashboard.c create mode 100644 app/widgets/gimpdashboard.h create mode 100644 icons/Color/16/gimp-dashboard.png create mode 100644 icons/Color/24/gimp-dashboard.png create mode 100644 icons/Color/scalable/gimp-dashboard.svg create mode 100644 icons/Symbolic/16/gimp-dashboard.png create mode 100644 icons/Symbolic/24/gimp-dashboard.png create mode 100644 icons/Symbolic/scalable/gimp-dashboard.svg create mode 100644 menus/dashboard-menu.xml diff --git a/app/actions/Makefile.am b/app/actions/Makefile.am index 3613fbb11a..8b5eb8c95b 100644 --- a/app/actions/Makefile.am +++ b/app/actions/Makefile.am @@ -44,6 +44,10 @@ libappactions_a_SOURCES = \ cursor-info-actions.h \ cursor-info-commands.c \ cursor-info-commands.h \ + dashboard-actions.c \ + dashboard-actions.h \ + dashboard-commands.c \ + dashboard-commands.h \ data-commands.c \ data-commands.h \ data-editor-commands.c \ diff --git a/app/actions/actions.c b/app/actions/actions.c index ecae6d541a..22bee0a6a3 100644 --- a/app/actions/actions.c +++ b/app/actions/actions.c @@ -57,6 +57,7 @@ #include "colormap-actions.h" #include "context-actions.h" #include "cursor-info-actions.h" +#include "dashboard-actions.h" #include "debug-actions.h" #include "dialogs-actions.h" #include "dock-actions.h" @@ -128,6 +129,9 @@ static const GimpActionFactoryEntry action_groups[] = { "cursor-info", N_("Pointer Information"), NULL, cursor_info_actions_setup, cursor_info_actions_update }, + { "dashboard", N_("Dashboard"), GIMP_ICON_DIALOG_DASHBOARD, + dashboard_actions_setup, + dashboard_actions_update }, { "debug", N_("Debug"), NULL, debug_actions_setup, debug_actions_update }, diff --git a/app/actions/dashboard-actions.c b/app/actions/dashboard-actions.c new file mode 100644 index 0000000000..73449e537a --- /dev/null +++ b/app/actions/dashboard-actions.c @@ -0,0 +1,193 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "actions-types.h" + +#include "widgets/gimpactiongroup.h" +#include "widgets/gimpdashboard.h" +#include "widgets/gimphelp-ids.h" + +#include "dashboard-actions.h" +#include "dashboard-commands.h" + +#include "gimp-intl.h" + + +static const GimpActionEntry dashboard_actions[] = +{ + { "dashboard-popup", GIMP_ICON_DIALOG_DASHBOARD, + NC_("dashboard-action", "Dashboard Menu"), NULL, NULL, NULL, + GIMP_HELP_DASHBOARD_DIALOG }, + + { "dashboard-update-interval", NULL, + NC_("dashboard-action", "Update Interval") }, + { "dashboard-history-duration", NULL, + NC_("dashboard-action", "History Duration") } +}; + +static const GimpToggleActionEntry dashboard_toggle_actions[] = +{ + { "dashboard-low-swap-space-warning", NULL, + NC_("dashboard-action", "Low Swap Space Warning"), NULL, + N_("Raise the dashboard when the swap size approaches its limit"), + G_CALLBACK (dashboard_low_swap_space_warning_cmd_callback), + FALSE, + GIMP_HELP_DASHBOARD_LOW_SWAP_SPACE_WARNING } +}; + +static const GimpRadioActionEntry dashboard_update_interval_actions[] = +{ + { "dashboard-update-interval-0-25-sec", NULL, + NC_("dashboard-update-interval", "0.25 Seconds"), NULL, NULL, + GIMP_DASHBOARD_UPDATE_INTERVAL_0_25_SEC, + GIMP_HELP_DASHBOARD_UPDATE_INTERVAL }, + + { "dashboard-update-interval-0-5-sec", NULL, + NC_("dashboard-update-interval", "0.5 Seconds"), NULL, NULL, + GIMP_DASHBOARD_UPDATE_INTERVAL_0_5_SEC, + GIMP_HELP_DASHBOARD_UPDATE_INTERVAL }, + + { "dashboard-update-interval-1-sec", NULL, + NC_("dashboard-update-interval", "1 Second"), NULL, NULL, + GIMP_DASHBOARD_UPDATE_INTERVAL_1_SEC, + GIMP_HELP_DASHBOARD_UPDATE_INTERVAL }, + + { "dashboard-update-interval-2-sec", NULL, + NC_("dashboard-update-interval", "2 Seconds"), NULL, NULL, + GIMP_DASHBOARD_UPDATE_INTERVAL_2_SEC, + GIMP_HELP_DASHBOARD_UPDATE_INTERVAL }, + + { "dashboard-update-interval-4-sec", NULL, + NC_("dashboard-update-interval", "4 Seconds"), NULL, NULL, + GIMP_DASHBOARD_UPDATE_INTERVAL_4_SEC, + GIMP_HELP_DASHBOARD_UPDATE_INTERVAL } +}; + +static const GimpRadioActionEntry dashboard_history_duration_actions[] = +{ + { "dashboard-history-duration-15-sec", NULL, + NC_("dashboard-history-duration", "15 Seconds"), NULL, NULL, + GIMP_DASHBOARD_HISTORY_DURATION_15_SEC, + GIMP_HELP_DASHBOARD_HISTORY_DURATION }, + + { "dashboard-history-duration-30-sec", NULL, + NC_("dashboard-history-duration", "30 Seconds"), NULL, NULL, + GIMP_DASHBOARD_HISTORY_DURATION_30_SEC, + GIMP_HELP_DASHBOARD_HISTORY_DURATION }, + + { "dashboard-history-duration-60-sec", NULL, + NC_("dashboard-history-duration", "60 Seconds"), NULL, NULL, + GIMP_DASHBOARD_HISTORY_DURATION_60_SEC, + GIMP_HELP_DASHBOARD_HISTORY_DURATION }, + + { "dashboard-history-duration-120-sec", NULL, + NC_("dashboard-history-duration", "120 Seconds"), NULL, NULL, + GIMP_DASHBOARD_HISTORY_DURATION_120_SEC, + GIMP_HELP_DASHBOARD_HISTORY_DURATION }, + + { "dashboard-history-duration-240-sec", NULL, + NC_("dashboard-history-duration", "240 Seconds"), NULL, NULL, + GIMP_DASHBOARD_HISTORY_DURATION_240_SEC, + GIMP_HELP_DASHBOARD_HISTORY_DURATION } +}; + + +void +dashboard_actions_setup (GimpActionGroup *group) +{ + gimp_action_group_add_actions (group, "dashboard-action", + dashboard_actions, + G_N_ELEMENTS (dashboard_actions)); + + gimp_action_group_add_toggle_actions (group, "dashboard-action", + dashboard_toggle_actions, + G_N_ELEMENTS (dashboard_toggle_actions)); + + gimp_action_group_add_radio_actions (group, "dashboard-update-interval", + dashboard_update_interval_actions, + G_N_ELEMENTS (dashboard_update_interval_actions), + NULL, + 0, + G_CALLBACK (dashboard_update_interval_cmd_callback)); + + gimp_action_group_add_radio_actions (group, "dashboard-history-duration", + dashboard_history_duration_actions, + G_N_ELEMENTS (dashboard_history_duration_actions), + NULL, + 0, + G_CALLBACK (dashboard_history_duration_cmd_callback)); +} + +void +dashboard_actions_update (GimpActionGroup *group, + gpointer data) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (data); + +#define SET_ACTIVE(action,condition) \ + gimp_action_group_set_action_active (group, action, (condition) != 0) + + switch (dashboard->update_interval) + { + case GIMP_DASHBOARD_UPDATE_INTERVAL_0_25_SEC: + SET_ACTIVE ("dashboard-update-interval-0-25-sec", TRUE); + break; + case GIMP_DASHBOARD_UPDATE_INTERVAL_0_5_SEC: + SET_ACTIVE ("dashboard-update-interval-0-5-sec", TRUE); + break; + case GIMP_DASHBOARD_UPDATE_INTERVAL_1_SEC: + SET_ACTIVE ("dashboard-update-interval-1-sec", TRUE); + break; + case GIMP_DASHBOARD_UPDATE_INTERVAL_2_SEC: + SET_ACTIVE ("dashboard-update-interval-2-sec", TRUE); + break; + case GIMP_DASHBOARD_UPDATE_INTERVAL_4_SEC: + SET_ACTIVE ("dashboard-update-interval-4-sec", TRUE); + break; + } + + switch (dashboard->history_duration) + { + case GIMP_DASHBOARD_HISTORY_DURATION_15_SEC: + SET_ACTIVE ("dashboard-history-duration-15-sec", TRUE); + break; + case GIMP_DASHBOARD_HISTORY_DURATION_30_SEC: + SET_ACTIVE ("dashboard-history-duration-30-sec", TRUE); + break; + case GIMP_DASHBOARD_HISTORY_DURATION_60_SEC: + SET_ACTIVE ("dashboard-history-duration-60-sec", TRUE); + break; + case GIMP_DASHBOARD_HISTORY_DURATION_120_SEC: + SET_ACTIVE ("dashboard-history-duration-120-sec", TRUE); + break; + case GIMP_DASHBOARD_HISTORY_DURATION_240_SEC: + SET_ACTIVE ("dashboard-history-duration-240-sec", TRUE); + break; + } + + SET_ACTIVE ("dashboard-low-swap-space-warning", + dashboard->low_swap_space_warning); + +#undef SET_ACTIVE +} diff --git a/app/actions/dashboard-actions.h b/app/actions/dashboard-actions.h new file mode 100644 index 0000000000..08b7a4166e --- /dev/null +++ b/app/actions/dashboard-actions.h @@ -0,0 +1,27 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DASHBOARD_ACTIONS_H__ +#define __DASHBOARD_ACTIONS_H__ + + +void dashboard_actions_setup (GimpActionGroup *group); +void dashboard_actions_update (GimpActionGroup *group, + gpointer data); + + +#endif /* __DASHBOARD_ACTIONS_H__ */ diff --git a/app/actions/dashboard-commands.c b/app/actions/dashboard-commands.c new file mode 100644 index 0000000000..c7b110b780 --- /dev/null +++ b/app/actions/dashboard-commands.c @@ -0,0 +1,74 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "actions-types.h" + +#include "widgets/gimpdashboard.h" +#include "widgets/gimphelp-ids.h" + +#include "dashboard-commands.h" + +#include "gimp-intl.h" + + +/* public functionss */ + + +void +dashboard_update_interval_cmd_callback (GtkAction *action, + GtkAction *current, + gpointer data) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (data); + GimpDashboardUpdateInteval update_interval; + + update_interval = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); + + gimp_dashboard_set_update_interval (dashboard, update_interval); +} + +void +dashboard_history_duration_cmd_callback (GtkAction *action, + GtkAction *current, + gpointer data) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (data); + GimpDashboardHistoryDuration history_duration; + + history_duration = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); + + gimp_dashboard_set_history_duration (dashboard, history_duration); +} + +void +dashboard_low_swap_space_warning_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (data); + gboolean low_swap_space_warning; + + low_swap_space_warning = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + + gimp_dashboard_set_low_swap_space_warning (dashboard, low_swap_space_warning); +} diff --git a/app/actions/dashboard-commands.h b/app/actions/dashboard-commands.h new file mode 100644 index 0000000000..4314a144f1 --- /dev/null +++ b/app/actions/dashboard-commands.h @@ -0,0 +1,33 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DASHBOARD_COMMANDS_H__ +#define __DASHBOARD_COMMANDS_H__ + + +void dashboard_update_interval_cmd_callback (GtkAction *action, + GtkAction *current, + gpointer data); +void dashboard_history_duration_cmd_callback (GtkAction *action, + GtkAction *current, + gpointer data); + +void dashboard_low_swap_space_warning_cmd_callback (GtkAction *action, + gpointer data); + + +#endif /* __DASHBOARD_COMMANDS_H__ */ diff --git a/app/actions/dialogs-actions.c b/app/actions/dialogs-actions.c index 08aa4264ed..8c573dc9d2 100644 --- a/app/actions/dialogs-actions.c +++ b/app/actions/dialogs-actions.c @@ -233,6 +233,12 @@ const GimpStringActionEntry dialogs_dockable_actions[] = NC_("dialogs-action", "Error Co_nsole"), NULL, NC_("dialogs-action", "Open the error console"), "gimp-error-console", + GIMP_HELP_ERRORS_DIALOG }, + + { "dialogs-dashboard", GIMP_ICON_DIALOG_DASHBOARD, + NC_("dialogs-action", "_Dashboard"), NULL, + NC_("dialogs-action", "Open the dashboard"), + "gimp-dashboard", GIMP_HELP_ERRORS_DIALOG } }; diff --git a/app/dialogs/dialogs-constructors.c b/app/dialogs/dialogs-constructors.c index 7a659284d0..7ef92fe973 100644 --- a/app/dialogs/dialogs-constructors.c +++ b/app/dialogs/dialogs-constructors.c @@ -35,6 +35,7 @@ #include "widgets/gimpchanneltreeview.h" #include "widgets/gimpcoloreditor.h" #include "widgets/gimpcolormapeditor.h" +#include "widgets/gimpdashboard.h" #include "widgets/gimpdevicestatus.h" #include "widgets/gimpdialogfactory.h" #include "widgets/gimpdockwindow.h" @@ -344,6 +345,16 @@ dialogs_cursor_view_new (GimpDialogFactory *factory, return gimp_cursor_view_new (gimp_dialog_factory_get_menu_factory (factory)); } +GtkWidget * +dialogs_dashboard_new (GimpDialogFactory *factory, + GimpContext *context, + GimpUIManager *ui_manager, + gint view_size) +{ + return gimp_dashboard_new (context->gimp, + gimp_dialog_factory_get_menu_factory (factory)); +} + /***** list views *****/ diff --git a/app/dialogs/dialogs-constructors.h b/app/dialogs/dialogs-constructors.h index 496725c578..bcdfbedcc6 100644 --- a/app/dialogs/dialogs-constructors.h +++ b/app/dialogs/dialogs-constructors.h @@ -125,6 +125,10 @@ GtkWidget * dialogs_cursor_view_new (GimpDialogFactory *factory, GimpContext *context, GimpUIManager *ui_manager, gint view_size); +GtkWidget * dialogs_dashboard_new (GimpDialogFactory *factory, + GimpContext *context, + GimpUIManager *ui_manager, + gint view_size); GtkWidget * dialogs_image_list_view_new (GimpDialogFactory *factory, GimpContext *context, diff --git a/app/dialogs/dialogs.c b/app/dialogs/dialogs.c index 8a4ed321b0..d817d741be 100644 --- a/app/dialogs/dialogs.c +++ b/app/dialogs/dialogs.c @@ -320,6 +320,10 @@ static const GimpDialogFactoryEntry entries[] = N_("Pointer"), N_("Pointer Information"), GIMP_ICON_CURSOR, GIMP_HELP_POINTER_INFO_DIALOG, dialogs_cursor_view_new, 0, TRUE), + DOCKABLE ("gimp-dashboard", + N_("Dashboard"), N_("Dashboard"), GIMP_ICON_DIALOG_DASHBOARD, + GIMP_HELP_ERRORS_DIALOG, + dialogs_dashboard_new, 0, TRUE), /* list & grid views */ LISTGRID (image, image, diff --git a/app/menus/menus.c b/app/menus/menus.c index fff8b3cfbd..2c7ff98e31 100644 --- a/app/menus/menus.c +++ b/app/menus/menus.c @@ -387,6 +387,14 @@ menus_init (Gimp *gimp, "sample-points-menu.xml", NULL, NULL); + + gimp_menu_factory_manager_register (global_menu_factory, "", + "dashboard", + NULL, + "/dashboard-popup", + "dashboard-menu.xml", + NULL, + NULL); } void diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am index 6501bda556..bb6546ce43 100644 --- a/app/widgets/Makefile.am +++ b/app/widgets/Makefile.am @@ -120,6 +120,8 @@ libappwidgets_a_sources = \ gimpcursor.h \ gimpcurveview.c \ gimpcurveview.h \ + gimpdashboard.c \ + gimpdashboard.h \ gimpdasheditor.c \ gimpdasheditor.h \ gimpdataeditor.c \ diff --git a/app/widgets/gimpdashboard.c b/app/widgets/gimpdashboard.c new file mode 100644 index 0000000000..bea895f039 --- /dev/null +++ b/app/widgets/gimpdashboard.c @@ -0,0 +1,818 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis + * + * gimpdashboard.c + * Copyright (C) 2017 Ell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include + +#include +#include +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpmath/gimpmath.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "widgets-types.h" + +#include "core/gimp.h" + +#include "gimpdocked.h" +#include "gimpdashboard.h" +#include "gimpdialogfactory.h" +#include "gimpmeter.h" +#include "gimpsessioninfo-aux.h" +#include "gimpwindowstrategy.h" + +#include "gimp-intl.h" + + +#define DEFAULT_UPDATE_INTERVAL GIMP_DASHBOARD_UPDATE_INTERVAL_0_25_SEC +#define DEFAULT_HISTORY_DURATION GIMP_DASHBOARD_HISTORY_DURATION_60_SEC +#define DEFAULT_LOW_SWAP_SPACE_WARNING TRUE + +#define LOW_SWAP_SPACE_WARNING_ON /* swap occupied is above */ 0.90 /* times swap limit */ +#define LOW_SWAP_SPACE_WARNING_OFF /* swap occupied is below */ 0.85 /* times swap limit */ + +#define CACHE_OCCUPIED_COLOR {0.3, 0.6, 0.3, 1.0} +#define SWAP_OCCUPIED_COLOR {0.8, 0.2, 0.2, 1.0} +#define SWAP_SIZE_COLOR {0.8, 0.6, 0.4, 1.0} + + +static void gimp_dashboard_docked_iface_init (GimpDockedInterface *iface); + +static void gimp_dashboard_finalize (GObject *object); + +static void gimp_dashboard_map (GtkWidget *widget); +static void gimp_dashboard_unmap (GtkWidget *widget); + +static void gimp_dashboard_set_aux_info (GimpDocked *docked, + GList *aux_info); +static GList * gimp_dashboard_get_aux_info (GimpDocked *docked); + +static gboolean gimp_dashboard_update (GimpDashboard *dashboard); +static gboolean gimp_dashboard_low_swap_space (GimpDashboard *dashboard); +static gpointer gimp_dashboard_sample (GimpDashboard *dashboard); + +static void gimp_dashboard_label_set_text (GtkLabel *label, + const gchar *text); +static void gimp_dashboard_label_set_size (GtkLabel *label, + guint64 size, + guint64 limit); + +static guint64 gimp_dashboard_get_swap_limit (guint64 swap_size); + + +G_DEFINE_TYPE_WITH_CODE (GimpDashboard, gimp_dashboard, GIMP_TYPE_EDITOR, + G_IMPLEMENT_INTERFACE (GIMP_TYPE_DOCKED, + gimp_dashboard_docked_iface_init)) + +#define parent_class gimp_dashboard_parent_class + +static GimpDockedInterface *parent_docked_iface = NULL; + + +/* private functions */ + + +static void +gimp_dashboard_class_init (GimpDashboardClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = gimp_dashboard_finalize; + + widget_class->map = gimp_dashboard_map; + widget_class->unmap = gimp_dashboard_unmap; +} + +static void +gimp_dashboard_init (GimpDashboard *dashboard) +{ + GtkWidget *box; + GtkWidget *vbox; + GtkWidget *frame; + GtkWidget *table; + GtkWidget *meter; + GtkWidget *label; + gint content_spacing; + + dashboard->update_interval = DEFAULT_UPDATE_INTERVAL; + dashboard->history_duration = DEFAULT_HISTORY_DURATION; + dashboard->low_swap_space_warning = DEFAULT_LOW_SWAP_SPACE_WARNING; + + gtk_widget_style_get (GTK_WIDGET (dashboard), + "content-spacing", &content_spacing, + NULL); + + /* we put the dashboard inside an event box, so that it gets its own window, + * which reduces the overhead of updating the ui, since it gets updated + * frequently. unfortunately, this means that the dashboard's background + * color may be a bit off for some themes. + */ + box = dashboard->box = gtk_event_box_new (); + gtk_box_pack_start (GTK_BOX (dashboard), box, TRUE, TRUE, 0); + gtk_widget_show (box); + + /* main vbox */ + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2 * content_spacing); + gtk_container_add (GTK_CONTAINER (box), vbox); + gtk_widget_show (vbox); + + + /* cache frame */ + frame = gimp_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + /* cache frame label */ + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_frame_set_label_widget (GTK_FRAME (frame), box); + gtk_widget_show (box); + + label = gtk_label_new (_("Cache")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gimp_label_set_attributes (GTK_LABEL (label), + PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, + -1); + gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + /* cache table */ + table = gtk_table_new (3, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), content_spacing); + gtk_table_set_col_spacings (GTK_TABLE (table), 4); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + /* cache meter */ + meter = dashboard->cache_meter = gimp_meter_new (1); + gimp_meter_set_color (GIMP_METER (meter), + 0, &(GimpRGB) CACHE_OCCUPIED_COLOR); + gimp_meter_set_history_resolution (GIMP_METER (meter), + dashboard->update_interval / 1000.0); + gimp_meter_set_history_duration (GIMP_METER (meter), + dashboard->history_duration / 1000.0); + gtk_table_attach (GTK_TABLE (table), meter, 0, 2, 0, 1, + GTK_EXPAND | GTK_FILL, 0, 1, 0); + gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2 * content_spacing); + gtk_widget_show (meter); + + /* cache occupied field */ + label = gtk_label_new (_("Occupied:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, + GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + label = dashboard->cache_occupied_label = gtk_label_new (_("N/A")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2, + GTK_EXPAND | GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + /* cache limit field */ + label = gtk_label_new (_("Limit:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, + GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + label = dashboard->cache_limit_label = gtk_label_new (_("N/A")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, 2, 3, + GTK_EXPAND | GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + + /* swap frame */ + frame = gimp_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + /* swap frame label */ + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_frame_set_label_widget (GTK_FRAME (frame), box); + gtk_widget_show (box); + + label = gtk_label_new (_("Swap")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gimp_label_set_attributes (GTK_LABEL (label), + PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, + -1); + gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + /* swap table */ + table = gtk_table_new (4, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), content_spacing); + gtk_table_set_col_spacings (GTK_TABLE (table), 4); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + /* swap meter */ + meter = dashboard->swap_meter = gimp_meter_new (2); + gimp_meter_set_color (GIMP_METER (meter), + 0, &(GimpRGB) SWAP_SIZE_COLOR); + gimp_meter_set_color (GIMP_METER (meter), + 1, &(GimpRGB) SWAP_OCCUPIED_COLOR); + gimp_meter_set_history_resolution (GIMP_METER (meter), + dashboard->update_interval / 1000.0); + gimp_meter_set_history_duration (GIMP_METER (meter), + dashboard->history_duration / 1000.0); + gimp_meter_set_led_color (GIMP_METER (meter), + &(GimpRGB) {0.8, 0.4, 0.4, 1.0}); + gtk_table_attach (GTK_TABLE (table), meter, 0, 2, 0, 1, + GTK_EXPAND | GTK_FILL, 0, 1, 0); + gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2 * content_spacing); + gtk_widget_show (meter); + + /* swap occupied field */ + label = gtk_label_new (_("Occupied:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, + GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + label = dashboard->swap_occupied_label = gtk_label_new (_("N/A")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2, + GTK_EXPAND | GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + /* swap size field */ + label = gtk_label_new (_("Size:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, + GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + label = dashboard->swap_size_label = gtk_label_new (_("N/A")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, 2, 3, + GTK_EXPAND | GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + /* swap limit field */ + label = gtk_label_new (_("Limit:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, + GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + label = dashboard->swap_limit_label = gtk_label_new (_("N/A")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, 3, 4, + GTK_EXPAND | GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + + /* sampler thread */ + g_mutex_init (&dashboard->mutex); + g_cond_init (&dashboard->cond); + + /* we use a separate thread for sampling, so that data is sampled even when + * the main thread is busy + */ + dashboard->thread = g_thread_new ("dashboard", + (GThreadFunc) gimp_dashboard_sample, + dashboard); +} + +static void +gimp_dashboard_docked_iface_init (GimpDockedInterface *iface) +{ + parent_docked_iface = g_type_interface_peek_parent (iface); + + if (! parent_docked_iface) + parent_docked_iface = g_type_default_interface_peek (GIMP_TYPE_DOCKED); + + iface->set_aux_info = gimp_dashboard_set_aux_info; + iface->get_aux_info = gimp_dashboard_get_aux_info; +} + +static void +gimp_dashboard_finalize (GObject *object) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (object); + + if (dashboard->timeout_id) + { + g_source_remove (dashboard->timeout_id); + dashboard->timeout_id = 0; + } + + if (dashboard->low_swap_space_idle_id) + { + g_source_remove (dashboard->low_swap_space_idle_id); + dashboard->low_swap_space_idle_id = 0; + } + + if (dashboard->thread) + { + g_mutex_lock (&dashboard->mutex); + + dashboard->quit = TRUE; + g_cond_signal (&dashboard->cond); + + g_mutex_unlock (&dashboard->mutex); + + g_clear_pointer (&dashboard->thread, g_thread_join); + } + + g_mutex_clear (&dashboard->mutex); + g_cond_clear (&dashboard->cond); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_dashboard_map (GtkWidget *widget) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (widget); + + GTK_WIDGET_CLASS (parent_class)->map (widget); + + if (! dashboard->timeout_id) + { + dashboard->timeout_id = g_timeout_add (dashboard->update_interval, + (GSourceFunc) gimp_dashboard_update, + dashboard); + } +} + +static void +gimp_dashboard_unmap (GtkWidget *widget) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (widget); + + if (dashboard->timeout_id) + { + g_source_remove (dashboard->timeout_id); + dashboard->timeout_id = 0; + } + + GTK_WIDGET_CLASS (parent_class)->unmap (widget); +} + +#define AUX_INFO_UPDATE_INTERVAL "update-interval" +#define AUX_INFO_HISTORY_DURATION "history-duration" +#define AUX_INFO_LOW_SWAP_SPACE_WARNING "low-swap-space-warning" + +static void +gimp_dashboard_set_aux_info (GimpDocked *docked, + GList *aux_info) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (docked); + GList *list; + + parent_docked_iface->set_aux_info (docked, aux_info); + + for (list = aux_info; list; list = g_list_next (list)) + { + GimpSessionInfoAux *aux = list->data; + + if (! strcmp (aux->name, AUX_INFO_UPDATE_INTERVAL)) + { + gint value = atoi (aux->value); + GimpDashboardUpdateInteval update_interval; + + for (update_interval = GIMP_DASHBOARD_UPDATE_INTERVAL_0_25_SEC; + update_interval < value && + update_interval < GIMP_DASHBOARD_UPDATE_INTERVAL_4_SEC; + update_interval *= 2); + + gimp_dashboard_set_update_interval (dashboard, update_interval); + } + else if (! strcmp (aux->name, AUX_INFO_HISTORY_DURATION)) + { + gint value = atoi (aux->value); + GimpDashboardHistoryDuration history_duration; + + for (history_duration = GIMP_DASHBOARD_HISTORY_DURATION_15_SEC; + history_duration < value && + history_duration < GIMP_DASHBOARD_HISTORY_DURATION_240_SEC; + history_duration *= 2); + + gimp_dashboard_set_history_duration (dashboard, history_duration); + } + else if (! strcmp (aux->name, AUX_INFO_LOW_SWAP_SPACE_WARNING)) + { + gimp_dashboard_set_low_swap_space_warning (dashboard, + ! strcmp (aux->value, "yes")); + } + } +} + +static GList * +gimp_dashboard_get_aux_info (GimpDocked *docked) +{ + GimpDashboard *dashboard = GIMP_DASHBOARD (docked); + GList *aux_info; + GimpSessionInfoAux *aux; + gchar *value; + + aux_info = parent_docked_iface->get_aux_info (docked); + + value = g_strdup_printf ("%d", dashboard->update_interval); + aux = gimp_session_info_aux_new (AUX_INFO_UPDATE_INTERVAL, value); + aux_info = g_list_append (aux_info, aux); + g_free (value); + + value = g_strdup_printf ("%d", dashboard->history_duration); + aux = gimp_session_info_aux_new (AUX_INFO_HISTORY_DURATION, value); + aux_info = g_list_append (aux_info, aux); + g_free (value); + + value = dashboard->low_swap_space_warning ? "yes" : "no"; + aux = gimp_session_info_aux_new (AUX_INFO_LOW_SWAP_SPACE_WARNING, value); + aux_info = g_list_append (aux_info, aux); + + return aux_info; +} + +static gboolean +gimp_dashboard_update (GimpDashboard *dashboard) +{ + /* cache */ + { + guint64 cache_occupied; + guint64 cache_limit; + + g_object_get (gegl_stats (), + "tile-cache-total", &cache_occupied, + NULL); + g_object_get (gegl_config (), + "tile-cache-size", &cache_limit, + NULL); + + gimp_meter_set_range (GIMP_METER (dashboard->cache_meter), + 0.0, cache_limit); + + gimp_dashboard_label_set_size (GTK_LABEL (dashboard->cache_occupied_label), + cache_occupied, cache_limit); + gimp_dashboard_label_set_size (GTK_LABEL (dashboard->cache_limit_label), + cache_limit, 0); + } + + /* swap */ + { + guint64 swap_occupied; + guint64 swap_size; + guint64 swap_limit; + gboolean swap_busy; + + g_mutex_lock (&dashboard->mutex); + + g_object_get (gegl_stats (), + "swap-total", &swap_occupied, + "swap-file-size", &swap_size, + "swap-busy", &swap_busy, + NULL); + swap_limit = gimp_dashboard_get_swap_limit (swap_size); + + g_mutex_unlock (&dashboard->mutex); + + gimp_meter_set_range (GIMP_METER (dashboard->swap_meter), + 0.0, swap_limit ? swap_limit : swap_size); + gimp_meter_set_led_visible (GIMP_METER (dashboard->swap_meter), swap_busy); + + gimp_dashboard_label_set_size (GTK_LABEL (dashboard->swap_occupied_label), + swap_occupied, swap_limit); + gimp_dashboard_label_set_size (GTK_LABEL (dashboard->swap_size_label), + swap_size, swap_limit); + + if (swap_limit) + { + gimp_dashboard_label_set_size (GTK_LABEL (dashboard->swap_limit_label), + swap_limit, 0); + } + else + { + gimp_dashboard_label_set_text (GTK_LABEL (dashboard->swap_limit_label), + _("N/A")); + } + } + + return G_SOURCE_CONTINUE; +} + +static gboolean +gimp_dashboard_low_swap_space (GimpDashboard *dashboard) +{ + if (dashboard->gimp) + { + GdkScreen *screen; + gint monitor; + + monitor = gimp_get_monitor_at_pointer (&screen); + + gimp_window_strategy_show_dockable_dialog ( + GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (dashboard->gimp)), + dashboard->gimp, + gimp_dialog_factory_get_singleton (), + screen, monitor, + "gimp-dashboard"); + + g_mutex_lock (&dashboard->mutex); + + dashboard->low_swap_space_idle_id = 0; + + g_mutex_unlock (&dashboard->mutex); + } + + return G_SOURCE_REMOVE; +} + +static gpointer +gimp_dashboard_sample (GimpDashboard *dashboard) +{ + GimpDashboardUpdateInteval update_interval; + gint64 end_time; + gboolean seen_low_swap_space = FALSE; + + g_mutex_lock (&dashboard->mutex); + + update_interval = dashboard->update_interval; + end_time = g_get_monotonic_time (); + + while (! dashboard->quit) + { + if (! g_cond_wait_until (&dashboard->cond, &dashboard->mutex, end_time)) + { + /* cache */ + { + guint64 cache_occupied; + gdouble sample[1]; + + g_object_get (gegl_stats (), + "tile-cache-total", &cache_occupied, + NULL); + + sample[0] = cache_occupied; + gimp_meter_add_sample (GIMP_METER (dashboard->cache_meter), sample); + } + + /* swap */ + { + guint64 swap_occupied; + guint64 swap_size; + gdouble sample[2]; + + g_object_get (gegl_stats (), + "swap-total", &swap_occupied, + "swap-file-size", &swap_size, + NULL); + + sample[0] = swap_size; + sample[1] = swap_occupied; + gimp_meter_add_sample (GIMP_METER (dashboard->swap_meter), sample); + + if (dashboard->low_swap_space_warning) + { + guint64 swap_limit = gimp_dashboard_get_swap_limit (swap_size); + + if (! seen_low_swap_space && + swap_occupied >= LOW_SWAP_SPACE_WARNING_ON * swap_limit) + { + if (! dashboard->low_swap_space_idle_id) + { + dashboard->low_swap_space_idle_id = + g_idle_add_full (G_PRIORITY_HIGH, + (GSourceFunc) gimp_dashboard_low_swap_space, + dashboard, NULL); + } + + seen_low_swap_space = TRUE; + } + else if (seen_low_swap_space && + swap_occupied <= LOW_SWAP_SPACE_WARNING_OFF * swap_limit) + { + if (dashboard->low_swap_space_idle_id) + { + g_source_remove (dashboard->low_swap_space_idle_id); + + dashboard->low_swap_space_idle_id = 0; + } + + seen_low_swap_space = FALSE; + } + } + } + + end_time = g_get_monotonic_time () + + update_interval * G_TIME_SPAN_SECOND / 1000; + } + else if (dashboard->update_interval != update_interval) + { + update_interval = dashboard->update_interval; + end_time = g_get_monotonic_time () + + update_interval * G_TIME_SPAN_SECOND / 1000; + } + } + + g_mutex_unlock (&dashboard->mutex); + + return NULL; +} + +static void +gimp_dashboard_label_set_text (GtkLabel *label, + const gchar *text) +{ + /* the strcmp() reduces the overhead of gtk_label_set_text() when the text + * isn't changed + */ + if (strcmp (gtk_label_get_text (label), text)) + gtk_label_set_text (label, text); +} + +static void +gimp_dashboard_label_set_size (GtkLabel *label, + guint64 size, + guint64 limit) +{ + gchar *text; + + text = g_format_size_full (size, G_FORMAT_SIZE_IEC_UNITS); + + if (limit) + { + gchar *temp; + + temp = g_strdup_printf ("%s (%d%%)", text, ROUND (100.0 * size / limit)); + g_free (text); + + text = temp; + } + + gimp_dashboard_label_set_text (label, text); + + g_free (text); +} + +static guint64 +gimp_dashboard_get_swap_limit (guint64 swap_size) +{ + static guint64 free_space = 0; + static gboolean has_free_space = FALSE; + static gint64 last_check_time = 0; + gint64 time; + + /* we don't have a config option for limiting the swap size, so we simply + * return the free space available on the filesystem containing the swap + */ + + time = g_get_monotonic_time (); + + if (time - last_check_time >= G_TIME_SPAN_SECOND) + { + gchar *swap_dir; + + g_object_get (gegl_config (), + "swap", &swap_dir, + NULL); + + free_space = 0; + has_free_space = FALSE; + + if (swap_dir) + { + GFile *file; + GFileInfo *info; + + file = g_file_new_for_path (swap_dir); + + info = g_file_query_filesystem_info (file, + G_FILE_ATTRIBUTE_FILESYSTEM_FREE, + NULL, NULL); + + if (info) + { + free_space = + g_file_info_get_attribute_uint64 (info, + G_FILE_ATTRIBUTE_FILESYSTEM_FREE); + has_free_space = TRUE; + + g_object_unref (info); + } + + g_object_unref (file); + + g_free (swap_dir); + } + + last_check_time = time; + } + + /* the swap limit is the sum of free_space and swap_size, since the swap + * itself occupies space in the filesystem + */ + return has_free_space ? free_space + swap_size : 0; +} + + +/* public functions */ + + +GtkWidget * +gimp_dashboard_new (Gimp *gimp, + GimpMenuFactory *menu_factory) +{ + GimpDashboard *dashboard; + + dashboard = g_object_new (GIMP_TYPE_DASHBOARD, + "menu-factory", menu_factory, + "menu-identifier", "", + "ui-path", "/dashboard-popup", + NULL); + + dashboard->gimp = gimp; + + return GTK_WIDGET (dashboard); +} + +void +gimp_dashboard_set_update_interval (GimpDashboard *dashboard, + GimpDashboardUpdateInteval update_interval) +{ + g_return_if_fail (GIMP_IS_DASHBOARD (dashboard)); + + if (update_interval != dashboard->update_interval) + { + g_mutex_lock (&dashboard->mutex); + + dashboard->update_interval = update_interval; + + gimp_meter_set_history_resolution (GIMP_METER (dashboard->cache_meter), + update_interval / 1000.0); + gimp_meter_set_history_resolution (GIMP_METER (dashboard->swap_meter), + update_interval / 1000.0); + + if (dashboard->timeout_id) + { + g_source_remove (dashboard->timeout_id); + + dashboard->timeout_id = g_timeout_add (update_interval, + (GSourceFunc) gimp_dashboard_update, + dashboard); + } + + g_cond_signal (&dashboard->cond); + + g_mutex_unlock (&dashboard->mutex); + } +} + +void +gimp_dashboard_set_history_duration (GimpDashboard *dashboard, + GimpDashboardHistoryDuration history_duration) +{ + g_return_if_fail (GIMP_IS_DASHBOARD (dashboard)); + + if (history_duration != dashboard->history_duration) + { + dashboard->history_duration = history_duration; + + gimp_meter_set_history_duration (GIMP_METER (dashboard->cache_meter), + history_duration / 1000.0); + gimp_meter_set_history_duration (GIMP_METER (dashboard->swap_meter), + history_duration / 1000.0); + } +} + +void +gimp_dashboard_set_low_swap_space_warning (GimpDashboard *dashboard, + gboolean low_swap_space_warning) +{ + g_return_if_fail (GIMP_IS_DASHBOARD (dashboard)); + + if (low_swap_space_warning != dashboard->low_swap_space_warning) + { + g_mutex_lock (&dashboard->mutex); + + dashboard->low_swap_space_warning = low_swap_space_warning; + + g_mutex_unlock (&dashboard->mutex); + } +} diff --git a/app/widgets/gimpdashboard.h b/app/widgets/gimpdashboard.h new file mode 100644 index 0000000000..dae7d42e05 --- /dev/null +++ b/app/widgets/gimpdashboard.h @@ -0,0 +1,90 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpdashboard.h + * Copyright (C) 2017 Ell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_DASHBOARD_H__ +#define __GIMP_DASHBOARD_H__ + + +#include "gimpeditor.h" + + +#define GIMP_TYPE_DASHBOARD (gimp_dashboard_get_type ()) +#define GIMP_DASHBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DASHBOARD, GimpDashboard)) +#define GIMP_DASHBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DASHBOARD, GimpDashboardClass)) +#define GIMP_IS_DASHBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_DASHBOARD)) +#define GIMP_IS_DASHBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DASHBOARD)) +#define GIMP_DASHBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DASHBOARD, GimpDashboardClass)) + + +typedef struct _GimpDashboardClass GimpDashboardClass; + +struct _GimpDashboard +{ + GimpEditor parent_instance; + + Gimp *gimp; + + GtkWidget *box; + + GtkWidget *cache_meter; + GtkWidget *cache_occupied_label; + GtkWidget *cache_occupied_pct_label; + GtkWidget *cache_limit_label; + + GtkWidget *swap_meter; + GtkWidget *swap_occupied_label; + GtkWidget *swap_occupied_pct_label; + GtkWidget *swap_size_label; + GtkWidget *swap_size_pct_label; + GtkWidget *swap_limit_label; + + gint timeout_id; + gint low_swap_space_idle_id; + + GThread *thread; + GMutex mutex; + GCond cond; + gboolean quit; + + GimpDashboardUpdateInteval update_interval; + GimpDashboardHistoryDuration history_duration; + gboolean low_swap_space_warning; +}; + +struct _GimpDashboardClass +{ + GimpEditorClass parent_class; +}; + + +GType gimp_dashboard_get_type (void) G_GNUC_CONST; + +GtkWidget * gimp_dashboard_new (Gimp *gimp, + GimpMenuFactory *menu_factory); + +void gimp_dashboard_set_update_interval (GimpDashboard *dashboard, + GimpDashboardUpdateInteval update_interval); +void gimp_dashboard_set_history_duration (GimpDashboard *dashboard, + GimpDashboardHistoryDuration history_duration); +void gimp_dashboard_set_low_swap_space_warning (GimpDashboard *dashboard, + gboolean low_swap_space_warning); + + +#endif /* __GIMP_DASHBOARD_H__ */ diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h index b3b8aeec08..f8cec3142e 100644 --- a/app/widgets/gimphelp-ids.h +++ b/app/widgets/gimphelp-ids.h @@ -662,6 +662,11 @@ #define GIMP_HELP_SAMPLE_POINT_DIALOG "gimp-sample-point-dialog" #define GIMP_HELP_SAMPLE_POINT_SAMPLE_MERGED "gimp-sample-point-sample-merged" +#define GIMP_HELP_DASHBOARD_DIALOG "gimp-dashboard-dialog" +#define GIMP_HELP_DASHBOARD_UPDATE_INTERVAL "gimp-dashboard-update-interval" +#define GIMP_HELP_DASHBOARD_HISTORY_DURATION "gimp-dashboard-history-duration" +#define GIMP_HELP_DASHBOARD_LOW_SWAP_SPACE_WARNING "gimp-dashboard-low-swap-space-warning" + #define GIMP_HELP_DOCK "gimp-dock" #define GIMP_HELP_DOCK_CLOSE "gimp-dock-close" #define GIMP_HELP_DOCK_IMAGE_MENU "gimp-dock-image-menu" diff --git a/app/widgets/widgets-enums.h b/app/widgets/widgets-enums.h index 3443a6d72f..74ae105379 100644 --- a/app/widgets/widgets-enums.h +++ b/app/widgets/widgets-enums.h @@ -306,5 +306,23 @@ typedef enum /*< skip >*/ GIMP_DIALOGS_HIDDEN_WITH_DISPLAY /* dialogs are hidden with the display */ } GimpDialogsState; +typedef enum /*< skip >*/ +{ + GIMP_DASHBOARD_UPDATE_INTERVAL_0_25_SEC = 250, + GIMP_DASHBOARD_UPDATE_INTERVAL_0_5_SEC = 500, + GIMP_DASHBOARD_UPDATE_INTERVAL_1_SEC = 1000, + GIMP_DASHBOARD_UPDATE_INTERVAL_2_SEC = 2000, + GIMP_DASHBOARD_UPDATE_INTERVAL_4_SEC = 4000 +} GimpDashboardUpdateInteval; + +typedef enum /*< skip >*/ +{ + GIMP_DASHBOARD_HISTORY_DURATION_15_SEC = 15000, + GIMP_DASHBOARD_HISTORY_DURATION_30_SEC = 30000, + GIMP_DASHBOARD_HISTORY_DURATION_60_SEC = 60000, + GIMP_DASHBOARD_HISTORY_DURATION_120_SEC = 120000, + GIMP_DASHBOARD_HISTORY_DURATION_240_SEC = 240000 +} GimpDashboardHistoryDuration; + #endif /* __WIDGETS_ENUMS_H__ */ diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h index 63a6fe5ca0..30f79c5c2f 100644 --- a/app/widgets/widgets-types.h +++ b/app/widgets/widgets-types.h @@ -57,6 +57,7 @@ typedef struct _GimpDeviceStatus GimpDeviceStatus; typedef struct _GimpEditor GimpEditor; typedef struct _GimpErrorConsole GimpErrorConsole; typedef struct _GimpToolOptionsEditor GimpToolOptionsEditor; +typedef struct _GimpDashboard GimpDashboard; /* GimpDataEditor widgets */ diff --git a/icons/Color/16/gimp-dashboard.png b/icons/Color/16/gimp-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..2c2981b3824c92a0a1ea3b129475577bd687540e GIT binary patch literal 603 zcmV-h0;K(kP)a13nWKw11P2FkEE!q^CyT8C3qoR2tTr~c#oX5+wOMFegXS{nbC9Zn`2kJp8XT<)?iGdT&N$P zZN8Me+Iq5WmDV@sfQLY%Ghi}uM87)!AP_ll!PBcNZVfzL8aD5qS^U1G(rfikADTNU zU{wQWM^3q3n=iuQe&)j)Q=3?boAZQd~{`b*%c76wNg6h(kc=1M@pN`djJ}kJ$~IMHx`EMkrS>4 za0eI!9v2D)TSTN-EXsJmCkrRz_O)n8fLX`8$F$4KI*@SImrT>N#UY!`3NY_cst!!| z8WkYuRDUcMTdmb9hcsJ2U{ey8;?cy`RhF#-h>a-a)lm1*mjr`ePVIMMNZ( zN;Q+o#h!3-!#S&E<&hLp7no-3 z@1gu__f~wc2W`Il1>5XaN>UYD`$ui}CtZ4g9)M|;%c?8!;P%!G3O6Rr>hN4r?sunb zTu12T_bzNw(`YNsPj*<6t^m~_thQPN=rXi^NgB`!1OP|WdOq;Bsi{e#85$ZAAY$ac09p)<_~Q-a z#N3tJH8nL7OGihC0AV99cZQeYx9rKw%ahU3(Vq-jT3Q5nI#adr$N)|^Ha3!#mGx6F z91a77=3=nk?RMu>R#p-S1n_t~6c-mWI5-GEC={Br!IF}al5g|b+)Q_Ox390Sud}VK zZPo@evEAeGh=@pkf4?}LPI0+h;`jSSM5MH|RDfM`F;Ib#*zpt*@p`=iyadwc`s-CG zit?qQp+P!3JH_YoNqv32n9XJlsQO!9s|UDcJOOWv%eajH{0+VW*Q#QPQyaZ600000 LNkvXXu0mjf4n2F< literal 0 HcmV?d00001 diff --git a/icons/Color/color-scalable.svg b/icons/Color/color-scalable.svg index 678fca92a9..df03c1e982 100644 --- a/icons/Color/color-scalable.svg +++ b/icons/Color/color-scalable.svg @@ -61,8 +61,8 @@ inkscape:window-maximized="1" inkscape:window-y="24" inkscape:window-x="65" - inkscape:cy="181.50558" - inkscape:cx="960.06476" + inkscape:cy="117.27625" + inkscape:cx="757.84583" inkscape:zoom="1" showgrid="true" id="namedview88" @@ -40418,7 +40418,7 @@ inkscape:r_cy="true" inkscape:r_cx="true" id="path4926" - d="M 7.8738374,1044.3622 C 6.8302869,1044.4246 6,1045.2489 6,1046.2491 c 0,0.039 0.00388,0.075 0.00629,0.1131 h 3.9874254 c 0.00241,-0.038 0.00629,-0.074 0.00629,-0.1131 0,-1.0409 -0.8967429,-1.8869 -2.0000024,-1.8869 -0.043099,0 -0.083767,0 -0.1261851,0 z" + d="M 7.8738374,1044.3622 C 6.8302869,1044.4246 6,1045.2489 6,1046.2491 c 0,0.039 0.00388,0.075 0.00629,0.1131 h 3.9874254 c 0.00241,-0.038 0.00629,-0.074 0.00629,-0.1131 0,-1.0409 -0.8967381,-1.8869 -1.9999976,-1.8869 -0.043099,0 -0.083767,0 -0.1261851,0 z" style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fffbd7;fill-opacity:0.55681817;fill-rule:evenodd;stroke:none;stroke-width:1.01903164;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" inkscape:connector-curvature="0" /> @@ -50746,6 +50746,48 @@ id="rect52867" style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + + + + + + + + + + + + + + + + + GIMP Dashboard + + + + + + + + + + + + + + + image/svg+xml + + GIMP Dashboard + + + Ell + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/Symbolic/16/gimp-dashboard.png b/icons/Symbolic/16/gimp-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..8767fa952befbb3fbccf78695772d11ac5a684fb GIT binary patch literal 513 zcmV+c0{;DpP)i`d1RKFX>h!|0dHW&aAF$X& z(k2kWfc=AQLQ+K#8?muet8GMf9Csj9DoGmbkbS_q-pYPF6h z+;BLY_uiiYPl3H=v$>jO*`kP?SZn_R)F$FFabtGQiT8eYY(`Zt0B$b;5T>ABuYVX9 zce}`Ys0GN4vPMo~1cs)>kfc<&<-c?-;*Tysj8fq{pvV>e0fGwts4PS{K@c@X$i64Jvr2@7Xp=4wh!FL#kepuLjm;CDmmha} zDKpj1?96^=zWZGk_N<9XvxH)?*pbWS`s?-jN#GC=8)H_DG0RaDEfflc`hNjLQ4|0Z zsyYgEZIku|cp@T``Fy_I62SEIbiXm?0dTqn2IfWNjjG-P-T~LGwV%=nrlIR=#+ca_ z5C7?T-ngpvB>oxTgLCf6mH^JVJF0pg=xFi&ZVwF&EsDs|RBXS9Ja*0%{-P*~qFz;9 z0FG?pP-IqBpR4NoIF45UJkPr*B7MM9;4U!OP*xF<{(L^aA}Q|sj4`i)z9h5^+_2WZ zYM`-8Rp)^d0IGUbL~a7dla!@;y?!nTf~8HDTq>2iYqi=7;8-S;34GsQZJa0!!$-hG z;%c>8J($gAJ8QMtl!&Z*o_E3b{k3gXG&eW5uTrUWj*N_aZ`^avjf%+IRNXggZBH`U z;cPbhV_;yQ_D>HjMa^MVT?Bel;g8nZQ#;j}RsmG?VZ-5w$ZE5?mH?b{W5A^?KtHz) zP%f9VB62TrCxNu8+6SmstAjuf@X}g))>?ZWC??zOQzRk>l4V*|>#4W0qh*?QU`$C> zE5LXdhQAW!T?W=fBy9UXNa_C>(EUgMsya42JUq24001*HGr5h84PQhgj^ii@g0Fl3 b^{&`&n^DjsX^{Cw00000NkvXXu0mjf2umUM literal 0 HcmV?d00001 diff --git a/icons/Symbolic/scalable/gimp-dashboard.svg b/icons/Symbolic/scalable/gimp-dashboard.svg new file mode 100644 index 0000000000..1a4116d921 --- /dev/null +++ b/icons/Symbolic/scalable/gimp-dashboard.svg @@ -0,0 +1,102 @@ + + + + + GIMP Dashboard + + + + + + + + image/svg+xml + + GIMP Dashboard + + + Ell + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/Symbolic/symbolic-scalable.svg b/icons/Symbolic/symbolic-scalable.svg index b3beafd493..cd1daa6a9c 100644 --- a/icons/Symbolic/symbolic-scalable.svg +++ b/icons/Symbolic/symbolic-scalable.svg @@ -49,13 +49,13 @@ inkscape:window-height="876" id="namedview88" showgrid="true" - inkscape:zoom="2" - inkscape:cx="1093.8358" - inkscape:cy="133.58911" + inkscape:zoom="1" + inkscape:cx="713.21137" + inkscape:cy="113.29003" inkscape:window-x="65" inkscape:window-y="24" inkscape:window-maximized="1" - inkscape:current-layer="stock" + inkscape:current-layer="svg7384" showborder="false" inkscape:snap-nodes="true" inkscape:snap-bbox="true" @@ -25937,7 +25937,7 @@ y="1036.3622" /> @@ -28400,19 +28400,19 @@ inkscape:connector-curvature="0" /> @@ -28434,7 +28434,7 @@ inkscape:connector-curvature="0" id="rect6886" transform="translate(241.0002,217)" - d="m -179,283 0,14 14,0 0,-14 z m 1,1 12,0 0,12 -12,0 z" + d="m -179,283 v 14 h 14 v -14 z m 1,1 h 12 v 12 h -12 z" style="fill:url(#linearGradient7639);fill-opacity:1;stroke:none" /> @@ -29316,16 +29316,16 @@ inkscape:connector-curvature="0" id="path8303" transform="translate(241.0002,217)" - d="m -96.5,389 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.765268,0 3.228659,-1.301 3.46875,-3 0.01078,3.4e-4 0.02039,0 0.03125,0 l 2,0 c 0.01086,0 0.02047,3.4e-4 0.03125,0 0.240091,1.699 1.703482,3 3.46875,3 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 -1.424592,0 -2.641241,0.84103 -3.1875,2.0625 C -90.789453,391.02764 -90.885941,391 -91,391 l -2,0 c -0.114059,0 -0.210547,0.0276 -0.3125,0.0625 C -93.858759,389.84103 -95.075408,389 -96.5,389 Z m 0.0625,1.40625 c 1.17613,0 2.125,0.93497 2.125,2.09375 0,1.15878 -0.94887,2.09375 -2.125,2.09375 -1.17613,0 -2.125,-0.93497 -2.125,-2.09375 0,-1.15878 0.94887,-2.09375 2.125,-2.09375 z m 9,0 c 1.17613,0 2.125,0.93497 2.125,2.09375 0,1.15878 -0.94887,2.09375 -2.125,2.09375 -1.17613,0 -2.125,-0.93497 -2.125,-2.09375 0,-1.15878 0.94887,-2.09375 2.125,-2.09375 z" + d="m -96.5,389 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.765268,0 3.228659,-1.301 3.46875,-3 0.01078,3.4e-4 0.02039,0 0.03125,0 h 2 c 0.01086,0 0.02047,3.4e-4 0.03125,0 0.240091,1.699 1.703482,3 3.46875,3 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 -1.424592,0 -2.641241,0.84103 -3.1875,2.0625 C -90.789453,391.02764 -90.885941,391 -91,391 h -2 c -0.114059,0 -0.210547,0.0276 -0.3125,0.0625 C -93.858759,389.84103 -95.075408,389 -96.5,389 Z m 0.0625,1.40625 c 1.17613,0 2.125,0.93497 2.125,2.09375 0,1.15878 -0.94887,2.09375 -2.125,2.09375 -1.17613,0 -2.125,-0.93497 -2.125,-2.09375 0,-1.15878 0.94887,-2.09375 2.125,-2.09375 z m 9,0 c 1.17613,0 2.125,0.93497 2.125,2.09375 0,1.15878 -0.94887,2.09375 -2.125,2.09375 -1.17613,0 -2.125,-0.93497 -2.125,-2.09375 0,-1.15878 0.94887,-2.09375 2.125,-2.09375 z" style="fill:url(#linearGradient7105);fill-opacity:1;stroke:none" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7107);fill-opacity:1;stroke:none;stroke-width:1.00960875;marker:none;enable-background:accumulate" /> @@ -30007,24 +30007,24 @@ id="rect9174" style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1.78100002;marker:none;enable-background:new" /> @@ -30055,7 +30055,7 @@ inkscape:connector-curvature="0" id="rect5523" transform="translate(719.96895,404)" - d="m -156,-22 c 0,0 0,0 0,2 l 0,12 c 0,2 -1,2 -1,2 l 1,0 c 0,0 1,0 1,-1 l 1,0 c 0,1 -1,1 -1,1 l 1,0 c 0,0 1,0 1,-1 l 6,0 c 0,1 -0.67515,1 -1,1 l 1,0 c 0,0 1,0 1,-1 l 1,0 c 0,1 -1,1 -1,1 l 1,0 c 0,0 1,0 1,-2 l 0,-12 c 0,-2 0,-2 0,-2 l -3,0 c 0,0 0,0 0,2 l 0,2 -6,0 0,-2 c 0,-2 0,-2 0,-2 z m 1,1 1,0 0,1 -1,0 z m 9,0 1,0 0,1 -1,0 z m -9,2 1,0 0,1 -1,0 z m 9,0 1,0 0,1 -1,0 z m -9,2 1,0 0,1 -1,0 z m 2,0 6,0 0,4 -6,0 z m 7,0 1,0 0,1 -1,0 z m -9,2 1,0 0,1 -1,0 z m 9,0 1,0 0,1 -1,0 z m -9,2 1,0 0,1 -1,0 z m 9,0 1,0 0,1 -1,0 z m -7,1 6,0 0,4 -6,0 z m -2,1 1,0 0,1 -1,0 z m 9,0 1,0 0,1 -1,0 z m -9,2 1,0 0,1 -1,0 z m 9,0 1,0 0,1 -1,0 z" + d="m -156,-22 c 0,0 0,0 0,2 v 12 c 0,2 -1,2 -1,2 h 1 c 0,0 1,0 1,-1 h 1 c 0,1 -1,1 -1,1 h 1 c 0,0 1,0 1,-1 h 6 c 0,1 -0.67515,1 -1,1 h 1 c 0,0 1,0 1,-1 h 1 c 0,1 -1,1 -1,1 h 1 c 0,0 1,0 1,-2 v -12 c 0,-2 0,-2 0,-2 h -3 c 0,0 0,0 0,2 v 2 h -6 v -2 c 0,-2 0,-2 0,-2 z m 1,1 h 1 v 1 h -1 z m 9,0 h 1 v 1 h -1 z m -9,2 h 1 v 1 h -1 z m 9,0 h 1 v 1 h -1 z m -9,2 h 1 v 1 h -1 z m 2,0 h 6 v 4 h -6 z m 7,0 h 1 v 1 h -1 z m -9,2 h 1 v 1 h -1 z m 9,0 h 1 v 1 h -1 z m -9,2 h 1 v 1 h -1 z m 9,0 h 1 v 1 h -1 z m -7,1 h 6 v 4 h -6 z m -2,1 h 1 v 1 h -1 z m 9,0 h 1 v 1 h -1 z m -9,2 h 1 v 1 h -1 z m 9,0 h 1 v 1 h -1 z" style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.50793636;marker:none;enable-background:new" /> @@ -30090,7 +30090,7 @@ inkscape:connector-curvature="0" id="rect6573-9" transform="translate(241.0002,217)" - d="m -59,263 0,14 14,0 0,-14 z m 1,1 12,0 0,12 -12,0 z" + d="m -59,263 v 14 h 14 v -14 z m 1,1 h 12 v 12 h -12 z" style="fill:#bebebe;fill-opacity:1;stroke:url(#linearGradient7611)" /> @@ -30188,19 +30188,19 @@ sodipodi:nodetypes="csssssssc" inkscape:connector-curvature="0" id="rect3940-5" - d="m 87.355,510.36221 202.14715,0 c 0.19667,0 0.355,0.15833 0.355,0.355 l 0,211.29 c 0,0.19667 -0.15833,0.355 -0.355,0.355 l -202.14715,0 c -0.19667,0 -0.227971,-0.24605 -0.355,-0.355 -53.380966,-45.78312 -59.452394,-145.14974 0,-211.29 0.111874,-0.12446 0.515473,-10.71214 0.355,-0.355 z" + d="m 87.355,510.36221 h 202.14715 c 0.19667,0 0.355,0.15833 0.355,0.355 v 211.29 c 0,0.19667 -0.15833,0.355 -0.355,0.355 H 87.355 c -0.19667,0 -0.227971,-0.24605 -0.355,-0.355 -53.380966,-45.78312 -59.452394,-145.14974 0,-211.29 0.111874,-0.12446 0.515473,-10.71214 0.355,-0.355 z" style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.13499999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -30208,7 +30208,7 @@ sodipodi:nodetypes="cssssccacc" inkscape:connector-curvature="0" id="rect3956" - d="m 244.06687,58.36454 6.61554,0 c 0.0327,0 0.0591,0.026 0.0591,0.059 l 0,0.2705 c 0,0.033 -0.0264,0.059 -0.0591,0.059 l -6.4577,0.063 c 1.55084,0.036 0.0988,-0.059 0.0988,-0.059 0,0 -0.8257,-0.1199 -0.75762,-0.3967 0.0399,-0.1622 1.28905,0.099 0.50103,0 z" + d="m 244.06687,58.36454 h 6.61554 c 0.0327,0 0.0591,0.026 0.0591,0.059 v 0.2705 c 0,0.033 -0.0264,0.059 -0.0591,0.059 l -6.4577,0.063 c 1.55084,0.036 0.0988,-0.059 0.0988,-0.059 0,0 -0.8257,-0.1199 -0.75762,-0.3967 0.0399,-0.1622 1.28905,0.099 0.50103,0 z" style="opacity:1;fill:#464646;fill-opacity:1;stroke:none;stroke-width:0.12168574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -31622,7 +31622,7 @@ @@ -31630,7 +31630,7 @@ sodipodi:nodetypes="cccc" inkscape:connector-curvature="0" id="path5241-1" - d="m 9,1049.3622 0,-6 -6,3 z" + d="m 9,1049.3622 v -6 l -6,3 z" style="fill:url(#linearGradient7915);fill-opacity:1;stroke:none;stroke-width:0.95650649" /> @@ -31657,7 +31657,7 @@ sodipodi:nodetypes="cccc" inkscape:connector-curvature="0" id="path5241-2" - d="m 9,1049.3622 0,-6 -6,3 z" + d="m 9,1049.3622 v -6 l -6,3 z" style="fill:url(#linearGradient7819);fill-opacity:1;stroke:none;stroke-width:0.95650649" /> @@ -31805,7 +31805,7 @@ transform="matrix(0.85714286,0,0,0.79876989,-35.143029,529.1679)"> @@ -31813,14 +31813,14 @@ sodipodi:nodetypes="cccc" inkscape:connector-curvature="0" id="path6938-4" - d="m 41.0002,643.99184 4.666667,-4.01491 0,7.51155 z" + d="m 41.0002,643.99184 4.666667,-4.01491 v 7.51155 z" style="fill:url(#linearGradient7813);fill-opacity:1;stroke:none;stroke-width:0.9689911" /> + d="m 10.1,1041.2122 v -3.85 H 5.9 v 3.85 l 2.1,2.1 z m -5.25,1.05 H 1 v 4.2 h 3.85 l 2.1,-2.1 z m 1.05,5.25 v 3.85 h 4.2 v -3.85 l -2.1,-2.1 z m 5.25,-5.25 -2.1,2.1 2.1,2.1 H 15 v -4.2 z" /> + transform="rotate(-90,-408.42234,362.03324)"> + transform="rotate(90,660.93004,650.67506)"> + transform="rotate(90,631.9265,679.0817)"> + transform="rotate(180,160.09574,521.0536)"> @@ -34312,7 +34312,7 @@ inkscape:connector-curvature="0" id="rect6791-5" transform="matrix(0,0.6666668,-0.6666668,0,77.000215,619.33333)" - d="M 7,3 C 5.3380003,3 4,4.3380003 4,6 L 3.996488,9.9999947 H 6.9938647 L 7,7.5 C 7.0020394,6.6690027 7.6690002,6 8.5,6 h 6 C 15.331,6 16,6.6690002 16,7.5 l -0.014,2.4999947 h 2.997377 L 19,6 C 19.006909,4.3380147 17.662,3 16,3 Z M 3.996488,13.999995 4,18 c 0.00146,1.661999 1.3380003,3 3,3 h 9 c 1.662,0 3,-1.338 3,-3 l -0.01663,-4.000005 H 15.985995 L 16,16.5 c 0.0047,0.830987 -0.669,1.5 -1.5,1.5 h -6 C 7.6690002,18 7,17.331 7,16.5 l -0.00614,-2.500005 z" + d="M 7,3 C 5.3380003,3 4,4.3380003 4,6 L 3.996488,9.9999947 H 6.9938647 L 7,7.5 C 7.0020394,6.6690027 7.6690002,6 8.5,6 h 6 C 15.331,6 16,6.6690002 16,7.5 l -0.014,2.4999947 h 2.997377 L 19,6 C 19.006909,4.3380147 17.662,3 16,3 Z M 3.996488,13.999995 4,18 c 0.00146,1.661999 1.3380003,3 3,3 h 9 c 1.662,0 3,-1.338 3,-3 L 18.98337,13.999995 H 15.985995 L 16,16.5 c 0.0047,0.830987 -0.669,1.5 -1.5,1.5 h -6 C 7.6690002,18 7,17.331 7,16.5 L 6.99386,13.999995 Z" style="fill:url(#linearGradient9944);fill-opacity:1;stroke:none;stroke-width:1.49999964" sodipodi:nodetypes="ssccssssccssscssssccsssscc" /> @@ -34357,7 +34357,7 @@ transform="matrix(1.4999997,0,0,1.4999997,-91.500275,99.36239)"> @@ -34370,7 +34370,7 @@ sodipodi:nodetypes="cccccccc" inkscape:connector-curvature="0" id="path12078-82" - d="m 14,1039.3622 5,6.0352 -5,5.9648 0,-4.041 c -1.332094,-0.029 -9,0.041 -9,0.041 l 0,-4 c 0,0 7.667576,0.01 9,0.019 z" + d="m 14,1039.3622 5,6.0352 -5,5.9648 v -4.041 c -1.332094,-0.029 -9,0.041 -9,0.041 v -4 c 0,0 7.667576,0.01 9,0.019 z" style="fill:url(#linearGradient9998);fill-opacity:1;stroke:none;stroke-width:1.20939934" /> @@ -34448,7 +34448,7 @@ Use the swatch paletteto change color globally + d="m 0.79999995,1037.16 v 14.4 H 15.2 v -14.4 H 0.79999995 m 1.02857145,1.0286 H 14.171429 v 12.3428 H 1.8285714 v -12.3428" /> + d="m 3,1039.36 h 10 v 10 H 3 Z" /> + d="m 4,1040.36 h 8 v 8 H 4 Z" /> + d="m 5,1041.36 h 6 v 6 H 5 Z" /> + d="m 6,1042.36 h 4 v 4 H 6 Z" /> + d="m 7,1043.36 h 2 v 2 H 7 Z" /> + d="m 7.5,1043.86 h 1 v 1 h -1 z" /> @@ -34724,13 +34724,13 @@ sodipodi:nodetypes="sccscsccsccccs" inkscape:connector-curvature="0" id="rect33604-9" - d="m 20,1048.3682 c 0,0.8275 -0.566618,1.494 -1.394165,1.494 l 0,0 c -0.827546,0 -1.577479,-0.2327 -1.577479,-1.0603 l -0.02799,-13.423 L 3.5,1035.3455 c -0.8275538,0 -1.3582674,-1.1199 -1.3582674,-1.9474 L 2.1,1034.5788 c 0,-0.8275 0.5724523,-2.2151 1.4,-2.2166 l 15.105835,-0.027 0,0.027 c 0.827547,0 1.494165,0.2083 1.494165,1.0359 l -0.1,0 z" + d="m 20,1048.3682 c 0,0.8275 -0.566618,1.494 -1.394165,1.494 v 0 c -0.827546,0 -1.577479,-0.2327 -1.577479,-1.0603 l -0.02799,-13.423 L 3.5,1035.3455 c -0.8275538,0 -1.3582674,-1.1199 -1.3582674,-1.9474 L 2.1,1034.5788 c 0,-0.8275 0.5724523,-2.2151 1.4,-2.2166 l 15.105835,-0.027 v 0.027 c 0.827547,0 1.494165,0.2083 1.494165,1.0359 H 20 Z" style="opacity:1;fill:url(#linearGradient8049);fill-opacity:1;stroke:none;stroke-width:1.4970088" /> @@ -34839,7 +34839,7 @@ sodipodi:nodetypes="sccccsccccccccccccccccccssccccccccccccccccccccccccccccccccccccccccccccccccccccccc" inkscape:connector-curvature="0" id="path2-5" - d="m 10.580078,1042.3661 c -0.318412,-10e-5 -1.0595543,0 -1.580078,0 l 0,1.9643 2,0 0,-1.9682 c -0.06781,0 -0.353208,0 -0.419922,0 z m 2.419922,0.01 0,1.9623 2,0 0,-1.9584 c -0.390555,-7e-4 -1.629665,0 -2,0 z m -6,0 c -0.7571058,0 -1.3966717,0 -2,0.01 l 0,1.9545 2,0 z m 10,0.01 0,1.9545 2,0 0,-1.9506 c -0.442413,-9e-4 -1.523571,0 -2,0 z m -14,0.01 c -1.2278557,0 -1.0749419,0 -3,0.01 l 0.00390625,7.9627 c 4.8801e-4,1.095 -0.14951124,1.9975 1.49999995,1.9975 l 20.9921878,0 c 1.649511,0 1.499512,-0.9022 1.5,-1.9975 L 24,1042.3934 c -1.940993,0 -2.066277,0 -3,-0.01 l 0,1.9467 2,0 0,2.0268 -2,0 0,-1.9975 -2,0 0,1.9975 -2,0 0,-1.9975 -2,0 0,1.9975 -2,0 0,-1.9975 -2,0 0,1.9975 -2,0 0,-1.9975 -2,0 0,1.9975 -2,0 0,-1.9975 -2,0 0,1.9975 -2,0 0,-2.0268 2,0 z m 0,4.9742 2,0 0,1.9975 -2,0 z m 4,0 2,0 0,1.9975 -2,0 z m 4,0 2,0 0,1.9975 -2,0 z m 4,0 2,0 0,1.9975 -2,0 z m 4,0 2,0 0,1.9975 -2,0 z" + d="m 10.580078,1042.3661 c -0.318412,-10e-5 -1.0595543,0 -1.580078,0 v 1.9643 h 2 v -1.9682 c -0.06781,0 -0.353208,0 -0.419922,0 z M 13,1042.3761 v 1.9623 h 2 v -1.9584 c -0.390555,-7e-4 -1.629665,0 -2,0 z m -6,0 c -0.7571058,0 -1.3966717,0 -2,0.01 v 1.9545 h 2 z m 10,0.01 v 1.9545 h 2 v -1.9506 c -0.442413,-9e-4 -1.523571,0 -2,0 z m -14,0.01 c -1.2278557,0 -1.0749419,0 -3,0.01 l 0.00390625,7.9627 c 4.8801e-4,1.095 -0.14951124,1.9975 1.49999995,1.9975 H 22.496094 c 1.649511,0 1.499512,-0.9022 1.5,-1.9975 L 24,1042.3934 c -1.940993,0 -2.066277,0 -3,-0.01 v 1.9467 h 2 v 2.0268 h -2 v -1.9975 h -2 v 1.9975 h -2 v -1.9975 h -2 v 1.9975 h -2 v -1.9975 h -2 v 1.9975 H 9 v -1.9975 H 7 v 1.9975 H 5 v -1.9975 H 3 v 1.9975 H 1 v -2.0268 h 2 z m 0,4.9742 h 2 v 1.9975 H 3 Z m 4,0 h 2 v 1.9975 H 7 Z m 4,0 h 2 v 1.9975 h -2 z m 4,0 h 2 v 1.9975 h -2 z m 4,0 h 2 v 1.9975 h -2 z" style="fill:url(#linearGradient8248);fill-opacity:1;stroke-width:1.22178757" /> + transform="rotate(44.999999)" /> @@ -35513,7 +35513,7 @@ id="gimp-tool-rotate-24"> @@ -35556,7 +35556,7 @@ style="fill:none;stroke:none;stroke-width:1.5" /> @@ -35564,13 +35564,13 @@ sodipodi:nodetypes="cccc" inkscape:connector-curvature="0" id="path11889-0" - d="m 15,1038.8622 -6,-4.5 0,9 z" + d="m 15,1038.8622 -6,-4.5 v 9 z" style="fill:url(#linearGradient7924-7);fill-opacity:1;stroke:none;stroke-width:1.5" /> @@ -35775,7 +35775,7 @@ sodipodi:nodetypes="cccccccc" inkscape:connector-curvature="0" style="fill:url(#linearGradient8868);fill-opacity:1;stroke-width:1.22687316" - d="m 3.8515434,1041.7655 8.6774936,0 0,2.5967 3.47095,-3.0296 -3.47095,-3.0295 0,2.5968 -8.6774936,0 z" + d="m 3.8515434,1041.7655 h 8.6774936 v 2.5967 l 3.47095,-3.0296 -3.47095,-3.0295 v 2.5968 H 3.8515434 Z" id="path15603-2" /> @@ -35833,12 +35833,12 @@ transform="matrix(-0.99633454,0,0,0.99853616,77.670479,383.24872)"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient8922);fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new" /> @@ -35848,14 +35848,14 @@ transform="matrix(1.1428571,0,0,1.1347519,-155.28595,604.26997)"> @@ -35881,14 +35881,14 @@ @@ -36040,20 +36040,20 @@ @@ -36077,14 +36077,14 @@ y="1028.3622" /> @@ -36164,7 +36164,7 @@ transform="matrix(1.5,0,0,1.4998125,6.922215,-1558.8431)"> @@ -36174,7 +36174,7 @@ transform="matrix(-1.5,0,0,1.4998125,17.077785,-1558.8431)"> @@ -36184,7 +36184,7 @@ transform="matrix(0,1.5,-1.4998125,0,1582.8431,6.922215)"> @@ -36194,7 +36194,7 @@ transform="matrix(0,-1.5,-1.4998125,0,1582.8431,17.077785)"> @@ -36718,7 +36718,7 @@ sodipodi:nodetypes="cccccccccc" inkscape:connector-curvature="0" id="rect13095-4" - d="m -6e-6,1028.3622 0,11 11,0 0,-11 z m 1.000006,1 9,0 0,9 -9,0 z" + d="m -6e-6,1028.3622 v 11 h 11 v -11 z m 1.000006,1 h 9 v 9 H 1 Z" style="fill:url(#linearGradient10124-6);fill-opacity:1;stroke:none;stroke-width:1.57142842" /> @@ -36980,13 +36980,13 @@ + d="M 0,1 V 1.5 2 H 1 V 1 Z M 2,1 V 2 H 3 V 1 Z M 4,1 V 2 H 5 V 1 Z M 6,1 V 2 H 7 V 1 Z M 8,1 V 2 H 9 V 1 Z m 2,0 v 1 h 1 V 1 Z m 2,0 v 1 h 1 V 1 Z m 2,0 v 1 h 1 V 1 Z m 2,0 v 1 h 1 V 1 Z m 2,0 v 1 h 1 V 1 Z m 2,0 v 1 h 1 V 1 Z m 2,0 v 1 h 1 V 1 Z M 0,3 V 4 H 1 V 3 Z m 22,0 v 1 h 1 V 3 Z M 0,5 V 6 H 1 V 5 Z m 22,0 v 1 h 1 V 5 Z M 0,7 V 8 H 1 V 7 Z m 22,0 v 1 h 1 V 7 Z M 0,9 v 1 H 1 V 9 Z m 22,0 v 1 h 1 V 9 Z M 0,11 v 1 h 1 v -1 z m 22,0 v 1 h 1 V 11 Z M 0,13 v 1 h 1 v -1 z m 22,0 v 1 h 1 V 13 Z M 0,15 v 1 h 1 v -1 z m 22,0 v 1 h 1 V 15 Z M 0,17 v 1 h 1 v -1 z m 22,0 v 1 h 1 V 17 Z M 0,19 v 1 h 1 v -1 z m 22,0 v 1 h 1 V 19 Z M 0,21 v 1 h 1 v -1 z m 22,0 v 1 h 1 V 21 Z M 0,23 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z m 2,0 v 1 h 1 v -1 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient9137);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99992293;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> @@ -37098,17 +37098,17 @@ sodipodi:nodetypes="cccccccccccccc" inkscape:connector-curvature="0" id="path35057-7" - d="m 14.389178,1028.3633 c -0.151229,-0.01 -0.303679,0.047 -0.459719,0.1826 -6.5592873,5.3793 -12.458361,11.509 -12.458361,14.4319 0.241569,1.3007 -0.3272751,0.8141 -0.3677745,2.1009 0.06973,0.4759 0.4610274,0.8117 0.8734645,0.7308 0.3265249,-0.064 1.3773744,-0.3168 1.471098,-0.9592 2.0884002,0.056 2.8378805,-2.4674 4.4592659,-4.4757 l 6.9877161,-10.8696 c 0.285128,-0.548 -0.05193,-1.1235 -0.50569,-1.1417 z m -8.5047859,8.7687 1.4710981,0 -2.9421961,4.3844 -1.471098,0 z" + d="m 14.389178,1028.3633 c -0.151229,-0.01 -0.303679,0.047 -0.459719,0.1826 -6.5592873,5.3793 -12.458361,11.509 -12.458361,14.4319 0.241569,1.3007 -0.3272751,0.8141 -0.3677745,2.1009 0.06973,0.4759 0.4610274,0.8117 0.8734645,0.7308 0.3265249,-0.064 1.3773744,-0.3168 1.471098,-0.9592 2.0884002,0.056 2.8378805,-2.4674 4.4592659,-4.4757 l 6.9877161,-10.8696 c 0.285128,-0.548 -0.05193,-1.1235 -0.50569,-1.1417 z m -8.5047859,8.7687 h 1.4710981 l -2.9421961,4.3844 h -1.471098 z" style="display:inline;fill:url(#linearGradient7802-1);fill-opacity:1;stroke:none;stroke-width:1.46627092" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient8971);fill-opacity:1;stroke:none;stroke-width:1.00960875;marker:none;enable-background:accumulate" /> @@ -37492,7 +37492,7 @@ y="-2.6074218e-05" /> @@ -37510,7 +37510,7 @@ sodipodi:nodetypes="ssssssssssssssssss" inkscape:connector-curvature="0" id="rect18257-7" - d="m 2.4843707,10.000007 c -1.3771948,0 -2.4843747,1.607175 -2.4843747,2.98437 l 0,8.531249 C -4e-6,22.892821 1.1071759,24 2.4843707,24 l 19.0312473,0 c 1.377195,0 2.484375,-1.107179 2.484375,-2.484374 l 0,-8.531249 c 0,-1.377195 -1.10718,-2.98437 -2.484375,-2.98437 z m 0.5156283,0.99999 18,0 c 1.377195,0 1.999999,0.622808 2,2.000003 l 4e-6,8 c 1e-6,1.377195 -0.622809,1.999996 -2.000004,1.999996 l -18,0 C 1.6228042,22.999996 1.0000009,22.377195 1.0000009,21 l 0,-8 c 0,-1.377195 0.6228033,-2.000003 1.9999981,-2.000003 z" + d="m 2.4843707,10.000007 c -1.3771948,0 -2.4843747,1.607175 -2.4843747,2.98437 v 8.531249 C -4e-6,22.892821 1.1071759,24 2.4843707,24 H 21.515618 c 1.377195,0 2.484375,-1.107179 2.484375,-2.484374 v -8.531249 c 0,-1.377195 -1.10718,-2.98437 -2.484375,-2.98437 z m 0.5156283,0.99999 h 18 c 1.377195,0 1.999999,0.622808 2,2.000003 l 4e-6,8 c 1e-6,1.377195 -0.622809,1.999996 -2.000004,1.999996 h -18 C 1.6228042,22.999996 1.0000009,22.377195 1.0000009,21 v -8 c 0,-1.377195 0.6228033,-2.000003 1.9999981,-2.000003 z" style="fill:url(#linearGradient7818-5);fill-opacity:1;stroke:none" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7816-5);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate" + d="m 8.5781217,5.9999994 h 4.2336223 0.688252 v 0 c 0.964114,0 3,-0.5218799 3,2.9999996 v 1.5 h 1.499999 V 7.4999992 c 0,0 0,-2.9999996 -2.999999,-2.9999996 -0.405765,0.012 -0.931872,-7.5e-4 -1.078125,0 H 11.999996 8.1960552 c -0.3674924,0 -2.5606602,0.349425 -1.4082013,-1.4999998 L 8.3953332,2.0000004e-7 6.3977444,0.0010502 4.8867751,2.9999998 c -0.8591473,2.0946447 0.3648945,2.9999996 1.9252063,2.9999996 0.4057649,-0.012 1.6198873,7.5e-4 1.7661403,0" /> @@ -37690,7 +37690,7 @@ y="599" /> @@ -37706,12 +37706,12 @@ @@ -37756,7 +37756,7 @@ y="-24.000004" ry="1.4999998" /> + d="m 11.9997,0.5 c -4.1243625,0 -7.5,3.37563 -7.5,7.5 0,2.37933 1.266882,4.35504 3,5.71875 V 17 H 7.5 9 h 6 1.5 -3e-4 v -3.28125 c 1.733118,-1.36371 3,-3.33942 3,-5.71875 0,-4.12437 -3.375638,-7.5 -7.5,-7.5 z m 0,3 c 2.503027,0 4.5,1.99698 4.5,4.5 0,1.673775 -0.892601,3.05682 -2.25,3.84375 l -0.75,0.46875 v 0.84375 L 13.5,14 h -3 l -3e-4,-0.84375 V 12.3125 l -0.75,-0.46875 C 8.3923005,11.05682 7.4997,9.673775 7.4997,8 c 0,-2.50302 1.9969725,-4.5 4.5,-4.5 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient10236-7);fill-opacity:1;stroke:none;stroke-width:2.00000024;marker:none;enable-background:accumulate" /> + d="m 9,22 v 1 h 6 v -1 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient10230-3);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;enable-background:accumulate" /> + d="m 7.5,18 v 3 h 9 v -3 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient10232-6);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;enable-background:accumulate" /> + d="m 9.999999,23 v 1 h 4 v -1 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient10230-7);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;enable-background:accumulate" /> @@ -37877,7 +37877,7 @@ style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:2;marker:none;enable-background:accumulate" /> @@ -37899,20 +37899,20 @@ @@ -37991,8 +37991,8 @@ transform="translate(241.0002,217)" /> + d="m 602.0002,301.99999 v 12 l 12.66667,10e-6 3.33333,-3.33333 v 0 -8.66668 z m 0.66667,0.66668 h 14.66666 V 310 h -3.33333 v 3.33333 h -11.33333 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7901-6);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:new" /> @@ -38149,7 +38149,7 @@ @@ -39072,6 +39072,22 @@ id="rect51745" style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/menus/dialogs-menuitems.xml b/menus/dialogs-menuitems.xml index f7608bf45c..ad3c1c7021 100644 --- a/menus/dialogs-menuitems.xml +++ b/menus/dialogs-menuitems.xml @@ -31,4 +31,5 @@ + diff --git a/po/POTFILES.in b/po/POTFILES.in index fe15ef3c75..7cf35216d2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -24,6 +24,7 @@ app/actions/colormap-commands.c app/actions/context-actions.c app/actions/context-commands.c app/actions/cursor-info-actions.c +app/actions/dashboard-actions.c app/actions/data-commands.c app/actions/debug-actions.c app/actions/dialogs-actions.c @@ -512,6 +513,7 @@ app/widgets/gimpcontrollerkeyboard.c app/widgets/gimpcontrollerlist.c app/widgets/gimpcontrollermouse.c app/widgets/gimpcontrollerwheel.c +app/widgets/gimpdashboard.c app/widgets/gimpdataeditor.c app/widgets/gimpdeviceeditor.c app/widgets/gimpdeviceinfo.c