Initial checkin of Pika from heckimp

This commit is contained in:
2023-09-25 15:35:21 -07:00
commit 891e999216
6761 changed files with 5240685 additions and 0 deletions

57
app/about.h Normal file
View File

@ -0,0 +1,57 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __ABOUT_H__
#define __ABOUT_H__
#define PIKA_ACRONYM \
_("PIKA")
#define PIKA_NAME \
_("Photo and Image Kooker Application")
/* The year of the last commit (UTC) will be inserted into this string. */
#define PIKA_COPYRIGHT \
_("Copyright © 1995-%s\n" \
"Based on work by Spencer Kimball, Peter Mattis and the GnuImp Development Team")
/* TRANSLATORS: do not end the license URL with a dot, because it would
* be in the link. Because of technical limitations, make sure the URL
* ends with a space, a newline or is end of text.
* Cf. bug 762282.
*/
#define PIKA_LICENSE \
_("PIKA 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." \
"\n\n" \
"PIKA 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." \
"\n\n" \
"You should have received a copy of the GNU General Public License " \
"along with PIKA. If not, see: https://www.gnu.org/licenses/")
#endif /* __ABOUT_H__ */

View File

@ -0,0 +1,58 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __ACTIONS_TYPES_H__
#define __ACTIONS_TYPES_H__
#include "dialogs/dialogs-types.h"
#include "tools/tools-types.h"
typedef enum
{
PIKA_ACTION_SELECT_SET = 0,
PIKA_ACTION_SELECT_SET_TO_DEFAULT = -1,
PIKA_ACTION_SELECT_FIRST = -2,
PIKA_ACTION_SELECT_LAST = -3,
PIKA_ACTION_SELECT_SMALL_PREVIOUS = -4,
PIKA_ACTION_SELECT_SMALL_NEXT = -5,
PIKA_ACTION_SELECT_PREVIOUS = -6,
PIKA_ACTION_SELECT_NEXT = -7,
PIKA_ACTION_SELECT_SKIP_PREVIOUS = -8,
PIKA_ACTION_SELECT_SKIP_NEXT = -9,
PIKA_ACTION_SELECT_PERCENT_PREVIOUS = -10,
PIKA_ACTION_SELECT_PERCENT_NEXT = -11
} PikaActionSelectType;
typedef enum
{
PIKA_SAVE_MODE_SAVE,
PIKA_SAVE_MODE_SAVE_AS,
PIKA_SAVE_MODE_SAVE_A_COPY,
PIKA_SAVE_MODE_SAVE_AND_CLOSE,
PIKA_SAVE_MODE_EXPORT,
PIKA_SAVE_MODE_EXPORT_AS,
PIKA_SAVE_MODE_OVERWRITE
} PikaSaveMode;
#endif /* __ACTIONS_TYPES_H__ */

775
app/actions/actions.c Normal file
View File

@ -0,0 +1,775 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikacontainer.h"
#include "core/pikacontext.h"
#include "core/pikaimage.h"
#include "core/pikatooloptions.h"
#include "core/pikatoolinfo.h"
#include "widgets/pikaactionfactory.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikacontainereditor.h"
#include "widgets/pikacontainerview.h"
#include "widgets/pikadock.h"
#include "widgets/pikadockable.h"
#include "widgets/pikadockwindow.h"
#include "widgets/pikaimageeditor.h"
#include "widgets/pikaitemtreeview.h"
#include "display/pikadisplay.h"
#include "display/pikadisplayshell.h"
#include "display/pikaimagewindow.h"
#include "display/pikanavigationeditor.h"
#include "display/pikastatusbar.h"
#include "dialogs/dialogs.h"
#include "actions.h"
#include "brush-editor-actions.h"
#include "brushes-actions.h"
#include "buffers-actions.h"
#include "channels-actions.h"
#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"
#include "dockable-actions.h"
#include "documents-actions.h"
#include "drawable-actions.h"
#include "dynamics-actions.h"
#include "dynamics-editor-actions.h"
#include "edit-actions.h"
#include "error-console-actions.h"
#include "file-actions.h"
#include "filters-actions.h"
#include "fonts-actions.h"
#include "gradient-editor-actions.h"
#include "gradients-actions.h"
#include "help-actions.h"
#include "image-actions.h"
#include "images-actions.h"
#include "layers-actions.h"
#include "mypaint-brushes-actions.h"
#include "palette-editor-actions.h"
#include "palettes-actions.h"
#include "patterns-actions.h"
#include "plug-in-actions.h"
#include "quick-mask-actions.h"
#include "sample-points-actions.h"
#include "select-actions.h"
#include "templates-actions.h"
#include "text-editor-actions.h"
#include "text-tool-actions.h"
#include "tool-options-actions.h"
#include "tool-presets-actions.h"
#include "tool-preset-editor-actions.h"
#include "tools-actions.h"
#include "vector-toolpath-actions.h"
#include "vectors-actions.h"
#include "view-actions.h"
#include "windows-actions.h"
#include "pika-intl.h"
/* global variables */
PikaActionFactory *global_action_factory = NULL;
/* private variables */
static const PikaActionFactoryEntry action_groups[] =
{
{ "brush-editor", N_("Brush Editor"), PIKA_ICON_BRUSH,
brush_editor_actions_setup,
brush_editor_actions_update },
{ "brushes", N_("Brushes"), PIKA_ICON_BRUSH,
brushes_actions_setup,
brushes_actions_update },
{ "buffers", N_("Buffers"), PIKA_ICON_BUFFER,
buffers_actions_setup,
buffers_actions_update },
{ "channels", N_("Channels"), PIKA_ICON_CHANNEL,
channels_actions_setup,
channels_actions_update },
{ "colormap", N_("Colormap"), PIKA_ICON_COLORMAP,
colormap_actions_setup,
colormap_actions_update },
{ "context", N_("Context"), PIKA_ICON_DIALOG_TOOL_OPTIONS /* well... */,
context_actions_setup,
context_actions_update },
{ "cursor-info", N_("Pointer Information"), NULL,
cursor_info_actions_setup,
cursor_info_actions_update },
{ "dashboard", N_("Dashboard"), PIKA_ICON_DIALOG_DASHBOARD,
dashboard_actions_setup,
dashboard_actions_update },
{ "debug", N_("Debug"), NULL,
debug_actions_setup,
debug_actions_update },
{ "dialogs", N_("Dialogs"), NULL,
dialogs_actions_setup,
dialogs_actions_update },
{ "dock", N_("Dock"), NULL,
dock_actions_setup,
dock_actions_update },
{ "dockable", N_("Dockable"), NULL,
dockable_actions_setup,
dockable_actions_update },
{ "documents", N_("Document History"), NULL,
documents_actions_setup,
documents_actions_update },
{ "drawable", N_("Drawable"), PIKA_ICON_LAYER,
drawable_actions_setup,
drawable_actions_update },
{ "dynamics", N_("Paint Dynamics"), PIKA_ICON_DYNAMICS,
dynamics_actions_setup,
dynamics_actions_update },
{ "dynamics-editor", N_("Paint Dynamics Editor"), PIKA_ICON_DYNAMICS,
dynamics_editor_actions_setup,
dynamics_editor_actions_update },
{ "edit", N_("Edit"), PIKA_ICON_EDIT,
edit_actions_setup,
edit_actions_update },
{ "error-console", N_("Error Console"), PIKA_ICON_DIALOG_WARNING,
error_console_actions_setup,
error_console_actions_update },
{ "file", N_("File"), "text-x-generic",
file_actions_setup,
file_actions_update },
{ "filters", N_("Filters"), PIKA_ICON_GEGL,
filters_actions_setup,
filters_actions_update },
{ "fonts", N_("Fonts"), PIKA_ICON_FONT,
fonts_actions_setup,
fonts_actions_update },
{ "gradient-editor", N_("Gradient Editor"), PIKA_ICON_GRADIENT,
gradient_editor_actions_setup,
gradient_editor_actions_update },
{ "gradients", N_("Gradients"), PIKA_ICON_GRADIENT,
gradients_actions_setup,
gradients_actions_update },
{ "tool-presets", N_("Tool Presets"), PIKA_ICON_TOOL_PRESET,
tool_presets_actions_setup,
tool_presets_actions_update },
{ "tool-preset-editor", N_("Tool Preset Editor"), PIKA_ICON_TOOL_PRESET,
tool_preset_editor_actions_setup,
tool_preset_editor_actions_update },
{ "help", N_("Help"), "help-browser",
help_actions_setup,
help_actions_update },
{ "image", N_("Image"), PIKA_ICON_IMAGE,
image_actions_setup,
image_actions_update },
{ "images", N_("Images"), PIKA_ICON_IMAGE,
images_actions_setup,
images_actions_update },
{ "layers", N_("Layers"), PIKA_ICON_LAYER,
layers_actions_setup,
layers_actions_update },
{ "mypaint-brushes", N_("MyPaint Brushes"), PIKA_ICON_MYPAINT_BRUSH,
mypaint_brushes_actions_setup,
mypaint_brushes_actions_update },
{ "palette-editor", N_("Palette Editor"), PIKA_ICON_PALETTE,
palette_editor_actions_setup,
palette_editor_actions_update },
{ "palettes", N_("Palettes"), PIKA_ICON_PALETTE,
palettes_actions_setup,
palettes_actions_update },
{ "patterns", N_("Patterns"), PIKA_ICON_PATTERN,
patterns_actions_setup,
patterns_actions_update },
{ "plug-in", N_("Plug-ins"), PIKA_ICON_PLUGIN,
plug_in_actions_setup,
plug_in_actions_update },
{ "quick-mask", N_("Quick Mask"), PIKA_ICON_QUICK_MASK_ON,
quick_mask_actions_setup,
quick_mask_actions_update },
{ "sample-points", N_("Sample Points"), PIKA_ICON_SAMPLE_POINT,
sample_points_actions_setup,
sample_points_actions_update },
{ "select", N_("Select"), PIKA_ICON_SELECTION,
select_actions_setup,
select_actions_update },
{ "templates", N_("Templates"), PIKA_ICON_TEMPLATE,
templates_actions_setup,
templates_actions_update },
{ "text-tool", N_("Text Tool"), PIKA_ICON_EDIT,
text_tool_actions_setup,
text_tool_actions_update },
{ "text-editor", N_("Text Editor"), PIKA_ICON_EDIT,
text_editor_actions_setup,
text_editor_actions_update },
{ "tool-options", N_("Tool Options"), PIKA_ICON_DIALOG_TOOL_OPTIONS,
tool_options_actions_setup,
tool_options_actions_update },
{ "tools", N_("Tools"), PIKA_ICON_DIALOG_TOOLS,
tools_actions_setup,
tools_actions_update },
{ "vector-toolpath", N_("Path Toolpath"), PIKA_ICON_PATH,
vector_toolpath_actions_setup,
vector_toolpath_actions_update },
{ "vectors", N_("Paths"), PIKA_ICON_PATH,
vectors_actions_setup,
vectors_actions_update },
{ "view", N_("View"), PIKA_ICON_VISIBLE,
view_actions_setup,
view_actions_update },
{ "windows", N_("Windows"), NULL,
windows_actions_setup,
windows_actions_update }
};
/* public functions */
void
actions_init (Pika *pika)
{
gint i;
g_return_if_fail (PIKA_IS_PIKA (pika));
g_return_if_fail (global_action_factory == NULL);
global_action_factory = pika_action_factory_new (pika);
for (i = 0; i < G_N_ELEMENTS (action_groups); i++)
pika_action_factory_group_register (global_action_factory,
action_groups[i].identifier,
gettext (action_groups[i].label),
action_groups[i].icon_name,
action_groups[i].setup_func,
action_groups[i].update_func);
}
void
actions_exit (Pika *pika)
{
g_return_if_fail (PIKA_IS_PIKA (pika));
g_return_if_fail (global_action_factory != NULL);
g_return_if_fail (global_action_factory->pika == pika);
g_clear_object (&global_action_factory);
}
Pika *
action_data_get_pika (gpointer data)
{
Pika *result = NULL;
static gboolean recursion = FALSE;
if (! data || recursion)
return NULL;
recursion = TRUE;
if (PIKA_IS_PIKA (data))
result = data;
if (! result)
{
PikaDisplay *display = action_data_get_display (data);
if (display)
result = display->pika;
}
if (! result)
{
PikaContext *context = action_data_get_context (data);
if (context)
result = context->pika;
}
recursion = FALSE;
return result;
}
PikaContext *
action_data_get_context (gpointer data)
{
PikaContext *result = NULL;
static gboolean recursion = FALSE;
if (! data || recursion)
return NULL;
recursion = TRUE;
if (PIKA_IS_DOCK (data))
result = pika_dock_get_context ((PikaDock *) data);
else if (PIKA_IS_DOCK_WINDOW (data))
result = pika_dock_window_get_context (((PikaDockWindow *) data));
else if (PIKA_IS_CONTAINER_VIEW (data))
result = pika_container_view_get_context ((PikaContainerView *) data);
else if (PIKA_IS_CONTAINER_EDITOR (data))
result = pika_container_view_get_context (((PikaContainerEditor *) data)->view);
else if (PIKA_IS_IMAGE_EDITOR (data))
result = ((PikaImageEditor *) data)->context;
else if (PIKA_IS_NAVIGATION_EDITOR (data))
result = ((PikaNavigationEditor *) data)->context;
if (! result)
{
Pika *pika = action_data_get_pika (data);
if (pika)
result = pika_get_user_context (pika);
}
recursion = FALSE;
return result;
}
PikaImage *
action_data_get_image (gpointer data)
{
PikaImage *result = NULL;
static gboolean recursion = FALSE;
if (! data || recursion)
return NULL;
recursion = TRUE;
if (PIKA_IS_ITEM_TREE_VIEW (data))
{
result = pika_item_tree_view_get_image ((PikaItemTreeView *) data);
recursion = FALSE;
return result;
}
else if (PIKA_IS_IMAGE_EDITOR (data))
{
result = ((PikaImageEditor *) data)->image;
recursion = FALSE;
return result;
}
if (! result)
{
PikaDisplay *display = action_data_get_display (data);
if (display)
result = pika_display_get_image (display);
}
if (! result)
{
PikaContext *context = action_data_get_context (data);
if (context)
result = pika_context_get_image (context);
}
recursion = FALSE;
return result;
}
PikaDisplay *
action_data_get_display (gpointer data)
{
PikaDisplay *result = NULL;
static gboolean recursion = FALSE;
if (! data || recursion)
return NULL;
recursion = TRUE;
if (PIKA_IS_DISPLAY (data))
result = data;
else if (PIKA_IS_IMAGE_WINDOW (data))
{
PikaDisplayShell *shell = pika_image_window_get_active_shell (data);
result = shell ? shell->display : NULL;
}
if (! result)
{
PikaContext *context = action_data_get_context (data);
if (context)
result = pika_context_get_display (context);
}
recursion = FALSE;
return result;
}
PikaDisplayShell *
action_data_get_shell (gpointer data)
{
PikaDisplayShell *result = NULL;
static gboolean recursion = FALSE;
if (! data || recursion)
return NULL;
recursion = TRUE;
if (! result)
{
PikaDisplay *display = action_data_get_display (data);
if (display)
result = pika_display_get_shell (display);
}
recursion = FALSE;
return result;
}
GtkWidget *
action_data_get_widget (gpointer data)
{
GtkWidget *result = NULL;
static gboolean recursion = FALSE;
if (! data || recursion)
return NULL;
recursion = TRUE;
if (GTK_IS_WIDGET (data))
result = data;
if (! result)
{
PikaDisplay *display = action_data_get_display (data);
if (display)
result = GTK_WIDGET (pika_display_get_shell (display));
}
if (! result)
result = dialogs_get_toolbox ();
recursion = FALSE;
return result;
}
gint
action_data_sel_count (gpointer data)
{
if (PIKA_IS_CONTAINER_EDITOR (data))
{
PikaContainerEditor *editor;
editor = PIKA_CONTAINER_EDITOR (data);
return pika_container_view_get_selected (editor->view, NULL, NULL);
}
else
{
return 0;
}
}
/* action_select_value:
* @select_type:
* @value:
* @min:
* max:
* def:
* small_inc:
* inc:
* skip_inc:
* delta_factor:
* wrap:
*
* For any valid enum @value (which are all negative), the corresponding
* action computes the semantic value (default, first, next, etc.).
* For a positive @value, it is considered as a per-thousand value
* between the @min and @max (possibly wrapped if @wrap is set, clamped
* otherwise), allowing to compute the returned value.
*
* Returns: the computed value to use for the action.
*/
gdouble
action_select_value (PikaActionSelectType select_type,
gdouble value,
gdouble min,
gdouble max,
gdouble def,
gdouble small_inc,
gdouble inc,
gdouble skip_inc,
gdouble delta_factor,
gboolean wrap)
{
switch (select_type)
{
case PIKA_ACTION_SELECT_SET_TO_DEFAULT:
value = def;
break;
case PIKA_ACTION_SELECT_FIRST:
value = min;
break;
case PIKA_ACTION_SELECT_LAST:
value = max;
break;
case PIKA_ACTION_SELECT_SMALL_PREVIOUS:
value -= small_inc;
break;
case PIKA_ACTION_SELECT_SMALL_NEXT:
value += small_inc;
break;
case PIKA_ACTION_SELECT_PREVIOUS:
value -= inc;
break;
case PIKA_ACTION_SELECT_NEXT:
value += inc;
break;
case PIKA_ACTION_SELECT_SKIP_PREVIOUS:
value -= skip_inc;
break;
case PIKA_ACTION_SELECT_SKIP_NEXT:
value += skip_inc;
break;
case PIKA_ACTION_SELECT_PERCENT_PREVIOUS:
g_return_val_if_fail (delta_factor >= 0.0, value);
value /= (1.0 + delta_factor);
break;
case PIKA_ACTION_SELECT_PERCENT_NEXT:
g_return_val_if_fail (delta_factor >= 0.0, value);
value *= (1.0 + delta_factor);
break;
default:
if ((gint) select_type >= 0)
value = (gdouble) select_type * (max - min) / 1000.0 + min;
else
g_return_val_if_reached (value);
break;
}
if (wrap)
{
while (value < min)
value = max - (min - value);
while (value > max)
value = min + (value - max);
}
else
{
value = CLAMP (value, min, max);
}
return value;
}
void
action_select_property (PikaActionSelectType select_type,
PikaDisplay *display,
GObject *object,
const gchar *property_name,
gdouble small_inc,
gdouble inc,
gdouble skip_inc,
gdouble delta_factor,
gboolean wrap)
{
GParamSpec *pspec;
g_return_if_fail (display == NULL || PIKA_IS_DISPLAY (display));
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (property_name != NULL);
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
property_name);
if (G_IS_PARAM_SPEC_DOUBLE (pspec))
{
gdouble value;
g_object_get (object, property_name, &value, NULL);
value = action_select_value (select_type,
value,
G_PARAM_SPEC_DOUBLE (pspec)->minimum,
G_PARAM_SPEC_DOUBLE (pspec)->maximum,
G_PARAM_SPEC_DOUBLE (pspec)->default_value,
small_inc, inc, skip_inc, delta_factor, wrap);
g_object_set (object, property_name, value, NULL);
if (display)
{
const gchar *blurb = g_param_spec_get_blurb (pspec);
if (blurb)
{
/* value description and new value shown in the status bar */
action_message (display, object, _("%s: %.2f"), blurb, value);
}
}
}
else if (G_IS_PARAM_SPEC_INT (pspec))
{
gint value;
g_object_get (object, property_name, &value, NULL);
value = action_select_value (select_type,
value,
G_PARAM_SPEC_INT (pspec)->minimum,
G_PARAM_SPEC_INT (pspec)->maximum,
G_PARAM_SPEC_INT (pspec)->default_value,
small_inc, inc, skip_inc, delta_factor, wrap);
g_object_set (object, property_name, value, NULL);
if (display)
{
const gchar *blurb = g_param_spec_get_blurb (pspec);
if (blurb)
{
/* value description and new value shown in the status bar */
action_message (display, object, _("%s: %d"), blurb, value);
}
}
}
else
{
g_return_if_reached ();
}
}
PikaObject *
action_select_object (PikaActionSelectType select_type,
PikaContainer *container,
PikaObject *current)
{
gint select_index;
gint n_children;
g_return_val_if_fail (PIKA_IS_CONTAINER (container), NULL);
g_return_val_if_fail (current == NULL || PIKA_IS_OBJECT (current), NULL);
if (! current &&
select_type != PIKA_ACTION_SELECT_FIRST &&
select_type != PIKA_ACTION_SELECT_LAST)
return NULL;
n_children = pika_container_get_n_children (container);
if (n_children == 0)
return NULL;
switch (select_type)
{
case PIKA_ACTION_SELECT_FIRST:
select_index = 0;
break;
case PIKA_ACTION_SELECT_LAST:
select_index = n_children - 1;
break;
case PIKA_ACTION_SELECT_PREVIOUS:
select_index = pika_container_get_child_index (container, current) - 1;
break;
case PIKA_ACTION_SELECT_NEXT:
select_index = pika_container_get_child_index (container, current) + 1;
break;
case PIKA_ACTION_SELECT_SKIP_PREVIOUS:
select_index = pika_container_get_child_index (container, current) - 10;
break;
case PIKA_ACTION_SELECT_SKIP_NEXT:
select_index = pika_container_get_child_index (container, current) + 10;
break;
default:
if ((gint) select_type >= 0)
select_index = (gint) select_type;
else
g_return_val_if_reached (current);
break;
}
select_index = CLAMP (select_index, 0, n_children - 1);
return pika_container_get_child_by_index (container, select_index);
}
void
action_message (PikaDisplay *display,
GObject *object,
const gchar *format,
...)
{
PikaDisplayShell *shell = pika_display_get_shell (display);
PikaStatusbar *statusbar = pika_display_shell_get_statusbar (shell);
const gchar *icon_name = NULL;
va_list args;
if (PIKA_IS_TOOL_OPTIONS (object))
{
PikaToolInfo *tool_info = PIKA_TOOL_OPTIONS (object)->tool_info;
icon_name = pika_viewable_get_icon_name (PIKA_VIEWABLE (tool_info));
}
else if (PIKA_IS_VIEWABLE (object))
{
icon_name = pika_viewable_get_icon_name (PIKA_VIEWABLE (object));
}
va_start (args, format);
pika_statusbar_push_temp_valist (statusbar, PIKA_MESSAGE_INFO,
icon_name, format, args);
va_end (args);
}

123
app/actions/actions.h Normal file
View File

@ -0,0 +1,123 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __ACTIONS_H__
#define __ACTIONS_H__
extern PikaActionFactory *global_action_factory;
void actions_init (Pika *pika);
void actions_exit (Pika *pika);
Pika * action_data_get_pika (gpointer data);
PikaContext * action_data_get_context (gpointer data);
PikaImage * action_data_get_image (gpointer data);
PikaDisplay * action_data_get_display (gpointer data);
PikaDisplayShell * action_data_get_shell (gpointer data);
GtkWidget * action_data_get_widget (gpointer data);
gint action_data_sel_count (gpointer data);
gdouble action_select_value (PikaActionSelectType select_type,
gdouble value,
gdouble min,
gdouble max,
gdouble def,
gdouble small_inc,
gdouble inc,
gdouble skip_inc,
gdouble delta_factor,
gboolean wrap);
void action_select_property (PikaActionSelectType select_type,
PikaDisplay *display,
GObject *object,
const gchar *property_name,
gdouble small_inc,
gdouble inc,
gdouble skip_inc,
gdouble delta_factor,
gboolean wrap);
PikaObject * action_select_object (PikaActionSelectType select_type,
PikaContainer *container,
PikaObject *current);
void action_message (PikaDisplay *display,
GObject *object,
const gchar *format,
...) G_GNUC_PRINTF(3,4);
#define return_if_no_pika(pika,data) \
pika = action_data_get_pika (data); \
if (! pika) \
return
#define return_if_no_context(context,data) \
context = action_data_get_context (data); \
if (! context) \
return
#define return_if_no_image(image,data) \
image = action_data_get_image (data); \
if (! image) \
return
#define return_if_no_display(display,data) \
display = action_data_get_display (data); \
if (! display) \
return
#define return_if_no_shell(shell,data) \
shell = action_data_get_shell (data); \
if (! shell) \
return
#define return_if_no_widget(widget,data) \
widget = action_data_get_widget (data); \
if (! widget) \
return
#define return_if_no_drawables(image,drawables,data) \
return_if_no_image (image,data); \
drawables = pika_image_get_selected_drawables (image); \
if (! drawables) \
return
#define return_if_no_layers(image,layers,data) \
return_if_no_image (image,data); \
layers = pika_image_get_selected_layers (image); \
if (! layers) \
return
#define return_if_no_channels(image,channels,data) \
return_if_no_image (image,data); \
channels = pika_image_get_selected_channels (image); \
if (! channels) \
return
#define return_if_no_vectors_list(image,list,data) \
return_if_no_image (image,data); \
list = pika_image_get_selected_vectors (image); \
if (! list) \
return
#endif /* __ACTIONS_H__ */

View File

@ -0,0 +1,80 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikacontext.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikabrusheditor.h"
#include "brush-editor-actions.h"
#include "data-editor-commands.h"
#include "pika-intl.h"
static const PikaToggleActionEntry brush_editor_toggle_actions[] =
{
{ "brush-editor-edit-active", PIKA_ICON_LINKED,
NC_("brush-editor-action", "Edit Active Brush"), NULL, { NULL }, NULL,
data_editor_edit_active_cmd_callback,
FALSE,
PIKA_HELP_BRUSH_EDITOR_EDIT_ACTIVE }
};
void
brush_editor_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_toggle_actions (group, "brush-editor-action",
brush_editor_toggle_actions,
G_N_ELEMENTS (brush_editor_toggle_actions));
}
void
brush_editor_actions_update (PikaActionGroup *group,
gpointer user_data)
{
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (user_data);
gboolean edit_active = FALSE;
edit_active = pika_data_editor_get_edit_active (data_editor);
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0)
#define SET_ACTIVE(action,condition) \
pika_action_group_set_action_active (group, action, (condition) != 0)
SET_ACTIVE ("brush-editor-edit-active", edit_active);
#undef SET_SENSITIVE
#undef SET_ACTIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __BRUSH_EDITOR_ACTIONS_H__
#define __BRUSH_EDITOR_ACTIONS_H__
void brush_editor_actions_setup (PikaActionGroup *group);
void brush_editor_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __BRUSH_EDITOR_ACTIONS_H__ */

View File

@ -0,0 +1,149 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikabrushgenerated.h"
#include "core/pikacontext.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "brushes-actions.h"
#include "data-commands.h"
#include "pika-intl.h"
static const PikaActionEntry brushes_actions[] =
{
{ "brushes-open-as-image", PIKA_ICON_DOCUMENT_OPEN,
NC_("brushes-action", "_Open Brush as Image"), NULL, { NULL },
NC_("brushes-action", "Open brush as image"),
data_open_as_image_cmd_callback,
PIKA_HELP_BRUSH_OPEN_AS_IMAGE },
{ "brushes-new", PIKA_ICON_DOCUMENT_NEW,
NC_("brushes-action", "_New Brush"), NULL, { NULL },
NC_("brushes-action", "Create a new brush"),
data_new_cmd_callback,
PIKA_HELP_BRUSH_NEW },
{ "brushes-duplicate", PIKA_ICON_OBJECT_DUPLICATE,
NC_("brushes-action", "D_uplicate Brush"), NULL, { NULL },
NC_("brushes-action", "Duplicate this brush"),
data_duplicate_cmd_callback,
PIKA_HELP_BRUSH_DUPLICATE },
{ "brushes-copy-location", PIKA_ICON_EDIT_COPY,
NC_("brushes-action", "Copy Brush _Location"), NULL, { NULL },
NC_("brushes-action", "Copy brush file location to clipboard"),
data_copy_location_cmd_callback,
PIKA_HELP_BRUSH_COPY_LOCATION },
{ "brushes-show-in-file-manager", PIKA_ICON_FILE_MANAGER,
NC_("brushes-action", "Show in _File Manager"), NULL, { NULL },
NC_("brushes-action", "Show brush file location in the file manager"),
data_show_in_file_manager_cmd_callback,
PIKA_HELP_BRUSH_SHOW_IN_FILE_MANAGER },
{ "brushes-delete", PIKA_ICON_EDIT_DELETE,
NC_("brushes-action", "_Delete Brush"), NULL, { NULL },
NC_("brushes-action", "Delete this brush"),
data_delete_cmd_callback,
PIKA_HELP_BRUSH_DELETE },
{ "brushes-refresh", PIKA_ICON_VIEW_REFRESH,
NC_("brushes-action", "_Refresh Brushes"), NULL, { NULL },
NC_("brushes-action", "Refresh brushes"),
data_refresh_cmd_callback,
PIKA_HELP_BRUSH_REFRESH }
};
static const PikaStringActionEntry brushes_edit_actions[] =
{
{ "brushes-edit", PIKA_ICON_EDIT,
NC_("brushes-action", "_Edit Brush..."), NULL, { NULL },
NC_("brushes-action", "Edit this brush"),
"pika-brush-editor",
PIKA_HELP_BRUSH_EDIT }
};
void
brushes_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "brushes-action",
brushes_actions,
G_N_ELEMENTS (brushes_actions));
pika_action_group_add_string_actions (group, "brushes-action",
brushes_edit_actions,
G_N_ELEMENTS (brushes_edit_actions),
data_edit_cmd_callback);
}
void
brushes_actions_update (PikaActionGroup *group,
gpointer user_data)
{
PikaContext *context = action_data_get_context (user_data);
PikaBrush *brush = NULL;
PikaData *data = NULL;
GFile *file = NULL;
if (context)
{
brush = pika_context_get_brush (context);
if (action_data_sel_count (user_data) > 1)
{
brush = NULL;
}
if (brush)
{
data = PIKA_DATA (brush);
file = pika_data_get_file (data);
}
}
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("brushes-edit", brush);
SET_SENSITIVE ("brushes-open-as-image", file && ! PIKA_IS_BRUSH_GENERATED (brush));
SET_SENSITIVE ("brushes-duplicate", brush && pika_data_is_duplicatable (data));
SET_SENSITIVE ("brushes-copy-location", file);
SET_SENSITIVE ("brushes-show-in-file-manager", file);
SET_SENSITIVE ("brushes-delete", brush && pika_data_is_deletable (data));
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __BRUSHES_ACTIONS_H__
#define __BRUSHES_ACTIONS_H__
void brushes_actions_setup (PikaActionGroup *group);
void brushes_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __BRUSHES_ACTIONS_H__ */

View File

@ -0,0 +1,136 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikacontext.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "buffers-actions.h"
#include "buffers-commands.h"
#include "pika-intl.h"
static const PikaActionEntry buffers_actions[] =
{
{ "buffers-paste-as-new-image", PIKA_ICON_EDIT_PASTE_AS_NEW,
NC_("buffers-action", "Paste Buffer as _New Image"), NULL, { NULL },
NC_("buffers-action", "Paste the selected buffer as a new image"),
buffers_paste_as_new_image_cmd_callback,
PIKA_HELP_BUFFER_PASTE_AS_NEW_IMAGE },
{ "buffers-delete", PIKA_ICON_EDIT_DELETE,
NC_("buffers-action", "_Delete Buffer"), NULL, { NULL },
NC_("buffers-action", "Delete the selected buffer"),
buffers_delete_cmd_callback,
PIKA_HELP_BUFFER_DELETE }
};
static const PikaEnumActionEntry buffers_paste_actions[] =
{
{ "buffers-paste", PIKA_ICON_EDIT_PASTE,
NC_("buffers-action", "_Paste Buffer"), NULL, { NULL },
NC_("buffers-action", "Paste the selected buffer"),
PIKA_PASTE_TYPE_FLOATING, FALSE,
PIKA_HELP_BUFFER_PASTE },
{ "buffers-paste-in-place", PIKA_ICON_EDIT_PASTE,
NC_("buffers-action", "Paste Buffer In Pl_ace"), NULL, { NULL },
NC_("buffers-action", "Paste the selected buffer at its original position"),
PIKA_PASTE_TYPE_FLOATING_IN_PLACE, FALSE,
PIKA_HELP_BUFFER_PASTE_IN_PLACE },
{ "buffers-paste-into", PIKA_ICON_EDIT_PASTE_INTO,
NC_("buffers-action", "Paste Buffer _Into The Selection"), NULL, { NULL },
NC_("buffers-action", "Paste the selected buffer into the selection"),
PIKA_PASTE_TYPE_FLOATING_INTO, FALSE,
PIKA_HELP_BUFFER_PASTE_INTO },
{ "buffers-paste-into-in-place", PIKA_ICON_EDIT_PASTE_INTO,
NC_("buffers-action", "Paste Buffer Into The Selection In Place"), NULL, { NULL },
NC_("buffers-action",
"Paste the selected buffer into the selection at its original position"),
PIKA_PASTE_TYPE_FLOATING_INTO_IN_PLACE, FALSE,
PIKA_HELP_BUFFER_PASTE_INTO_IN_PLACE },
{ "buffers-paste-as-new-layer", PIKA_ICON_EDIT_PASTE_AS_NEW,
NC_("buffers-action", "Paste Buffer as New _Layer"), NULL, { NULL },
NC_("buffers-action", "Paste the selected buffer as a new layer"),
PIKA_PASTE_TYPE_NEW_LAYER, FALSE,
PIKA_HELP_BUFFER_PASTE_AS_NEW_LAYER },
{ "buffers-paste-as-new-layer-in-place", PIKA_ICON_EDIT_PASTE_AS_NEW,
NC_("buffers-action", "Paste Buffer as New Layer in Place"), NULL, { NULL },
NC_("buffers-action",
"Paste the selected buffer as a new layer at its original position"),
PIKA_PASTE_TYPE_NEW_LAYER_IN_PLACE, FALSE,
PIKA_HELP_BUFFER_PASTE_AS_NEW_LAYER_IN_PLACE },
};
void
buffers_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "buffers-action",
buffers_actions,
G_N_ELEMENTS (buffers_actions));
pika_action_group_add_enum_actions (group, "buffers-action",
buffers_paste_actions,
G_N_ELEMENTS (buffers_paste_actions),
buffers_paste_cmd_callback);
}
void
buffers_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaContext *context = action_data_get_context (data);
PikaBuffer *buffer = NULL;
if (context)
buffer = pika_context_get_buffer (context);
#define SET_SENSITIVE(action,condition,reason) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, reason)
SET_SENSITIVE ("buffers-paste", buffer, _("No selected buffer"));
SET_SENSITIVE ("buffers-paste-in-place", buffer, _("No selected buffer"));
SET_SENSITIVE ("buffers-paste-into", buffer, _("No selected buffer"));
SET_SENSITIVE ("buffers-paste-into-in-place", buffer, _("No selected buffer"));
SET_SENSITIVE ("buffers-paste-as-new-layer", buffer, _("No selected buffer"));
SET_SENSITIVE ("buffers-paste-as-new-layer-in-place", buffer, _("No selected buffer"));
SET_SENSITIVE ("buffers-paste-as-new-image", buffer, _("No selected buffer"));
SET_SENSITIVE ("buffers-delete", buffer, _("No selected buffer"));
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __BUFFERS_ACTIONS_H__
#define __BUFFERS_ACTIONS_H__
void buffers_actions_setup (PikaActionGroup *group);
void buffers_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __BUFFERS_ACTIONS_H__ */

View File

@ -0,0 +1,146 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pika-edit.h"
#include "core/pikacontainer.h"
#include "core/pikacontext.h"
#include "core/pikaimage.h"
#include "widgets/pikacontainereditor.h"
#include "widgets/pikacontainerview.h"
#include "widgets/pikacontainerview-utils.h"
#include "display/pikadisplay.h"
#include "display/pikadisplayshell.h"
#include "display/pikadisplayshell-transform.h"
#include "buffers-commands.h"
#include "pika-intl.h"
/* public functions */
void
buffers_paste_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContainer *container;
PikaContext *context;
PikaBuffer *buffer;
PikaPasteType paste_type = (PikaPasteType) g_variant_get_int32 (value);
container = pika_container_view_get_container (editor->view);
context = pika_container_view_get_context (editor->view);
buffer = pika_context_get_buffer (context);
if (buffer && pika_container_have (container, PIKA_OBJECT (buffer)))
{
PikaDisplay *display = pika_context_get_display (context);
PikaImage *image = NULL;
gint x = -1;
gint y = -1;
gint width = -1;
gint height = -1;
if (display)
{
PikaDisplayShell *shell = pika_display_get_shell (display);
pika_display_shell_untransform_viewport (
shell,
! pika_display_shell_get_infinite_canvas (shell),
&x, &y, &width, &height);
image = pika_display_get_image (display);
}
else
{
image = pika_context_get_image (context);
}
if (image)
{
GList *drawables = pika_image_get_selected_drawables (image);
g_list_free (pika_edit_paste (image, drawables,
PIKA_OBJECT (buffer), paste_type,
context, FALSE,
x, y, width, height));
pika_image_flush (image);
g_list_free (drawables);
}
}
}
void
buffers_paste_as_new_image_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContainer *container;
PikaContext *context;
PikaBuffer *buffer;
container = pika_container_view_get_container (editor->view);
context = pika_container_view_get_context (editor->view);
buffer = pika_context_get_buffer (context);
if (buffer && pika_container_have (container, PIKA_OBJECT (buffer)))
{
GtkWidget *widget = GTK_WIDGET (editor);
PikaImage *new_image;
new_image = pika_edit_paste_as_new_image (context->pika,
PIKA_OBJECT (buffer),
context);
pika_create_display (context->pika, new_image,
PIKA_UNIT_PIXEL, 1.0,
G_OBJECT (pika_widget_get_monitor (widget)));
g_object_unref (new_image);
}
}
void
buffers_delete_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
pika_container_view_remove_active (editor->view);
}

View File

@ -0,0 +1,37 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __BUFFERS_COMMANDS_H__
#define __BUFFERS_COMMANDS_H__
void buffers_paste_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void buffers_paste_as_new_image_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void buffers_delete_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __BUFFERS_COMMANDS_H__ */

View File

@ -0,0 +1,349 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikaimage.h"
#include "core/pikaitem.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikacomponenteditor.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "channels-actions.h"
#include "channels-commands.h"
#include "items-actions.h"
#include "pika-intl.h"
static const PikaActionEntry channels_actions[] =
{
{ "channels-edit-attributes", PIKA_ICON_EDIT,
NC_("channels-action", "_Edit Channel Attributes..."), NULL, { NULL },
NC_("channels-action", "Edit the channel's name, color and opacity"),
channels_edit_attributes_cmd_callback,
PIKA_HELP_CHANNEL_EDIT },
{ "channels-new", PIKA_ICON_DOCUMENT_NEW,
NC_("channels-action", "_New Channel..."), NULL, { NULL },
NC_("channels-action", "Create a new channel"),
channels_new_cmd_callback,
PIKA_HELP_CHANNEL_NEW },
{ "channels-new-last-values", PIKA_ICON_DOCUMENT_NEW,
NC_("channels-action", "_New Channel"), NULL, { NULL },
NC_("channels-action", "Create a new channel with last used values"),
channels_new_last_vals_cmd_callback,
PIKA_HELP_CHANNEL_NEW },
{ "channels-duplicate", PIKA_ICON_OBJECT_DUPLICATE,
NC_("channels-action", "D_uplicate Channels"), NULL, { NULL },
NC_("channels-action",
"Create duplicates of selected channels and add them to the image"),
channels_duplicate_cmd_callback,
PIKA_HELP_CHANNEL_DUPLICATE },
{ "channels-delete", PIKA_ICON_EDIT_DELETE,
NC_("channels-action", "_Delete Channels"), NULL, { NULL },
NC_("channels-action", "Delete selected channels"),
channels_delete_cmd_callback,
PIKA_HELP_CHANNEL_DELETE },
{ "channels-raise", PIKA_ICON_GO_UP,
NC_("channels-action", "_Raise Channels"), NULL, { NULL },
NC_("channels-action", "Raise these channels one step in the channel stack"),
channels_raise_cmd_callback,
PIKA_HELP_CHANNEL_RAISE },
{ "channels-raise-to-top", PIKA_ICON_GO_TOP,
NC_("channels-action", "Raise Channels to _Top"), NULL, { NULL },
NC_("channels-action",
"Raise these channels to the top of the channel stack"),
channels_raise_to_top_cmd_callback,
PIKA_HELP_CHANNEL_RAISE_TO_TOP },
{ "channels-lower", PIKA_ICON_GO_DOWN,
NC_("channels-action", "_Lower Channels"), NULL, { NULL },
NC_("channels-action", "Lower these channels one step in the channel stack"),
channels_lower_cmd_callback,
PIKA_HELP_CHANNEL_LOWER },
{ "channels-lower-to-bottom", PIKA_ICON_GO_BOTTOM,
NC_("channels-action", "Lower Channels to _Bottom"), NULL, { NULL },
NC_("channels-action",
"Lower these channels to the bottom of the channel stack"),
channels_lower_to_bottom_cmd_callback,
PIKA_HELP_CHANNEL_LOWER_TO_BOTTOM }
};
static const PikaToggleActionEntry channels_toggle_actions[] =
{
{ "channels-visible", PIKA_ICON_VISIBLE,
NC_("channels-action", "Toggle Channel _Visibility"), NULL, { NULL }, NULL,
channels_visible_cmd_callback,
FALSE,
PIKA_HELP_CHANNEL_VISIBLE },
{ "channels-lock-content", PIKA_ICON_LOCK_CONTENT,
NC_("channels-action", "L_ock Pixels of Channel"), NULL, { NULL }, NULL,
channels_lock_content_cmd_callback,
FALSE,
PIKA_HELP_CHANNEL_LOCK_PIXELS },
{ "channels-lock-position", PIKA_ICON_LOCK_POSITION,
NC_("channels-action", "L_ock Position of Channel"), NULL, { NULL }, NULL,
channels_lock_position_cmd_callback,
FALSE,
PIKA_HELP_CHANNEL_LOCK_POSITION }
};
static const PikaEnumActionEntry channels_color_tag_actions[] =
{
{ "channels-color-tag-none", PIKA_ICON_EDIT_CLEAR,
NC_("channels-action", "None"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Clear"),
PIKA_COLOR_TAG_NONE, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG },
{ "channels-color-tag-blue", NULL,
NC_("channels-action", "Blue"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Set to Blue"),
PIKA_COLOR_TAG_BLUE, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG },
{ "channels-color-tag-green", NULL,
NC_("channels-action", "Green"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Set to Green"),
PIKA_COLOR_TAG_GREEN, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG },
{ "channels-color-tag-yellow", NULL,
NC_("channels-action", "Yellow"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Set to Yellow"),
PIKA_COLOR_TAG_YELLOW, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG },
{ "channels-color-tag-orange", NULL,
NC_("channels-action", "Orange"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Set to Orange"),
PIKA_COLOR_TAG_ORANGE, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG },
{ "channels-color-tag-brown", NULL,
NC_("channels-action", "Brown"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Set to Brown"),
PIKA_COLOR_TAG_BROWN, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG },
{ "channels-color-tag-red", NULL,
NC_("channels-action", "Red"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Set to Red"),
PIKA_COLOR_TAG_RED, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG },
{ "channels-color-tag-violet", NULL,
NC_("channels-action", "Violet"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Set to Violet"),
PIKA_COLOR_TAG_VIOLET, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG },
{ "channels-color-tag-gray", NULL,
NC_("channels-action", "Gray"), NULL, { NULL },
NC_("channels-action", "Channel Color Tag: Set to Gray"),
PIKA_COLOR_TAG_GRAY, FALSE,
PIKA_HELP_CHANNEL_COLOR_TAG }
};
static const PikaEnumActionEntry channels_to_selection_actions[] =
{
{ "channels-selection-replace", PIKA_ICON_SELECTION_REPLACE,
NC_("channels-action", "Channels to Sele_ction"), NULL, { NULL },
NC_("channels-action", "Replace the selection with selected channels"),
PIKA_CHANNEL_OP_REPLACE, FALSE,
PIKA_HELP_CHANNEL_SELECTION_REPLACE },
{ "channels-selection-add", PIKA_ICON_SELECTION_ADD,
NC_("channels-action", "_Add Channels to Selection"), NULL, { NULL },
NC_("channels-action", "Add selected channels to the current selection"),
PIKA_CHANNEL_OP_ADD, FALSE,
PIKA_HELP_CHANNEL_SELECTION_ADD },
{ "channels-selection-subtract", PIKA_ICON_SELECTION_SUBTRACT,
NC_("channels-action", "_Subtract Channels from Selection"), NULL, { NULL },
NC_("channels-action", "Subtract selected channels from the current selection"),
PIKA_CHANNEL_OP_SUBTRACT, FALSE,
PIKA_HELP_CHANNEL_SELECTION_SUBTRACT },
{ "channels-selection-intersect", PIKA_ICON_SELECTION_INTERSECT,
NC_("channels-action", "_Intersect Channels with Selection"), NULL, { NULL },
NC_("channels-action", "Intersect selected channels with the current selection and each other"),
PIKA_CHANNEL_OP_INTERSECT, FALSE,
PIKA_HELP_CHANNEL_SELECTION_INTERSECT }
};
static const PikaEnumActionEntry channels_select_actions[] =
{
{ "channels-select-top", NULL,
NC_("channels-action", "Select _Top Channel"), NULL, { NULL },
NC_("channels-action", "Select the topmost channel"),
PIKA_ACTION_SELECT_FIRST, FALSE,
PIKA_HELP_CHANNEL_TOP },
{ "channels-select-bottom", NULL,
NC_("channels-action", "Select _Bottom Channel"), NULL, { NULL },
NC_("channels-action", "Select the bottommost channel"),
PIKA_ACTION_SELECT_LAST, FALSE,
PIKA_HELP_CHANNEL_BOTTOM },
{ "channels-select-previous", NULL,
NC_("channels-action", "Select _Previous Channels"), NULL, { NULL },
NC_("channels-action", "Select the channels above the selected channels"),
PIKA_ACTION_SELECT_PREVIOUS, FALSE,
PIKA_HELP_CHANNEL_PREVIOUS },
{ "channels-select-next", NULL,
NC_("channels-action", "Select _Next Channels"), NULL, { NULL },
NC_("channels-action", "Select the channels below the selected channels"),
PIKA_ACTION_SELECT_NEXT, FALSE,
PIKA_HELP_CHANNEL_NEXT }
};
void
channels_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "channels-action",
channels_actions,
G_N_ELEMENTS (channels_actions));
pika_action_group_add_toggle_actions (group, "channels-action",
channels_toggle_actions,
G_N_ELEMENTS (channels_toggle_actions));
pika_action_group_add_enum_actions (group, "channels-action",
channels_color_tag_actions,
G_N_ELEMENTS (channels_color_tag_actions),
channels_color_tag_cmd_callback);
pika_action_group_add_enum_actions (group, "channels-action",
channels_to_selection_actions,
G_N_ELEMENTS (channels_to_selection_actions),
channels_to_selection_cmd_callback);
pika_action_group_add_enum_actions (group, "channels-action",
channels_select_actions,
G_N_ELEMENTS (channels_select_actions),
channels_select_cmd_callback);
items_actions_setup (group, "channels");
}
void
channels_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaImage *image = action_data_get_image (data);
gboolean fs = FALSE;
gboolean component = FALSE;
GList *selected_channels = NULL;
gint n_selected_channels = 0;
gint n_channels = 0;
gboolean have_prev = FALSE; /* At least 1 selected channel has a previous sibling. */
gboolean have_next = FALSE; /* At least 1 selected channel has a next sibling. */
if (image)
{
fs = (pika_image_get_floating_selection (image) != NULL);
if (PIKA_IS_COMPONENT_EDITOR (data))
{
if (PIKA_COMPONENT_EDITOR (data)->clicked_component != -1)
component = TRUE;
}
else
{
GList *iter;
selected_channels = pika_image_get_selected_channels (image);
n_selected_channels = g_list_length (selected_channels);
n_channels = pika_image_get_n_channels (image);
for (iter = selected_channels; iter; iter = iter->next)
{
GList *channel_list;
GList *list;
channel_list = pika_item_get_container_iter (PIKA_ITEM (iter->data));
list = g_list_find (channel_list, iter->data);
if (list)
{
if (g_list_previous (list))
have_prev = TRUE;
if (g_list_next (list))
have_next = TRUE;
}
if (have_prev && have_next)
break;
}
}
}
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("channels-edit-attributes", !fs && n_selected_channels == 1);
SET_SENSITIVE ("channels-new", !fs && image);
SET_SENSITIVE ("channels-new-last-values", !fs && image);
SET_SENSITIVE ("channels-duplicate", !fs && (n_selected_channels > 0 || component));
SET_SENSITIVE ("channels-delete", !fs && n_selected_channels > 0);
SET_SENSITIVE ("channels-raise", !fs && n_selected_channels > 0 && have_prev);
SET_SENSITIVE ("channels-raise-to-top", !fs && n_selected_channels > 0 && have_prev);
SET_SENSITIVE ("channels-lower", !fs && n_selected_channels > 0 && have_next);
SET_SENSITIVE ("channels-lower-to-bottom", !fs && n_selected_channels > 0 && have_next);
SET_SENSITIVE ("channels-selection-replace", !fs && (n_selected_channels > 0 || component));
SET_SENSITIVE ("channels-selection-add", !fs && (n_selected_channels > 0 || component));
SET_SENSITIVE ("channels-selection-subtract", !fs && (n_selected_channels > 0 || component));
SET_SENSITIVE ("channels-selection-intersect", !fs && (n_selected_channels > 0 || component));
SET_SENSITIVE ("channels-select-top", !fs && n_channels > 0 && (n_selected_channels == 0 || have_prev));
SET_SENSITIVE ("channels-select-bottom", !fs && n_channels > 0 && (n_selected_channels == 0 || have_next));
SET_SENSITIVE ("channels-select-previous", !fs && n_selected_channels > 0 && have_prev);
SET_SENSITIVE ("channels-select-next", !fs && n_selected_channels > 0 && have_next);
#undef SET_SENSITIVE
items_actions_update (group, "channels", selected_channels);
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __CHANNELS_ACTIONS_H__
#define __CHANNELS_ACTIONS_H__
void channels_actions_setup (PikaActionGroup *group);
void channels_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __CHANNELS_ACTIONS_H__ */

View File

@ -0,0 +1,728 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "libpikacolor/pikacolor.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "config/pikadialogconfig.h"
#include "core/pika.h"
#include "core/pikachannel.h"
#include "core/pikachannel-select.h"
#include "core/pikacontainer.h"
#include "core/pikacontext.h"
#include "core/pikadrawable-fill.h"
#include "core/pikaimage.h"
#include "core/pikaimage-undo.h"
#include "widgets/pikaaction.h"
#include "widgets/pikacolorpanel.h"
#include "widgets/pikacomponenteditor.h"
#include "widgets/pikadock.h"
#include "widgets/pikahelp-ids.h"
#include "dialogs/dialogs.h"
#include "dialogs/channel-options-dialog.h"
#include "actions.h"
#include "channels-commands.h"
#include "items-commands.h"
#include "pika-intl.h"
#define RGBA_EPSILON 1e-6
/* local function prototypes */
static void channels_new_callback (GtkWidget *dialog,
PikaImage *image,
PikaChannel *channel,
PikaContext *context,
const gchar *channel_name,
const PikaRGB *channel_color,
gboolean save_selection,
gboolean channel_visible,
PikaColorTag channel_color_tag,
gboolean channel_lock_content,
gboolean channel_lock_position,
gboolean channel_lock_visibility,
gpointer user_data);
static void channels_edit_attributes_callback (GtkWidget *dialog,
PikaImage *image,
PikaChannel *channel,
PikaContext *context,
const gchar *channel_name,
const PikaRGB *channel_color,
gboolean save_selection,
gboolean channel_visible,
PikaColorTag channel_color_tag,
gboolean channel_lock_content,
gboolean channel_lock_position,
gboolean channel_lock_visibility,
gpointer user_data);
/* public functions */
void
channels_edit_attributes_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
PikaChannel *channel;
GList *channels;
GtkWidget *widget;
GtkWidget *dialog;
return_if_no_channels (image, channels, data);
return_if_no_widget (widget, data);
#define EDIT_DIALOG_KEY "pika-channel-edit-attributes-dialog"
if (g_list_length (channels) != 1)
return;
channel = channels->data;
dialog = dialogs_get_dialog (G_OBJECT (channel), EDIT_DIALOG_KEY);
if (! dialog)
{
PikaItem *item = PIKA_ITEM (channel);
dialog = channel_options_dialog_new (image, channel,
action_data_get_context (data),
widget,
_("Channel Attributes"),
"pika-channel-edit",
PIKA_ICON_EDIT,
_("Edit Channel Attributes"),
PIKA_HELP_CHANNEL_EDIT,
_("Edit Channel Color"),
_("_Fill opacity:"),
FALSE,
pika_object_get_name (channel),
&channel->color,
pika_item_get_visible (item),
pika_item_get_color_tag (item),
pika_item_get_lock_content (item),
pika_item_get_lock_position (item),
pika_item_get_lock_visibility (item),
channels_edit_attributes_callback,
NULL);
dialogs_attach_dialog (G_OBJECT (channel), EDIT_DIALOG_KEY, dialog);
}
gtk_window_present (GTK_WINDOW (dialog));
}
void
channels_new_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GtkWidget *widget;
GtkWidget *dialog;
return_if_no_image (image, data);
return_if_no_widget (widget, data);
#define NEW_DIALOG_KEY "pika-channel-new-dialog"
dialog = dialogs_get_dialog (G_OBJECT (image), NEW_DIALOG_KEY);
if (! dialog)
{
PikaDialogConfig *config = PIKA_DIALOG_CONFIG (image->pika->config);
dialog = channel_options_dialog_new (image, NULL,
action_data_get_context (data),
widget,
_("New Channel"),
"pika-channel-new",
PIKA_ICON_CHANNEL,
_("Create a New Channel"),
PIKA_HELP_CHANNEL_NEW,
_("New Channel Color"),
_("_Fill opacity:"),
TRUE,
config->channel_new_name,
&config->channel_new_color,
TRUE,
PIKA_COLOR_TAG_NONE,
FALSE,
FALSE,
FALSE,
channels_new_callback,
NULL);
dialogs_attach_dialog (G_OBJECT (image), NEW_DIALOG_KEY, dialog);
}
gtk_window_present (GTK_WINDOW (dialog));
}
void
channels_new_last_vals_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
PikaChannel *channel;
PikaDialogConfig *config;
return_if_no_image (image, data);
config = PIKA_DIALOG_CONFIG (image->pika->config);
channel = pika_channel_new (image,
pika_image_get_width (image),
pika_image_get_height (image),
config->channel_new_name,
&config->channel_new_color);
pika_drawable_fill (PIKA_DRAWABLE (channel),
action_data_get_context (data),
PIKA_FILL_TRANSPARENT);
pika_image_add_channel (image, channel,
PIKA_IMAGE_ACTIVE_PARENT, -1, TRUE);
pika_image_flush (image);
}
void
channels_raise_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
GList *iter;
GList *raised_channels = NULL;
return_if_no_channels (image, channels, data);
for (iter = channels; iter; iter = iter->next)
{
gint index;
index = pika_item_get_index (iter->data);
if (index > 0)
raised_channels = g_list_prepend (raised_channels, iter->data);
}
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_ITEM_DISPLACE,
ngettext ("Raise Channel",
"Raise Channels",
g_list_length (raised_channels)));
for (iter = raised_channels; iter; iter = iter->next)
pika_image_raise_item (image, iter->data, NULL);
pika_image_flush (image);
pika_image_undo_group_end (image);
g_list_free (raised_channels);
}
void
channels_raise_to_top_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
GList *iter;
GList *raised_channels = NULL;
return_if_no_channels (image, channels, data);
for (iter = channels; iter; iter = iter->next)
{
gint index;
index = pika_item_get_index (iter->data);
if (index > 0)
raised_channels = g_list_prepend (raised_channels, iter->data);
}
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_ITEM_DISPLACE,
ngettext ("Raise Channel to Top",
"Raise Channels to Top",
g_list_length (raised_channels)));
for (iter = raised_channels; iter; iter = iter->next)
pika_image_raise_item_to_top (image, iter->data);
pika_image_flush (image);
pika_image_undo_group_end (image);
g_list_free (raised_channels);
}
void
channels_lower_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
GList *iter;
GList *lowered_channels = NULL;
return_if_no_channels (image, channels, data);
for (iter = channels; iter; iter = iter->next)
{
GList *layer_list;
gint index;
layer_list = pika_item_get_container_iter (PIKA_ITEM (iter->data));
index = pika_item_get_index (iter->data);
if (index < g_list_length (layer_list) - 1)
lowered_channels = g_list_prepend (lowered_channels, iter->data);
}
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_ITEM_DISPLACE,
ngettext ("Lower Channel",
"Lower Channels",
g_list_length (lowered_channels)));
for (iter = lowered_channels; iter; iter = iter->next)
pika_image_lower_item (image, iter->data, NULL);
pika_image_flush (image);
pika_image_undo_group_end (image);
g_list_free (lowered_channels);
}
void
channels_lower_to_bottom_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
GList *iter;
GList *lowered_channels = NULL;
return_if_no_channels (image, channels, data);
for (iter = channels; iter; iter = iter->next)
{
GList *layer_list;
gint index;
layer_list = pika_item_get_container_iter (PIKA_ITEM (iter->data));
index = pika_item_get_index (iter->data);
if (index < g_list_length (layer_list) - 1)
lowered_channels = g_list_prepend (lowered_channels, iter->data);
}
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_ITEM_DISPLACE,
ngettext ("Lower Channel to Bottom",
"Lower Channels to Bottom",
g_list_length (lowered_channels)));
for (iter = lowered_channels; iter; iter = iter->next)
pika_image_lower_item_to_bottom (image, iter->data);
pika_image_flush (image);
pika_image_undo_group_end (image);
g_list_free (lowered_channels);
}
void
channels_duplicate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image = NULL;
GList *channels;
PikaChannel *parent = PIKA_IMAGE_ACTIVE_PARENT;
return_if_no_channels (image, channels, data);
if (PIKA_IS_COMPONENT_EDITOR (data))
{
PikaChannelType component;
PikaChannel *new_channel;
const gchar *desc;
gchar *name;
component = PIKA_COMPONENT_EDITOR (data)->clicked_component;
pika_enum_get_value (PIKA_TYPE_CHANNEL_TYPE, component,
NULL, NULL, &desc, NULL);
name = g_strdup_printf (_("%s Channel Copy"), desc);
new_channel = pika_channel_new_from_component (image, component,
name, NULL);
/* copied components are invisible by default so subsequent copies
* of components don't affect each other
*/
pika_item_set_visible (PIKA_ITEM (new_channel), FALSE, FALSE);
pika_image_add_channel (image, new_channel, parent, -1, TRUE);
g_free (name);
}
else
{
GList *new_channels = NULL;
GList *iter;
channels = g_list_copy (channels);
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_CHANNEL_ADD,
_("Duplicate channels"));
for (iter = channels; iter; iter = iter->next)
{
PikaChannel *new_channel;
new_channel = PIKA_CHANNEL (pika_item_duplicate (PIKA_ITEM (iter->data),
G_TYPE_FROM_INSTANCE (iter->data)));
/* use the actual parent here, not PIKA_IMAGE_ACTIVE_PARENT because
* the latter would add a duplicated group inside itself instead of
* above it
*/
pika_image_add_channel (image, new_channel,
pika_channel_get_parent (iter->data),
pika_item_get_index (iter->data),
TRUE);
new_channels = g_list_prepend (new_channels, new_channel);
}
pika_image_set_selected_channels (image, new_channels);
g_list_free (channels);
g_list_free (new_channels);
pika_image_undo_group_end (image);
}
pika_image_flush (image);
}
void
channels_delete_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
GList *iter;
return_if_no_channels (image, channels, data);
channels = g_list_copy (channels);
if (g_list_length (channels) > 1)
{
gchar *undo_name;
undo_name = g_strdup_printf (C_("undo-type", "Remove %d Channels"),
g_list_length (channels));
pika_image_undo_group_start (image, PIKA_UNDO_GROUP_IMAGE_ITEM_REMOVE,
undo_name);
}
for (iter = channels; iter; iter = iter->next)
pika_image_remove_channel (image, iter->data, TRUE, NULL);
if (g_list_length (channels) > 1)
pika_image_undo_group_end (image);
g_list_free (channels);
pika_image_flush (image);
}
void
channels_to_selection_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaChannelOps op;
PikaImage *image;
op = (PikaChannelOps) g_variant_get_int32 (value);
if (PIKA_IS_COMPONENT_EDITOR (data))
{
PikaChannelType component;
return_if_no_image (image, data);
component = PIKA_COMPONENT_EDITOR (data)->clicked_component;
pika_channel_select_component (pika_image_get_mask (image), component,
op, FALSE, 0.0, 0.0);
}
else
{
GList *channels;
GList *iter;
return_if_no_channels (image, channels, data);
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_DRAWABLE_MOD,
_("Channels to selection"));
for (iter = channels; iter; iter = iter->next)
{
pika_item_to_selection (iter->data, op, TRUE, FALSE, 0.0, 0.0);
if (op == PIKA_CHANNEL_OP_REPLACE && iter == channels)
op = PIKA_CHANNEL_OP_ADD;
}
pika_image_undo_group_end (image);
}
pika_image_flush (image);
}
void
channels_visible_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
return_if_no_channels (image, channels, data);
items_visible_cmd_callback (action, value, image, channels);
}
void
channels_lock_content_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
return_if_no_channels (image, channels, data);
items_lock_content_cmd_callback (action, value, image, channels);
}
void
channels_lock_position_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
return_if_no_channels (image, channels, data);
items_lock_position_cmd_callback (action, value, image, channels);
}
void
channels_color_tag_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
PikaColorTag color_tag;
return_if_no_channels (image, channels, data);
color_tag = (PikaColorTag) g_variant_get_int32 (value);
items_color_tag_cmd_callback (action, image, channels, color_tag);
}
void
channels_select_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *channels;
GList *new_channels = NULL;
GList *iter;
PikaActionSelectType select_type;
gboolean run_once;
return_if_no_image (image, data);
select_type = (PikaActionSelectType) g_variant_get_int32 (value);
channels = pika_image_get_selected_channels (image);
run_once = (g_list_length (channels) == 0);
for (iter = channels; iter || run_once; iter = iter ? iter->next : NULL)
{
PikaChannel *new_channel = NULL;
PikaContainer *container;
if (iter)
{
container = pika_item_get_container (PIKA_ITEM (iter->data));
}
else /* run_once */
{
container = pika_image_get_channels (image);
run_once = FALSE;
}
new_channel = (PikaChannel *) action_select_object (select_type,
container,
iter ? iter->data : NULL);
if (new_channel)
new_channels = g_list_prepend (new_channels, new_channel);
}
if (new_channels)
{
pika_image_set_selected_channels (image, new_channels);
pika_image_flush (image);
}
g_list_free (new_channels);
}
/* private functions */
static void
channels_new_callback (GtkWidget *dialog,
PikaImage *image,
PikaChannel *channel,
PikaContext *context,
const gchar *channel_name,
const PikaRGB *channel_color,
gboolean save_selection,
gboolean channel_visible,
PikaColorTag channel_color_tag,
gboolean channel_lock_content,
gboolean channel_lock_position,
gboolean channel_lock_visibility,
gpointer user_data)
{
PikaDialogConfig *config = PIKA_DIALOG_CONFIG (image->pika->config);
g_object_set (config,
"channel-new-name", channel_name,
"channel-new-color", channel_color,
NULL);
if (save_selection)
{
PikaChannel *selection = pika_image_get_mask (image);
channel = PIKA_CHANNEL (pika_item_duplicate (PIKA_ITEM (selection),
PIKA_TYPE_CHANNEL));
pika_object_set_name (PIKA_OBJECT (channel),
config->channel_new_name);
pika_channel_set_color (channel, &config->channel_new_color, FALSE);
}
else
{
channel = pika_channel_new (image,
pika_image_get_width (image),
pika_image_get_height (image),
config->channel_new_name,
&config->channel_new_color);
pika_drawable_fill (PIKA_DRAWABLE (channel), context,
PIKA_FILL_TRANSPARENT);
}
pika_item_set_visible (PIKA_ITEM (channel), channel_visible, FALSE);
pika_item_set_color_tag (PIKA_ITEM (channel), channel_color_tag, FALSE);
pika_item_set_lock_content (PIKA_ITEM (channel), channel_lock_content, FALSE);
pika_item_set_lock_position (PIKA_ITEM (channel), channel_lock_position, FALSE);
pika_item_set_lock_visibility (PIKA_ITEM (channel), channel_lock_visibility, FALSE);
pika_image_add_channel (image, channel,
PIKA_IMAGE_ACTIVE_PARENT, -1, TRUE);
pika_image_flush (image);
gtk_widget_destroy (dialog);
}
static void
channels_edit_attributes_callback (GtkWidget *dialog,
PikaImage *image,
PikaChannel *channel,
PikaContext *context,
const gchar *channel_name,
const PikaRGB *channel_color,
gboolean save_selection,
gboolean channel_visible,
PikaColorTag channel_color_tag,
gboolean channel_lock_content,
gboolean channel_lock_position,
gboolean channel_lock_visibility,
gpointer user_data)
{
PikaItem *item = PIKA_ITEM (channel);
if (strcmp (channel_name, pika_object_get_name (channel)) ||
pika_rgba_distance (channel_color, &channel->color) > RGBA_EPSILON ||
channel_visible != pika_item_get_visible (item) ||
channel_color_tag != pika_item_get_color_tag (item) ||
channel_lock_content != pika_item_get_lock_content (item) ||
channel_lock_position != pika_item_get_lock_position (item) ||
channel_lock_visibility != pika_item_get_lock_visibility (item))
{
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_ITEM_PROPERTIES,
_("Channel Attributes"));
if (strcmp (channel_name, pika_object_get_name (channel)))
pika_item_rename (PIKA_ITEM (channel), channel_name, NULL);
if (pika_rgba_distance (channel_color, &channel->color) > RGBA_EPSILON)
pika_channel_set_color (channel, channel_color, TRUE);
if (channel_visible != pika_item_get_visible (item))
pika_item_set_visible (item, channel_visible, TRUE);
if (channel_color_tag != pika_item_get_color_tag (item))
pika_item_set_color_tag (item, channel_color_tag, TRUE);
if (channel_lock_content != pika_item_get_lock_content (item))
pika_item_set_lock_content (item, channel_lock_content, TRUE);
if (channel_lock_position != pika_item_get_lock_position (item))
pika_item_set_lock_position (item, channel_lock_position, TRUE);
if (channel_lock_visibility != pika_item_get_lock_visibility (item))
pika_item_set_lock_visibility (item, channel_lock_visibility, TRUE);
pika_image_undo_group_end (image);
pika_image_flush (image);
}
gtk_widget_destroy (dialog);
}

View File

@ -0,0 +1,78 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __CHANNELS_COMMANDS_H__
#define __CHANNELS_COMMANDS_H__
void channels_edit_attributes_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_new_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_new_last_vals_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_raise_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_raise_to_top_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_lower_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_lower_to_bottom_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_duplicate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_delete_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_to_selection_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_visible_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_lock_content_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_lock_position_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_color_tag_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void channels_select_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __CHANNELS_COMMANDS_H__ */

View File

@ -0,0 +1,177 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikacontext.h"
#include "core/pikadrawable.h"
#include "core/pikaimage.h"
#include "core/pikaimage-colormap.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "colormap-actions.h"
#include "colormap-commands.h"
#include "pika-intl.h"
static const PikaActionEntry colormap_actions[] =
{
{ "colormap-edit-color", PIKA_ICON_EDIT,
NC_("colormap-action", "_Edit Color..."), NULL, { NULL },
NC_("colormap-action", "Edit this color"),
colormap_edit_color_cmd_callback,
PIKA_HELP_INDEXED_PALETTE_EDIT }
};
static const PikaEnumActionEntry colormap_add_color_actions[] =
{
{ "colormap-add-color-from-fg", PIKA_ICON_LIST_ADD,
NC_("colormap-action", "_Add Color from FG"), NULL, { NULL },
NC_("colormap-action", "Add current foreground color"),
FALSE, FALSE,
PIKA_HELP_INDEXED_PALETTE_ADD },
{ "colormap-add-color-from-bg", PIKA_ICON_LIST_ADD,
NC_("colormap-action", "_Add Color from BG"), NULL, { NULL },
NC_("colormap-action", "Add current background color"),
TRUE, FALSE,
PIKA_HELP_INDEXED_PALETTE_ADD }
};
static const PikaEnumActionEntry colormap_to_selection_actions[] =
{
{ "colormap-selection-replace", PIKA_ICON_SELECTION_REPLACE,
NC_("colormap-action", "_Select this Color"), NULL, { NULL },
NC_("colormap-action", "Select all pixels with this color"),
PIKA_CHANNEL_OP_REPLACE, FALSE,
PIKA_HELP_INDEXED_PALETTE_SELECTION_REPLACE },
{ "colormap-selection-add", PIKA_ICON_SELECTION_ADD,
NC_("colormap-action", "_Add to Selection"), NULL, { NULL },
NC_("colormap-action", "Add all pixels with this color to the current selection"),
PIKA_CHANNEL_OP_ADD, FALSE,
PIKA_HELP_INDEXED_PALETTE_SELECTION_ADD },
{ "colormap-selection-subtract", PIKA_ICON_SELECTION_SUBTRACT,
NC_("colormap-action", "_Subtract from Selection"), NULL, { NULL },
NC_("colormap-action", "Subtract all pixels with this color from the current selection"),
PIKA_CHANNEL_OP_SUBTRACT, FALSE,
PIKA_HELP_INDEXED_PALETTE_SELECTION_SUBTRACT },
{ "colormap-selection-intersect", PIKA_ICON_SELECTION_INTERSECT,
NC_("colormap-action", "_Intersect with Selection"), NULL, { NULL },
NC_("colormap-action", "Intersect all pixels with this color with the current selection"),
PIKA_CHANNEL_OP_INTERSECT, FALSE,
PIKA_HELP_INDEXED_PALETTE_SELECTION_INTERSECT }
};
void
colormap_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "colormap-action",
colormap_actions,
G_N_ELEMENTS (colormap_actions));
pika_action_group_add_enum_actions (group, "colormap-action",
colormap_add_color_actions,
G_N_ELEMENTS (colormap_add_color_actions),
colormap_add_color_cmd_callback);
pika_action_group_add_enum_actions (group, "colormap-action",
colormap_to_selection_actions,
G_N_ELEMENTS (colormap_to_selection_actions),
colormap_to_selection_cmd_callback);
}
void
colormap_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaImage *image = action_data_get_image (data);
PikaContext *context = action_data_get_context (data);
gboolean indexed = FALSE;
gboolean drawable_indexed = FALSE;
gint num_colors = 0;
PikaRGB fg;
PikaRGB bg;
if (image)
{
indexed = (pika_image_get_base_type (image) == PIKA_INDEXED);
if (indexed)
{
GList *drawables = pika_image_get_selected_drawables (image);
num_colors = pika_image_get_colormap_size (image);
if (g_list_length (drawables) == 1)
drawable_indexed = pika_drawable_is_indexed (drawables->data);
g_list_free (drawables);
}
}
if (context)
{
pika_context_get_foreground (context, &fg);
pika_context_get_background (context, &bg);
}
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
#define SET_COLOR(action,color) \
pika_action_group_set_action_color (group, action, color, FALSE);
SET_SENSITIVE ("colormap-edit-color",
indexed && num_colors > 0);
SET_SENSITIVE ("colormap-add-color-from-fg",
indexed && num_colors < 256);
SET_SENSITIVE ("colormap-add-color-from-bg",
indexed && num_colors < 256);
SET_COLOR ("colormap-add-color-from-fg", context ? &fg : NULL);
SET_COLOR ("colormap-add-color-from-bg", context ? &bg : NULL);
SET_SENSITIVE ("colormap-selection-replace",
drawable_indexed && num_colors > 0);
SET_SENSITIVE ("colormap-selection-add",
drawable_indexed && num_colors > 0);
SET_SENSITIVE ("colormap-selection-subtract",
drawable_indexed && num_colors > 0);
SET_SENSITIVE ("colormap-selection-intersect",
drawable_indexed && num_colors > 0);
#undef SET_SENSITIVE
#undef SET_COLOR
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __COLORMAP_ACTIONS_H__
#define __COLORMAP_ACTIONS_H__
void colormap_actions_setup (PikaActionGroup *group);
void colormap_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __COLORMAP_ACTIONS_H__ */

View File

@ -0,0 +1,118 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "actions-types.h"
#include "core/pikachannel-select.h"
#include "core/pikacontext.h"
#include "core/pikaimage.h"
#include "core/pikaimage-colormap.h"
#include "widgets/pikacolormapeditor.h"
#include "widgets/pikacolormapselection.h"
#include "actions.h"
#include "colormap-commands.h"
/* public functions */
void
colormap_edit_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaColormapEditor *editor = PIKA_COLORMAP_EDITOR (data);
pika_colormap_editor_edit_color (editor);
}
void
colormap_add_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContext *context;
PikaImage *image;
gboolean background;
return_if_no_context (context, data);
return_if_no_image (image, data);
background = (gboolean) g_variant_get_int32 (value);
if (pika_image_get_colormap_size (image) < 256)
{
PikaRGB color;
if (background)
pika_context_get_background (context, &color);
else
pika_context_get_foreground (context, &color);
pika_image_add_colormap_entry (image, &color);
pika_image_flush (image);
}
}
void
colormap_to_selection_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaColormapSelection *selection;
PikaColormapEditor *editor;
PikaImage *image;
GList *drawables;
PikaChannelOps op;
gint col_index;
return_if_no_image (image, data);
editor = PIKA_COLORMAP_EDITOR (data);
selection = PIKA_COLORMAP_SELECTION (editor->selection);
col_index = pika_colormap_selection_get_index (selection, NULL);
op = (PikaChannelOps) g_variant_get_int32 (value);
drawables = pika_image_get_selected_drawables (image);
if (g_list_length (drawables) != 1)
{
/* We should not reach this anyway as colormap-actions.c normally takes
* care at making the action insensitive when the item selection is wrong.
*/
g_warning ("This action requires exactly one selected drawable.");
g_list_free (drawables);
return;
}
pika_channel_select_by_index (pika_image_get_mask (image),
drawables->data,
col_index, op,
FALSE, 0.0, 0.0);
g_list_free (drawables);
pika_image_flush (image);
}

View File

@ -0,0 +1,37 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __COLORMAP_COMMANDS_H__
#define __COLORMAP_COMMANDS_H__
void colormap_edit_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void colormap_add_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void colormap_to_selection_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __COLORMAP_COMMANDS_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __CONTEXT_ACTIONS_H__
#define __CONTEXT_ACTIONS_H__
void context_actions_setup (PikaActionGroup *group);
void context_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __CONTEXT_ACTIONS_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,148 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __CONTEXT_COMMANDS_H__
#define __CONTEXT_COMMANDS_H__
void context_colors_default_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_colors_swap_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_palette_foreground_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_palette_background_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_colormap_foreground_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_colormap_background_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_swatch_foreground_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_swatch_background_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_foreground_red_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_foreground_green_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_foreground_blue_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_background_red_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_background_green_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_background_blue_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_foreground_hue_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_foreground_saturation_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_foreground_value_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_background_hue_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_background_saturation_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_background_value_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_opacity_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_paint_mode_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_tool_select_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_brush_select_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_pattern_select_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_palette_select_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_gradient_select_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_font_select_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_brush_spacing_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_brush_shape_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_brush_radius_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_brush_spikes_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_brush_hardness_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_brush_aspect_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_brush_angle_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void context_toggle_dynamics_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __CONTEXT_COMMANDS_H__ */

View File

@ -0,0 +1,74 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "display/pikacursorview.h"
#include "cursor-info-actions.h"
#include "cursor-info-commands.h"
#include "pika-intl.h"
static const PikaToggleActionEntry cursor_info_toggle_actions[] =
{
{ "cursor-info-sample-merged", NULL,
NC_("cursor-info-action", "_Sample Merged"), NULL, { NULL },
NC_("cursor-info-action", "Use the composite color of all visible layers"),
cursor_info_sample_merged_cmd_callback,
TRUE,
PIKA_HELP_POINTER_INFO_SAMPLE_MERGED }
};
void
cursor_info_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_toggle_actions (group, "cursor-info-action",
cursor_info_toggle_actions,
G_N_ELEMENTS (cursor_info_toggle_actions));
}
void
cursor_info_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaCursorView *view = PIKA_CURSOR_VIEW (data);
#define SET_ACTIVE(action,condition) \
pika_action_group_set_action_active (group, action, (condition) != 0)
SET_ACTIVE ("cursor-info-sample-merged",
pika_cursor_view_get_sample_merged (view));
#undef SET_ACTIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __CURSOR_INFO_ACIONS_H__
#define __CURSOR_INFO_ACIONS_H__
void cursor_info_actions_setup (PikaActionGroup *group);
void cursor_info_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __CURSOR_INFO_ACTIONS_H__ */

View File

@ -0,0 +1,45 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "actions-types.h"
#include "display/pikacursorview.h"
#include "cursor-info-commands.h"
/* public functions */
void
cursor_info_sample_merged_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaCursorView *view = PIKA_CURSOR_VIEW (data);
gboolean active = g_variant_get_boolean (value);
pika_cursor_view_set_sample_merged (view, active);
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __CURSOR_INFO_COMMANDS_H__
#define __CURSOR_INFO_COMMANDS_H__
void cursor_info_sample_merged_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __CURSOR_INFO_COMMANDS_H__ */

View File

@ -0,0 +1,230 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikadashboard.h"
#include "widgets/pikahelp-ids.h"
#include "dashboard-actions.h"
#include "dashboard-commands.h"
#include "pika-intl.h"
static const PikaActionEntry dashboard_actions[] =
{
{ "dashboard-groups", NULL,
NC_("dashboard-action", "_Groups") },
{ "dashboard-update-interval", NULL,
NC_("dashboard-action", "_Update Interval") },
{ "dashboard-history-duration", NULL,
NC_("dashboard-action", "_History Duration") },
{ "dashboard-log-record", PIKA_ICON_RECORD,
NC_("dashboard-action", "_Start/Stop Recording..."), NULL, { NULL },
NC_("dashboard-action", "Start/stop recording performance log"),
dashboard_log_record_cmd_callback,
PIKA_HELP_DASHBOARD_LOG_RECORD },
{ "dashboard-log-add-marker", PIKA_ICON_MARKER,
NC_("dashboard-action", "_Add Marker..."), NULL, { NULL },
NC_("dashboard-action", "Add an event marker "
"to the performance log"),
dashboard_log_add_marker_cmd_callback,
PIKA_HELP_DASHBOARD_LOG_ADD_MARKER },
{ "dashboard-log-add-empty-marker", PIKA_ICON_MARKER,
NC_("dashboard-action", "Add _Empty Marker"), NULL, { NULL },
NC_("dashboard-action", "Add an empty event marker "
"to the performance log"),
dashboard_log_add_empty_marker_cmd_callback,
PIKA_HELP_DASHBOARD_LOG_ADD_EMPTY_MARKER },
{ "dashboard-reset", PIKA_ICON_RESET,
NC_("dashboard-action", "_Reset"), NULL, { NULL },
NC_("dashboard-action", "Reset cumulative data"),
dashboard_reset_cmd_callback,
PIKA_HELP_DASHBOARD_RESET },
};
static const PikaToggleActionEntry dashboard_toggle_actions[] =
{
{ "dashboard-low-swap-space-warning", NULL,
NC_("dashboard-action", "_Low Swap Space Warning"), NULL, { NULL },
NC_("dashboard-action", "Raise the dashboard when "
"the swap size approaches its limit"),
dashboard_low_swap_space_warning_cmd_callback,
FALSE,
PIKA_HELP_DASHBOARD_LOW_SWAP_SPACE_WARNING }
};
static const PikaRadioActionEntry dashboard_update_interval_actions[] =
{
{ "dashboard-update-interval-0-25-sec", NULL,
NC_("dashboard-update-interval", "0.25 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_UPDATE_INTERVAL_0_25_SEC,
PIKA_HELP_DASHBOARD_UPDATE_INTERVAL },
{ "dashboard-update-interval-0-5-sec", NULL,
NC_("dashboard-update-interval", "0.5 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_UPDATE_INTERVAL_0_5_SEC,
PIKA_HELP_DASHBOARD_UPDATE_INTERVAL },
{ "dashboard-update-interval-1-sec", NULL,
NC_("dashboard-update-interval", "1 Second"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_UPDATE_INTERVAL_1_SEC,
PIKA_HELP_DASHBOARD_UPDATE_INTERVAL },
{ "dashboard-update-interval-2-sec", NULL,
NC_("dashboard-update-interval", "2 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_UPDATE_INTERVAL_2_SEC,
PIKA_HELP_DASHBOARD_UPDATE_INTERVAL },
{ "dashboard-update-interval-4-sec", NULL,
NC_("dashboard-update-interval", "4 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_UPDATE_INTERVAL_4_SEC,
PIKA_HELP_DASHBOARD_UPDATE_INTERVAL }
};
static const PikaRadioActionEntry dashboard_history_duration_actions[] =
{
{ "dashboard-history-duration-15-sec", NULL,
NC_("dashboard-history-duration", "15 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_HISTORY_DURATION_15_SEC,
PIKA_HELP_DASHBOARD_HISTORY_DURATION },
{ "dashboard-history-duration-30-sec", NULL,
NC_("dashboard-history-duration", "30 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_HISTORY_DURATION_30_SEC,
PIKA_HELP_DASHBOARD_HISTORY_DURATION },
{ "dashboard-history-duration-60-sec", NULL,
NC_("dashboard-history-duration", "60 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_HISTORY_DURATION_60_SEC,
PIKA_HELP_DASHBOARD_HISTORY_DURATION },
{ "dashboard-history-duration-120-sec", NULL,
NC_("dashboard-history-duration", "120 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_HISTORY_DURATION_120_SEC,
PIKA_HELP_DASHBOARD_HISTORY_DURATION },
{ "dashboard-history-duration-240-sec", NULL,
NC_("dashboard-history-duration", "240 Seconds"), NULL, { NULL }, NULL,
PIKA_DASHBOARD_HISTORY_DURATION_240_SEC,
PIKA_HELP_DASHBOARD_HISTORY_DURATION }
};
void
dashboard_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "dashboard-action",
dashboard_actions,
G_N_ELEMENTS (dashboard_actions));
pika_action_group_add_toggle_actions (group, "dashboard-action",
dashboard_toggle_actions,
G_N_ELEMENTS (dashboard_toggle_actions));
pika_action_group_add_radio_actions (group, "dashboard-update-interval",
dashboard_update_interval_actions,
G_N_ELEMENTS (dashboard_update_interval_actions),
NULL,
0,
dashboard_update_interval_cmd_callback);
pika_action_group_add_radio_actions (group, "dashboard-history-duration",
dashboard_history_duration_actions,
G_N_ELEMENTS (dashboard_history_duration_actions),
NULL,
0,
dashboard_history_duration_cmd_callback);
}
void
dashboard_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaDashboard *dashboard = PIKA_DASHBOARD (data);
gboolean recording;
recording = pika_dashboard_log_is_recording (dashboard);
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
#define SET_ACTIVE(action,condition) \
pika_action_group_set_action_active (group, action, (condition) != 0)
switch (pika_dashboard_get_update_interval (dashboard))
{
case PIKA_DASHBOARD_UPDATE_INTERVAL_0_25_SEC:
SET_ACTIVE ("dashboard-update-interval-0-25-sec", TRUE);
break;
case PIKA_DASHBOARD_UPDATE_INTERVAL_0_5_SEC:
SET_ACTIVE ("dashboard-update-interval-0-5-sec", TRUE);
break;
case PIKA_DASHBOARD_UPDATE_INTERVAL_1_SEC:
SET_ACTIVE ("dashboard-update-interval-1-sec", TRUE);
break;
case PIKA_DASHBOARD_UPDATE_INTERVAL_2_SEC:
SET_ACTIVE ("dashboard-update-interval-2-sec", TRUE);
break;
case PIKA_DASHBOARD_UPDATE_INTERVAL_4_SEC:
SET_ACTIVE ("dashboard-update-interval-4-sec", TRUE);
break;
}
switch (pika_dashboard_get_history_duration (dashboard))
{
case PIKA_DASHBOARD_HISTORY_DURATION_15_SEC:
SET_ACTIVE ("dashboard-history-duration-15-sec", TRUE);
break;
case PIKA_DASHBOARD_HISTORY_DURATION_30_SEC:
SET_ACTIVE ("dashboard-history-duration-30-sec", TRUE);
break;
case PIKA_DASHBOARD_HISTORY_DURATION_60_SEC:
SET_ACTIVE ("dashboard-history-duration-60-sec", TRUE);
break;
case PIKA_DASHBOARD_HISTORY_DURATION_120_SEC:
SET_ACTIVE ("dashboard-history-duration-120-sec", TRUE);
break;
case PIKA_DASHBOARD_HISTORY_DURATION_240_SEC:
SET_ACTIVE ("dashboard-history-duration-240-sec", TRUE);
break;
}
SET_SENSITIVE ("dashboard-log-add-marker", recording);
SET_SENSITIVE ("dashboard-log-add-empty-marker", recording);
SET_SENSITIVE ("dashboard-reset", !recording);
SET_ACTIVE ("dashboard-low-swap-space-warning",
pika_dashboard_get_low_swap_space_warning (dashboard));
#undef SET_SENSITIVE
#undef SET_ACTIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DASHBOARD_ACTIONS_H__
#define __DASHBOARD_ACTIONS_H__
void dashboard_actions_setup (PikaActionGroup *group);
void dashboard_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __DASHBOARD_ACTIONS_H__ */

View File

@ -0,0 +1,410 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "widgets/pikadashboard.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikauimanager.h"
#include "dialogs/dialogs.h"
#include "dashboard-commands.h"
#include "pika-intl.h"
typedef struct
{
GFile *folder;
PikaDashboardLogParams params;
} DashboardLogDialogInfo;
/* local function prototypes */
static void dashboard_log_record_response (GtkWidget *dialog,
int response_id,
PikaDashboard *dashboard);
static void dashboard_log_add_marker_response (GtkWidget *dialog,
const gchar *description,
PikaDashboard *dashboard);
static DashboardLogDialogInfo * dashboard_log_dialog_info_new (PikaDashboard *dashboard);
static void dashboard_log_dialog_info_free (DashboardLogDialogInfo *info);
/* public functions */
void
dashboard_update_interval_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDashboard *dashboard = PIKA_DASHBOARD (data);
PikaDashboardUpdateInteval update_interval;
update_interval = g_variant_get_int32 (value);
pika_dashboard_set_update_interval (dashboard, update_interval);
}
void
dashboard_history_duration_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDashboard *dashboard = PIKA_DASHBOARD (data);
PikaDashboardHistoryDuration history_duration;
history_duration = g_variant_get_int32 (value);
pika_dashboard_set_history_duration (dashboard, history_duration);
}
void
dashboard_log_record_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDashboard *dashboard = PIKA_DASHBOARD (data);
if (! pika_dashboard_log_is_recording (dashboard))
{
GtkWidget *dialog;
#define LOG_RECORD_KEY "pika-dashboard-log-record-dialog"
dialog = dialogs_get_dialog (G_OBJECT (dashboard), LOG_RECORD_KEY);
if (! dialog)
{
GtkFileFilter *filter;
DashboardLogDialogInfo *info;
GtkWidget *hbox;
GtkWidget *hbox2;
GtkWidget *label;
GtkWidget *spinbutton;
GtkWidget *toggle;
dialog = gtk_file_chooser_dialog_new (
"Record Performance Log", NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Record"), GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog),
GTK_RESPONSE_OK);
pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
gtk_window_set_screen (
GTK_WINDOW (dialog),
gtk_widget_get_screen (GTK_WIDGET (dashboard)));
gtk_window_set_role (GTK_WINDOW (dialog),
"pika-dashboard-log-record");
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_file_chooser_set_do_overwrite_confirmation (
GTK_FILE_CHOOSER (dialog), TRUE);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("All Files"));
gtk_file_filter_add_pattern (filter, "*");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Log Files (*.log)"));
gtk_file_filter_add_pattern (filter, "*.log");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
info = g_object_get_data (G_OBJECT (dashboard),
"pika-dashboard-log-dialog-info");
if (! info)
{
info = dashboard_log_dialog_info_new (dashboard);
g_object_set_data_full (
G_OBJECT (dashboard),
"pika-dashboard-log-dialog-info", info,
(GDestroyNotify) dashboard_log_dialog_info_free);
}
if (info->folder)
{
gtk_file_chooser_set_current_folder_file (
GTK_FILE_CHOOSER (dialog), info->folder, NULL);
}
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog),
"pika-performance.log");
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), hbox);
gtk_widget_show (hbox);
hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
pika_help_set_help_data (hbox2, _("Log samples per second"), NULL);
gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0);
gtk_widget_show (hbox2);
label = gtk_label_new_with_mnemonic (_("Sample fre_quency:"));
gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
gtk_widget_show (label);
spinbutton = pika_spin_button_new_with_range (1, 1000, 1);
gtk_box_pack_start (GTK_BOX (hbox2), spinbutton, FALSE, FALSE, 0);
gtk_widget_show (spinbutton);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton),
info->params.sample_frequency);
g_signal_connect (gtk_spin_button_get_adjustment (
GTK_SPIN_BUTTON (spinbutton)),
"value-changed",
G_CALLBACK (pika_int_adjustment_update),
&info->params.sample_frequency);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton);
toggle = gtk_check_button_new_with_mnemonic (_("_Backtrace"));
pika_help_set_help_data (toggle, _("Include backtraces in log"),
NULL);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_widget_show (toggle);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
info->params.backtrace);
g_signal_connect (toggle, "toggled",
G_CALLBACK (pika_toggle_button_update),
&info->params.backtrace);
toggle = gtk_check_button_new_with_mnemonic (_("_Messages"));
pika_help_set_help_data (toggle,
_("Include diagnostic messages in log"),
NULL);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_widget_show (toggle);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
info->params.messages);
g_signal_connect (toggle, "toggled",
G_CALLBACK (pika_toggle_button_update),
&info->params.messages);
toggle = gtk_check_button_new_with_mnemonic (_("Progressi_ve"));
pika_help_set_help_data (toggle,
_("Produce complete log "
"even if not properly terminated"),
NULL);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_widget_show (toggle);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
info->params.progressive);
g_signal_connect (toggle, "toggled",
G_CALLBACK (pika_toggle_button_update),
&info->params.progressive);
g_signal_connect (dialog, "response",
G_CALLBACK (dashboard_log_record_response),
dashboard);
g_signal_connect (dialog, "delete-event",
G_CALLBACK (gtk_true),
NULL);
pika_help_connect (dialog, pika_standard_help_func,
PIKA_HELP_DASHBOARD_LOG_RECORD, NULL, NULL);
dialogs_attach_dialog (G_OBJECT (dashboard), LOG_RECORD_KEY, dialog);
g_signal_connect_object (dashboard, "destroy",
G_CALLBACK (gtk_widget_destroy),
dialog,
G_CONNECT_SWAPPED);
#undef LOG_RECORD_KEY
}
gtk_window_present (GTK_WINDOW (dialog));
}
else
{
GError *error = NULL;
if (! pika_dashboard_log_stop_recording (dashboard, &error))
{
pika_message_literal (
pika_editor_get_ui_manager (PIKA_EDITOR (dashboard))->pika,
NULL, PIKA_MESSAGE_ERROR, error->message);
}
}
}
void
dashboard_log_add_marker_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDashboard *dashboard = PIKA_DASHBOARD (data);
GtkWidget *dialog;
#define LOG_ADD_MARKER_KEY "pika-dashboard-log-add-marker-dialog"
dialog = dialogs_get_dialog (G_OBJECT (dashboard), LOG_ADD_MARKER_KEY);
if (! dialog)
{
dialog = pika_query_string_box (
_("Add Marker"), GTK_WIDGET (dashboard),
pika_standard_help_func, PIKA_HELP_DASHBOARD_LOG_ADD_MARKER,
_("Enter a description for the marker"),
NULL,
G_OBJECT (dashboard), "destroy",
(PikaQueryStringCallback) dashboard_log_add_marker_response,
dashboard, NULL);
dialogs_attach_dialog (G_OBJECT (dashboard), LOG_ADD_MARKER_KEY, dialog);
#undef LOG_ADD_MARKER_KEY
}
gtk_window_present (GTK_WINDOW (dialog));
}
void
dashboard_log_add_empty_marker_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDashboard *dashboard = PIKA_DASHBOARD (data);
pika_dashboard_log_add_marker (dashboard, NULL);
}
void
dashboard_reset_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDashboard *dashboard = PIKA_DASHBOARD (data);
pika_dashboard_reset (dashboard);
}
void
dashboard_low_swap_space_warning_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDashboard *dashboard = PIKA_DASHBOARD (data);
gboolean low_swap_space_warning = g_variant_get_boolean (value);
pika_dashboard_set_low_swap_space_warning (dashboard, low_swap_space_warning);
}
/* private functions */
static void
dashboard_log_record_response (GtkWidget *dialog,
int response_id,
PikaDashboard *dashboard)
{
if (response_id == GTK_RESPONSE_OK)
{
GFile *file;
DashboardLogDialogInfo *info;
GError *error = NULL;
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
info = g_object_get_data (G_OBJECT (dashboard),
"pika-dashboard-log-dialog-info");
g_return_if_fail (info != NULL);
g_set_object (&info->folder, g_file_get_parent (file));
if (! pika_dashboard_log_start_recording (dashboard,
file, &info->params,
&error))
{
pika_message_literal (
pika_editor_get_ui_manager (PIKA_EDITOR (dashboard))->pika,
NULL, PIKA_MESSAGE_ERROR, error->message);
g_clear_error (&error);
}
g_object_unref (file);
}
gtk_widget_destroy (dialog);
}
static void
dashboard_log_add_marker_response (GtkWidget *dialog,
const gchar *description,
PikaDashboard *dashboard)
{
pika_dashboard_log_add_marker (dashboard, description);
}
static DashboardLogDialogInfo *
dashboard_log_dialog_info_new (PikaDashboard *dashboard)
{
DashboardLogDialogInfo *info = g_slice_new (DashboardLogDialogInfo);
info->folder = NULL;
info->params = *pika_dashboard_log_get_default_params (dashboard);
return info;
}
static void
dashboard_log_dialog_info_free (DashboardLogDialogInfo *info)
{
g_clear_object (&info->folder);
g_slice_free (DashboardLogDialogInfo, info);
}

View File

@ -0,0 +1,52 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DASHBOARD_COMMANDS_H__
#define __DASHBOARD_COMMANDS_H__
void dashboard_update_interval_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dashboard_history_duration_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dashboard_log_record_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dashboard_log_add_marker_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dashboard_log_add_empty_marker_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dashboard_reset_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dashboard_low_swap_space_warning_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DASHBOARD_COMMANDS_H__ */

305
app/actions/data-commands.c Normal file
View File

@ -0,0 +1,305 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikacontainer.h"
#include "core/pikacontext.h"
#include "core/pikadata.h"
#include "core/pikadatafactory.h"
#include "file/file-open.h"
#include "widgets/pikaclipboard.h"
#include "widgets/pikacontainerview.h"
#include "widgets/pikadataeditor.h"
#include "widgets/pikadatafactoryview.h"
#include "widgets/pikadialogfactory.h"
#include "widgets/pikamessagebox.h"
#include "widgets/pikamessagedialog.h"
#include "widgets/pikawidgets-utils.h"
#include "widgets/pikawindowstrategy.h"
#include "widgets/pikawidgets-utils.h"
#include "dialogs/data-delete-dialog.h"
#include "actions.h"
#include "data-commands.h"
#include "pika-intl.h"
/* public functions */
void
data_open_as_image_cmd_callback (PikaAction *action,
GVariant *value,
gpointer user_data)
{
PikaDataFactoryView *view = PIKA_DATA_FACTORY_VIEW (user_data);
PikaContext *context;
PikaData *data;
context =
pika_container_view_get_context (PIKA_CONTAINER_EDITOR (view)->view);
data = (PikaData *)
pika_context_get_by_type (context,
pika_data_factory_view_get_children_type (view));
if (data && pika_data_get_file (data))
{
GFile *file = pika_data_get_file (data);
GtkWidget *widget = GTK_WIDGET (view);
PikaImage *image;
PikaPDBStatusType status;
GError *error = NULL;
image = file_open_with_display (context->pika, context, NULL,
file, FALSE,
G_OBJECT (pika_widget_get_monitor (widget)),
&status, &error);
if (! image && status != PIKA_PDB_CANCEL)
{
pika_message (context->pika, G_OBJECT (view),
PIKA_MESSAGE_ERROR,
_("Opening '%s' failed:\n\n%s"),
pika_file_get_utf8_name (file), error->message);
g_clear_error (&error);
}
}
}
void
data_new_cmd_callback (PikaAction *action,
GVariant *value,
gpointer user_data)
{
PikaDataFactoryView *view = PIKA_DATA_FACTORY_VIEW (user_data);
if (pika_data_factory_view_has_data_new_func (view))
{
PikaDataFactory *factory;
PikaContext *context;
PikaData *data;
factory = pika_data_factory_view_get_data_factory (view);
context =
pika_container_view_get_context (PIKA_CONTAINER_EDITOR (view)->view);
data = pika_data_factory_data_new (factory, context, _("Untitled"));
if (data)
{
pika_context_set_by_type (context,
pika_data_factory_view_get_children_type (view),
PIKA_OBJECT (data));
gtk_button_clicked (GTK_BUTTON (pika_data_factory_view_get_edit_button (view)));
}
}
}
void
data_duplicate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer user_data)
{
PikaDataFactoryView *view = PIKA_DATA_FACTORY_VIEW (user_data);
PikaContext *context;
PikaData *data;
context = pika_container_view_get_context (PIKA_CONTAINER_EDITOR (view)->view);
data = (PikaData *)
pika_context_get_by_type (context,
pika_data_factory_view_get_children_type (view));
if (data && pika_data_factory_view_have (view, PIKA_OBJECT (data)))
{
PikaData *new_data;
new_data = pika_data_factory_data_duplicate (pika_data_factory_view_get_data_factory (view), data);
if (new_data)
{
pika_context_set_by_type (context,
pika_data_factory_view_get_children_type (view),
PIKA_OBJECT (new_data));
gtk_button_clicked (GTK_BUTTON (pika_data_factory_view_get_edit_button (view)));
}
}
}
void
data_copy_location_cmd_callback (PikaAction *action,
GVariant *value,
gpointer user_data)
{
PikaDataFactoryView *view = PIKA_DATA_FACTORY_VIEW (user_data);
PikaContext *context;
PikaData *data;
context = pika_container_view_get_context (PIKA_CONTAINER_EDITOR (view)->view);
data = (PikaData *)
pika_context_get_by_type (context,
pika_data_factory_view_get_children_type (view));
if (data)
{
GFile *file = pika_data_get_file (data);
if (file)
{
gchar *uri = g_file_get_uri (file);
pika_clipboard_set_text (context->pika, uri);
g_free (uri);
}
}
}
void
data_show_in_file_manager_cmd_callback (PikaAction *action,
GVariant *value,
gpointer user_data)
{
PikaDataFactoryView *view = PIKA_DATA_FACTORY_VIEW (user_data);
PikaContext *context;
PikaData *data;
context = pika_container_view_get_context (PIKA_CONTAINER_EDITOR (view)->view);
data = (PikaData *)
pika_context_get_by_type (context,
pika_data_factory_view_get_children_type (view));
if (data)
{
GFile *file = pika_data_get_file (data);
if (file)
{
GError *error = NULL;
if (! pika_file_show_in_file_manager (file, &error))
{
pika_message (context->pika, G_OBJECT (view),
PIKA_MESSAGE_ERROR,
_("Can't show file in file manager: %s"),
error->message);
g_clear_error (&error);
}
}
}
}
void
data_delete_cmd_callback (PikaAction *action,
GVariant *value,
gpointer user_data)
{
PikaDataFactoryView *view = PIKA_DATA_FACTORY_VIEW (user_data);
PikaContext *context;
PikaData *data;
context =
pika_container_view_get_context (PIKA_CONTAINER_EDITOR (view)->view);
data = (PikaData *)
pika_context_get_by_type (context,
pika_data_factory_view_get_children_type (view));
if (data &&
pika_data_is_deletable (data) &&
pika_data_factory_view_have (view, PIKA_OBJECT (data)))
{
PikaDataFactory *factory;
GtkWidget *dialog;
factory = pika_data_factory_view_get_data_factory (view);
dialog = data_delete_dialog_new (factory, data, context,
GTK_WIDGET (view));
gtk_widget_show (dialog);
}
}
void
data_refresh_cmd_callback (PikaAction *action,
GVariant *value,
gpointer user_data)
{
PikaDataFactoryView *view = PIKA_DATA_FACTORY_VIEW (user_data);
Pika *pika;
return_if_no_pika (pika, user_data);
pika_set_busy (pika);
pika_data_factory_data_refresh (pika_data_factory_view_get_data_factory (view),
action_data_get_context (user_data));
pika_unset_busy (pika);
}
void
data_edit_cmd_callback (PikaAction *action,
GVariant *value,
gpointer user_data)
{
PikaDataFactoryView *view = PIKA_DATA_FACTORY_VIEW (user_data);
PikaContext *context;
PikaData *data;
context = pika_container_view_get_context (PIKA_CONTAINER_EDITOR (view)->view);
data = (PikaData *)
pika_context_get_by_type (context,
pika_data_factory_view_get_children_type (view));
if (data && pika_data_factory_view_have (view, PIKA_OBJECT (data)))
{
GdkMonitor *monitor = pika_widget_get_monitor (GTK_WIDGET (view));
GtkWidget *dockable;
dockable =
pika_window_strategy_show_dockable_dialog (PIKA_WINDOW_STRATEGY (pika_get_window_strategy (context->pika)),
context->pika,
pika_dialog_factory_get_singleton (),
monitor,
g_variant_get_string (value,
NULL));
pika_data_editor_set_data (PIKA_DATA_EDITOR (gtk_bin_get_child (GTK_BIN (dockable))),
data);
}
}

View File

@ -0,0 +1,52 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DATA_COMMANDS_H__
#define __DATA_COMMANDS_H__
void data_open_as_image_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void data_new_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void data_duplicate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void data_copy_location_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void data_show_in_file_manager_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void data_delete_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void data_refresh_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void data_edit_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DATA_COMMANDS_H__ */

View File

@ -0,0 +1,47 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "actions-types.h"
#include "widgets/pikadataeditor.h"
#include "data-editor-commands.h"
/* public functions */
void
data_editor_edit_active_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDataEditor *editor = PIKA_DATA_EDITOR (data);
gboolean edit_active;
edit_active = g_variant_get_boolean (value);
pika_data_editor_set_edit_active (editor, edit_active);
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DATA_EDITOR_COMMANDS_H__
#define __DATA_EDITOR_COMMANDS_H__
void data_editor_edit_active_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DATA_EDITOR_COMMANDS_H__ */

106
app/actions/debug-actions.c Normal file
View File

@ -0,0 +1,106 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "widgets/pikaactiongroup.h"
#include "debug-actions.h"
#include "debug-commands.h"
#include "pika-intl.h"
static const PikaActionEntry debug_actions[] =
{
{ "debug-gtk-inspector", NULL,
N_("Start _GtkInspector"), NULL, { NULL }, NULL,
debug_gtk_inspector_cmd_callback,
NULL },
{ "debug-mem-profile", NULL,
N_("_Memory Profile"), NULL, { NULL }, NULL,
debug_mem_profile_cmd_callback,
NULL },
{ "debug-benchmark-projection", NULL,
N_("Benchmark _Projection"), NULL, { NULL },
N_("Invalidates the entire projection, measures the time it takes to "
"validate (render) the part that is visible in the active display, "
"and print the result to stdout."),
debug_benchmark_projection_cmd_callback,
NULL },
{ "debug-show-image-graph", NULL,
N_("Show Image _Graph"), NULL, { NULL },
N_("Creates a new image showing the GEGL graph of this image"),
debug_show_image_graph_cmd_callback,
NULL },
{ "debug-dump-keyboard-shortcuts", NULL,
N_("Dump _Keyboard Shortcuts"), NULL, { NULL }, NULL,
debug_dump_keyboard_shortcuts_cmd_callback,
NULL },
{ "debug-dump-attached-data", NULL,
N_("Dump _Attached Data"), NULL, { NULL }, NULL,
debug_dump_attached_data_cmd_callback,
NULL }
};
void
debug_actions_setup (PikaActionGroup *group)
{
gint i;
pika_action_group_add_actions (group, NULL,
debug_actions,
G_N_ELEMENTS (debug_actions));
#define SET_VISIBLE(action,condition) \
pika_action_group_set_action_visible (group, action, (condition) != 0)
for (i = 0; i < G_N_ELEMENTS (debug_actions); i++)
SET_VISIBLE (debug_actions[i].name, group->pika->show_debug_menu);
#undef SET_VISIBLE
}
void
debug_actions_update (PikaActionGroup *group,
gpointer data)
{
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("debug-show-image-graph", gegl_has_operation ("gegl:introspect"));
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DEBUG_ACTIONS_H__
#define __DEBUG_ACTIONS_H__
void debug_actions_setup (PikaActionGroup *group);
void debug_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __DEBUG_ACTIONS_H__ */

View File

@ -0,0 +1,302 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pika-utils.h"
#include "core/pikacontext.h"
#include "core/pikaimage.h"
#include "core/pikaprojectable.h"
#include "core/pikaprojection.h"
#include "gegl/pika-gegl-utils.h"
#include "widgets/pikaaction.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikamenufactory.h"
#include "widgets/pikauimanager.h"
#include "display/pikadisplay.h"
#include "display/pikadisplayshell.h"
#include "display/pikaimagewindow.h"
#include "menus/menus.h"
#include "actions.h"
#include "debug-commands.h"
/* local function prototypes */
static gboolean debug_benchmark_projection (PikaDisplay *display);
static gboolean debug_show_image_graph (PikaImage *source_image);
static void debug_print_qdata (PikaObject *object);
static void debug_print_qdata_foreach (GQuark key_id,
gpointer data,
gpointer user_data);
/* public functions */
void
debug_gtk_inspector_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
gtk_window_set_interactive_debugging (TRUE);
}
void
debug_mem_profile_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
extern gboolean pika_debug_memsize;
Pika *pika;
return_if_no_pika (pika, data);
pika_debug_memsize = TRUE;
pika_object_get_memsize (PIKA_OBJECT (pika), NULL);
pika_debug_memsize = FALSE;
}
void
debug_benchmark_projection_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDisplay *display;
return_if_no_display (display, data);
g_idle_add ((GSourceFunc) debug_benchmark_projection, g_object_ref (display));
}
void
debug_show_image_graph_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *source_image = NULL;
return_if_no_image (source_image, data);
g_idle_add ((GSourceFunc) debug_show_image_graph, g_object_ref (source_image));
}
void
debug_dump_keyboard_shortcuts_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDisplay *display;
PikaUIManager *manager;
GList *group_it;
GList *strings = NULL;
return_if_no_display (display, data);
manager = menus_get_image_manager_singleton (display->pika);
/* Gather formatted strings of keyboard shortcuts */
for (group_it = pika_ui_manager_get_action_groups (manager);
group_it;
group_it = g_list_next (group_it))
{
PikaActionGroup *group = group_it->data;
GList *actions = NULL;
GList *action_it = NULL;
actions = pika_action_group_list_actions (group);
actions = g_list_sort (actions, (GCompareFunc) pika_action_name_compare);
for (action_it = actions; action_it; action_it = g_list_next (action_it))
{
gchar **accels;
PikaAction *action = action_it->data;
const gchar *name = pika_action_get_name (action);
if (name[0] == '<')
continue;
accels = pika_action_get_display_accels (action);
if (accels && accels[0])
{
const gchar *label_tmp;
gchar *label;
label_tmp = pika_action_get_label (action);
label = pika_strip_uline (label_tmp);
strings = g_list_prepend (strings,
g_strdup_printf ("%-20s %s",
accels[0], label));
g_free (label);
for (gint i = 1; accels[i] != NULL; i++)
strings = g_list_prepend (strings, g_strdup (accels[i]));
}
g_strfreev (accels);
}
g_list_free (actions);
}
/* Sort and prints the strings */
{
GList *string_it = NULL;
strings = g_list_sort (strings, (GCompareFunc) strcmp);
for (string_it = strings; string_it; string_it = g_list_next (string_it))
{
g_print ("%s\n", (gchar *) string_it->data);
g_free (string_it->data);
}
g_list_free (strings);
}
}
void
debug_dump_attached_data_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika = action_data_get_pika (data);
PikaContext *user_context = pika_get_user_context (pika);
debug_print_qdata (PIKA_OBJECT (pika));
debug_print_qdata (PIKA_OBJECT (user_context));
}
/* private functions */
static gboolean
debug_benchmark_projection (PikaDisplay *display)
{
PikaImage *image = pika_display_get_image (display);
if (image)
{
PikaProjection *projection = pika_image_get_projection (image);
pika_projection_stop_rendering (projection);
PIKA_TIMER_START ();
pika_image_invalidate_all (image);
pika_projection_flush_now (projection, TRUE);
PIKA_TIMER_END ("Validation of the entire projection");
g_object_unref (display);
}
return FALSE;
}
static gboolean
debug_show_image_graph (PikaImage *source_image)
{
GeglNode *image_graph;
GeglNode *output_node;
PikaImage *new_image;
GeglNode *introspect;
GeglNode *sink;
GeglBuffer *buffer = NULL;
image_graph = pika_projectable_get_graph (PIKA_PROJECTABLE (source_image));
output_node = gegl_node_get_output_proxy (image_graph, "output");
introspect = gegl_node_new_child (NULL,
"operation", "gegl:introspect",
"node", output_node,
NULL);
sink = gegl_node_new_child (NULL,
"operation", "gegl:buffer-sink",
"buffer", &buffer,
NULL);
gegl_node_link_many (introspect, sink, NULL);
gegl_node_process (sink);
if (buffer)
{
gchar *new_name;
/* This should not happen but "gegl:introspect" is a bit fickle as
* it uses an external binary `dot`. Prevent useless crashes.
* I don't output a warning when buffer is NULL because anyway
* GEGL will output one itself.
*/
new_name = g_strdup_printf ("%s GEGL graph",
pika_image_get_display_name (source_image));
new_image = pika_create_image_from_buffer (source_image->pika,
buffer, new_name);
pika_image_set_file (new_image, g_file_new_for_uri (new_name));
g_free (new_name);
g_object_unref (buffer);
}
g_object_unref (sink);
g_object_unref (introspect);
g_object_unref (source_image);
return FALSE;
}
static void
debug_print_qdata (PikaObject *object)
{
g_print ("\nData attached to '%s':\n\n", pika_object_get_name (object));
g_datalist_foreach (&G_OBJECT (object)->qdata,
debug_print_qdata_foreach,
NULL);
g_print ("\n");
}
static void
debug_print_qdata_foreach (GQuark key_id,
gpointer data,
gpointer user_data)
{
g_print ("%s: %p\n", g_quark_to_string (key_id), data);
}

View File

@ -0,0 +1,49 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DEBUG_COMMANDS_H__
#define __DEBUG_COMMANDS_H__
void debug_gtk_inspector_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void debug_mem_profile_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void debug_benchmark_projection_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void debug_show_image_graph_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void debug_dump_menus_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void debug_dump_keyboard_shortcuts_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void debug_dump_attached_data_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DEBUG_COMMANDS_H__ */

View File

@ -0,0 +1,456 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikadialogfactory.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikasessioninfo.h"
#include "widgets/pikatoolbox.h"
#include "display/pikaimagewindow.h"
#include "actions.h"
#include "dialogs-actions.h"
#include "dialogs-commands.h"
#include "pika-intl.h"
const PikaStringActionEntry dialogs_dockable_actions[] =
{
{ "dialogs-toolbox", NULL,
NC_("windows-action", "Tool_box"), NULL, { "<primary>B", NULL },
NULL /* set in dialogs_actions_update() */,
"pika-toolbox",
PIKA_HELP_TOOLBOX },
{ "dialogs-tool-options", PIKA_ICON_DIALOG_TOOL_OPTIONS,
NC_("dialogs-action", "Tool _Options Dialog"),
NC_("dialogs-action", "Tool _Options"),
{ NULL },
NC_("dialogs-action", "Open the tool options dialog"),
"pika-tool-options",
PIKA_HELP_TOOL_OPTIONS_DIALOG },
{ "dialogs-device-status", PIKA_ICON_DIALOG_DEVICE_STATUS,
NC_("dialogs-action", "_Device Status Dialog"),
NC_("dialogs-action", "_Device Status"),
{ NULL },
NC_("dialogs-action", "Open the device status dialog"),
"pika-device-status",
PIKA_HELP_DEVICE_STATUS_DIALOG },
{ "dialogs-symmetry", PIKA_ICON_SYMMETRY,
NC_("dialogs-action", "_Symmetry Painting Dialog"),
NC_("dialogs-action", "_Symmetry Painting"),
{ NULL },
NC_("dialogs-action", "Open the symmetry dialog"),
"pika-symmetry-editor",
PIKA_HELP_SYMMETRY_DIALOG },
{ "dialogs-layers", PIKA_ICON_DIALOG_LAYERS,
NC_("dialogs-action", "_Layers Dialog"),
NC_("dialogs-action", "_Layers"),
{ "<primary>L", NULL },
NC_("dialogs-action", "Open the layers dialog"),
"pika-layer-list",
PIKA_HELP_LAYER_DIALOG },
{ "dialogs-channels", PIKA_ICON_DIALOG_CHANNELS,
NC_("dialogs-action", "_Channels Dialog"),
NC_("dialogs-action", "_Channels"),
{ NULL },
NC_("dialogs-action", "Open the channels dialog"),
"pika-channel-list",
PIKA_HELP_CHANNEL_DIALOG },
{ "dialogs-vectors", PIKA_ICON_DIALOG_PATHS,
NC_("dialogs-action", "_Paths Dialog"),
NC_("dialogs-action", "_Paths"),
{ NULL },
NC_("dialogs-action", "Open the paths dialog"),
"pika-vectors-list",
PIKA_HELP_PATH_DIALOG },
{ "dialogs-indexed-palette", PIKA_ICON_COLORMAP,
NC_("dialogs-action", "Color_map Dialog"),
NC_("dialogs-action", "Color_map"),
{ NULL },
NC_("dialogs-action", "Open the colormap dialog"),
"pika-indexed-palette",
PIKA_HELP_INDEXED_PALETTE_DIALOG },
{ "dialogs-histogram", PIKA_ICON_HISTOGRAM,
NC_("dialogs-action", "Histogra_m Dialog"),
NC_("dialogs-action", "Histogra_m"),
{ NULL },
NC_("dialogs-action", "Open the histogram dialog"),
"pika-histogram-editor",
PIKA_HELP_HISTOGRAM_DIALOG },
{ "dialogs-selection-editor", PIKA_ICON_SELECTION,
NC_("dialogs-action", "_Selection Editor"), NULL,
{ NULL },
NC_("dialogs-action", "Open the selection editor"),
"pika-selection-editor",
PIKA_HELP_SELECTION_DIALOG },
{ "dialogs-navigation", PIKA_ICON_DIALOG_NAVIGATION,
NC_("dialogs-action", "Na_vigation Dialog"),
NC_("dialogs-action", "Na_vigation"),
{ NULL },
NC_("dialogs-action", "Open the display navigation dialog"),
"pika-navigation-view",
PIKA_HELP_NAVIGATION_DIALOG },
{ "dialogs-undo-history", PIKA_ICON_DIALOG_UNDO_HISTORY,
NC_("dialogs-action", "Undo _History Dialog"),
NC_("dialogs-action", "Undo _History"),
{ NULL },
NC_("dialogs-action", "Open the undo history dialog"),
"pika-undo-history",
PIKA_HELP_UNDO_DIALOG },
{ "dialogs-cursor", PIKA_ICON_CURSOR,
NC_("dialogs-action", "_Pointer Dialog"),
NC_("dialogs-action", "_Pointer"),
{ NULL },
NC_("dialogs-action", "Open the pointer information dialog"),
"pika-cursor-view",
PIKA_HELP_POINTER_INFO_DIALOG },
{ "dialogs-sample-points", PIKA_ICON_SAMPLE_POINT,
NC_("dialogs-action", "_Sample Points Dialog"),
NC_("dialogs-action", "_Sample Points"),
{ NULL },
NC_("dialogs-action", "Open the sample points dialog"),
"pika-sample-point-editor",
PIKA_HELP_SAMPLE_POINT_DIALOG },
{ "dialogs-colors", PIKA_ICON_COLORS_DEFAULT,
NC_("dialogs-action", "Colo_rs Dialog"),
NC_("dialogs-action", "Colo_rs"),
{ NULL },
NC_("dialogs-action", "Open the FG/BG color dialog"),
"pika-color-editor",
PIKA_HELP_COLOR_DIALOG },
{ "dialogs-brushes", PIKA_ICON_BRUSH,
NC_("dialogs-action", "_Brushes Dialog"),
NC_("dialogs-action", "_Brushes"),
{ "<primary><shift>B", NULL },
NC_("dialogs-action", "Open the brushes dialog"),
"pika-brush-grid|pika-brush-list",
PIKA_HELP_BRUSH_DIALOG },
{ "dialogs-brush-editor", PIKA_ICON_BRUSH,
NC_("dialogs-action", "Brush Editor"), NULL,
{ NULL },
NC_("dialogs-action", "Open the brush editor"),
"pika-brush-editor",
PIKA_HELP_BRUSH_EDIT },
{ "dialogs-dynamics", PIKA_ICON_DYNAMICS,
NC_("dialogs-action", "Paint D_ynamics Dialog"),
NC_("dialogs-action", "Paint D_ynamics"),
{ NULL },
NC_("dialogs-action", "Open paint dynamics dialog"),
"pika-dynamics-list|pika-dynamics-grid",
PIKA_HELP_DYNAMICS_DIALOG },
{ "dialogs-dynamics-editor", PIKA_ICON_DYNAMICS,
NC_("dialogs-action", "Paint Dynamics Editor"), NULL,
{ NULL },
NC_("dialogs-action", "Open the paint dynamics editor"),
"pika-dynamics-editor",
PIKA_HELP_DYNAMICS_EDITOR_DIALOG },
{ "dialogs-mypaint-brushes", PIKA_ICON_MYPAINT_BRUSH,
NC_("dialogs-action", "_MyPaint Brushes Dialog"),
NC_("dialogs-action", "_MyPaint Brushes"),
{ NULL },
NC_("dialogs-action", "Open the mypaint brushes dialog"),
"pika-mypaint-brush-grid|pika-mapyint-brush-list",
PIKA_HELP_MYPAINT_BRUSH_DIALOG },
{ "dialogs-patterns", PIKA_ICON_PATTERN,
NC_("dialogs-action", "P_atterns Dialog"),
NC_("dialogs-action", "P_atterns"),
{ "<primary><shift>P", NULL },
NC_("dialogs-action", "Open the patterns dialog"),
"pika-pattern-grid|pika-pattern-list",
PIKA_HELP_PATTERN_DIALOG },
{ "dialogs-gradients", PIKA_ICON_GRADIENT,
NC_("dialogs-action", "_Gradients Dialog"),
NC_("dialogs-action", "_Gradients"),
{ "<primary>G", NULL },
NC_("dialogs-action", "Open the gradients dialog"),
"pika-gradient-list|pika-gradient-grid",
PIKA_HELP_GRADIENT_DIALOG },
{ "dialogs-gradient-editor", PIKA_ICON_GRADIENT,
NC_("dialogs-action", "Gradient Editor"), NULL,
{ NULL },
NC_("dialogs-action", "Open the gradient editor"),
"pika-gradient-editor",
PIKA_HELP_GRADIENT_EDIT },
{ "dialogs-palettes", PIKA_ICON_PALETTE,
NC_("dialogs-action", "Pal_ettes Dialog"),
NC_("dialogs-action", "Pal_ettes"),
{ NULL },
NC_("dialogs-action", "Open the palettes dialog"),
"pika-palette-list|pika-palette-grid",
PIKA_HELP_PALETTE_DIALOG },
{ "dialogs-palette-editor", PIKA_ICON_PALETTE,
NC_("dialogs-action", "Palette _Editor"),
NC_("dialogs-action", "Palette _Editor"),
{ NULL },
NC_("dialogs-action", "Open the palette editor"),
"pika-palette-editor",
PIKA_HELP_PALETTE_EDIT },
{ "dialogs-tool-presets", PIKA_ICON_TOOL_PRESET,
NC_("dialogs-action", "Tool Pre_sets Dialog"),
NC_("dialogs-action", "Tool Pre_sets"),
{ NULL },
NC_("dialogs-action", "Open tool presets dialog"),
"pika-tool-preset-list|pika-tool-preset-grid",
PIKA_HELP_TOOL_PRESET_DIALOG },
{ "dialogs-fonts", PIKA_ICON_FONT,
NC_("dialogs-action", "_Fonts Dialog"),
NC_("dialogs-action", "_Fonts"),
{ NULL },
NC_("dialogs-action", "Open the fonts dialog"),
"pika-font-list|pika-font-grid",
PIKA_HELP_FONT_DIALOG },
{ "dialogs-buffers", PIKA_ICON_BUFFER,
NC_("dialogs-action", "B_uffers Dialog"),
NC_("dialogs-action", "B_uffers"),
{ NULL },
NC_("dialogs-action", "Open the named buffers dialog"),
"pika-buffer-list|pika-buffer-grid",
PIKA_HELP_BUFFER_DIALOG },
{ "dialogs-images", PIKA_ICON_DIALOG_IMAGES,
NC_("dialogs-action", "_Images Dialog"),
NC_("dialogs-action", "_Images"),
{ NULL },
NC_("dialogs-action", "Open the images dialog"),
"pika-image-list|pika-image-grid",
PIKA_HELP_IMAGE_DIALOG },
{ "dialogs-document-history", PIKA_ICON_DOCUMENT_OPEN_RECENT,
NC_("dialogs-action", "Document Histor_y Dialog"),
NC_("dialogs-action", "Document Histor_y"),
{ NULL },
NC_("dialogs-action", "Open the document history dialog"),
"pika-document-list|pika-document-grid",
PIKA_HELP_DOCUMENT_DIALOG },
{ "dialogs-templates", PIKA_ICON_TEMPLATE,
NC_("dialogs-action", "_Templates Dialog"),
NC_("dialogs-action", "_Templates"),
{ NULL },
NC_("dialogs-action", "Open the image templates dialog"),
"pika-template-list|pika-template-grid",
PIKA_HELP_TEMPLATE_DIALOG },
{ "dialogs-error-console", PIKA_ICON_DIALOG_WARNING,
NC_("dialogs-action", "Error Co_nsole"),
NC_("dialogs-action", "Error Co_nsole"),
{ NULL },
NC_("dialogs-action", "Open the error console"),
"pika-error-console",
PIKA_HELP_ERRORS_DIALOG },
{ "dialogs-dashboard", PIKA_ICON_DIALOG_DASHBOARD,
NC_("dialogs-action", "_Dashboard"),
NC_("dialogs-action", "_Dashboard"),
{ NULL },
NC_("dialogs-action", "Open the dashboard"),
"pika-dashboard",
PIKA_HELP_ERRORS_DIALOG }
};
gint n_dialogs_dockable_actions = G_N_ELEMENTS (dialogs_dockable_actions);
static const PikaStringActionEntry dialogs_toplevel_actions[] =
{
{ "dialogs-preferences", PIKA_ICON_PREFERENCES_SYSTEM,
NC_("dialogs-action", "_Preferences"),
NC_("dialogs-action", "_Preferences"),
{ NULL },
NC_("dialogs-action", "Open the preferences dialog"),
"pika-preferences-dialog",
PIKA_HELP_PREFS_DIALOG },
{ "dialogs-input-devices", PIKA_ICON_INPUT_DEVICE,
NC_("dialogs-action", "_Input Devices Editor"),
NC_("dialogs-action", "_Input Devices"),
{ NULL },
NC_("dialogs-action", "Open the input devices editor"),
"pika-input-devices-dialog",
PIKA_HELP_INPUT_DEVICES },
{ "dialogs-keyboard-shortcuts", PIKA_ICON_CHAR_PICKER,
NC_("dialogs-action", "_Keyboard Shortcuts Editor"),
NC_("dialogs-action", "_Keyboard Shortcuts"),
{ NULL },
NC_("dialogs-action", "Open the keyboard shortcuts editor"),
"pika-keyboard-shortcuts-dialog",
PIKA_HELP_KEYBOARD_SHORTCUTS },
{ "dialogs-module-dialog", PIKA_ICON_SYSTEM_RUN,
NC_("dialogs-action", "_Modules Dialog"),
NC_("dialogs-action", "_Modules"),
{ NULL },
NC_("dialogs-action", "Open the module manager dialog"),
"pika-module-dialog",
PIKA_HELP_MODULE_DIALOG },
{ "dialogs-tips", PIKA_ICON_DIALOG_INFORMATION,
NC_("dialogs-action", "_Tip of the Day"), NULL,
{ NULL },
NC_("dialogs-action", "Show some helpful tips on using PIKA"),
"pika-tips-dialog",
PIKA_HELP_TIPS_DIALOG },
{ "dialogs-welcome", PIKA_ICON_DIALOG_INFORMATION,
NC_("dialogs-action", "Welcome Dialog"), NULL,
{ NULL },
NC_("dialogs-action", "Show information on running PIKA release"),
"pika-welcome-dialog",
PIKA_HELP_WELCOME_DIALOG },
{ "dialogs-about", PIKA_ICON_HELP_ABOUT,
#if defined(G_OS_WIN32)
NC_("dialogs-action", "About PIKA"),
#elif defined(PLATFORM_OSX)
NC_("dialogs-action", "About"),
#else /* UNIX: use GNOME HIG */
NC_("dialogs-action", "_About"),
#endif
NULL, { NULL },
NC_("dialogs-action", "About PIKA"),
"pika-about-dialog",
PIKA_HELP_ABOUT_DIALOG },
{ "dialogs-action-search", PIKA_ICON_TOOL_ZOOM,
NC_("dialogs-action", "_Search and Run a Command"), NULL,
{ "slash", "KP_Divide", NULL },
NC_("dialogs-action", "Search commands by keyword, and run them"),
"pika-action-search-dialog",
PIKA_HELP_ACTION_SEARCH_DIALOG },
{ "dialogs-extensions", PIKA_ICON_PLUGIN,
NC_("dialogs-action", "Manage _Extensions"), NULL,
{ NULL },
NC_("dialogs-action", "Manage Extensions: search, install, uninstall, update."),
"pika-extensions-dialog",
PIKA_HELP_EXTENSIONS_DIALOG }
};
gboolean
dialogs_actions_toolbox_exists (Pika *pika)
{
PikaDialogFactory *factory = pika_dialog_factory_get_singleton ();
gboolean toolbox_found = FALSE;
GList *iter;
/* First look in session managed windows */
toolbox_found =
pika_dialog_factory_find_widget (factory, "pika-toolbox-window") != NULL;
/* Then in image windows */
if (! toolbox_found)
{
GList *windows = pika ? pika_get_image_windows (pika) : NULL;
for (iter = windows; iter; iter = g_list_next (iter))
{
PikaImageWindow *window = PIKA_IMAGE_WINDOW (windows->data);
if (pika_image_window_has_toolbox (window))
{
toolbox_found = TRUE;
break;
}
}
g_list_free (windows);
}
return toolbox_found;
}
void
dialogs_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_string_actions (group, "dialogs-action",
dialogs_dockable_actions,
G_N_ELEMENTS (dialogs_dockable_actions),
dialogs_create_dockable_cmd_callback);
pika_action_group_add_string_actions (group, "dialogs-action",
dialogs_toplevel_actions,
G_N_ELEMENTS (dialogs_toplevel_actions),
dialogs_create_toplevel_cmd_callback);
}
void
dialogs_actions_update (PikaActionGroup *group,
gpointer data)
{
Pika *pika = action_data_get_pika (data);
const gchar *toolbox_label = NULL;
const gchar *toolbox_tooltip = NULL;
if (dialogs_actions_toolbox_exists (pika))
{
toolbox_label = _("Tool_box");
toolbox_tooltip = _("Raise the toolbox");
}
else
{
toolbox_label = _("New Tool_box");
toolbox_tooltip = _("Create a new toolbox");
}
pika_action_group_set_action_label (group, "dialogs-toolbox", toolbox_label);
pika_action_group_set_action_tooltip (group, "dialogs-toolbox", toolbox_tooltip);
}

View File

@ -0,0 +1,42 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DIALOGS_ACTIONS_H__
#define __DIALOGS_ACTIONS_H__
/* this check is needed for the extern declaration below to be correct */
#ifndef __PIKA_ACTION_GROUP_H__
#error "widgets/pikaactiongroup.h must be included prior to dialogs-actions.h"
#endif
extern const PikaStringActionEntry dialogs_dockable_actions[];
extern gint n_dialogs_dockable_actions;
void dialogs_actions_setup (PikaActionGroup *group);
void dialogs_actions_update (PikaActionGroup *group,
gpointer data);
gboolean dialogs_actions_toolbox_exists (Pika *pika);
#endif /* __DIALOGS_ACTIONS_H__ */

View File

@ -0,0 +1,81 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "widgets/pikadialogfactory.h"
#include "widgets/pikawidgets-utils.h"
#include "widgets/pikawindowstrategy.h"
#include "actions.h"
#include "dialogs-commands.h"
/* public functions */
void
dialogs_create_toplevel_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
GtkWidget *widget;
const gchar *identifier;
return_if_no_widget (widget, data);
identifier = g_variant_get_string (value, NULL);
if (identifier)
pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
pika_widget_get_monitor (widget),
NULL /*ui_manager*/,
widget,
identifier, -1, TRUE);
}
void
dialogs_create_dockable_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
GtkWidget *widget;
const gchar *identifier;
return_if_no_pika (pika, data);
return_if_no_widget (widget, data);
identifier = g_variant_get_string (value, NULL);
if (identifier)
pika_window_strategy_show_dockable_dialog (PIKA_WINDOW_STRATEGY (pika_get_window_strategy (pika)),
pika,
pika_dialog_factory_get_singleton (),
pika_widget_get_monitor (widget),
identifier);
}

View File

@ -0,0 +1,34 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DIALOGS_COMMANDS_H__
#define __DIALOGS_COMMANDS_H__
void dialogs_create_toplevel_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dialogs_create_dockable_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DIALOGS_COMMANDS_H__ */

141
app/actions/dock-actions.c Normal file
View File

@ -0,0 +1,141 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikadockwindow.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikamenudock.h"
#include "display/pikaimagewindow.h"
#include "actions.h"
#include "dock-actions.h"
#include "dock-commands.h"
#include "window-actions.h"
#include "window-commands.h"
#include "pika-intl.h"
static const PikaActionEntry dock_actions[] =
{
{ "dock-close", PIKA_ICON_WINDOW_CLOSE,
NC_("dock-action", "Close Dock"), NULL, { NULL }, NULL,
window_close_cmd_callback,
PIKA_HELP_DOCK_CLOSE },
{ "dock-open-display", NULL,
NC_("dock-action", "_Open Display..."), NULL, { NULL },
NC_("dock-action", "Connect to another display"),
window_open_display_cmd_callback,
NULL }
};
static const PikaToggleActionEntry dock_toggle_actions[] =
{
{ "dock-show-image-menu", NULL,
NC_("dock-action", "_Show Image Selection"), NULL, { NULL }, NULL,
dock_toggle_image_menu_cmd_callback,
TRUE,
PIKA_HELP_DOCK_IMAGE_MENU },
{ "dock-auto-follow-active", NULL,
NC_("dock-action", "Auto _Follow Active Image"), NULL, { NULL }, NULL,
dock_toggle_auto_cmd_callback,
TRUE,
PIKA_HELP_DOCK_AUTO_BUTTON }
};
void
dock_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "dock-action",
dock_actions,
G_N_ELEMENTS (dock_actions));
pika_action_group_add_toggle_actions (group, "dock-action",
dock_toggle_actions,
G_N_ELEMENTS (dock_toggle_actions));
window_actions_setup (group, PIKA_HELP_DOCK_CHANGE_SCREEN);
}
void
dock_actions_update (PikaActionGroup *group,
gpointer data)
{
GtkWidget *widget = action_data_get_widget (data);
GtkWidget *toplevel = NULL;
if (widget)
toplevel = gtk_widget_get_toplevel (widget);
#define SET_ACTIVE(action,active) \
pika_action_group_set_action_active (group, action, (active) != 0)
#define SET_VISIBLE(action,active) \
pika_action_group_set_action_visible (group, action, (active) != 0)
if (PIKA_IS_DOCK_WINDOW (toplevel))
{
PikaDockWindow *dock_window = PIKA_DOCK_WINDOW (toplevel);
gboolean show_image_menu = ! pika_dock_window_has_toolbox (dock_window);
if (show_image_menu)
{
SET_VISIBLE ("dock-show-image-menu", TRUE);
SET_VISIBLE ("dock-auto-follow-active", TRUE);
SET_ACTIVE ("dock-show-image-menu",
pika_dock_window_get_show_image_menu (dock_window));
SET_ACTIVE ("dock-auto-follow-active",
pika_dock_window_get_auto_follow_active (dock_window));
}
else
{
SET_VISIBLE ("dock-show-image-menu", FALSE);
SET_VISIBLE ("dock-auto-follow-active", FALSE);
}
/* update the window actions only in the context of their
* own window (not in the context of some display or NULL)
* (see view-actions.c)
*/
window_actions_update (group, toplevel);
}
else if (PIKA_IS_IMAGE_WINDOW (toplevel))
{
SET_VISIBLE ("dock-show-image-menu", FALSE);
SET_VISIBLE ("dock-auto-follow-active", FALSE);
}
#undef SET_ACTIVE
#undef SET_VISIBLE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DOCK_ACTIONS_H__
#define __DOCK_ACTIONS_H__
void dock_actions_setup (PikaActionGroup *group);
void dock_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __DOCK_ACTIONS_H__ */

View File

@ -0,0 +1,89 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "widgets/pikadockwindow.h"
#include "widgets/pikadockwindow.h"
#include "actions.h"
#include "dock-commands.h"
static PikaDockWindow *
dock_commands_get_dock_window_from_widget (GtkWidget *widget)
{
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
PikaDockWindow *dock_window = NULL;
if (PIKA_IS_DOCK_WINDOW (toplevel))
dock_window = PIKA_DOCK_WINDOW (toplevel);
return dock_window;
}
/* public functions */
void
dock_toggle_image_menu_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
GtkWidget *widget = NULL;
PikaDockWindow *dock_window = NULL;
return_if_no_widget (widget, data);
dock_window = dock_commands_get_dock_window_from_widget (widget);
if (dock_window)
{
gboolean active = g_variant_get_boolean (value);
pika_dock_window_set_show_image_menu (dock_window, active);
}
}
void
dock_toggle_auto_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
GtkWidget *widget = NULL;
PikaDockWindow *dock_window = NULL;
return_if_no_widget (widget, data);
dock_window = dock_commands_get_dock_window_from_widget (widget);
if (dock_window)
{
gboolean active = g_variant_get_boolean (value);
pika_dock_window_set_auto_follow_active (dock_window, active);
}
}

View File

@ -0,0 +1,34 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DOCK_COMMANDS_H__
#define __DOCK_COMMANDS_H__
void dock_toggle_image_menu_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dock_toggle_auto_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DOCK_COMMANDS_H__ */

View File

@ -0,0 +1,361 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <string.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikacontainerview.h"
#include "widgets/pikacontainerview-utils.h"
#include "widgets/pikadialogfactory.h"
#include "widgets/pikadock.h"
#include "widgets/pikadockable.h"
#include "widgets/pikadockbook.h"
#include "widgets/pikadocked.h"
#include "widgets/pikahelp-ids.h"
#include "dialogs-actions.h"
#include "dockable-actions.h"
#include "dockable-commands.h"
#include "pika-intl.h"
static const PikaActionEntry dockable_actions[] =
{
{ "dockable-close-tab", "window-close",
NC_("dockable-action", "_Close Tab"), NULL, { NULL }, NULL,
dockable_close_tab_cmd_callback,
PIKA_HELP_DOCK_TAB_CLOSE },
{ "dockable-detach-tab", PIKA_ICON_DETACH,
NC_("dockable-action", "_Detach Tab"), NULL, { NULL }, NULL,
dockable_detach_tab_cmd_callback,
PIKA_HELP_DOCK_TAB_DETACH }
};
#define VIEW_SIZE(action,label,size) \
{ "dockable-preview-size-" action, NULL, \
(label), NULL, { NULL }, NULL, \
(size), \
PIKA_HELP_DOCK_PREVIEW_SIZE }
#define TAB_STYLE(action,label,style) \
{ "dockable-tab-style-" action, NULL, \
(label), NULL, { NULL }, NULL, \
(style), \
PIKA_HELP_DOCK_TAB_STYLE }
static const PikaRadioActionEntry dockable_view_size_actions[] =
{
VIEW_SIZE ("tiny",
NC_("preview-size", "_Tiny"), PIKA_VIEW_SIZE_TINY),
VIEW_SIZE ("extra-small",
NC_("preview-size", "E_xtra Small"), PIKA_VIEW_SIZE_EXTRA_SMALL),
VIEW_SIZE ("small",
NC_("preview-size", "_Small"), PIKA_VIEW_SIZE_SMALL),
VIEW_SIZE ("medium",
NC_("preview-size", "_Medium"), PIKA_VIEW_SIZE_MEDIUM),
VIEW_SIZE ("large",
NC_("preview-size", "_Large"), PIKA_VIEW_SIZE_LARGE),
VIEW_SIZE ("extra-large",
NC_("preview-size", "Ex_tra Large"), PIKA_VIEW_SIZE_EXTRA_LARGE),
VIEW_SIZE ("huge",
NC_("preview-size", "_Huge"), PIKA_VIEW_SIZE_HUGE),
VIEW_SIZE ("enormous",
NC_("preview-size", "_Enormous"), PIKA_VIEW_SIZE_ENORMOUS),
VIEW_SIZE ("gigantic",
NC_("preview-size", "_Gigantic"), PIKA_VIEW_SIZE_GIGANTIC)
};
static const PikaRadioActionEntry dockable_tab_style_actions[] =
{
TAB_STYLE ("icon",
NC_("tab-style", "_Icon"), PIKA_TAB_STYLE_ICON),
TAB_STYLE ("preview",
NC_("tab-style", "Current _Status"), PIKA_TAB_STYLE_PREVIEW),
TAB_STYLE ("name",
NC_("tab-style", "_Text"), PIKA_TAB_STYLE_NAME),
TAB_STYLE ("icon-name",
NC_("tab-style", "I_con & Text"), PIKA_TAB_STYLE_ICON_NAME),
TAB_STYLE ("preview-name",
NC_("tab-style", "St_atus & Text"), PIKA_TAB_STYLE_PREVIEW_NAME)
};
#undef VIEW_SIZE
#undef TAB_STYLE
static const PikaToggleActionEntry dockable_toggle_actions[] =
{
{ "dockable-lock-tab", NULL,
NC_("dockable-action", "Loc_k Tab to Dock"), NULL, { NULL },
NC_("dockable-action",
"Protect this tab from being dragged with the mouse pointer"),
dockable_lock_tab_cmd_callback,
FALSE,
PIKA_HELP_DOCK_TAB_LOCK },
{ "dockable-show-button-bar", NULL,
NC_("dockable-action", "Show _Button Bar"), NULL, { NULL }, NULL,
dockable_show_button_bar_cmd_callback,
TRUE,
PIKA_HELP_DOCK_SHOW_BUTTON_BAR }
};
static const PikaRadioActionEntry dockable_view_type_actions[] =
{
{ "dockable-view-type-list", NULL,
NC_("dockable-action", "View as _List"), NULL, { NULL }, NULL,
PIKA_VIEW_TYPE_LIST,
PIKA_HELP_DOCK_VIEW_AS_LIST },
{ "dockable-view-type-grid", NULL,
NC_("dockable-action", "View as _Grid"), NULL, { NULL }, NULL,
PIKA_VIEW_TYPE_GRID,
PIKA_HELP_DOCK_VIEW_AS_GRID }
};
void
dockable_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "dockable-action",
dockable_actions,
G_N_ELEMENTS (dockable_actions));
pika_action_group_add_toggle_actions (group, "dockable-action",
dockable_toggle_actions,
G_N_ELEMENTS (dockable_toggle_actions));
pika_action_group_add_string_actions (group, "dialogs-action",
dialogs_dockable_actions,
n_dialogs_dockable_actions,
dockable_add_tab_cmd_callback);
pika_action_group_add_radio_actions (group, "preview-size",
dockable_view_size_actions,
G_N_ELEMENTS (dockable_view_size_actions),
NULL,
PIKA_VIEW_SIZE_MEDIUM,
dockable_view_size_cmd_callback);
pika_action_group_add_radio_actions (group, "tab-style",
dockable_tab_style_actions,
G_N_ELEMENTS (dockable_tab_style_actions),
NULL,
PIKA_TAB_STYLE_PREVIEW,
dockable_tab_style_cmd_callback);
pika_action_group_add_radio_actions (group, "dockable-action",
dockable_view_type_actions,
G_N_ELEMENTS (dockable_view_type_actions),
NULL,
PIKA_VIEW_TYPE_LIST,
dockable_toggle_view_cmd_callback);
}
void
dockable_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaDockable *dockable;
PikaDockbook *dockbook;
PikaDocked *docked;
PikaDock *dock;
PikaDialogFactoryEntry *entry;
PikaContainerView *view;
PikaViewType view_type = -1;
gboolean list_view_available = FALSE;
gboolean grid_view_available = FALSE;
gboolean locked = FALSE;
PikaViewSize view_size = -1;
PikaTabStyle tab_style = -1;
gint n_pages = 0;
gint n_books = 0;
PikaDockedInterface *docked_iface = NULL;
if (PIKA_IS_DOCKBOOK (data))
{
gint page_num;
dockbook = PIKA_DOCKBOOK (data);
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook));
dockable = (PikaDockable *)
gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num);
}
else if (PIKA_IS_DOCKABLE (data))
{
dockable = PIKA_DOCKABLE (data);
dockbook = pika_dockable_get_dockbook (dockable);
}
else
{
return;
}
docked = PIKA_DOCKED (gtk_bin_get_child (GTK_BIN (dockable)));
dock = pika_dockbook_get_dock (dockbook);
pika_dialog_factory_from_widget (GTK_WIDGET (dockable), &entry);
if (entry)
{
gchar *identifier;
gchar *substring = NULL;
identifier = g_strdup (entry->identifier);
if ((substring = strstr (identifier, "grid")))
view_type = PIKA_VIEW_TYPE_GRID;
else if ((substring = strstr (identifier, "list")))
view_type = PIKA_VIEW_TYPE_LIST;
if (substring)
{
memcpy (substring, "list", 4);
if (pika_dialog_factory_find_entry (pika_dock_get_dialog_factory (dock),
identifier))
list_view_available = TRUE;
memcpy (substring, "grid", 4);
if (pika_dialog_factory_find_entry (pika_dock_get_dialog_factory (dock),
identifier))
grid_view_available = TRUE;
}
g_free (identifier);
}
view = pika_container_view_get_by_dockable (dockable);
if (view)
view_size = pika_container_view_get_view_size (view, NULL);
tab_style = pika_dockable_get_tab_style (dockable);
n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (dockbook));
n_books = g_list_length (pika_dock_get_dockbooks (dock));
#define SET_ACTIVE(action,active) \
pika_action_group_set_action_active (group, action, (active) != 0)
#define SET_VISIBLE(action,active) \
pika_action_group_set_action_visible (group, action, (active) != 0)
#define SET_SENSITIVE(action,sensitive) \
pika_action_group_set_action_sensitive (group, action, (sensitive) != 0, NULL)
locked = pika_dockable_get_locked (dockable);
SET_SENSITIVE ("dockable-detach-tab", (! locked &&
(n_pages > 1 || n_books > 1)));
SET_ACTIVE ("dockable-lock-tab", locked);
if (view_size != -1)
{
if (view_size >= PIKA_VIEW_SIZE_GIGANTIC)
{
SET_ACTIVE ("dockable-preview-size-gigantic", TRUE);
}
else if (view_size >= PIKA_VIEW_SIZE_ENORMOUS)
{
SET_ACTIVE ("dockable-preview-size-enormous", TRUE);
}
else if (view_size >= PIKA_VIEW_SIZE_HUGE)
{
SET_ACTIVE ("dockable-preview-size-huge", TRUE);
}
else if (view_size >= PIKA_VIEW_SIZE_EXTRA_LARGE)
{
SET_ACTIVE ("dockable-preview-size-extra-large", TRUE);
}
else if (view_size >= PIKA_VIEW_SIZE_LARGE)
{
SET_ACTIVE ("dockable-preview-size-large", TRUE);
}
else if (view_size >= PIKA_VIEW_SIZE_MEDIUM)
{
SET_ACTIVE ("dockable-preview-size-medium", TRUE);
}
else if (view_size >= PIKA_VIEW_SIZE_SMALL)
{
SET_ACTIVE ("dockable-preview-size-small", TRUE);
}
else if (view_size >= PIKA_VIEW_SIZE_EXTRA_SMALL)
{
SET_ACTIVE ("dockable-preview-size-extra-small", TRUE);
}
else if (view_size >= PIKA_VIEW_SIZE_TINY)
{
SET_ACTIVE ("dockable-preview-size-tiny", TRUE);
}
}
if (tab_style == PIKA_TAB_STYLE_ICON)
SET_ACTIVE ("dockable-tab-style-icon", TRUE);
else if (tab_style == PIKA_TAB_STYLE_PREVIEW)
SET_ACTIVE ("dockable-tab-style-preview", TRUE);
else if (tab_style == PIKA_TAB_STYLE_NAME)
SET_ACTIVE ("dockable-tab-style-name", TRUE);
else if (tab_style == PIKA_TAB_STYLE_ICON_NAME)
SET_ACTIVE ("dockable-tab-style-icon-name", TRUE);
else if (tab_style == PIKA_TAB_STYLE_PREVIEW_NAME)
SET_ACTIVE ("dockable-tab-style-preview-name", TRUE);
docked_iface = PIKA_DOCKED_GET_IFACE (docked);
SET_SENSITIVE ("dockable-tab-style-preview",
docked_iface->get_preview);
SET_SENSITIVE ("dockable-tab-style-preview-name",
docked_iface->get_preview);
SET_VISIBLE ("dockable-view-type-grid", view_type != -1);
SET_VISIBLE ("dockable-view-type-list", view_type != -1);
if (view_type != -1)
{
if (view_type == PIKA_VIEW_TYPE_LIST)
SET_ACTIVE ("dockable-view-type-list", TRUE);
else
SET_ACTIVE ("dockable-view-type-grid", TRUE);
SET_SENSITIVE ("dockable-view-type-grid", grid_view_available);
SET_SENSITIVE ("dockable-view-type-list", list_view_available);
}
SET_VISIBLE ("dockable-show-button-bar", pika_docked_has_button_bar (docked));
SET_ACTIVE ("dockable-show-button-bar",
pika_docked_get_show_button_bar (docked));
#undef SET_ACTIVE
#undef SET_VISIBLE
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DOCKABLE_ACTIONS_H__
#define __DOCKABLE_ACTIONS_H__
void dockable_actions_setup (PikaActionGroup *group);
void dockable_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __DOCKABLE_ACTIONS_H__ */

View File

@ -0,0 +1,297 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "widgets/pikacontainerview.h"
#include "widgets/pikacontainerview-utils.h"
#include "widgets/pikadialogfactory.h"
#include "widgets/pikadock.h"
#include "widgets/pikadockable.h"
#include "widgets/pikadockbook.h"
#include "widgets/pikadocked.h"
#include "widgets/pikasessioninfo.h"
#include "dockable-commands.h"
static PikaDockable * dockable_get_current (PikaDockbook *dockbook);
/* public functions */
void
dockable_add_tab_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDockbook *dockbook = PIKA_DOCKBOOK (data);
pika_dockbook_add_from_dialog_factory (dockbook,
g_variant_get_string (value, NULL));
}
void
dockable_close_tab_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDockbook *dockbook = PIKA_DOCKBOOK (data);
PikaDockable *dockable = dockable_get_current (dockbook);
if (dockable)
gtk_container_remove (GTK_CONTAINER (dockbook),
GTK_WIDGET (dockable));
}
void
dockable_detach_tab_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDockbook *dockbook = PIKA_DOCKBOOK (data);
PikaDockable *dockable = dockable_get_current (dockbook);
if (dockable)
pika_dockable_detach (dockable);
}
void
dockable_lock_tab_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDockbook *dockbook = PIKA_DOCKBOOK (data);
PikaDockable *dockable = dockable_get_current (dockbook);
if (dockable)
{
gboolean lock = g_variant_get_boolean (value);
pika_dockable_set_locked (dockable, lock);
}
}
void
dockable_toggle_view_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDockbook *dockbook = PIKA_DOCKBOOK (data);
PikaDockable *dockable;
PikaViewType view_type;
gint page_num;
view_type = (PikaViewType) g_variant_get_int32 (value);
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook));
dockable = (PikaDockable *)
gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num);
if (dockable)
{
PikaDialogFactoryEntry *entry;
pika_dialog_factory_from_widget (GTK_WIDGET (dockable), &entry);
if (entry)
{
gchar *identifier;
gchar *substring = NULL;
identifier = g_strdup (entry->identifier);
substring = strstr (identifier, "grid");
if (substring && view_type == PIKA_VIEW_TYPE_GRID)
{
g_free (identifier);
return;
}
if (! substring)
{
substring = strstr (identifier, "list");
if (substring && view_type == PIKA_VIEW_TYPE_LIST)
{
g_free (identifier);
return;
}
}
if (substring)
{
PikaContainerView *old_view;
GtkWidget *new_dockable;
PikaDock *dock;
gint view_size = -1;
if (view_type == PIKA_VIEW_TYPE_LIST)
memcpy (substring, "list", 4);
else if (view_type == PIKA_VIEW_TYPE_GRID)
memcpy (substring, "grid", 4);
old_view = pika_container_view_get_by_dockable (dockable);
if (old_view)
view_size = pika_container_view_get_view_size (old_view, NULL);
dock = pika_dockbook_get_dock (dockbook);
new_dockable = pika_dialog_factory_dockable_new (pika_dock_get_dialog_factory (dock),
dock,
identifier,
view_size);
if (new_dockable)
{
PikaDocked *old;
PikaDocked *new;
gboolean show;
pika_dockable_set_locked (PIKA_DOCKABLE (new_dockable),
pika_dockable_get_locked (dockable));
old = PIKA_DOCKED (gtk_bin_get_child (GTK_BIN (dockable)));
new = PIKA_DOCKED (gtk_bin_get_child (GTK_BIN (new_dockable)));
show = pika_docked_get_show_button_bar (old);
pika_docked_set_show_button_bar (new, show);
/* Maybe pika_dialog_factory_dockable_new() returned
* an already existing singleton dockable, so check
* if it already is attached to a dockbook.
*/
if (! pika_dockable_get_dockbook (PIKA_DOCKABLE (new_dockable)))
{
gtk_notebook_insert_page (GTK_NOTEBOOK (dockbook),
new_dockable, NULL,
page_num);
gtk_widget_show (new_dockable);
gtk_container_remove (GTK_CONTAINER (dockbook),
GTK_WIDGET (dockable));
gtk_notebook_set_current_page (GTK_NOTEBOOK (dockbook),
page_num);
}
}
}
g_free (identifier);
}
}
}
void
dockable_view_size_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDockbook *dockbook = PIKA_DOCKBOOK (data);
PikaDockable *dockable = dockable_get_current (dockbook);
gint view_size;
view_size = g_variant_get_int32 (value);
if (dockable)
{
PikaContainerView *view = pika_container_view_get_by_dockable (dockable);
if (view)
{
gint old_size;
gint border_width;
old_size = pika_container_view_get_view_size (view, &border_width);
if (old_size != view_size)
pika_container_view_set_view_size (view, view_size, border_width);
}
}
}
void
dockable_tab_style_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDockbook *dockbook = PIKA_DOCKBOOK (data);
PikaDockable *dockable = dockable_get_current (dockbook);
PikaTabStyle tab_style;
tab_style = (PikaTabStyle) g_variant_get_int32 (value);
if (dockable && pika_dockable_get_tab_style (dockable) != tab_style)
{
GtkWidget *tab_widget;
pika_dockable_set_tab_style (dockable, tab_style);
tab_widget = pika_dockbook_create_tab_widget (dockbook, dockable);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (dockbook),
GTK_WIDGET (dockable),
tab_widget);
}
}
void
dockable_show_button_bar_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDockbook *dockbook = PIKA_DOCKBOOK (data);
PikaDockable *dockable = dockable_get_current (dockbook);
if (dockable)
{
PikaDocked *docked;
gboolean show;
docked = PIKA_DOCKED (gtk_bin_get_child (GTK_BIN (dockable)));
show = g_variant_get_boolean (value);
pika_docked_set_show_button_bar (docked, show);
}
}
/* private functions */
static PikaDockable *
dockable_get_current (PikaDockbook *dockbook)
{
gint page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook));
return (PikaDockable *) gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook),
page_num);
}

View File

@ -0,0 +1,53 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DOCKABLE_COMMANDS_H__
#define __DOCKABLE_COMMANDS_H__
void dockable_add_tab_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dockable_close_tab_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dockable_detach_tab_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dockable_lock_tab_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dockable_toggle_view_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dockable_view_size_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dockable_tab_style_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void dockable_show_button_bar_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DOCKABLE_COMMANDS_H__ */

View File

@ -0,0 +1,143 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikacontext.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "documents-actions.h"
#include "documents-commands.h"
#include "pika-intl.h"
static const PikaActionEntry documents_actions[] =
{
{ "documents-open", PIKA_ICON_DOCUMENT_OPEN,
NC_("documents-action", "_Open Image"), NULL, { NULL },
NC_("documents-action", "Open the selected entry"),
documents_open_cmd_callback,
PIKA_HELP_DOCUMENT_OPEN },
{ "documents-raise-or-open", NULL,
NC_("documents-action", "_Raise or Open Image"), NULL, { NULL },
NC_("documents-action", "Raise window if already open"),
documents_raise_or_open_cmd_callback,
PIKA_HELP_DOCUMENT_OPEN },
{ "documents-file-open-dialog", NULL,
NC_("documents-action", "File Open _Dialog"), NULL, { NULL },
NC_("documents-action", "Open image dialog"),
documents_file_open_dialog_cmd_callback,
PIKA_HELP_DOCUMENT_OPEN },
{ "documents-copy-location", PIKA_ICON_EDIT_COPY,
NC_("documents-action", "Copy Image _Location"), NULL, { NULL },
NC_("documents-action", "Copy image location to clipboard"),
documents_copy_location_cmd_callback,
PIKA_HELP_DOCUMENT_COPY_LOCATION },
{ "documents-show-in-file-manager", PIKA_ICON_FILE_MANAGER,
NC_("documents-action", "Show in _File Manager"), NULL, { NULL },
NC_("documents-action", "Show image location in the file manager"),
documents_show_in_file_manager_cmd_callback,
PIKA_HELP_DOCUMENT_SHOW_IN_FILE_MANAGER },
{ "documents-remove", PIKA_ICON_LIST_REMOVE,
NC_("documents-action", "Remove _Entry"), NULL, { NULL },
NC_("documents-action", "Remove the selected entry"),
documents_remove_cmd_callback,
PIKA_HELP_DOCUMENT_REMOVE },
{ "documents-clear", PIKA_ICON_SHRED,
NC_("documents-action", "_Clear History"), NULL, { NULL },
NC_("documents-action", "Clear the entire document history"),
documents_clear_cmd_callback,
PIKA_HELP_DOCUMENT_CLEAR },
{ "documents-recreate-preview", PIKA_ICON_VIEW_REFRESH,
NC_("documents-action", "Recreate _Preview"), NULL, { NULL },
NC_("documents-action", "Recreate preview"),
documents_recreate_preview_cmd_callback,
PIKA_HELP_DOCUMENT_REFRESH },
{ "documents-reload-previews", NULL,
NC_("documents-action", "Reload _all Previews"), NULL, { NULL },
NC_("documents-action", "Reload all previews"),
documents_reload_previews_cmd_callback,
PIKA_HELP_DOCUMENT_REFRESH },
{ "documents-remove-dangling", NULL,
NC_("documents-action", "Remove Dangling E_ntries"), NULL, { NULL },
NC_("documents-action",
"Remove entries for which the corresponding file is not available"),
documents_remove_dangling_cmd_callback,
PIKA_HELP_DOCUMENT_REFRESH }
};
void
documents_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "documents-action",
documents_actions,
G_N_ELEMENTS (documents_actions));
}
void
documents_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaContext *context;
PikaImagefile *imagefile = NULL;
context = action_data_get_context (data);
if (context)
imagefile = pika_context_get_imagefile (context);
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("documents-open", imagefile);
SET_SENSITIVE ("documents-raise-or-open", imagefile);
SET_SENSITIVE ("documents-file-open-dialog", TRUE);
SET_SENSITIVE ("documents-copy-location", imagefile);
SET_SENSITIVE ("documents-show-in-file-manager", imagefile);
SET_SENSITIVE ("documents-remove", imagefile);
SET_SENSITIVE ("documents-clear", TRUE);
SET_SENSITIVE ("documents-recreate-preview", imagefile);
SET_SENSITIVE ("documents-reload-previews", imagefile);
SET_SENSITIVE ("documents-remove-dangling", imagefile);
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DOCUMENTS_ACTIONS_H__
#define __DOCUMENTS_ACTIONS_H__
void documents_actions_setup (PikaActionGroup *group);
void documents_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __DOCUMENTS_ACTIONS_H__ */

View File

@ -0,0 +1,427 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "libpikathumb/pikathumb.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "config/pikacoreconfig.h"
#include "core/pika.h"
#include "core/pikacontainer.h"
#include "core/pikacontext.h"
#include "core/pikaimagefile.h"
#include "core/pikaimage.h"
#include "file/file-open.h"
#include "widgets/pikaclipboard.h"
#include "widgets/pikacontainerview.h"
#include "widgets/pikacontainerview-utils.h"
#include "widgets/pikadocumentview.h"
#include "widgets/pikamessagebox.h"
#include "widgets/pikamessagedialog.h"
#include "widgets/pikawidgets-utils.h"
#include "display/pikadisplay.h"
#include "display/pikadisplay-foreach.h"
#include "display/pikadisplayshell.h"
#include "documents-commands.h"
#include "file-commands.h"
#include "pika-intl.h"
typedef struct
{
const gchar *name;
gboolean found;
} RaiseClosure;
/* local function prototypes */
static void documents_open_image (GtkWidget *editor,
PikaContext *context,
PikaImagefile *imagefile);
static void documents_raise_display (PikaDisplay *display,
RaiseClosure *closure);
/* public functions */
void
documents_open_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context;
PikaContainer *container;
PikaImagefile *imagefile;
context = pika_container_view_get_context (editor->view);
container = pika_container_view_get_container (editor->view);
imagefile = pika_context_get_imagefile (context);
if (imagefile && pika_container_have (container, PIKA_OBJECT (imagefile)))
{
documents_open_image (GTK_WIDGET (editor), context, imagefile);
}
else
{
file_file_open_dialog (context->pika, NULL, GTK_WIDGET (editor));
}
}
void
documents_raise_or_open_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context;
PikaContainer *container;
PikaImagefile *imagefile;
context = pika_container_view_get_context (editor->view);
container = pika_container_view_get_container (editor->view);
imagefile = pika_context_get_imagefile (context);
if (imagefile && pika_container_have (container, PIKA_OBJECT (imagefile)))
{
RaiseClosure closure;
closure.name = pika_object_get_name (imagefile);
closure.found = FALSE;
pika_container_foreach (PIKA_CONTAINER (context->pika->displays),
(GFunc) documents_raise_display,
&closure);
if (! closure.found)
documents_open_image (GTK_WIDGET (editor), context, imagefile);
}
}
void
documents_file_open_dialog_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context;
PikaContainer *container;
PikaImagefile *imagefile;
context = pika_container_view_get_context (editor->view);
container = pika_container_view_get_container (editor->view);
imagefile = pika_context_get_imagefile (context);
if (imagefile && pika_container_have (container, PIKA_OBJECT (imagefile)))
{
file_file_open_dialog (context->pika,
pika_imagefile_get_file (imagefile),
GTK_WIDGET (editor));
}
}
void
documents_copy_location_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context;
PikaImagefile *imagefile;
context = pika_container_view_get_context (editor->view);
imagefile = pika_context_get_imagefile (context);
if (imagefile)
pika_clipboard_set_text (context->pika,
pika_object_get_name (imagefile));
}
void
documents_show_in_file_manager_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context;
PikaImagefile *imagefile;
context = pika_container_view_get_context (editor->view);
imagefile = pika_context_get_imagefile (context);
if (imagefile)
{
GFile *file = g_file_new_for_uri (pika_object_get_name (imagefile));
GError *error = NULL;
if (! pika_file_show_in_file_manager (file, &error))
{
pika_message (context->pika, G_OBJECT (editor),
PIKA_MESSAGE_ERROR,
_("Can't show file in file manager: %s"),
error->message);
g_clear_error (&error);
}
g_object_unref (file);
}
}
void
documents_remove_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context = pika_container_view_get_context (editor->view);
PikaImagefile *imagefile = pika_context_get_imagefile (context);
const gchar *uri;
uri = pika_object_get_name (imagefile);
gtk_recent_manager_remove_item (gtk_recent_manager_get_default (), uri, NULL);
pika_container_view_remove_active (editor->view);
}
void
documents_clear_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context = pika_container_view_get_context (editor->view);
Pika *pika = context->pika;
GtkWidget *dialog;
dialog = pika_message_dialog_new (_("Clear Document History"),
PIKA_ICON_SHRED,
GTK_WIDGET (editor),
GTK_DIALOG_MODAL |
GTK_DIALOG_DESTROY_WITH_PARENT,
pika_standard_help_func, NULL,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("Cl_ear"), GTK_RESPONSE_OK,
NULL);
pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
g_signal_connect_object (gtk_widget_get_toplevel (GTK_WIDGET (editor)),
"unmap",
G_CALLBACK (gtk_widget_destroy),
dialog, G_CONNECT_SWAPPED);
pika_message_box_set_primary_text (PIKA_MESSAGE_DIALOG (dialog)->box,
_("Clear the Recent Documents list?"));
pika_message_box_set_text (PIKA_MESSAGE_DIALOG (dialog)->box,
_("Clearing the document history will "
"permanently remove all images from "
"the recent documents list."));
if (pika_dialog_run (PIKA_DIALOG (dialog)) == GTK_RESPONSE_OK)
{
GtkRecentManager *manager = gtk_recent_manager_get_default ();
GList *items;
GList *list;
items = gtk_recent_manager_get_items (manager);
for (list = items; list; list = list->next)
{
GtkRecentInfo *info = list->data;
if (gtk_recent_info_has_application (info,
"Photo and Image Kooker Application"))
{
gtk_recent_manager_remove_item (manager,
gtk_recent_info_get_uri (info),
NULL);
}
gtk_recent_info_unref (info);
}
g_list_free (items);
pika_container_clear (pika->documents);
}
gtk_widget_destroy (dialog);
}
void
documents_recreate_preview_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context;
PikaContainer *container;
PikaImagefile *imagefile;
context = pika_container_view_get_context (editor->view);
container = pika_container_view_get_container (editor->view);
imagefile = pika_context_get_imagefile (context);
if (imagefile && pika_container_have (container, PIKA_OBJECT (imagefile)))
{
GError *error = NULL;
if (! pika_imagefile_create_thumbnail (imagefile,
context, NULL,
context->pika->config->thumbnail_size,
FALSE, &error))
{
pika_message_literal (context->pika,
NULL , PIKA_MESSAGE_ERROR,
error->message);
g_clear_error (&error);
}
}
}
void
documents_reload_previews_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContainer *container;
container = pika_container_view_get_container (editor->view);
pika_container_foreach (container,
(GFunc) pika_imagefile_update,
editor->view);
}
static void
documents_remove_dangling_foreach (PikaImagefile *imagefile,
PikaContainer *container)
{
PikaThumbnail *thumbnail = pika_imagefile_get_thumbnail (imagefile);
if (pika_thumbnail_peek_image (thumbnail) == PIKA_THUMB_STATE_NOT_FOUND)
{
const gchar *uri = pika_object_get_name (imagefile);
gtk_recent_manager_remove_item (gtk_recent_manager_get_default (), uri,
NULL);
pika_container_remove (container, PIKA_OBJECT (imagefile));
}
}
void
documents_remove_dangling_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContainer *container;
container = pika_container_view_get_container (editor->view);
pika_container_foreach (container,
(GFunc) documents_remove_dangling_foreach,
container);
}
/* private functions */
static void
documents_open_image (GtkWidget *editor,
PikaContext *context,
PikaImagefile *imagefile)
{
GFile *file;
PikaImage *image;
PikaPDBStatusType status;
GError *error = NULL;
file = pika_imagefile_get_file (imagefile);
image = file_open_with_display (context->pika, context, NULL, file, FALSE,
G_OBJECT (pika_widget_get_monitor (editor)),
&status, &error);
if (! image && status != PIKA_PDB_CANCEL)
{
pika_message (context->pika, G_OBJECT (editor), PIKA_MESSAGE_ERROR,
_("Opening '%s' failed:\n\n%s"),
pika_file_get_utf8_name (file), error->message);
g_clear_error (&error);
}
}
static void
documents_raise_display (PikaDisplay *display,
RaiseClosure *closure)
{
PikaImage *image;
GFile *file;
gchar *uri = NULL;
image = pika_display_get_image (display);
file = pika_image_get_file (image);
if (! file)
file = pika_image_get_imported_file (image);
if (file)
uri = g_file_get_uri (file);
if (! g_strcmp0 (closure->name, uri))
{
closure->found = TRUE;
pika_display_shell_present (pika_display_get_shell (display));
}
g_free (uri);
}

View File

@ -0,0 +1,58 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DOCUMENTS_COMMANDS_H__
#define __DOCUMENTS_COMMANDS_H__
void documents_open_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_raise_or_open_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_file_open_dialog_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_copy_location_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_show_in_file_manager_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_remove_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_clear_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_recreate_preview_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_reload_previews_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void documents_remove_dangling_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DOCUMENTS_COMMANDS_H__ */

View File

@ -0,0 +1,249 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikacontext.h"
#include "core/pikaimage.h"
#include "core/pikalayermask.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "drawable-actions.h"
#include "drawable-commands.h"
#include "pika-intl.h"
static const PikaActionEntry drawable_actions[] =
{
{ "drawable-equalize", NULL,
NC_("drawable-action", "_Equalize"), NULL, { NULL },
NC_("drawable-action", "Automatic contrast enhancement"),
drawable_equalize_cmd_callback,
PIKA_HELP_LAYER_EQUALIZE },
{ "drawable-levels-stretch", NULL,
NC_("drawable-action", "_White Balance"), NULL, { NULL },
NC_("drawable-action", "Automatic white balance correction"),
drawable_levels_stretch_cmd_callback,
PIKA_HELP_LAYER_WHITE_BALANCE }
};
static const PikaToggleActionEntry drawable_toggle_actions[] =
{
{ "drawable-visible", PIKA_ICON_VISIBLE,
NC_("drawable-action", "Toggle Drawables _Visibility"), NULL, { NULL }, NULL,
drawable_visible_cmd_callback,
FALSE,
PIKA_HELP_LAYER_VISIBLE },
{ "drawable-lock-content", PIKA_ICON_LOCK_CONTENT,
NC_("drawable-action", "L_ock Pixels of Drawables"), NULL, { NULL },
NC_("drawable-action",
"Keep the pixels on selected drawables from being modified"),
drawable_lock_content_cmd_callback,
FALSE,
PIKA_HELP_LAYER_LOCK_PIXELS },
{ "drawable-lock-position", PIKA_ICON_LOCK_POSITION,
NC_("drawable-action", "L_ock Position of Drawables"), NULL, { NULL },
NC_("drawable-action",
"Keep the position on selected drawables from being modified"),
drawable_lock_position_cmd_callback,
FALSE,
PIKA_HELP_LAYER_LOCK_POSITION },
};
static const PikaEnumActionEntry drawable_flip_actions[] =
{
{ "drawable-flip-horizontal", PIKA_ICON_OBJECT_FLIP_HORIZONTAL,
NC_("drawable-action", "Flip _Horizontally"), NULL, { NULL },
NC_("drawable-action", "Flip drawable horizontally"),
PIKA_ORIENTATION_HORIZONTAL, FALSE,
PIKA_HELP_LAYER_FLIP_HORIZONTAL },
{ "drawable-flip-vertical", PIKA_ICON_OBJECT_FLIP_VERTICAL,
NC_("drawable-action", "Flip _Vertically"), NULL, { NULL },
NC_("drawable-action", "Flip drawable vertically"),
PIKA_ORIENTATION_VERTICAL, FALSE,
PIKA_HELP_LAYER_FLIP_VERTICAL }
};
static const PikaEnumActionEntry drawable_rotate_actions[] =
{
{ "drawable-rotate-90", PIKA_ICON_OBJECT_ROTATE_90,
NC_("drawable-action", "Rotate 90° _clockwise"), NULL, { NULL },
NC_("drawable-action", "Rotate drawable 90 degrees to the right"),
PIKA_ROTATE_90, FALSE,
PIKA_HELP_LAYER_ROTATE_90 },
{ "drawable-rotate-180", PIKA_ICON_OBJECT_ROTATE_180,
NC_("drawable-action", "Rotate _180°"), NULL, { NULL },
NC_("drawable-action", "Turn drawable upside-down"),
PIKA_ROTATE_180, FALSE,
PIKA_HELP_LAYER_ROTATE_180 },
{ "drawable-rotate-270", PIKA_ICON_OBJECT_ROTATE_270,
NC_("drawable-action", "Rotate 90° counter-clock_wise"), NULL, { NULL },
NC_("drawable-action", "Rotate drawable 90 degrees to the left"),
PIKA_ROTATE_270, FALSE,
PIKA_HELP_LAYER_ROTATE_270 }
};
void
drawable_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "drawable-action",
drawable_actions,
G_N_ELEMENTS (drawable_actions));
pika_action_group_add_toggle_actions (group, "drawable-action",
drawable_toggle_actions,
G_N_ELEMENTS (drawable_toggle_actions));
pika_action_group_add_enum_actions (group, "drawable-action",
drawable_flip_actions,
G_N_ELEMENTS (drawable_flip_actions),
drawable_flip_cmd_callback);
pika_action_group_add_enum_actions (group, "drawable-action",
drawable_rotate_actions,
G_N_ELEMENTS (drawable_rotate_actions),
drawable_rotate_cmd_callback);
#define SET_ALWAYS_SHOW_IMAGE(action,show) \
pika_action_group_set_action_always_show_image (group, action, show)
SET_ALWAYS_SHOW_IMAGE ("drawable-rotate-90", TRUE);
SET_ALWAYS_SHOW_IMAGE ("drawable-rotate-180", TRUE);
SET_ALWAYS_SHOW_IMAGE ("drawable-rotate-270", TRUE);
#undef SET_ALWAYS_SHOW_IMAGE
}
void
drawable_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaImage *image;
GList *drawables = NULL;
GList *iter;
gboolean has_visible = FALSE;
gboolean locked = TRUE;
gboolean can_lock = FALSE;
gboolean locked_pos = TRUE;
gboolean can_lock_pos = FALSE;
gboolean all_rgb = TRUE;
gboolean all_writable = TRUE;
gboolean all_movable = TRUE;
gboolean none_children = TRUE;
image = action_data_get_image (data);
if (image)
{
drawables = pika_image_get_selected_drawables (image);
for (iter = drawables; iter; iter = iter->next)
{
PikaItem *item;
if (pika_item_get_visible (iter->data))
has_visible = TRUE;
if (pika_item_can_lock_content (iter->data))
{
if (! pika_item_get_lock_content (iter->data))
locked = FALSE;
can_lock = TRUE;
}
if (pika_item_can_lock_position (iter->data))
{
if (! pika_item_get_lock_position (iter->data))
locked_pos = FALSE;
can_lock_pos = TRUE;
}
if (pika_viewable_get_children (PIKA_VIEWABLE (iter->data)))
none_children = FALSE;
if (! pika_drawable_is_rgb (iter->data))
all_rgb = FALSE;
if (PIKA_IS_LAYER_MASK (iter->data))
item = PIKA_ITEM (pika_layer_mask_get_layer (PIKA_LAYER_MASK (iter->data)));
else
item = PIKA_ITEM (iter->data);
if (pika_item_is_content_locked (item, NULL))
all_writable = FALSE;
if (pika_item_is_position_locked (item, NULL))
all_movable = FALSE;
if (has_visible && ! locked && ! locked_pos &&
! none_children && ! all_rgb &&
! all_writable && ! all_movable)
break;
}
}
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
#define SET_ACTIVE(action,condition) \
pika_action_group_set_action_active (group, action, (condition) != 0)
SET_SENSITIVE ("drawable-equalize", drawables && all_writable && none_children);
SET_SENSITIVE ("drawable-levels-stretch", drawables && all_writable && none_children && all_rgb);
SET_SENSITIVE ("drawable-visible", drawables);
SET_SENSITIVE ("drawable-lock-content", can_lock);
SET_SENSITIVE ("drawable-lock-position", can_lock_pos);
SET_ACTIVE ("drawable-visible", has_visible);
SET_ACTIVE ("drawable-lock-content", locked);
SET_ACTIVE ("drawable-lock-position", locked_pos);
SET_SENSITIVE ("drawable-flip-horizontal", drawables && all_writable && all_movable);
SET_SENSITIVE ("drawable-flip-vertical", drawables && all_writable && all_movable);
SET_SENSITIVE ("drawable-rotate-90", drawables && all_writable && all_movable);
SET_SENSITIVE ("drawable-rotate-180", drawables && all_writable && all_movable);
SET_SENSITIVE ("drawable-rotate-270", drawables && all_writable && all_movable);
#undef SET_SENSITIVE
#undef SET_ACTIVE
g_list_free (drawables);
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DRAWABLE_ACTIONS_H__
#define __DRAWABLE_ACTIONS_H__
void drawable_actions_setup (PikaActionGroup *group);
void drawable_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __DRAWABLE_ACTIONS_H__ */

View File

@ -0,0 +1,429 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikadrawable-equalize.h"
#include "core/pikadrawable-levels.h"
#include "core/pikadrawable-operation.h"
#include "core/pikaimage.h"
#include "core/pikaimage-undo.h"
#include "core/pikaitemundo.h"
#include "core/pikalayermask.h"
#include "core/pikaprogress.h"
#include "dialogs/dialogs.h"
#include "actions.h"
#include "drawable-commands.h"
#include "pika-intl.h"
/* public functions */
void
drawable_equalize_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
return_if_no_drawables (image, drawables, data);
if (g_list_length (drawables) > 1)
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_DRAWABLE_MOD,
_("Equalize"));
for (iter = drawables; iter; iter = iter->next)
pika_drawable_equalize (iter->data, TRUE);
if (g_list_length (drawables) > 1)
pika_image_undo_group_end (image);
pika_image_flush (image);
g_list_free (drawables);
}
void
drawable_levels_stretch_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
PikaDisplay *display;
GtkWidget *widget;
return_if_no_drawables (image, drawables, data);
return_if_no_display (display, data);
return_if_no_widget (widget, data);
for (iter = drawables; iter; iter = iter->next)
{
if (! pika_drawable_is_rgb (iter->data))
{
pika_message_literal (image->pika,
G_OBJECT (widget), PIKA_MESSAGE_WARNING,
_("White Balance operates only on RGB color "
"layers."));
return;
}
}
if (g_list_length (drawables) > 1)
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_DRAWABLE_MOD,
_("Levels"));
for (iter = drawables; iter; iter = iter->next)
pika_drawable_levels_stretch (iter->data, PIKA_PROGRESS (display));
if (g_list_length (drawables) > 1)
pika_image_undo_group_end (image);
pika_image_flush (image);
g_list_free (drawables);
}
void
drawable_visible_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
PikaUndo *undo;
gboolean push_undo = TRUE;
gboolean visible;
return_if_no_drawables (image, drawables, data);
visible = g_variant_get_boolean (value);
if (PIKA_IS_LAYER_MASK (drawables->data))
{
PikaLayerMask *mask = PIKA_LAYER_MASK (drawables->data);
g_list_free (drawables);
drawables = g_list_prepend (NULL, pika_layer_mask_get_layer (mask));
}
for (iter = drawables; iter; iter = iter->next)
{
if (visible && pika_item_get_visible (iter->data))
{
/* If any of the drawables are already visible, we don't
* toggle the selection visibility. This prevents the
* SET_ACTIVE() in drawables-actions.c to toggle visibility
* unexpectedly.
*/
g_list_free (drawables);
return;
}
}
for (iter = drawables; iter; iter = iter->next)
if (visible != pika_item_get_visible (iter->data))
break;
if (! iter)
{
g_list_free (drawables);
return;
}
if (g_list_length (drawables) == 1)
{
undo = pika_image_undo_can_compress (image, PIKA_TYPE_ITEM_UNDO,
PIKA_UNDO_ITEM_VISIBILITY);
if (undo && PIKA_ITEM_UNDO (undo)->item == PIKA_ITEM (drawables->data))
push_undo = FALSE;
}
else
{
/* TODO: undo groups cannot be compressed so far. */
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_ITEM_VISIBILITY,
"Item visibility");
}
for (; iter; iter = iter->next)
pika_item_set_visible (iter->data, visible, push_undo);
if (g_list_length (drawables) != 1)
pika_image_undo_group_end (image);
pika_image_flush (image);
g_list_free (drawables);
}
void
drawable_lock_content_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
gboolean locked;
gboolean push_undo = TRUE;
return_if_no_drawables (image, drawables, data);
locked = g_variant_get_boolean (value);
if (PIKA_IS_LAYER_MASK (drawables->data))
{
PikaLayerMask *mask = PIKA_LAYER_MASK (drawables->data);
g_list_free (drawables);
drawables = g_list_prepend (NULL, pika_layer_mask_get_layer (mask));
}
for (iter = drawables; iter; iter = iter->next)
{
if (! locked && ! pika_item_get_lock_content (iter->data))
{
/* If any of the drawables are already unlocked, we don't toggle the
* lock. This prevents the SET_ACTIVE() in drawables-actions.c to
* toggle locks unexpectedly.
*/
g_list_free (drawables);
return;
}
}
for (iter = drawables; iter; iter = iter->next)
if (locked != pika_item_get_lock_content (iter->data))
break;
if (g_list_length (drawables) == 1)
{
PikaUndo *undo;
undo = pika_image_undo_can_compress (image, PIKA_TYPE_ITEM_UNDO,
PIKA_UNDO_ITEM_LOCK_CONTENT);
if (undo && PIKA_ITEM_UNDO (undo)->item == PIKA_ITEM (drawables->data))
push_undo = FALSE;
}
else
{
/* TODO: undo groups cannot be compressed so far. */
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_ITEM_LOCK_CONTENTS,
_("Lock/Unlock content"));
}
for (; iter; iter = iter->next)
pika_item_set_lock_content (iter->data, locked, push_undo);
if (g_list_length (drawables) != 1)
pika_image_undo_group_end (image);
pika_image_flush (image);
g_list_free (drawables);
}
void
drawable_lock_position_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
gboolean locked;
gboolean push_undo = TRUE;
return_if_no_drawables (image, drawables, data);
locked = g_variant_get_boolean (value);
if (PIKA_IS_LAYER_MASK (drawables->data))
{
PikaLayerMask *mask = PIKA_LAYER_MASK (drawables->data);
g_list_free (drawables);
drawables = g_list_prepend (NULL, pika_layer_mask_get_layer (mask));
}
for (iter = drawables; iter; iter = iter->next)
{
if (! locked && ! pika_item_get_lock_position (iter->data))
{
/* If any of the drawables are already unlocked, we don't toggle the
* lock. This prevents the SET_ACTIVE() in drawables-actions.c to
* toggle locks unexpectedly.
*/
g_list_free (drawables);
return;
}
}
for (iter = drawables; iter; iter = iter->next)
if (locked != pika_item_get_lock_position (iter->data))
break;
if (g_list_length (drawables) == 1)
{
PikaUndo *undo;
undo = pika_image_undo_can_compress (image, PIKA_TYPE_ITEM_UNDO,
PIKA_UNDO_ITEM_LOCK_POSITION);
if (undo && PIKA_ITEM_UNDO (undo)->item == PIKA_ITEM (drawables->data))
push_undo = FALSE;
}
else
{
/* TODO: undo groups cannot be compressed so far. */
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_ITEM_LOCK_POSITION,
_("Lock/Unlock position"));
}
for (; iter; iter = iter->next)
pika_item_set_lock_position (iter->data, locked, push_undo);
if (g_list_length (drawables) != 1)
pika_image_undo_group_end (image);
pika_image_flush (image);
g_list_free (drawables);
}
void
drawable_flip_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
PikaContext *context;
gint off_x, off_y;
gdouble axis = 0.0;
PikaOrientationType orientation;
return_if_no_drawables (image, drawables, data);
return_if_no_context (context, data);
orientation = (PikaOrientationType) g_variant_get_int32 (value);
if (g_list_length (drawables) > 1)
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_DRAWABLE_MOD,
_("Flip Drawables"));
for (iter = drawables; iter; iter = iter->next)
{
PikaItem *item;
item = PIKA_ITEM (iter->data);
pika_item_get_offset (item, &off_x, &off_y);
switch (orientation)
{
case PIKA_ORIENTATION_HORIZONTAL:
axis = ((gdouble) off_x + (gdouble) pika_item_get_width (item) / 2.0);
break;
case PIKA_ORIENTATION_VERTICAL:
axis = ((gdouble) off_y + (gdouble) pika_item_get_height (item) / 2.0);
break;
default:
break;
}
pika_item_flip (item, context, orientation, axis,
pika_item_get_clip (item, FALSE));
}
if (g_list_length (drawables) > 1)
pika_image_undo_group_end (image);
pika_image_flush (image);
g_list_free (drawables);
}
void
drawable_rotate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
PikaContext *context;
PikaRotationType rotation_type;
return_if_no_drawables (image, drawables, data);
return_if_no_context (context, data);
rotation_type = (PikaRotationType) g_variant_get_int32 (value);
if (g_list_length (drawables) > 1)
pika_image_undo_group_start (image,
PIKA_UNDO_GROUP_DRAWABLE_MOD,
_("Rotate Drawables"));
for (iter = drawables; iter; iter = iter->next)
{
PikaItem *item;
gint off_x, off_y;
gdouble center_x, center_y;
item = PIKA_ITEM (iter->data);
pika_item_get_offset (item, &off_x, &off_y);
center_x = ((gdouble) off_x + (gdouble) pika_item_get_width (item) / 2.0);
center_y = ((gdouble) off_y + (gdouble) pika_item_get_height (item) / 2.0);
pika_item_rotate (item, context,
rotation_type, center_x, center_y,
pika_item_get_clip (item, FALSE));
}
if (g_list_length (drawables) > 1)
pika_image_undo_group_end (image);
pika_image_flush (image);
g_list_free (drawables);
}

View File

@ -0,0 +1,51 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DRAWABLE_COMMANDS_H__
#define __DRAWABLE_COMMANDS_H__
void drawable_equalize_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void drawable_levels_stretch_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void drawable_visible_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void drawable_lock_content_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void drawable_lock_position_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void drawable_flip_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void drawable_rotate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __DRAWABLE_COMMANDS_H__ */

View File

@ -0,0 +1,137 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikacontext.h"
#include "core/pikadata.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "data-commands.h"
#include "dynamics-actions.h"
#include "pika-intl.h"
static const PikaActionEntry dynamics_actions[] =
{
{ "dynamics-new", PIKA_ICON_DOCUMENT_NEW,
NC_("dynamics-action", "_New Dynamics"), NULL, { NULL },
NC_("dynamics-action", "Create a new dynamics"),
data_new_cmd_callback,
PIKA_HELP_DYNAMICS_NEW },
{ "dynamics-duplicate", PIKA_ICON_OBJECT_DUPLICATE,
NC_("dynamics-action", "D_uplicate Dynamics"), NULL, { NULL },
NC_("dynamics-action", "Duplicate this dynamics"),
data_duplicate_cmd_callback,
PIKA_HELP_DYNAMICS_DUPLICATE },
{ "dynamics-copy-location", PIKA_ICON_EDIT_COPY,
NC_("dynamics-action", "Copy Dynamics _Location"), NULL, { NULL },
NC_("dynamics-action", "Copy dynamics file location to clipboard"),
data_copy_location_cmd_callback,
PIKA_HELP_DYNAMICS_COPY_LOCATION },
{ "dynamics-show-in-file-manager", PIKA_ICON_FILE_MANAGER,
NC_("dynamics-action", "Show in _File Manager"), NULL, { NULL },
NC_("dynamics-action", "Show dynamics file location in the file manager"),
data_show_in_file_manager_cmd_callback,
PIKA_HELP_DYNAMICS_SHOW_IN_FILE_MANAGER },
{ "dynamics-delete", PIKA_ICON_EDIT_DELETE,
NC_("dynamics-action", "_Delete Dynamics"), NULL, { NULL },
NC_("dynamics-action", "Delete this dynamics"),
data_delete_cmd_callback,
PIKA_HELP_DYNAMICS_DELETE },
{ "dynamics-refresh", PIKA_ICON_VIEW_REFRESH,
NC_("dynamics-action", "_Refresh Dynamics"), NULL, { NULL },
NC_("dynamics-action", "Refresh dynamics"),
data_refresh_cmd_callback,
PIKA_HELP_DYNAMICS_REFRESH }
};
static const PikaStringActionEntry dynamics_edit_actions[] =
{
{ "dynamics-edit", PIKA_ICON_EDIT,
NC_("dynamics-action", "_Edit Dynamics..."), NULL, { NULL },
NC_("dynamics-action", "Edit this dynamics"),
"pika-dynamics-editor",
PIKA_HELP_DYNAMICS_EDIT }
};
void
dynamics_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "dynamics-action",
dynamics_actions,
G_N_ELEMENTS (dynamics_actions));
pika_action_group_add_string_actions (group, "dynamics-action",
dynamics_edit_actions,
G_N_ELEMENTS (dynamics_edit_actions),
data_edit_cmd_callback);
}
void
dynamics_actions_update (PikaActionGroup *group,
gpointer user_data)
{
PikaContext *context = action_data_get_context (user_data);
PikaDynamics *dynamics = NULL;
PikaData *data = NULL;
GFile *file = NULL;
if (context)
{
dynamics = pika_context_get_dynamics (context);
if (dynamics)
{
data = PIKA_DATA (dynamics);
file = pika_data_get_file (data);
}
}
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("dynamics-edit", dynamics);
SET_SENSITIVE ("dynamics-duplicate", dynamics && pika_data_is_duplicatable (data));
SET_SENSITIVE ("dynamics-copy-location", file);
SET_SENSITIVE ("dynamics-show-in-file-manager", file);
SET_SENSITIVE ("dynamics-delete", dynamics && pika_data_is_deletable (data));
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DYNAMICS_ACTIONS_H__
#define __DYNAMICS_ACTIONS_H__
void dynamics_actions_setup (PikaActionGroup *group);
void dynamics_actions_update (PikaActionGroup *group,
gpointer user_data);
#endif /* __DYNAMICS_ACTIONS_H__ */

View File

@ -0,0 +1,81 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikacontext.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikadataeditor.h"
#include "widgets/pikahelp-ids.h"
#include "data-editor-commands.h"
#include "dynamics-editor-actions.h"
#include "pika-intl.h"
static const PikaToggleActionEntry dynamics_editor_toggle_actions[] =
{
{ "dynamics-editor-edit-active", PIKA_ICON_LINKED,
NC_("dynamics-editor-action", "Edit Active Dynamics"), NULL, { NULL }, NULL,
data_editor_edit_active_cmd_callback,
FALSE,
PIKA_HELP_BRUSH_EDITOR_EDIT_ACTIVE }
};
void
dynamics_editor_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_toggle_actions (group, "dynamics-editor-action",
dynamics_editor_toggle_actions,
G_N_ELEMENTS (dynamics_editor_toggle_actions));
}
void
dynamics_editor_actions_update (PikaActionGroup *group,
gpointer user_data)
{
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (user_data);
gboolean edit_active = FALSE;
edit_active = pika_data_editor_get_edit_active (data_editor);
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0)
#define SET_ACTIVE(action,condition) \
pika_action_group_set_action_active (group, action, (condition) != 0)
SET_ACTIVE ("dynamics-editor-edit-active", edit_active);
#undef SET_SENSITIVE
#undef SET_ACTIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __DYNAMICS_EDITOR_ACTIONS_H__
#define __DYNAMICS_EDITOR_ACTIONS_H__
void dynamics_editor_actions_setup (PikaActionGroup *group);
void dynamics_editor_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __DYNAMICS_EDITOR_ACTIONS_H__ */

396
app/actions/edit-actions.c Normal file
View File

@ -0,0 +1,396 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikachannel.h"
#include "core/pikacontext.h"
#include "core/pikaimage.h"
#include "core/pikaimage-undo.h"
#include "core/pikalayer.h"
#include "core/pikalist.h"
#include "core/pikatoolinfo.h"
#include "core/pikaundostack.h"
#include "widgets/pikaaction.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "tools/tool_manager.h"
#include "actions.h"
#include "edit-actions.h"
#include "edit-commands.h"
#include "pika-intl.h"
/* local function prototypes */
static void edit_actions_foreground_changed (PikaContext *context,
const PikaRGB *color,
PikaActionGroup *group);
static void edit_actions_background_changed (PikaContext *context,
const PikaRGB *color,
PikaActionGroup *group);
static void edit_actions_pattern_changed (PikaContext *context,
PikaPattern *pattern,
PikaActionGroup *group);
static const PikaActionEntry edit_actions[] =
{
{ "edit-undo", PIKA_ICON_EDIT_UNDO,
NC_("edit-action", "_Undo"), NULL, { "<primary>Z", NULL },
NC_("edit-action", "Undo the last operation"),
edit_undo_cmd_callback,
PIKA_HELP_EDIT_UNDO },
{ "edit-redo", PIKA_ICON_EDIT_REDO,
NC_("edit-action", "_Redo"), NULL, { "<primary>Y", NULL },
NC_("edit-action", "Redo the last operation that was undone"),
edit_redo_cmd_callback,
PIKA_HELP_EDIT_REDO },
{ "edit-strong-undo", PIKA_ICON_EDIT_UNDO,
NC_("edit-action", "Strong Undo"), NULL, { "<primary><shift>Z", NULL },
NC_("edit-action", "Undo the last operation, skipping visibility changes"),
edit_strong_undo_cmd_callback,
PIKA_HELP_EDIT_STRONG_UNDO },
{ "edit-strong-redo", PIKA_ICON_EDIT_REDO,
NC_("edit-action", "Strong Redo"), NULL, { "<primary><shift>Y", NULL },
NC_("edit-action",
"Redo the last operation that was undone, skipping visibility changes"),
edit_strong_redo_cmd_callback,
PIKA_HELP_EDIT_STRONG_REDO },
{ "edit-undo-clear", PIKA_ICON_SHRED,
NC_("edit-action", "_Clear Undo History"), NULL, { NULL },
NC_("edit-action", "Remove all operations from the undo history"),
edit_undo_clear_cmd_callback,
PIKA_HELP_EDIT_UNDO_CLEAR },
{ "edit-cut", PIKA_ICON_EDIT_CUT,
NC_("edit-action", "Cu_t"), NULL, { "<primary>X", "Cut", NULL },
NC_("edit-action", "Move the selected pixels to the clipboard"),
edit_cut_cmd_callback,
PIKA_HELP_EDIT_CUT },
{ "edit-copy", PIKA_ICON_EDIT_COPY,
NC_("edit-action", "_Copy"), NULL, { "<primary>C", "Copy", NULL },
NC_("edit-action", "Copy the selected pixels to the clipboard"),
edit_copy_cmd_callback,
PIKA_HELP_EDIT_COPY },
{ "edit-copy-visible", NULL, /* PIKA_ICON_COPY_VISIBLE, */
NC_("edit-action", "Copy _Visible"), NULL, { "<primary><shift>C", "<shift>Copy", NULL },
NC_("edit-action", "Copy what is visible in the selected region"),
edit_copy_visible_cmd_callback,
PIKA_HELP_EDIT_COPY_VISIBLE },
{ "edit-paste-as-new-image", PIKA_ICON_EDIT_PASTE_AS_NEW,
NC_("edit-action", "Paste as _New Image"),
NC_("edit-action", "From _Clipboard"),
{ "<primary><shift>V", "<shift>Paste", NULL },
NC_("edit-action", "Create a new image from the content of the clipboard"),
edit_paste_as_new_image_cmd_callback,
PIKA_HELP_EDIT_PASTE_AS_NEW_IMAGE },
{ "edit-named-cut", PIKA_ICON_EDIT_CUT,
NC_("edit-action", "Cu_t Named..."), NULL, { NULL },
NC_("edit-action", "Move the selected pixels to a named buffer"),
edit_named_cut_cmd_callback,
PIKA_HELP_BUFFER_CUT },
{ "edit-named-copy", PIKA_ICON_EDIT_COPY,
NC_("edit-action", "_Copy Named..."), NULL, { NULL },
NC_("edit-action", "Copy the selected pixels to a named buffer"),
edit_named_copy_cmd_callback,
PIKA_HELP_BUFFER_COPY },
{ "edit-named-copy-visible", NULL, /* PIKA_ICON_COPY_VISIBLE, */
NC_("edit-action", "Copy _Visible Named..."), NULL, { NULL },
NC_("edit-action",
"Copy what is visible in the selected region to a named buffer"),
edit_named_copy_visible_cmd_callback,
PIKA_HELP_BUFFER_COPY },
{ "edit-named-paste", PIKA_ICON_EDIT_PASTE,
NC_("edit-action", "_Paste Named..."), NULL, { NULL },
NC_("edit-action", "Paste the content of a named buffer"),
edit_named_paste_cmd_callback,
PIKA_HELP_BUFFER_PASTE },
{ "edit-clear", PIKA_ICON_EDIT_CLEAR,
NC_("edit-action", "Cl_ear"), NULL, { "Delete", NULL },
NC_("edit-action", "Clear the selected pixels"),
edit_clear_cmd_callback,
PIKA_HELP_EDIT_CLEAR }
};
static const PikaEnumActionEntry edit_paste_actions[] =
{
{ "edit-paste", PIKA_ICON_EDIT_PASTE,
NC_("edit-action", "_Paste"), NULL, { "<primary>V", "Paste", NULL },
NC_("edit-action", "Paste the content of the clipboard"),
PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING, FALSE,
PIKA_HELP_EDIT_PASTE },
{ "edit-paste-in-place", PIKA_ICON_EDIT_PASTE,
NC_("edit-action", "Paste In P_lace"), NULL, { "<primary><alt>V", "<alt>Paste", NULL },
NC_("edit-action",
"Paste the content of the clipboard at its original position"),
PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE, FALSE,
PIKA_HELP_EDIT_PASTE_IN_PLACE },
{ "edit-paste-merged", PIKA_ICON_EDIT_PASTE,
NC_("edit-action", "_Paste as Single Layer"), NULL, { NULL },
NC_("edit-action", "Paste the content of the clipboard as a single layer"),
PIKA_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING, FALSE,
PIKA_HELP_EDIT_PASTE },
{ "edit-paste-merged-in-place", PIKA_ICON_EDIT_PASTE,
NC_("edit-action", "Paste as Single Layer In P_lace"), NULL, { NULL },
NC_("edit-action",
"Paste the content of the clipboard at its original position as a single layer"),
PIKA_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE, FALSE,
PIKA_HELP_EDIT_PASTE_IN_PLACE },
{ "edit-paste-into", PIKA_ICON_EDIT_PASTE_INTO,
NC_("edit-action", "Paste _Into Selection"), NULL, { NULL },
NC_("edit-action",
"Paste the content of the clipboard into the current selection"),
PIKA_PASTE_TYPE_FLOATING_INTO, FALSE,
PIKA_HELP_EDIT_PASTE_INTO },
{ "edit-paste-into-in-place", PIKA_ICON_EDIT_PASTE_INTO,
NC_("edit-action", "Paste Int_o Selection In Place"), NULL, { NULL },
NC_("edit-action",
"Paste the content of the clipboard into the current selection "
"at its original position"),
PIKA_PASTE_TYPE_FLOATING_INTO_IN_PLACE, FALSE,
PIKA_HELP_EDIT_PASTE_INTO_IN_PLACE }
};
static const PikaEnumActionEntry edit_fill_actions[] =
{
{ "edit-fill-fg", PIKA_ICON_TOOL_BUCKET_FILL,
NC_("edit-action", "Fill with _FG Color"), NULL, { "<primary>comma", NULL },
NC_("edit-action", "Fill the selection using the foreground color"),
PIKA_FILL_FOREGROUND, FALSE,
PIKA_HELP_EDIT_FILL_FG },
{ "edit-fill-bg", PIKA_ICON_TOOL_BUCKET_FILL,
NC_("edit-action", "Fill with B_G Color"), NULL, { "<primary>period", NULL },
NC_("edit-action", "Fill the selection using the background color"),
PIKA_FILL_BACKGROUND, FALSE,
PIKA_HELP_EDIT_FILL_BG },
{ "edit-fill-pattern", PIKA_ICON_PATTERN,
NC_("edit-action", "Fill _with Pattern"), NULL, { "<primary>semicolon", NULL },
NC_("edit-action", "Fill the selection using the active pattern"),
PIKA_FILL_PATTERN, FALSE,
PIKA_HELP_EDIT_FILL_PATTERN }
};
void
edit_actions_setup (PikaActionGroup *group)
{
PikaContext *context = pika_get_user_context (group->pika);
PikaRGB color;
PikaPattern *pattern;
pika_action_group_add_actions (group, "edit-action",
edit_actions,
G_N_ELEMENTS (edit_actions));
pika_action_group_add_enum_actions (group, "edit-action",
edit_paste_actions,
G_N_ELEMENTS (edit_paste_actions),
edit_paste_cmd_callback);
pika_action_group_add_enum_actions (group, "edit-action",
edit_fill_actions,
G_N_ELEMENTS (edit_fill_actions),
edit_fill_cmd_callback);
g_signal_connect_object (context, "foreground-changed",
G_CALLBACK (edit_actions_foreground_changed),
group, 0);
g_signal_connect_object (context, "background-changed",
G_CALLBACK (edit_actions_background_changed),
group, 0);
g_signal_connect_object (context, "pattern-changed",
G_CALLBACK (edit_actions_pattern_changed),
group, 0);
pika_context_get_foreground (context, &color);
edit_actions_foreground_changed (context, &color, group);
pika_context_get_background (context, &color);
edit_actions_background_changed (context, &color, group);
pattern = pika_context_get_pattern (context);
edit_actions_pattern_changed (context, pattern, group);
}
void
edit_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaImage *image = action_data_get_image (data);
PikaDisplay *display = action_data_get_display (data);
GList *drawables = NULL;
gchar *undo_name = NULL;
gchar *redo_name = NULL;
gboolean undo_enabled = FALSE;
gboolean have_no_groups = FALSE; /* At least 1 selected layer is not a group. */
gboolean have_writable = FALSE; /* At least 1 selected layer has no contents lock. */
if (image)
{
GList *iter;
drawables = pika_image_get_selected_drawables (image);
for (iter = drawables; iter; iter = iter->next)
{
if (! pika_viewable_get_children (PIKA_VIEWABLE (iter->data)))
have_no_groups = TRUE;
if (! pika_item_is_content_locked (PIKA_ITEM (iter->data), NULL))
have_writable = TRUE;
if (have_no_groups && have_writable)
break;
}
undo_enabled = pika_image_undo_is_enabled (image);
if (undo_enabled)
{
PikaUndoStack *undo_stack = pika_image_get_undo_stack (image);
PikaUndoStack *redo_stack = pika_image_get_redo_stack (image);
PikaUndo *undo = pika_undo_stack_peek (undo_stack);
PikaUndo *redo = pika_undo_stack_peek (redo_stack);
const gchar *tool_undo = NULL;
const gchar *tool_redo = NULL;
if (display)
{
tool_undo = tool_manager_can_undo_active (image->pika, display);
tool_redo = tool_manager_can_redo_active (image->pika, display);
}
if (tool_undo)
undo_name = g_strdup_printf (_("_Undo %s"), tool_undo);
else if (undo)
undo_name = g_strdup_printf (_("_Undo %s"),
pika_object_get_name (undo));
if (tool_redo)
redo_name = g_strdup_printf (_("_Redo %s"), tool_redo);
else if (redo)
redo_name = g_strdup_printf (_("_Redo %s"),
pika_object_get_name (redo));
}
}
#define SET_LABEL(action,label) \
pika_action_group_set_action_label (group, action, (label))
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_LABEL ("edit-undo", undo_name ? undo_name : _("_Undo"));
SET_LABEL ("edit-redo", redo_name ? redo_name : _("_Redo"));
SET_SENSITIVE ("edit-undo", undo_enabled && undo_name);
SET_SENSITIVE ("edit-redo", undo_enabled && redo_name);
SET_SENSITIVE ("edit-strong-undo", undo_enabled && undo_name);
SET_SENSITIVE ("edit-strong-redo", undo_enabled && redo_name);
SET_SENSITIVE ("edit-undo-clear", undo_enabled && (undo_name || redo_name));
g_free (undo_name);
g_free (redo_name);
SET_SENSITIVE ("edit-cut", have_writable && have_no_groups);
SET_SENSITIVE ("edit-copy", drawables);
SET_SENSITIVE ("edit-copy-visible", image);
/* "edit-paste" is always active */
SET_SENSITIVE ("edit-paste-in-place", image);
SET_SENSITIVE ("edit-paste-into", image);
SET_SENSITIVE ("edit-paste-into-in-place", image);
SET_SENSITIVE ("edit-named-cut", have_writable && have_no_groups);
SET_SENSITIVE ("edit-named-copy", drawables);
SET_SENSITIVE ("edit-named-copy-visible", drawables);
/* "edit-named-paste" is always active */
SET_SENSITIVE ("edit-clear", have_writable && have_no_groups);
SET_SENSITIVE ("edit-fill-fg", have_writable && have_no_groups);
SET_SENSITIVE ("edit-fill-bg", have_writable && have_no_groups);
SET_SENSITIVE ("edit-fill-pattern", have_writable && have_no_groups);
#undef SET_LABEL
#undef SET_SENSITIVE
g_list_free (drawables);
}
/* private functions */
static void
edit_actions_foreground_changed (PikaContext *context,
const PikaRGB *color,
PikaActionGroup *group)
{
pika_action_group_set_action_color (group, "edit-fill-fg", color, FALSE);
}
static void
edit_actions_background_changed (PikaContext *context,
const PikaRGB *color,
PikaActionGroup *group)
{
pika_action_group_set_action_color (group, "edit-fill-bg", color, FALSE);
}
static void
edit_actions_pattern_changed (PikaContext *context,
PikaPattern *pattern,
PikaActionGroup *group)
{
pika_action_group_set_action_viewable (group, "edit-fill-pattern",
PIKA_VIEWABLE (pattern));
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __EDIT_ACTIONS_H__
#define __EDIT_ACTIONS_H__
void edit_actions_setup (PikaActionGroup *group);
void edit_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __EDIT_ACTIONS_H__ */

830
app/actions/edit-commands.c Normal file
View File

@ -0,0 +1,830 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pika-edit.h"
#include "core/pikabuffer.h"
#include "core/pikacontainer.h"
#include "core/pikadrawable.h"
#include "core/pikadrawable-edit.h"
#include "core/pikafilloptions.h"
#include "core/pikalayer.h"
#include "core/pikalayer-new.h"
#include "core/pikalayermask.h"
#include "core/pikaimage.h"
#include "core/pikaimage-undo.h"
#include "vectors/pikavectors-import.h"
#include "widgets/pikaclipboard.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikadialogfactory.h"
#include "widgets/pikamessagebox.h"
#include "widgets/pikamessagedialog.h"
#include "widgets/pikawidgets-utils.h"
#include "widgets/pikawindowstrategy.h"
#include "display/pikadisplay.h"
#include "display/pikadisplayshell.h"
#include "display/pikadisplayshell-transform.h"
#include "tools/pikatools-utils.h"
#include "tools/tool_manager.h"
#include "actions.h"
#include "edit-commands.h"
#include "pika-intl.h"
/* local function prototypes */
static gboolean check_drawable_alpha (PikaDrawable *drawable,
gpointer data);
static void edit_paste (PikaDisplay *display,
PikaPasteType paste_type,
gboolean merged,
gboolean try_svg);
static void cut_named_buffer_callback (GtkWidget *widget,
const gchar *name,
gpointer data);
static void copy_named_buffer_callback (GtkWidget *widget,
const gchar *name,
gpointer data);
static void copy_named_visible_buffer_callback (GtkWidget *widget,
const gchar *name,
gpointer data);
/* public functions */
void
edit_undo_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
PikaDisplay *display;
return_if_no_image (image, data);
return_if_no_display (display, data);
if (tool_manager_undo_active (image->pika, display) ||
pika_image_undo (image))
{
pika_image_flush (image);
}
}
void
edit_redo_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
PikaDisplay *display;
return_if_no_image (image, data);
return_if_no_display (display, data);
if (tool_manager_redo_active (image->pika, display) ||
pika_image_redo (image))
{
pika_image_flush (image);
}
}
void
edit_strong_undo_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
return_if_no_image (image, data);
if (pika_image_strong_undo (image))
pika_image_flush (image);
}
void
edit_strong_redo_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
return_if_no_image (image, data);
if (pika_image_strong_redo (image))
pika_image_flush (image);
}
void
edit_undo_clear_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
PikaUndoStack *undo_stack;
PikaUndoStack *redo_stack;
GtkWidget *widget;
GtkWidget *dialog;
gchar *size;
gint64 memsize;
gint64 guisize;
return_if_no_image (image, data);
return_if_no_widget (widget, data);
dialog = pika_message_dialog_new (_("Clear Undo History"),
PIKA_ICON_DIALOG_WARNING,
widget,
GTK_DIALOG_MODAL |
GTK_DIALOG_DESTROY_WITH_PARENT,
pika_standard_help_func,
PIKA_HELP_EDIT_UNDO_CLEAR,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("Cl_ear"), GTK_RESPONSE_OK,
NULL);
pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
g_signal_connect_object (gtk_widget_get_toplevel (widget), "unmap",
G_CALLBACK (gtk_widget_destroy),
dialog, G_CONNECT_SWAPPED);
g_signal_connect_object (image, "disconnect",
G_CALLBACK (gtk_widget_destroy),
dialog, G_CONNECT_SWAPPED);
pika_message_box_set_primary_text (PIKA_MESSAGE_DIALOG (dialog)->box,
_("Really clear image's undo history?"));
undo_stack = pika_image_get_undo_stack (image);
redo_stack = pika_image_get_redo_stack (image);
memsize = pika_object_get_memsize (PIKA_OBJECT (undo_stack), &guisize);
memsize += guisize;
memsize += pika_object_get_memsize (PIKA_OBJECT (redo_stack), &guisize);
memsize += guisize;
size = g_format_size (memsize);
pika_message_box_set_text (PIKA_MESSAGE_DIALOG (dialog)->box,
_("Clearing the undo history of this "
"image will gain %s of memory."), size);
g_free (size);
if (pika_dialog_run (PIKA_DIALOG (dialog)) == GTK_RESPONSE_OK)
{
pika_image_undo_disable (image);
pika_image_undo_enable (image);
pika_image_flush (image);
}
gtk_widget_destroy (dialog);
}
void
edit_cut_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
PikaObject *cut;
GError *error = NULL;
return_if_no_drawables (image, drawables, data);
for (iter = drawables; iter; iter = iter->next)
if (! check_drawable_alpha (iter->data, data))
{
g_list_free (drawables);
return;
}
cut = pika_edit_cut (image, drawables, action_data_get_context (data), &error);
if (cut)
{
PikaDisplay *display = action_data_get_display (data);
if (display)
{
gchar *msg;
if (PIKA_IS_IMAGE (cut))
msg = g_strdup_printf (ngettext ("Cut layer to the clipboard.",
"Cut %d layers to the clipboard.",
g_list_length (drawables)),
g_list_length (drawables));
else
msg = g_strdup (_("Cut pixels to the clipboard."));
pika_message_literal (image->pika,
G_OBJECT (display), PIKA_MESSAGE_INFO,
msg);
g_free (msg);
}
pika_image_flush (image);
}
else
{
pika_message_literal (image->pika,
G_OBJECT (action_data_get_display (data)),
PIKA_MESSAGE_WARNING,
error->message);
g_clear_error (&error);
}
g_list_free (drawables);
}
void
edit_copy_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
PikaObject *copy;
GError *error = NULL;
return_if_no_drawables (image, drawables, data);
copy = pika_edit_copy (image, drawables, action_data_get_context (data),
&error);
if (copy)
{
PikaDisplay *display = action_data_get_display (data);
if (display)
pika_message_literal (image->pika,
G_OBJECT (display), PIKA_MESSAGE_INFO,
PIKA_IS_IMAGE (copy) ?
_("Copied layer to the clipboard.") :
_("Copied pixels to the clipboard."));
pika_image_flush (image);
}
else
{
pika_message_literal (image->pika,
G_OBJECT (action_data_get_display (data)),
PIKA_MESSAGE_WARNING,
error->message);
g_clear_error (&error);
}
g_list_free (drawables);
}
void
edit_copy_visible_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GError *error = NULL;
return_if_no_image (image, data);
if (pika_edit_copy_visible (image, action_data_get_context (data), &error))
{
PikaDisplay *display = action_data_get_display (data);
if (display)
pika_message_literal (image->pika,
G_OBJECT (display), PIKA_MESSAGE_INFO,
_("Copied pixels to the clipboard."));
pika_image_flush (image);
}
else
{
pika_message_literal (image->pika,
G_OBJECT (action_data_get_display (data)),
PIKA_MESSAGE_WARNING,
error->message);
g_clear_error (&error);
}
}
void
edit_paste_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
PikaDisplay *display = action_data_get_display (data);
PikaPasteType paste_type = (PikaPasteType) g_variant_get_int32 (value);
PikaPasteType converted_type;
GList *drawables;
gboolean merged = FALSE;
if (paste_type == PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING)
{
if (! display || ! pika_display_get_image (display))
{
edit_paste_as_new_image_cmd_callback (action, value, data);
return;
}
}
return_if_no_image (image, data);
if (! display)
return;
switch (paste_type)
{
case PIKA_PASTE_TYPE_FLOATING:
case PIKA_PASTE_TYPE_FLOATING_IN_PLACE:
case PIKA_PASTE_TYPE_FLOATING_INTO:
case PIKA_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
edit_paste (display, paste_type, merged, TRUE);
break;
case PIKA_PASTE_TYPE_NEW_LAYER:
case PIKA_PASTE_TYPE_NEW_LAYER_IN_PLACE:
edit_paste (display, paste_type, merged, FALSE);
break;
case PIKA_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING:
case PIKA_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE:
merged = TRUE;
case PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING:
case PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE:
drawables = pika_image_get_selected_drawables (image);
if (drawables &&
(g_list_length (drawables) == 1) &&
PIKA_IS_LAYER_MASK (drawables->data))
{
converted_type = (paste_type == PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING ||
paste_type == PIKA_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING) ?
PIKA_PASTE_TYPE_FLOATING :
PIKA_PASTE_TYPE_FLOATING_IN_PLACE;
edit_paste (display, converted_type, merged, TRUE);
}
else
{
converted_type = (paste_type == PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING ||
paste_type == PIKA_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING) ?
PIKA_PASTE_TYPE_NEW_LAYER :
PIKA_PASTE_TYPE_NEW_LAYER_IN_PLACE;
edit_paste (display, converted_type, merged, FALSE);
}
g_list_free (drawables);
break;
}
}
void
edit_paste_as_new_image_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
GtkWidget *widget;
PikaObject *paste;
PikaImage *image = NULL;
return_if_no_pika (pika, data);
return_if_no_widget (widget, data);
paste = pika_clipboard_get_object (pika);
if (paste)
{
image = pika_edit_paste_as_new_image (pika, paste,
action_data_get_context (data));
g_object_unref (paste);
}
if (image)
{
pika_create_display (pika, image, PIKA_UNIT_PIXEL, 1.0,
G_OBJECT (pika_widget_get_monitor (widget)));
g_object_unref (image);
}
else
{
pika_message_literal (pika, NULL, PIKA_MESSAGE_WARNING,
_("There is no image data in the clipboard "
"to paste."));
}
}
void
edit_named_cut_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GtkWidget *widget;
GtkWidget *dialog;
return_if_no_image (image, data);
return_if_no_widget (widget, data);
dialog = pika_query_string_box (_("Cut Named"), widget,
pika_standard_help_func,
PIKA_HELP_BUFFER_CUT,
_("Enter a name for this buffer"),
NULL,
G_OBJECT (image), "disconnect",
cut_named_buffer_callback,
image, NULL);
gtk_widget_show (dialog);
}
void
edit_named_copy_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GtkWidget *widget;
GtkWidget *dialog;
return_if_no_image (image, data);
return_if_no_widget (widget, data);
dialog = pika_query_string_box (_("Copy Named"), widget,
pika_standard_help_func,
PIKA_HELP_BUFFER_COPY,
_("Enter a name for this buffer"),
NULL,
G_OBJECT (image), "disconnect",
copy_named_buffer_callback,
image, NULL);
gtk_widget_show (dialog);
}
void
edit_named_copy_visible_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GtkWidget *widget;
GtkWidget *dialog;
return_if_no_image (image, data);
return_if_no_widget (widget, data);
dialog = pika_query_string_box (_("Copy Visible Named"), widget,
pika_standard_help_func,
PIKA_HELP_BUFFER_COPY,
_("Enter a name for this buffer"),
NULL,
G_OBJECT (image), "disconnect",
copy_named_visible_buffer_callback,
image, NULL);
gtk_widget_show (dialog);
}
void
edit_named_paste_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
GtkWidget *widget;
return_if_no_pika (pika, data);
return_if_no_widget (widget, data);
pika_window_strategy_show_dockable_dialog (PIKA_WINDOW_STRATEGY (pika_get_window_strategy (pika)),
pika,
pika_dialog_factory_get_singleton (),
pika_widget_get_monitor (widget),
"pika-buffer-list|pika-buffer-grid");
}
void
edit_clear_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
return_if_no_drawables (image, drawables, data);
for (iter = drawables; iter; iter = iter->next)
/* Return if any has a locked alpha. */
if (! check_drawable_alpha (iter->data, data))
{
g_list_free (drawables);
return;
}
pika_image_undo_group_start (image, PIKA_UNDO_GROUP_PAINT,
_("Clear"));
for (iter = drawables; iter; iter = iter->next)
if (! pika_viewable_get_children (PIKA_VIEWABLE (iter->data)) &&
! pika_item_is_content_locked (PIKA_ITEM (iter->data), NULL))
pika_drawable_edit_clear (iter->data, action_data_get_context (data));
pika_image_undo_group_end (image);
pika_image_flush (image);
g_list_free (drawables);
}
void
edit_fill_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
GList *iter;
PikaFillType fill_type;
PikaFillOptions *options;
GError *error = NULL;
return_if_no_drawables (image, drawables, data);
fill_type = (PikaFillType) g_variant_get_int32 (value);
options = pika_fill_options_new (action_data_get_pika (data), NULL, FALSE);
if (pika_fill_options_set_by_fill_type (options,
action_data_get_context (data),
fill_type, &error))
{
pika_image_undo_group_start (image, PIKA_UNDO_GROUP_PAINT,
pika_fill_options_get_undo_desc (options));
for (iter = drawables; iter; iter = iter->next)
pika_drawable_edit_fill (iter->data, options, NULL);
pika_image_undo_group_end (image);
pika_image_flush (image);
}
else
{
pika_message_literal (image->pika, NULL, PIKA_MESSAGE_WARNING,
error->message);
g_clear_error (&error);
}
g_list_free (drawables);
g_object_unref (options);
}
/* private functions */
static gboolean
check_drawable_alpha (PikaDrawable *drawable,
gpointer data)
{
PikaLayer *locked_layer = NULL;
if (pika_drawable_has_alpha (drawable) &&
PIKA_IS_LAYER (drawable) &&
pika_layer_is_alpha_locked (PIKA_LAYER (drawable), &locked_layer))
{
Pika *pika = action_data_get_pika (data);
PikaDisplay *display = action_data_get_display (data);
if (pika && display)
{
pika_message_literal (
pika, G_OBJECT (display), PIKA_MESSAGE_WARNING,
_("A selected layer's alpha channel is locked."));
pika_tools_blink_lock_box (pika, PIKA_ITEM (locked_layer));
}
return FALSE;
}
return TRUE;
}
static void
edit_paste (PikaDisplay *display,
PikaPasteType paste_type,
gboolean merged,
gboolean try_svg)
{
PikaImage *image = pika_display_get_image (display);
PikaObject *paste;
g_return_if_fail (paste_type != PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING &&
paste_type != PIKA_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE &&
paste_type != PIKA_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING &&
paste_type != PIKA_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE);
if (try_svg)
{
gchar *svg;
gsize svg_size;
svg = pika_clipboard_get_svg (display->pika, &svg_size);
if (svg)
{
if (pika_vectors_import_buffer (image, svg, svg_size,
TRUE, FALSE,
PIKA_IMAGE_ACTIVE_PARENT, -1,
NULL, NULL))
{
pika_image_flush (image);
}
g_free (svg);
return;
}
}
paste = pika_clipboard_get_object (display->pika);
if (paste)
{
PikaDisplayShell *shell = pika_display_get_shell (display);
GList *drawables = pika_image_get_selected_drawables (image);
GList *pasted_layers;
gint x, y;
gint width, height;
if (g_list_length (drawables) != 1 ||
(paste_type != PIKA_PASTE_TYPE_NEW_LAYER &&
paste_type != PIKA_PASTE_TYPE_NEW_LAYER_IN_PLACE))
{
if (g_list_length (drawables) != 1)
{
pika_message_literal (display->pika, G_OBJECT (display),
PIKA_MESSAGE_INFO,
_("Pasted as new layer because the "
"target is not a single layer or layer mask."));
}
else if (pika_viewable_get_children (PIKA_VIEWABLE (drawables->data)))
{
pika_message_literal (display->pika, G_OBJECT (display),
PIKA_MESSAGE_INFO,
_("Pasted as new layer because the "
"target is a layer group."));
}
else if (pika_item_is_content_locked (PIKA_ITEM (drawables->data), NULL))
{
pika_message_literal (display->pika, G_OBJECT (display),
PIKA_MESSAGE_INFO,
_("Pasted as new layer because the "
"target's pixels are locked."));
}
/* the actual paste-type conversion happens in pika_edit_paste() */
}
pika_display_shell_untransform_viewport (
shell,
! pika_display_shell_get_infinite_canvas (shell),
&x, &y, &width, &height);
if ((pasted_layers = pika_edit_paste (image, drawables, paste, paste_type,
pika_get_user_context (display->pika),
merged, x, y, width, height)))
{
pika_image_set_selected_layers (image, pasted_layers);
g_list_free (pasted_layers);
pika_image_flush (image);
}
g_list_free (drawables);
g_object_unref (paste);
}
else
{
pika_message_literal (display->pika, G_OBJECT (display),
PIKA_MESSAGE_WARNING,
_("There is no image data in the clipboard "
"to paste."));
}
}
static void
cut_named_buffer_callback (GtkWidget *widget,
const gchar *name,
gpointer data)
{
PikaImage *image = PIKA_IMAGE (data);
GList *drawables = pika_image_get_selected_drawables (image);
GError *error = NULL;
if (! drawables)
{
pika_message_literal (image->pika, NULL, PIKA_MESSAGE_WARNING,
_("There are no selected layers or channels to cut from."));
return;
}
if (! (name && strlen (name)))
name = _("(Unnamed Buffer)");
if (pika_edit_named_cut (image, name, drawables,
pika_get_user_context (image->pika), &error))
{
pika_image_flush (image);
}
else
{
pika_message_literal (image->pika, NULL, PIKA_MESSAGE_WARNING,
error->message);
g_clear_error (&error);
}
g_list_free (drawables);
}
static void
copy_named_buffer_callback (GtkWidget *widget,
const gchar *name,
gpointer data)
{
PikaImage *image = PIKA_IMAGE (data);
GList *drawables = pika_image_get_selected_drawables (image);
GError *error = NULL;
if (! drawables)
{
pika_message_literal (image->pika, NULL, PIKA_MESSAGE_WARNING,
_("There are no selected layers or channels to copy from."));
return;
}
if (! (name && strlen (name)))
name = _("(Unnamed Buffer)");
if (pika_edit_named_copy (image, name, drawables,
pika_get_user_context (image->pika), &error))
{
pika_image_flush (image);
}
else
{
pika_message_literal (image->pika, NULL, PIKA_MESSAGE_WARNING,
error->message);
g_clear_error (&error);
}
g_list_free (drawables);
}
static void
copy_named_visible_buffer_callback (GtkWidget *widget,
const gchar *name,
gpointer data)
{
PikaImage *image = PIKA_IMAGE (data);
GError *error = NULL;
if (! (name && strlen (name)))
name = _("(Unnamed Buffer)");
if (pika_edit_named_copy_visible (image, name,
pika_get_user_context (image->pika),
&error))
{
pika_image_flush (image);
}
else
{
pika_message_literal (image->pika, NULL, PIKA_MESSAGE_WARNING,
error->message);
g_clear_error (&error);
}
}

View File

@ -0,0 +1,80 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __EDIT_COMMANDS_H__
#define __EDIT_COMMANDS_H__
void edit_undo_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_redo_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_strong_undo_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_strong_redo_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_undo_clear_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_cut_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_copy_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_copy_visible_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_paste_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_paste_as_new_image_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_named_cut_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_named_copy_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_named_copy_visible_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_named_paste_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_clear_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void edit_fill_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __EDIT_COMMANDS_H__ */

View File

@ -0,0 +1,152 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikaerrorconsole.h"
#include "widgets/pikahelp-ids.h"
#include "error-console-actions.h"
#include "error-console-commands.h"
#include "pika-intl.h"
static const PikaActionEntry error_console_actions[] =
{
{ "error-console-clear", PIKA_ICON_EDIT_CLEAR,
NC_("error-console-action", "_Clear"), NULL, { NULL },
NC_("error-console-action", "Clear error console"),
error_console_clear_cmd_callback,
PIKA_HELP_ERRORS_CLEAR },
{ "error-console-select-all", NULL,
NC_("error-console-action", "Select _All"), NULL, { NULL },
NC_("error-console-action", "Select all error messages"),
error_console_select_all_cmd_callback,
PIKA_HELP_ERRORS_SELECT_ALL },
{ "error-console-highlight", NULL,
NC_("error-console-action", "_Highlight"), NULL, { NULL }, NULL, NULL,
PIKA_HELP_ERRORS_HIGHLIGHT }
};
static const PikaEnumActionEntry error_console_save_actions[] =
{
{ "error-console-save-all", PIKA_ICON_DOCUMENT_SAVE_AS,
NC_("error-console-action", "_Save Error Log to File..."), NULL, { NULL },
NC_("error-console-action", "Write all error messages to a file"),
FALSE, FALSE,
PIKA_HELP_ERRORS_SAVE },
{ "error-console-save-selection", PIKA_ICON_DOCUMENT_SAVE_AS,
NC_("error-console-action", "Save S_election to File..."), NULL, { NULL },
NC_("error-console-action", "Write the selected error messages to a file"),
TRUE, FALSE,
PIKA_HELP_ERRORS_SAVE }
};
static const PikaToggleActionEntry error_console_highlight_actions[] =
{
{ "error-console-highlight-error", NULL,
NC_("error-console-action", "_Errors"), NULL, { NULL },
NC_("error-console-action", "Highlight error console on errors"),
error_console_highlight_error_cmd_callback,
FALSE,
PIKA_HELP_ERRORS_HIGHLIGHT },
{ "error-console-highlight-warning", NULL,
NC_("error-console-action", "_Warnings"), NULL, { NULL },
NC_("error-console-action", "Highlight error console on warnings"),
error_console_highlight_warning_cmd_callback,
FALSE,
PIKA_HELP_ERRORS_HIGHLIGHT },
{ "error-console-highlight-info", NULL,
NC_("error-console-action", "_Messages"), NULL, { NULL },
NC_("error-console-action", "Highlight error console on messages"),
error_console_highlight_info_cmd_callback,
FALSE,
PIKA_HELP_ERRORS_HIGHLIGHT }
};
void
error_console_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "error-console-action",
error_console_actions,
G_N_ELEMENTS (error_console_actions));
pika_action_group_add_enum_actions (group, "error-console-action",
error_console_save_actions,
G_N_ELEMENTS (error_console_save_actions),
error_console_save_cmd_callback);
pika_action_group_add_toggle_actions (group, "error-console-action",
error_console_highlight_actions,
G_N_ELEMENTS (error_console_highlight_actions));
}
void
error_console_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaErrorConsole *console = PIKA_ERROR_CONSOLE (data);
gboolean selection;
selection = gtk_text_buffer_get_selection_bounds (console->text_buffer,
NULL, NULL);
#define SET_ACTIVE(action,condition) \
pika_action_group_set_action_active (group, action, (condition) != 0)
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("error-console-clear", TRUE);
SET_SENSITIVE ("error-console-select-all", TRUE);
SET_SENSITIVE ("error-console-save-all", TRUE);
SET_SENSITIVE ("error-console-save-selection", selection);
SET_SENSITIVE ("error-console-highlight", TRUE);
SET_SENSITIVE ("error-console-highlight-error", TRUE);
SET_ACTIVE ("error-console-highlight-error",
console->highlight[PIKA_MESSAGE_ERROR]);
SET_SENSITIVE ("error-console-highlight-warning", TRUE);
SET_ACTIVE ("error-console-highlight-warning",
console->highlight[PIKA_MESSAGE_WARNING]);
SET_SENSITIVE ("error-console-highlight-info", TRUE);
SET_ACTIVE ("error-console-highlight-info",
console->highlight[PIKA_MESSAGE_INFO]);
#undef SET_ACTIVE
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __ERROR_CONSOLE_ACIONS_H__
#define __ERROR_CONSOLE_ACIONS_H__
void error_console_actions_setup (PikaActionGroup *group);
void error_console_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __ERROR_CONSOLE_ACTIONS_H__ */

View File

@ -0,0 +1,204 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "widgets/pikaerrorconsole.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikatextbuffer.h"
#include "error-console-commands.h"
#include "pika-intl.h"
/* local function prototypes */
static void error_console_save_response (GtkWidget *dialog,
gint response_id,
PikaErrorConsole *console);
/* public functions */
void
error_console_clear_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaErrorConsole *console = PIKA_ERROR_CONSOLE (data);
GtkTextIter start_iter;
GtkTextIter end_iter;
gtk_text_buffer_get_bounds (console->text_buffer, &start_iter, &end_iter);
gtk_text_buffer_delete (console->text_buffer, &start_iter, &end_iter);
}
void
error_console_select_all_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaErrorConsole *console = PIKA_ERROR_CONSOLE (data);
GtkTextIter start_iter;
GtkTextIter end_iter;
gtk_text_buffer_get_bounds (console->text_buffer, &start_iter, &end_iter);
gtk_text_buffer_select_range (console->text_buffer, &start_iter, &end_iter);
}
void
error_console_save_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaErrorConsole *console = PIKA_ERROR_CONSOLE (data);
gboolean selection = (gboolean) g_variant_get_int32 (value);
if (selection &&
! gtk_text_buffer_get_selection_bounds (console->text_buffer,
NULL, NULL))
{
pika_message_literal (console->pika,
G_OBJECT (console), PIKA_MESSAGE_WARNING,
_("Cannot save. Nothing is selected."));
return;
}
if (! console->file_dialog)
{
GtkWidget *dialog;
dialog = console->file_dialog =
gtk_file_chooser_dialog_new (_("Save Error Log to File"), NULL,
GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Save"), GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
console->save_selection = selection;
g_set_weak_pointer (&console->file_dialog, dialog);
gtk_window_set_screen (GTK_WINDOW (dialog),
gtk_widget_get_screen (GTK_WIDGET (console)));
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_window_set_role (GTK_WINDOW (dialog), "pika-save-errors");
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
TRUE);
g_signal_connect (dialog, "response",
G_CALLBACK (error_console_save_response),
console);
g_signal_connect (dialog, "delete-event",
G_CALLBACK (gtk_true),
NULL);
pika_help_connect (dialog, pika_standard_help_func,
PIKA_HELP_ERRORS_DIALOG, NULL, NULL);
}
gtk_window_present (GTK_WINDOW (console->file_dialog));
}
void
error_console_highlight_error_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaErrorConsole *console = PIKA_ERROR_CONSOLE (data);
gboolean active = g_variant_get_boolean (value);
console->highlight[PIKA_MESSAGE_ERROR] = active;
}
void
error_console_highlight_warning_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaErrorConsole *console = PIKA_ERROR_CONSOLE (data);
gboolean active = g_variant_get_boolean (value);
console->highlight[PIKA_MESSAGE_WARNING] = active;
}
void
error_console_highlight_info_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaErrorConsole *console = PIKA_ERROR_CONSOLE (data);
gboolean active = g_variant_get_boolean (value);
console->highlight[PIKA_MESSAGE_INFO] = active;
}
/* private functions */
static void
error_console_save_response (GtkWidget *dialog,
gint response_id,
PikaErrorConsole *console)
{
if (response_id == GTK_RESPONSE_OK)
{
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
GError *error = NULL;
if (! pika_text_buffer_save (PIKA_TEXT_BUFFER (console->text_buffer),
file,
console->save_selection, &error))
{
pika_message (console->pika, G_OBJECT (dialog), PIKA_MESSAGE_ERROR,
_("Error writing file '%s':\n%s"),
pika_file_get_utf8_name (file),
error->message);
g_clear_error (&error);
g_object_unref (file);
return;
}
g_object_unref (file);
}
gtk_widget_destroy (dialog);
}

View File

@ -0,0 +1,47 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __ERROR_CONSOLE_COMMANDS_H__
#define __ERROR_CONSOLE_COMMANDS_H__
void error_console_clear_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void error_console_select_all_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void error_console_save_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void error_console_highlight_error_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void error_console_highlight_warning_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void error_console_highlight_info_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __ERROR_CONSOLE_COMMANDS_H__ */

456
app/actions/file-actions.c Normal file
View File

@ -0,0 +1,456 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "config/pikaguiconfig.h"
#include "core/pika.h"
#include "core/pikacontainer.h"
#include "core/pikaimage.h"
#include "core/pikaimagefile.h"
#include "core/pikaviewable.h"
#include "file/pika-file.h"
#include "plug-in/pikapluginmanager-file.h"
#include "widgets/pikaaction.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikaactionimpl.h"
#include "widgets/pikahelp-ids.h"
#include "display/pikadisplay.h"
#include "actions.h"
#include "file-actions.h"
#include "file-commands.h"
#include "pika-intl.h"
/* local function prototypes */
static void file_actions_last_opened_update (PikaContainer *container,
PikaImagefile *unused,
PikaActionGroup *group);
static void file_actions_last_opened_reorder (PikaContainer *container,
PikaImagefile *unused1,
gint unused2,
PikaActionGroup *group);
static void file_actions_close_all_update (PikaContainer *images,
PikaObject *unused,
PikaActionGroup *group);
static gchar * file_actions_create_label (const gchar *format,
GFile *file);
static const PikaActionEntry file_actions[] =
{
{ "file-open", PIKA_ICON_IMAGE_OPEN,
NC_("file-action", "_Open..."), NULL, { "<primary>O", NULL },
NC_("file-action", "Open an image file"),
file_open_cmd_callback,
PIKA_HELP_FILE_OPEN },
{ "file-open-as-layers", PIKA_ICON_LAYER,
NC_("file-action", "Op_en as Layers..."), NULL, { "<primary><alt>O", NULL },
NC_("file-action", "Open an image file as layers"),
file_open_as_layers_cmd_callback,
PIKA_HELP_FILE_OPEN_AS_LAYER },
{ "file-open-location", PIKA_ICON_WEB,
NC_("file-action", "Open _Location..."), NULL, { NULL },
NC_("file-action", "Open an image file from a specified location"),
file_open_location_cmd_callback,
PIKA_HELP_FILE_OPEN_LOCATION },
{ "file-create-template", NULL,
NC_("file-action", "Create _Template..."), NULL, { NULL },
NC_("file-action", "Create a new template from this image"),
file_create_template_cmd_callback,
PIKA_HELP_FILE_CREATE_TEMPLATE },
{ "file-revert", PIKA_ICON_IMAGE_RELOAD,
NC_("file-action", "Re_vert"), NULL, { NULL },
NC_("file-action", "Reload the image file from disk"),
file_revert_cmd_callback,
PIKA_HELP_FILE_REVERT },
{ "file-close-all", PIKA_ICON_CLOSE_ALL,
NC_("file-action", "C_lose All"), NULL, { "<primary><shift>W", NULL },
NC_("file-action", "Close all opened images"),
file_close_all_cmd_callback,
PIKA_HELP_FILE_CLOSE_ALL },
{ "file-copy-location", PIKA_ICON_EDIT_COPY,
NC_("file-action", "Copy _Image Location"), NULL, { NULL },
NC_("file-action", "Copy image file location to clipboard"),
file_copy_location_cmd_callback,
PIKA_HELP_FILE_COPY_LOCATION },
{ "file-show-in-file-manager", PIKA_ICON_FILE_MANAGER,
NC_("file-action", "Show in _File Manager"), NULL, { "<primary><alt>F", NULL },
NC_("file-action", "Show image file location in the file manager"),
file_show_in_file_manager_cmd_callback,
PIKA_HELP_FILE_SHOW_IN_FILE_MANAGER },
{ "file-quit", PIKA_ICON_APPLICATION_EXIT,
NC_("file-action", "_Quit"), NULL, { "<primary>Q", NULL },
NC_("file-action", "Quit the Photo and Image Kooker Application"),
file_quit_cmd_callback,
PIKA_HELP_FILE_QUIT }
};
static const PikaEnumActionEntry file_save_actions[] =
{
{ "file-save", PIKA_ICON_DOCUMENT_SAVE,
NC_("file-action", "_Save"), NULL, { "<primary>S", NULL },
NC_("file-action", "Save this image"),
PIKA_SAVE_MODE_SAVE, FALSE,
PIKA_HELP_FILE_SAVE },
{ "file-save-as", PIKA_ICON_DOCUMENT_SAVE_AS,
NC_("file-action", "Save _As..."), NULL, { "<primary><shift>S", NULL },
NC_("file-action", "Save this image with a different name"),
PIKA_SAVE_MODE_SAVE_AS, FALSE,
PIKA_HELP_FILE_SAVE_AS },
{ "file-save-a-copy", NULL,
NC_("file-action", "Save a Cop_y..."), NULL, { NULL },
NC_("file-action",
"Save a copy of this image, without affecting the source file "
"(if any) or the current state of the image"),
PIKA_SAVE_MODE_SAVE_A_COPY, FALSE,
PIKA_HELP_FILE_SAVE_A_COPY },
{ "file-save-and-close", NULL,
NC_("file-action", "Save and Close..."), NULL, { NULL },
NC_("file-action", "Save this image and close its window"),
PIKA_SAVE_MODE_SAVE_AND_CLOSE, FALSE,
PIKA_HELP_FILE_SAVE },
{ "file-export", NULL,
NC_("file-action", "E_xport..."), NULL, { "<primary>E", NULL },
NC_("file-action", "Export the image"),
PIKA_SAVE_MODE_EXPORT, FALSE,
PIKA_HELP_FILE_EXPORT },
{ "file-overwrite", NULL,
NC_("file-action", "Over_write"), NULL, { NULL },
NC_("file-action", "Export the image back to the imported file in the import format"),
PIKA_SAVE_MODE_OVERWRITE, FALSE,
PIKA_HELP_FILE_OVERWRITE },
{ "file-export-as", NULL,
NC_("file-action", "E_xport As..."), NULL, { "<primary><shift>E", NULL },
NC_("file-action", "Export the image to various file formats such as PNG or JPEG"),
PIKA_SAVE_MODE_EXPORT_AS, FALSE,
PIKA_HELP_FILE_EXPORT_AS }
};
void
file_actions_setup (PikaActionGroup *group)
{
PikaEnumActionEntry *entries;
gint n_entries;
gint i;
pika_action_group_add_actions (group, "file-action",
file_actions,
G_N_ELEMENTS (file_actions));
pika_action_group_add_enum_actions (group, "file-action",
file_save_actions,
G_N_ELEMENTS (file_save_actions),
file_save_cmd_callback);
n_entries = PIKA_GUI_CONFIG (group->pika->config)->last_opened_size;
entries = g_new0 (PikaEnumActionEntry, n_entries);
for (i = 0; i < n_entries; i++)
{
entries[i].name = g_strdup_printf ("file-open-recent-%02d",
i + 1);
entries[i].icon_name = PIKA_ICON_DOCUMENT_OPEN,
entries[i].label = entries[i].name;
entries[i].tooltip = NULL;
entries[i].value = i;
entries[i].value_variable = FALSE;
if (i < 9)
entries[i].accelerator[0] = g_strdup_printf ("<primary>%d", i + 1);
else if (i == 9)
entries[i].accelerator[0] = g_strdup ("<primary>0");
else
entries[i].accelerator[0] = NULL;
}
pika_action_group_add_enum_actions (group, NULL, entries, n_entries,
file_open_recent_cmd_callback);
for (i = 0; i < n_entries; i++)
{
pika_action_group_set_action_visible (group, entries[i].name, FALSE);
g_free ((gchar *) entries[i].name);
if (entries[i].accelerator[0])
g_free ((gchar *) entries[i].accelerator[0]);
}
g_free (entries);
g_signal_connect_object (group->pika->documents, "add",
G_CALLBACK (file_actions_last_opened_update),
group, 0);
g_signal_connect_object (group->pika->documents, "remove",
G_CALLBACK (file_actions_last_opened_update),
group, 0);
g_signal_connect_object (group->pika->documents, "reorder",
G_CALLBACK (file_actions_last_opened_reorder),
group, 0);
file_actions_last_opened_update (group->pika->documents, NULL, group);
/* also listen to image adding/removal so we catch the case where
* the last image is closed but its display stays open.
*/
g_signal_connect_object (group->pika->images, "add",
G_CALLBACK (file_actions_close_all_update),
group, 0);
g_signal_connect_object (group->pika->images, "remove",
G_CALLBACK (file_actions_close_all_update),
group, 0);
file_actions_close_all_update (group->pika->displays, NULL, group);
}
void
file_actions_update (PikaActionGroup *group,
gpointer data)
{
Pika *pika = action_data_get_pika (data);
PikaImage *image = action_data_get_image (data);
GList *drawables = NULL;
GFile *file = NULL;
GFile *source = NULL;
GFile *export = NULL;
gboolean show_overwrite = FALSE;
if (image)
{
drawables = pika_image_get_selected_drawables (image);
file = pika_image_get_file (image);
source = pika_image_get_imported_file (image);
export = pika_image_get_exported_file (image);
}
show_overwrite =
(source &&
pika_plug_in_manager_file_procedure_find (pika->plug_in_manager,
PIKA_FILE_PROCEDURE_GROUP_EXPORT,
source, NULL));
#define SET_VISIBLE(action,condition) \
pika_action_group_set_action_visible (group, action, (condition) != 0)
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("file-save", drawables);
SET_SENSITIVE ("file-save-as", drawables);
SET_SENSITIVE ("file-save-a-copy", drawables);
SET_SENSITIVE ("file-save-and-close", drawables);
SET_SENSITIVE ("file-revert", file || source);
SET_SENSITIVE ("file-export", drawables);
SET_VISIBLE ("file-export", ! show_overwrite);
SET_SENSITIVE ("file-overwrite", show_overwrite);
SET_VISIBLE ("file-overwrite", show_overwrite);
SET_SENSITIVE ("file-export-as", drawables);
SET_SENSITIVE ("file-create-template", image);
SET_SENSITIVE ("file-copy-location", file || source || export);
SET_SENSITIVE ("file-show-in-file-manager", file || source || export);
if (file)
{
pika_action_group_set_action_label (group,
"file-save",
C_("file-action", "_Save"));
}
else
{
pika_action_group_set_action_label (group,
"file-save",
C_("file-action", "_Save..."));
}
if (export)
{
gchar *label = file_actions_create_label (_("Export to %s"), export);
pika_action_group_set_action_label (group, "file-export", label);
g_free (label);
}
else if (show_overwrite)
{
gchar *label = file_actions_create_label (_("Over_write %s"), source);
pika_action_group_set_action_label (group, "file-overwrite", label);
g_free (label);
}
else
{
pika_action_group_set_action_label (group,
"file-export",
C_("file-action", "E_xport..."));
}
/* needed for the empty display */
SET_SENSITIVE ("file-close-all", image);
#undef SET_SENSITIVE
g_list_free (drawables);
}
/* private functions */
static void
file_actions_last_opened_update (PikaContainer *container,
PikaImagefile *unused,
PikaActionGroup *group)
{
gint num_documents;
gint i;
gint n = PIKA_GUI_CONFIG (group->pika->config)->last_opened_size;
num_documents = pika_container_get_n_children (container);
for (i = 0; i < n; i++)
{
PikaAction *action;
gchar *name = g_strdup_printf ("file-open-recent-%02d", i + 1);
action = pika_action_group_get_action (group, name);
if (i < num_documents)
{
PikaImagefile *imagefile = (PikaImagefile *)
pika_container_get_child_by_index (container, i);
if (pika_action_get_viewable (action) != (PikaViewable *) imagefile)
{
GFile *file;
const gchar *name;
gchar *basename;
gchar *escaped;
gchar *label;
file = pika_imagefile_get_file (imagefile);
name = pika_file_get_utf8_name (file);
basename = g_path_get_basename (name);
escaped = pika_escape_uline (basename);
g_free (basename);
/* TRANSLATORS: the %s will be replaced by the file name of a
* recently opened image.
*/
label = g_strdup_printf (_("Open \"%s\""), escaped);
g_object_set (action,
"label", label,
"short-label", escaped,
"tooltip", name,
"visible", TRUE,
"viewable", imagefile,
NULL);
g_free (label);
g_free (escaped);
}
}
else
{
g_object_set (action,
"label", name,
"tooltip", NULL,
"visible", FALSE,
"viewable", NULL,
NULL);
}
g_free (name);
}
}
static void
file_actions_last_opened_reorder (PikaContainer *container,
PikaImagefile *unused1,
gint unused2,
PikaActionGroup *group)
{
file_actions_last_opened_update (container, unused1, group);
}
static void
file_actions_close_all_update (PikaContainer *images,
PikaObject *unused,
PikaActionGroup *group)
{
PikaContainer *container = group->pika->displays;
gint n_displays = pika_container_get_n_children (container);
gboolean sensitive = (n_displays > 0);
if (n_displays == 1)
{
PikaDisplay *display;
display = PIKA_DISPLAY (pika_container_get_first_child (container));
if (! pika_display_get_image (display))
sensitive = FALSE;
}
pika_action_group_set_action_sensitive (group, "file-close-all", sensitive, NULL);
}
static gchar *
file_actions_create_label (const gchar *format,
GFile *file)
{
gchar *basename = g_path_get_basename (pika_file_get_utf8_name (file));
gchar *escaped_basename = pika_escape_uline (basename);
gchar *label = g_strdup_printf (format, escaped_basename);
g_free (escaped_basename);
g_free (basename);
return label;
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __FILE_ACTIONS_H__
#define __FILE_ACTIONS_H__
void file_actions_setup (PikaActionGroup *group);
void file_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __FILE_ACTIONS_H__ */

868
app/actions/file-commands.c Normal file
View File

@ -0,0 +1,868 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "config/pikaguiconfig.h"
#include "core/pika.h"
#include "core/pikacontainer.h"
#include "core/pikaimage.h"
#include "core/pikaimagefile.h"
#include "core/pikaprogress.h"
#include "core/pikatemplate.h"
#include "plug-in/pikapluginmanager-file.h"
#include "file/file-open.h"
#include "file/file-save.h"
#include "file/pika-file.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikaclipboard.h"
#include "widgets/pikadialogfactory.h"
#include "widgets/pikaexportdialog.h"
#include "widgets/pikafiledialog.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikamessagebox.h"
#include "widgets/pikamessagedialog.h"
#include "widgets/pikaopendialog.h"
#include "widgets/pikasavedialog.h"
#include "widgets/pikawidgets-utils.h"
#include "display/pikadisplay.h"
#include "display/pikadisplay-foreach.h"
#include "dialogs/dialogs.h"
#include "dialogs/file-save-dialog.h"
#include "actions.h"
#include "file-commands.h"
#include "pika-intl.h"
/* local function prototypes */
static void file_open_dialog_show (Pika *pika,
GtkWidget *parent,
const gchar *title,
PikaImage *image,
GFile *file,
gboolean open_as_layers);
static GtkWidget * file_save_dialog_show (Pika *pika,
PikaImage *image,
GtkWidget *parent,
const gchar *title,
gboolean save_a_copy,
gboolean close_after_saving,
PikaDisplay *display);
static GtkWidget * file_export_dialog_show (Pika *pika,
PikaImage *image,
GtkWidget *parent,
PikaDisplay *display);
static void file_save_dialog_response (GtkWidget *dialog,
gint response_id,
gpointer data);
static void file_export_dialog_response (GtkWidget *dialog,
gint response_id,
gpointer data);
static void file_new_template_callback (GtkWidget *widget,
const gchar *name,
gpointer data);
static void file_revert_confirm_response (GtkWidget *dialog,
gint response_id,
PikaDisplay *display);
/* public functions */
void
file_open_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
GtkWidget *widget;
PikaImage *image;
return_if_no_pika (pika, data);
return_if_no_widget (widget, data);
image = action_data_get_image (data);
file_open_dialog_show (pika, widget,
_("Open Image"),
image, NULL, FALSE);
}
void
file_open_as_layers_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
GtkWidget *widget;
PikaDisplay *display;
PikaImage *image = NULL;
return_if_no_pika (pika, data);
return_if_no_widget (widget, data);
display = action_data_get_display (data);
if (display)
image = pika_display_get_image (display);
file_open_dialog_show (pika, widget,
_("Open Image as Layers"),
image, NULL, TRUE);
}
void
file_open_location_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
GtkWidget *widget;
return_if_no_widget (widget, data);
pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
pika_widget_get_monitor (widget),
NULL /*ui_manager*/,
widget,
"pika-file-open-location-dialog", -1, TRUE);
}
void
file_open_recent_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
PikaImagefile *imagefile;
gint index;
gint num_entries;
return_if_no_pika (pika, data);
index = g_variant_get_int32 (value);
num_entries = pika_container_get_n_children (pika->documents);
if (index >= num_entries)
return;
imagefile = (PikaImagefile *)
pika_container_get_child_by_index (pika->documents, index);
if (imagefile)
{
GFile *file;
PikaDisplay *display;
GtkWidget *widget;
PikaProgress *progress;
PikaImage *image;
PikaPDBStatusType status;
GError *error = NULL;
return_if_no_display (display, data);
return_if_no_widget (widget, data);
g_object_ref (display);
g_object_ref (imagefile);
file = pika_imagefile_get_file (imagefile);
progress = pika_display_get_image (display) ?
NULL : PIKA_PROGRESS (display);
image = file_open_with_display (pika, action_data_get_context (data),
progress,
file, FALSE,
G_OBJECT (pika_widget_get_monitor (widget)),
&status, &error);
if (! image && status != PIKA_PDB_CANCEL)
{
pika_message (pika, G_OBJECT (display), PIKA_MESSAGE_ERROR,
_("Opening '%s' failed:\n\n%s"),
pika_file_get_utf8_name (file), error->message);
g_clear_error (&error);
}
g_object_unref (imagefile);
g_object_unref (display);
}
}
void
file_save_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
PikaDisplay *display;
PikaImage *image;
GList *drawables;
GtkWidget *widget;
PikaSaveMode save_mode;
GFile *file = NULL;
gboolean saved = FALSE;
return_if_no_pika (pika, data);
return_if_no_display (display, data);
return_if_no_widget (widget, data);
image = pika_display_get_image (display);
save_mode = (PikaSaveMode) g_variant_get_int32 (value);
drawables = pika_image_get_selected_drawables (image);
if (! drawables)
{
g_list_free (drawables);
return;
}
g_list_free (drawables);
file = pika_image_get_file (image);
switch (save_mode)
{
case PIKA_SAVE_MODE_SAVE:
case PIKA_SAVE_MODE_SAVE_AND_CLOSE:
/* Only save if the image has been modified, or if it is new. */
if ((pika_image_is_dirty (image) ||
! PIKA_GUI_CONFIG (image->pika->config)->trust_dirty_flag) ||
file == NULL)
{
PikaPlugInProcedure *save_proc = pika_image_get_save_proc (image);
gboolean valid_file = FALSE;
if (file)
{
gchar *uri = g_file_get_uri (file);
/* Non-valid URI (such as "Untitled.xcd" without a scheme) are
* considered non-native by GLib and will trigger remote file code
* path in file_save_dialog_save_image(), eventually failing with
* a weird error. When we encounter such non-valid URI, we just
* consider that the file was entered manually with a bogus name
* (possibly by some script or plug-in) and we fall through
* directly to showing the file dialog. The file name will still
* be useful as default file name.
*/
valid_file = g_uri_is_valid (uri, G_URI_FLAGS_NONE, NULL);
g_free (uri);
}
if (valid_file && ! save_proc)
{
save_proc =
pika_plug_in_manager_file_procedure_find (image->pika->plug_in_manager,
PIKA_FILE_PROCEDURE_GROUP_SAVE,
file, NULL);
}
if (valid_file && save_proc)
{
saved = file_save_dialog_save_image (PIKA_PROGRESS (display),
pika, image, file,
save_proc,
PIKA_RUN_WITH_LAST_VALS,
TRUE, FALSE, FALSE,
pika_image_get_xcf_compression (image),
TRUE);
break;
}
/* fall thru */
}
else
{
pika_message_literal (image->pika,
G_OBJECT (display), PIKA_MESSAGE_INFO,
_("No changes need to be saved"));
saved = TRUE;
break;
}
case PIKA_SAVE_MODE_SAVE_AS:
file_save_dialog_show (pika, image, widget,
_("Save Image"), FALSE,
save_mode == PIKA_SAVE_MODE_SAVE_AND_CLOSE, display);
break;
case PIKA_SAVE_MODE_SAVE_A_COPY:
file_save_dialog_show (pika, image, widget,
_("Save a Copy of the Image"), TRUE,
FALSE, display);
break;
case PIKA_SAVE_MODE_EXPORT_AS:
file_export_dialog_show (pika, image, widget, display);
break;
case PIKA_SAVE_MODE_EXPORT:
case PIKA_SAVE_MODE_OVERWRITE:
{
GFile *file = NULL;
PikaPlugInProcedure *export_proc = NULL;
gboolean overwrite = FALSE;
if (save_mode == PIKA_SAVE_MODE_EXPORT)
{
file = pika_image_get_exported_file (image);
export_proc = pika_image_get_export_proc (image);
if (! file)
{
/* Behave as if Export As... was invoked */
file_export_dialog_show (pika, image, widget, display);
break;
}
overwrite = FALSE;
}
else if (save_mode == PIKA_SAVE_MODE_OVERWRITE)
{
file = pika_image_get_imported_file (image);
overwrite = TRUE;
}
if (file && ! export_proc)
{
export_proc =
pika_plug_in_manager_file_procedure_find (image->pika->plug_in_manager,
PIKA_FILE_PROCEDURE_GROUP_EXPORT,
file, NULL);
}
if (file && export_proc)
{
saved = file_save_dialog_save_image (PIKA_PROGRESS (display),
pika, image, file,
export_proc,
PIKA_RUN_WITH_LAST_VALS,
FALSE,
overwrite, ! overwrite,
FALSE, TRUE);
}
}
break;
}
if (save_mode == PIKA_SAVE_MODE_SAVE_AND_CLOSE &&
saved &&
! pika_image_is_dirty (image))
{
pika_display_close (display);
}
}
void
file_create_template_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDisplay *display;
PikaImage *image;
GtkWidget *dialog;
return_if_no_display (display, data);
image = pika_display_get_image (display);
dialog = pika_query_string_box (_("Create New Template"),
GTK_WIDGET (pika_display_get_shell (display)),
pika_standard_help_func,
PIKA_HELP_FILE_CREATE_TEMPLATE,
_("Enter a name for this template"),
NULL,
G_OBJECT (image), "disconnect",
file_new_template_callback,
image, NULL);
gtk_widget_show (dialog);
}
void
file_revert_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaDisplay *display;
PikaImage *image;
GtkWidget *dialog;
GFile *file;
return_if_no_display (display, data);
image = pika_display_get_image (display);
file = pika_image_get_file (image);
if (! file)
file = pika_image_get_imported_file (image);
if (! file)
{
pika_message_literal (image->pika,
G_OBJECT (display), PIKA_MESSAGE_ERROR,
_("Revert failed. "
"No file name associated with this image."));
return;
}
#define REVERT_DIALOG_KEY "pika-revert-confirm-dialog"
dialog = dialogs_get_dialog (G_OBJECT (image), REVERT_DIALOG_KEY);
if (! dialog)
{
dialog =
pika_message_dialog_new (_("Revert Image"), PIKA_ICON_DOCUMENT_REVERT,
GTK_WIDGET (pika_display_get_shell (display)),
0,
pika_standard_help_func, PIKA_HELP_FILE_REVERT,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Revert"), GTK_RESPONSE_OK,
NULL);
pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
g_signal_connect_object (display, "disconnect",
G_CALLBACK (gtk_widget_destroy),
dialog, G_CONNECT_SWAPPED);
g_signal_connect (dialog, "response",
G_CALLBACK (file_revert_confirm_response),
display);
pika_message_box_set_primary_text (PIKA_MESSAGE_DIALOG (dialog)->box,
_("Revert '%s' to '%s'?"),
pika_image_get_display_name (image),
pika_file_get_utf8_name (file));
pika_message_box_set_text (PIKA_MESSAGE_DIALOG (dialog)->box,
_("By reverting the image to the state saved "
"on disk, you will lose all changes, "
"including all undo information."));
dialogs_attach_dialog (G_OBJECT (image), REVERT_DIALOG_KEY, dialog);
}
gtk_window_present (GTK_WINDOW (dialog));
}
void
file_close_all_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
return_if_no_pika (pika, data);
if (! pika_displays_dirty (pika))
{
pika_displays_close (pika);
}
else
{
GtkWidget *widget;
return_if_no_widget (widget, data);
pika_dialog_factory_dialog_raise (pika_dialog_factory_get_singleton (),
pika_widget_get_monitor (widget),
widget,
"pika-close-all-dialog", -1);
}
}
void
file_copy_location_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
PikaDisplay *display;
PikaImage *image;
GFile *file;
return_if_no_pika (pika, data);
return_if_no_display (display, data);
image = pika_display_get_image (display);
file = pika_image_get_any_file (image);
if (file)
{
gchar *uri = g_file_get_uri (file);
pika_clipboard_set_text (pika, uri);
g_free (uri);
}
}
void
file_show_in_file_manager_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
PikaDisplay *display;
PikaImage *image;
GFile *file;
return_if_no_pika (pika, data);
return_if_no_display (display, data);
image = pika_display_get_image (display);
file = pika_image_get_any_file (image);
if (file)
{
GError *error = NULL;
if (! pika_file_show_in_file_manager (file, &error))
{
pika_message (pika, G_OBJECT (display), PIKA_MESSAGE_ERROR,
_("Can't show file in file manager: %s"),
error->message);
g_clear_error (&error);
}
}
}
void
file_quit_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
return_if_no_pika (pika, data);
pika_exit (pika, FALSE);
}
void
file_file_open_dialog (Pika *pika,
GFile *file,
GtkWidget *parent)
{
file_open_dialog_show (pika, parent,
_("Open Image"),
NULL, file, FALSE);
}
/* private functions */
static void
file_open_dialog_show (Pika *pika,
GtkWidget *parent,
const gchar *title,
PikaImage *image,
GFile *file,
gboolean open_as_layers)
{
GtkWidget *dialog;
dialog = pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
pika_widget_get_monitor (parent),
NULL /*ui_manager*/,
parent,
"pika-file-open-dialog", -1, FALSE);
if (dialog)
{
if (! file && image)
file = pika_image_get_file (image);
if (! file)
file = g_object_get_data (G_OBJECT (pika),
PIKA_FILE_OPEN_LAST_FILE_KEY);
if (file)
{
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (dialog), file, NULL);
}
else if (pika->default_folder)
{
gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog),
pika->default_folder, NULL);
}
gtk_window_set_title (GTK_WINDOW (dialog), title);
pika_open_dialog_set_image (PIKA_OPEN_DIALOG (dialog),
image, open_as_layers);
gtk_window_set_transient_for (GTK_WINDOW (dialog),
GTK_WINDOW (gtk_widget_get_toplevel (parent)));
gtk_window_present (GTK_WINDOW (dialog));
}
}
static GtkWidget *
file_save_dialog_show (Pika *pika,
PikaImage *image,
GtkWidget *parent,
const gchar *title,
gboolean save_a_copy,
gboolean close_after_saving,
PikaDisplay *display)
{
GtkWidget *dialog;
#define SAVE_DIALOG_KEY "pika-file-save-dialog"
dialog = dialogs_get_dialog (G_OBJECT (image), SAVE_DIALOG_KEY);
if (! dialog)
{
dialog = pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
pika_widget_get_monitor (parent),
NULL /*ui_manager*/,
parent,
"pika-file-save-dialog",
-1, FALSE);
if (dialog)
{
gtk_window_set_transient_for (GTK_WINDOW (dialog),
GTK_WINDOW (gtk_widget_get_toplevel (parent)));
dialogs_attach_dialog (G_OBJECT (image), SAVE_DIALOG_KEY, dialog);
g_signal_connect_object (image, "disconnect",
G_CALLBACK (gtk_widget_destroy),
dialog, G_CONNECT_SWAPPED);
g_signal_connect (dialog, "response",
G_CALLBACK (file_save_dialog_response),
image);
}
}
if (dialog)
{
gtk_window_set_title (GTK_WINDOW (dialog), title);
pika_save_dialog_set_image (PIKA_SAVE_DIALOG (dialog),
image, save_a_copy,
close_after_saving, PIKA_OBJECT (display));
gtk_window_present (GTK_WINDOW (dialog));
}
return dialog;
}
static void
file_save_dialog_response (GtkWidget *dialog,
gint response_id,
gpointer data)
{
if (response_id == FILE_SAVE_RESPONSE_OTHER_DIALOG)
{
PikaFileDialog *file_dialog = PIKA_FILE_DIALOG (dialog);
GtkWindow *parent;
GtkWidget *other;
GFile *file;
gchar *folder;
gchar *basename;
parent = gtk_window_get_transient_for (GTK_WINDOW (dialog));
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
folder = g_path_get_dirname (pika_file_get_utf8_name (file));
basename = g_path_get_basename (pika_file_get_utf8_name (file));
g_object_unref (file);
other = file_export_dialog_show (PIKA_FILE_DIALOG (file_dialog)->image->pika,
PIKA_FILE_DIALOG (file_dialog)->image,
GTK_WIDGET (parent), NULL);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (other), folder);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (other), basename);
g_free (folder);
g_free (basename);
}
}
static GtkWidget *
file_export_dialog_show (Pika *pika,
PikaImage *image,
GtkWidget *parent,
PikaDisplay *display)
{
GtkWidget *dialog;
#define EXPORT_DIALOG_KEY "pika-file-export-dialog"
dialog = dialogs_get_dialog (G_OBJECT (image), EXPORT_DIALOG_KEY);
if (! dialog)
{
dialog = pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
pika_widget_get_monitor (parent),
NULL /*ui_manager*/,
parent,
"pika-file-export-dialog",
-1, FALSE);
if (dialog)
{
gtk_window_set_transient_for (GTK_WINDOW (dialog),
GTK_WINDOW (gtk_widget_get_toplevel (parent)));
dialogs_attach_dialog (G_OBJECT (image), EXPORT_DIALOG_KEY, dialog);
g_signal_connect_object (image, "disconnect",
G_CALLBACK (gtk_widget_destroy),
dialog, G_CONNECT_SWAPPED);
g_signal_connect (dialog, "response",
G_CALLBACK (file_export_dialog_response),
image);
}
}
if (dialog)
{
pika_export_dialog_set_image (PIKA_EXPORT_DIALOG (dialog), image,
PIKA_OBJECT (display));
gtk_window_present (GTK_WINDOW (dialog));
}
return dialog;
}
static void
file_export_dialog_response (GtkWidget *dialog,
gint response_id,
gpointer data)
{
if (response_id == FILE_SAVE_RESPONSE_OTHER_DIALOG)
{
PikaFileDialog *file_dialog = PIKA_FILE_DIALOG (dialog);
GtkWindow *parent;
GtkWidget *other;
GFile *file;
gchar *folder;
gchar *basename;
parent = gtk_window_get_transient_for (GTK_WINDOW (dialog));
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
folder = g_path_get_dirname (pika_file_get_utf8_name (file));
basename = g_path_get_basename (pika_file_get_utf8_name (file));
g_object_unref (file);
other = file_save_dialog_show (PIKA_FILE_DIALOG (file_dialog)->image->pika,
PIKA_FILE_DIALOG (file_dialog)->image,
GTK_WIDGET (parent),
_("Save Image"),
FALSE, FALSE, NULL);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (other), folder);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (other), basename);
g_free (folder);
g_free (basename);
}
}
static void
file_new_template_callback (GtkWidget *widget,
const gchar *name,
gpointer data)
{
PikaTemplate *template;
PikaImage *image;
image = (PikaImage *) data;
if (! (name && strlen (name)))
name = _("(Unnamed Template)");
template = pika_template_new (name);
pika_template_set_from_image (template, image);
pika_container_add (image->pika->templates, PIKA_OBJECT (template));
g_object_unref (template);
}
static void
file_revert_confirm_response (GtkWidget *dialog,
gint response_id,
PikaDisplay *display)
{
PikaImage *old_image = pika_display_get_image (display);
gtk_widget_destroy (dialog);
if (response_id == GTK_RESPONSE_OK)
{
Pika *pika = old_image->pika;
PikaImage *new_image;
GFile *file;
PikaPDBStatusType status;
GError *error = NULL;
file = pika_image_get_file (old_image);
if (! file)
file = pika_image_get_imported_file (old_image);
new_image = file_open_image (pika, pika_get_user_context (pika),
PIKA_PROGRESS (display),
file, FALSE, NULL,
PIKA_RUN_INTERACTIVE,
&status, NULL, &error);
if (new_image)
{
pika_displays_reconnect (pika, old_image, new_image);
pika_image_flush (new_image);
/* the displays own the image now */
g_object_unref (new_image);
}
else if (status != PIKA_PDB_CANCEL)
{
pika_message (pika, G_OBJECT (display), PIKA_MESSAGE_ERROR,
_("Reverting to '%s' failed:\n\n%s"),
pika_file_get_utf8_name (file), error->message);
g_clear_error (&error);
}
}
}

View File

@ -0,0 +1,67 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __FILE_COMMANDS_H__
#define __FILE_COMMANDS_H__
void file_open_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_open_as_layers_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_open_location_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_open_recent_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_save_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_create_template_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_revert_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_close_all_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_copy_location_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_show_in_file_manager_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_quit_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void file_file_open_dialog (Pika *pika,
GFile *file,
GtkWidget *parent);
#endif /* __FILE_COMMANDS_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __FILTERS_ACTIONS_H__
#define __FILTERS_ACTIONS_H__
void filters_actions_setup (PikaActionGroup *group);
void filters_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __FILTERS_ACTIONS_H__ */

View File

@ -0,0 +1,293 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikabase/pikabase.h"
#include "libpikaconfig/pikaconfig.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "operations/pika-operation-config.h"
#include "operations/pikaoperationsettings.h"
#include "core/pika.h"
#include "core/pika-filter-history.h"
#include "core/pikaimage.h"
#include "core/pikaprogress.h"
#include "widgets/pikaaction.h"
#include "actions.h"
#include "filters-commands.h"
#include "pikageglprocedure.h"
#include "procedure-commands.h"
/* local function prototypes */
static gchar * filters_parse_operation (Pika *pika,
const gchar *operation_str,
const gchar *icon_name,
PikaObject **settings);
static void filters_run_procedure (Pika *pika,
PikaDisplay *display,
PikaProcedure *procedure,
PikaRunMode run_mode);
/* public functions */
void
filters_apply_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
gchar *operation;
PikaObject *settings;
PikaProcedure *procedure;
GVariant *variant;
return_if_no_drawables (image, drawables, data);
if (g_list_length (drawables) != 1)
{
/* We only support running filters on single drawable for now. */
g_list_free (drawables);
return;
}
operation = filters_parse_operation (image->pika,
g_variant_get_string (value, NULL),
pika_action_get_icon_name (action),
&settings);
procedure = pika_gegl_procedure_new (image->pika,
PIKA_RUN_NONINTERACTIVE, settings,
operation,
pika_action_get_name (action),
pika_action_get_label (action),
pika_action_get_tooltip (action),
pika_action_get_icon_name (action),
pika_action_get_help_id (action));
g_free (operation);
if (settings)
g_object_unref (settings);
pika_filter_history_add (image->pika, procedure);
variant = g_variant_new_uint64 (GPOINTER_TO_SIZE (procedure));
g_variant_take_ref (variant);
filters_history_cmd_callback (NULL, variant, data);
g_variant_unref (variant);
g_object_unref (procedure);
g_list_free (drawables);
}
void
filters_apply_interactive_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaImage *image;
GList *drawables;
PikaProcedure *procedure;
GVariant *variant;
return_if_no_drawables (image, drawables, data);
if (g_list_length (drawables) != 1)
{
/* We only support running filters on single drawable for now. */
g_list_free (drawables);
return;
}
procedure = pika_gegl_procedure_new (image->pika,
PIKA_RUN_INTERACTIVE, NULL,
g_variant_get_string (value, NULL),
pika_action_get_name (action),
pika_action_get_label (action),
pika_action_get_tooltip (action),
pika_action_get_icon_name (action),
pika_action_get_help_id (action));
pika_filter_history_add (image->pika, procedure);
variant = g_variant_new_uint64 (GPOINTER_TO_SIZE (procedure));
g_variant_take_ref (variant);
filters_history_cmd_callback (NULL, variant, data);
g_variant_unref (variant);
g_object_unref (procedure);
g_list_free (drawables);
}
void
filters_repeat_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
PikaDisplay *display;
PikaProcedure *procedure;
PikaRunMode run_mode;
return_if_no_pika (pika, data);
return_if_no_display (display, data);
run_mode = (PikaRunMode) g_variant_get_int32 (value);
procedure = pika_filter_history_nth (pika, 0);
if (procedure)
filters_run_procedure (pika, display, procedure, run_mode);
}
void
filters_history_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
PikaDisplay *display;
PikaProcedure *procedure;
gsize hack;
return_if_no_pika (pika, data);
return_if_no_display (display, data);
hack = g_variant_get_uint64 (value);
procedure = GSIZE_TO_POINTER (hack);
filters_run_procedure (pika, display, procedure, PIKA_RUN_INTERACTIVE);
}
/* private functions */
static gchar *
filters_parse_operation (Pika *pika,
const gchar *operation_str,
const gchar *icon_name,
PikaObject **settings)
{
const gchar *newline = strchr (operation_str, '\n');
*settings = NULL;
if (newline)
{
gchar *operation;
const gchar *serialized;
operation = g_strndup (operation_str, newline - operation_str);
serialized = newline + 1;
if (*serialized)
{
GError *error = NULL;
*settings =
g_object_new (pika_operation_config_get_type (pika, operation,
icon_name,
PIKA_TYPE_OPERATION_SETTINGS),
NULL);
if (! pika_config_deserialize_string (PIKA_CONFIG (*settings),
serialized, -1, NULL,
&error))
{
g_warning ("filters_parse_operation: deserializing hardcoded "
"operation settings failed: %s",
error->message);
g_clear_error (&error);
g_object_unref (*settings);
*settings = NULL;
}
}
return operation;
}
return g_strdup (operation_str);
}
static void
filters_run_procedure (Pika *pika,
PikaDisplay *display,
PikaProcedure *procedure,
PikaRunMode run_mode)
{
PikaObject *settings = NULL;
PikaValueArray *args;
if (PIKA_IS_GEGL_PROCEDURE (procedure))
{
PikaGeglProcedure *gegl_procedure = PIKA_GEGL_PROCEDURE (procedure);
if (gegl_procedure->default_run_mode == PIKA_RUN_NONINTERACTIVE)
run_mode = PIKA_RUN_NONINTERACTIVE;
settings = gegl_procedure->default_settings;
}
args = procedure_commands_get_display_args (procedure, display, settings);
if (args)
{
gboolean success = FALSE;
if (run_mode == PIKA_RUN_NONINTERACTIVE)
{
success =
procedure_commands_run_procedure (procedure, pika,
PIKA_PROGRESS (display),
args);
}
else
{
success =
procedure_commands_run_procedure_async (procedure, pika,
PIKA_PROGRESS (display),
run_mode, args,
display);
}
if (success)
pika_filter_history_add (pika, procedure);
pika_value_array_unref (args);
}
}

View File

@ -0,0 +1,41 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __FILTERS_COMMANDS_H__
#define __FILTERS_COMMANDS_H__
void filters_apply_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void filters_apply_interactive_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void filters_repeat_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void filters_history_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __FILTERS_COMMANDS_H__ */

View File

@ -0,0 +1,73 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikacontext.h"
#include "text/pikafont.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "data-commands.h"
#include "fonts-actions.h"
#include "pika-intl.h"
static const PikaActionEntry fonts_actions[] =
{
{ "fonts-refresh", PIKA_ICON_VIEW_REFRESH,
NC_("fonts-action", "_Rescan Font List"), NULL, { NULL },
NC_("fonts-action", "Rescan the installed fonts"),
data_refresh_cmd_callback,
PIKA_HELP_FONT_REFRESH }
};
void
fonts_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "fonts-action",
fonts_actions,
G_N_ELEMENTS (fonts_actions));
}
void
fonts_actions_update (PikaActionGroup *group,
gpointer data)
{
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("fonts-refresh", TRUE);
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __FONTS_ACTIONS_H__
#define __FONTS_ACTIONS_H__
void fonts_actions_setup (PikaActionGroup *group);
void fonts_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __FONTS_ACTIONS_H__ */

View File

@ -0,0 +1,909 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikacontext.h"
#include "core/pikadatafactory.h"
#include "core/pikagradient.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikagradienteditor.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikaradioaction.h"
#include "data-editor-commands.h"
#include "gradient-editor-actions.h"
#include "gradient-editor-commands.h"
#include "pika-intl.h"
static const PikaActionEntry gradient_editor_actions[] =
{
{ "gradient-editor-left-color-type", NULL,
NC_("gradient-editor-action", "Left Color Type") },
{ "gradient-editor-load-left-color", PIKA_ICON_DOCUMENT_REVERT,
NC_("gradient-editor-action", "_Load Left Color From") },
{ "gradient-editor-save-left-color", PIKA_ICON_DOCUMENT_SAVE,
NC_("gradient-editor-action", "_Save Left Color To") },
{ "gradient-editor-right-color-type", NULL,
NC_("gradient-editor-action", "Right Color Type") },
{ "gradient-editor-load-right-color", PIKA_ICON_DOCUMENT_REVERT,
NC_("gradient-editor-action", "Load Right Color Fr_om") },
{ "gradient-editor-save-right-color", PIKA_ICON_DOCUMENT_SAVE,
NC_("gradient-editor-action", "Sa_ve Right Color To") },
/* TODO GMenu: remove these 2 bogus actions once old style XML menu files are
* deleted.
*/
{ "gradient-editor-blending-func", NULL, "blending-function" },
{ "gradient-editor-coloring-type", NULL, "coloring-type" },
{ "gradient-editor-left-color", NULL,
NC_("gradient-editor-action", "L_eft Endpoint's Color..."), NULL, { NULL }, NULL,
gradient_editor_left_color_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_LEFT_COLOR },
{ "gradient-editor-right-color", NULL,
NC_("gradient-editor-action", "R_ight Endpoint's Color..."), NULL, { NULL }, NULL,
gradient_editor_right_color_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_COLOR },
{ "gradient-editor-flip", PIKA_ICON_OBJECT_FLIP_HORIZONTAL,
NC_("gradient-editor-action", "Flip"), NULL, { NULL }, NULL,
gradient_editor_flip_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_FLIP },
{ "gradient-editor-replicate", PIKA_ICON_OBJECT_DUPLICATE,
NC_("gradient-editor-action", "Replicate"), NULL, { NULL }, NULL,
gradient_editor_replicate_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_FLIP },
{ "gradient-editor-split-midpoint", NULL,
NC_("gradient-editor-action", "Split Midpoint"), NULL, { NULL }, NULL,
gradient_editor_split_midpoint_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_SPLIT_MIDPOINT },
{ "gradient-editor-split-uniform", NULL,
NC_("gradient-editor-action", "Split Uniformly"), NULL, { NULL }, NULL,
gradient_editor_split_uniformly_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_SPLIT_UNIFORM },
{ "gradient-editor-delete", PIKA_ICON_EDIT_DELETE,
NC_("gradient-editor-action", "Delete"), NULL, { NULL }, NULL,
gradient_editor_delete_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_DELETE },
{ "gradient-editor-recenter", NULL,
NC_("gradient-editor-action", "Recenter"), NULL, { NULL }, NULL,
gradient_editor_recenter_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_RECENTER },
{ "gradient-editor-redistribute", NULL,
NC_("gradient-editor-action", "Redistribute"), NULL, { NULL }, NULL,
gradient_editor_redistribute_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_REDISTRIBUTE },
{ "gradient-editor-blend-color", NULL,
NC_("gradient-editor-action", "Ble_nd Endpoints' Colors"), NULL, { NULL }, NULL,
gradient_editor_blend_color_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_BLEND_COLOR },
{ "gradient-editor-blend-opacity", NULL,
NC_("gradient-editor-action", "Blend Endpoints' Opacit_y"), NULL, { NULL }, NULL,
gradient_editor_blend_opacity_cmd_callback,
PIKA_HELP_GRADIENT_EDITOR_BLEND_OPACITY }
};
static const PikaToggleActionEntry gradient_editor_toggle_actions[] =
{
{ "gradient-editor-edit-active", PIKA_ICON_LINKED,
NC_("gradient-editor-action", "Edit Active Gradient"), NULL, { NULL }, NULL,
data_editor_edit_active_cmd_callback,
FALSE,
PIKA_HELP_GRADIENT_EDITOR_EDIT_ACTIVE }
};
#define LOAD_LEFT_FROM(num,magic) \
{ "gradient-editor-load-left-" num, NULL, \
num, NULL, { NULL }, NULL, \
(magic), FALSE, \
PIKA_HELP_GRADIENT_EDITOR_LEFT_LOAD }
#define SAVE_LEFT_TO(num,magic) \
{ "gradient-editor-save-left-" num, NULL, \
num, NULL, { NULL }, NULL, \
(magic), FALSE, \
PIKA_HELP_GRADIENT_EDITOR_LEFT_SAVE }
#define LOAD_RIGHT_FROM(num,magic) \
{ "gradient-editor-load-right-" num, NULL, \
num, NULL, { NULL }, NULL, \
(magic), FALSE, \
PIKA_HELP_GRADIENT_EDITOR_RIGHT_LOAD }
#define SAVE_RIGHT_TO(num,magic) \
{ "gradient-editor-save-right-" num, NULL, \
num, NULL, { NULL }, NULL, \
(magic), FALSE, \
PIKA_HELP_GRADIENT_EDITOR_RIGHT_SAVE }
static const PikaEnumActionEntry gradient_editor_load_left_actions[] =
{
{ "gradient-editor-load-left-left-neighbor", NULL,
NC_("gradient-editor-action", "_Left Neighbor's Right Endpoint"), NULL, { NULL }, NULL,
GRADIENT_EDITOR_COLOR_NEIGHBOR_ENDPOINT, FALSE,
PIKA_HELP_GRADIENT_EDITOR_LEFT_LOAD },
{ "gradient-editor-load-left-right-endpoint", NULL,
NC_("gradient-editor-action", "_Right Endpoint"), NULL, { NULL }, NULL,
GRADIENT_EDITOR_COLOR_OTHER_ENDPOINT, FALSE,
PIKA_HELP_GRADIENT_EDITOR_LEFT_LOAD },
{ "gradient-editor-load-left-fg", NULL,
NC_("gradient-editor-action", "_Foreground Color"), NULL, { NULL }, NULL,
GRADIENT_EDITOR_COLOR_FOREGROUND, FALSE,
PIKA_HELP_GRADIENT_EDITOR_LEFT_LOAD },
{ "gradient-editor-load-left-bg", NULL,
NC_("gradient-editor-action", "_Background Color"), NULL, { NULL }, NULL,
GRADIENT_EDITOR_COLOR_BACKGROUND, FALSE,
PIKA_HELP_GRADIENT_EDITOR_LEFT_LOAD },
LOAD_LEFT_FROM ("01", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 0),
LOAD_LEFT_FROM ("02", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 1),
LOAD_LEFT_FROM ("03", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 2),
LOAD_LEFT_FROM ("04", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 3),
LOAD_LEFT_FROM ("05", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 4),
LOAD_LEFT_FROM ("06", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 5),
LOAD_LEFT_FROM ("07", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 6),
LOAD_LEFT_FROM ("08", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 7),
LOAD_LEFT_FROM ("09", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 8),
LOAD_LEFT_FROM ("10", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 9)
};
static const PikaEnumActionEntry gradient_editor_save_left_actions[] =
{
SAVE_LEFT_TO ("01", 0),
SAVE_LEFT_TO ("02", 1),
SAVE_LEFT_TO ("03", 2),
SAVE_LEFT_TO ("04", 3),
SAVE_LEFT_TO ("05", 4),
SAVE_LEFT_TO ("06", 5),
SAVE_LEFT_TO ("07", 6),
SAVE_LEFT_TO ("08", 7),
SAVE_LEFT_TO ("09", 8),
SAVE_LEFT_TO ("10", 9)
};
static const PikaEnumActionEntry gradient_editor_load_right_actions[] =
{
{ "gradient-editor-load-right-right-neighbor", NULL,
NC_("gradient-editor-action", "_Right Neighbor's Left Endpoint"), NULL, { NULL }, NULL,
GRADIENT_EDITOR_COLOR_NEIGHBOR_ENDPOINT, FALSE,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_LOAD },
{ "gradient-editor-load-right-left-endpoint", NULL,
NC_("gradient-editor-action", "_Left Endpoint"), NULL, { NULL }, NULL,
GRADIENT_EDITOR_COLOR_OTHER_ENDPOINT, FALSE,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_LOAD },
{ "gradient-editor-load-right-fg", NULL,
NC_("gradient-editor-action", "_Foreground Color"), NULL, { NULL }, NULL,
GRADIENT_EDITOR_COLOR_FOREGROUND, FALSE,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_LOAD },
{ "gradient-editor-load-right-bg", NULL,
NC_("gradient-editor-action", "_Background Color"), NULL, { NULL }, NULL,
GRADIENT_EDITOR_COLOR_BACKGROUND, FALSE,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_LOAD },
LOAD_RIGHT_FROM ("01", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 0),
LOAD_RIGHT_FROM ("02", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 1),
LOAD_RIGHT_FROM ("03", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 2),
LOAD_RIGHT_FROM ("04", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 3),
LOAD_RIGHT_FROM ("05", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 4),
LOAD_RIGHT_FROM ("06", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 5),
LOAD_RIGHT_FROM ("07", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 6),
LOAD_RIGHT_FROM ("08", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 7),
LOAD_RIGHT_FROM ("09", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 8),
LOAD_RIGHT_FROM ("10", GRADIENT_EDITOR_COLOR_FIRST_CUSTOM + 9)
};
static const PikaEnumActionEntry gradient_editor_save_right_actions[] =
{
SAVE_RIGHT_TO ("01", 0),
SAVE_RIGHT_TO ("02", 1),
SAVE_RIGHT_TO ("03", 2),
SAVE_RIGHT_TO ("04", 3),
SAVE_RIGHT_TO ("05", 4),
SAVE_RIGHT_TO ("06", 5),
SAVE_RIGHT_TO ("07", 6),
SAVE_RIGHT_TO ("08", 7),
SAVE_RIGHT_TO ("09", 8),
SAVE_RIGHT_TO ("10", 9)
};
#undef LOAD_LEFT_FROM
#undef SAVE_LEFT_TO
#undef LOAD_RIGHT_FROM
#undef SAVE_RIGHT_TO
static const PikaRadioActionEntry gradient_editor_left_color_type_actions[] =
{
{ "gradient-editor-left-color-fixed", NULL,
NC_("gradient-editor-color-type", "_Fixed"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_FIXED,
PIKA_HELP_GRADIENT_EDITOR_LEFT_COLOR },
{ "gradient-editor-left-color-foreground", NULL,
NC_("gradient-editor-color-type", "F_oreground Color"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_FOREGROUND,
PIKA_HELP_GRADIENT_EDITOR_LEFT_COLOR },
{ "gradient-editor-left-color-foreground-transparent", NULL,
NC_("gradient-editor-color-type", "Fo_reground Color (Transparent)"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_FOREGROUND_TRANSPARENT,
PIKA_HELP_GRADIENT_EDITOR_LEFT_COLOR },
{ "gradient-editor-left-color-background", NULL,
NC_("gradient-editor-color-type", "_Background Color"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_BACKGROUND,
PIKA_HELP_GRADIENT_EDITOR_LEFT_COLOR },
{ "gradient-editor-left-color-background-transparent", NULL,
NC_("gradient-editor-color-type", "B_ackground Color (Transparent)"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_BACKGROUND_TRANSPARENT,
PIKA_HELP_GRADIENT_EDITOR_LEFT_COLOR }
};
static const PikaRadioActionEntry gradient_editor_right_color_type_actions[] =
{
{ "gradient-editor-right-color-fixed", NULL,
NC_("gradient-editor-color-type", "_Fixed"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_FIXED,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_COLOR },
{ "gradient-editor-right-color-foreground", NULL,
NC_("gradient-editor-color-type", "F_oreground Color"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_FOREGROUND,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_COLOR },
{ "gradient-editor-right-color-foreground-transparent", NULL,
NC_("gradient-editor-color-type", "Fo_reground Color (Transparent)"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_FOREGROUND_TRANSPARENT,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_COLOR },
{ "gradient-editor-right-color-background", NULL,
NC_("gradient-editor-color-type", "_Background Color"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_BACKGROUND,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_COLOR },
{ "gradient-editor-right-color-background-transparent", NULL,
NC_("gradient-editor-color-type", "B_ackground Color (Transparent)"), NULL, { NULL }, NULL,
PIKA_GRADIENT_COLOR_BACKGROUND_TRANSPARENT,
PIKA_HELP_GRADIENT_EDITOR_RIGHT_COLOR }
};
static const PikaRadioActionEntry gradient_editor_blending_actions[] =
{
{ "gradient-editor-blending-linear", NULL,
NC_("gradient-editor-blending", "_Linear"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_LINEAR,
PIKA_HELP_GRADIENT_EDITOR_BLENDING },
{ "gradient-editor-blending-curved", NULL,
NC_("gradient-editor-blending", "_Curved"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_CURVED,
PIKA_HELP_GRADIENT_EDITOR_BLENDING },
{ "gradient-editor-blending-sine", NULL,
NC_("gradient-editor-blending", "_Sinusoidal"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_SINE,
PIKA_HELP_GRADIENT_EDITOR_BLENDING },
{ "gradient-editor-blending-sphere-increasing", NULL,
NC_("gradient-editor-blending", "Spherical (i_ncreasing)"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_SPHERE_INCREASING,
PIKA_HELP_GRADIENT_EDITOR_BLENDING },
{ "gradient-editor-blending-sphere-decreasing", NULL,
NC_("gradient-editor-blending", "Spherical (_decreasing)"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_SPHERE_DECREASING,
PIKA_HELP_GRADIENT_EDITOR_BLENDING },
{ "gradient-editor-blending-step", NULL,
NC_("gradient-editor-blending", "S_tep"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_STEP,
PIKA_HELP_GRADIENT_EDITOR_BLENDING },
{ "gradient-editor-blending-varies", NULL,
NC_("gradient-editor-blending", "(Varies)"), NULL, { NULL }, NULL,
-1,
PIKA_HELP_GRADIENT_EDITOR_BLENDING }
};
static const PikaRadioActionEntry gradient_editor_coloring_actions[] =
{
{ "gradient-editor-coloring-rgb", NULL,
NC_("gradient-editor-coloring", "_RGB"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_RGB,
PIKA_HELP_GRADIENT_EDITOR_COLORING },
{ "gradient-editor-coloring-hsv-ccw", NULL,
NC_("gradient-editor-coloring", "HSV (_counter-clockwise hue)"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_HSV_CCW,
PIKA_HELP_GRADIENT_EDITOR_COLORING },
{ "gradient-editor-coloring-hsv-cw", NULL,
NC_("gradient-editor-coloring", "HSV (clockwise _hue)"), NULL, { NULL }, NULL,
PIKA_GRADIENT_SEGMENT_HSV_CW,
PIKA_HELP_GRADIENT_EDITOR_COLORING },
{ "gradient-editor-coloring-varies", NULL,
NC_("gradient-editor-coloring", "(Varies)"), NULL, { NULL }, NULL,
-1,
PIKA_HELP_GRADIENT_EDITOR_COLORING }
};
static const PikaEnumActionEntry gradient_editor_zoom_actions[] =
{
{ "gradient-editor-zoom-in", PIKA_ICON_ZOOM_IN,
N_("Zoom In"), NULL, { NULL },
N_("Zoom in"),
PIKA_ZOOM_IN, FALSE,
PIKA_HELP_GRADIENT_EDITOR_ZOOM_IN },
{ "gradient-editor-zoom-out", PIKA_ICON_ZOOM_OUT,
N_("Zoom Out"), NULL, { NULL },
N_("Zoom out"),
PIKA_ZOOM_OUT, FALSE,
PIKA_HELP_GRADIENT_EDITOR_ZOOM_OUT },
{ "gradient-editor-zoom-all", PIKA_ICON_ZOOM_FIT_BEST,
N_("Zoom All"), NULL, { NULL },
N_("Zoom all"),
PIKA_ZOOM_OUT_MAX, FALSE,
PIKA_HELP_GRADIENT_EDITOR_ZOOM_ALL }
};
void
gradient_editor_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "gradient-editor-action",
gradient_editor_actions,
G_N_ELEMENTS (gradient_editor_actions));
pika_action_group_add_toggle_actions (group, "gradient-editor-action",
gradient_editor_toggle_actions,
G_N_ELEMENTS (gradient_editor_toggle_actions));
pika_action_group_add_enum_actions (group, "gradient-editor-action",
gradient_editor_load_left_actions,
G_N_ELEMENTS (gradient_editor_load_left_actions),
gradient_editor_load_left_cmd_callback);
pika_action_group_add_enum_actions (group, NULL,
gradient_editor_save_left_actions,
G_N_ELEMENTS (gradient_editor_save_left_actions),
gradient_editor_save_left_cmd_callback);
pika_action_group_add_enum_actions (group, "gradient-editor-action",
gradient_editor_load_right_actions,
G_N_ELEMENTS (gradient_editor_load_right_actions),
gradient_editor_load_right_cmd_callback);
pika_action_group_add_enum_actions (group, NULL,
gradient_editor_save_right_actions,
G_N_ELEMENTS (gradient_editor_save_right_actions),
gradient_editor_save_right_cmd_callback);
pika_action_group_add_radio_actions (group, "gradient-editor-color-type",
gradient_editor_left_color_type_actions,
G_N_ELEMENTS (gradient_editor_left_color_type_actions),
NULL,
0,
gradient_editor_left_color_type_cmd_callback);
pika_action_group_add_radio_actions (group, "gradient-editor-color-type",
gradient_editor_right_color_type_actions,
G_N_ELEMENTS (gradient_editor_right_color_type_actions),
NULL,
0,
gradient_editor_right_color_type_cmd_callback);
pika_action_group_add_radio_actions (group, "gradient-editor-blending",
gradient_editor_blending_actions,
G_N_ELEMENTS (gradient_editor_blending_actions),
NULL,
0,
gradient_editor_blending_func_cmd_callback);
pika_action_group_add_radio_actions (group, "gradient-editor-coloring",
gradient_editor_coloring_actions,
G_N_ELEMENTS (gradient_editor_coloring_actions),
NULL,
0,
gradient_editor_coloring_type_cmd_callback);
pika_action_group_add_enum_actions (group, NULL,
gradient_editor_zoom_actions,
G_N_ELEMENTS (gradient_editor_zoom_actions),
gradient_editor_zoom_cmd_callback);
}
void
gradient_editor_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (data);
PikaGradient *gradient;
gboolean editable = FALSE;
PikaRGB left_color;
PikaRGB right_color;
PikaRGB left_seg_color;
PikaRGB right_seg_color;
PikaRGB fg;
PikaRGB bg;
gboolean blending_equal = TRUE;
gboolean coloring_equal = TRUE;
gboolean left_editable = TRUE;
gboolean right_editable = TRUE;
gboolean selection = FALSE;
gboolean delete = FALSE;
gboolean edit_active = FALSE;
gradient = PIKA_GRADIENT (data_editor->data);
if (gradient)
{
PikaGradientSegmentType type;
PikaGradientSegmentColor color;
PikaGradientSegment *left_seg;
PikaGradientSegment *right_seg;
PikaGradientSegment *seg, *aseg;
if (data_editor->data_editable)
editable = TRUE;
pika_gradient_segment_get_left_flat_color (gradient,
data_editor->context,
editor->control_sel_l,
&left_color);
if (editor->control_sel_l->prev)
left_seg = editor->control_sel_l->prev;
else
left_seg = pika_gradient_segment_get_last (editor->control_sel_l);
pika_gradient_segment_get_right_flat_color (gradient,
data_editor->context,
left_seg,
&left_seg_color);
pika_gradient_segment_get_right_flat_color (gradient,
data_editor->context,
editor->control_sel_r,
&right_color);
if (editor->control_sel_r->next)
right_seg = editor->control_sel_r->next;
else
right_seg = pika_gradient_segment_get_first (editor->control_sel_r);
pika_gradient_segment_get_left_flat_color (gradient,
data_editor->context,
right_seg,
&right_seg_color);
left_editable = (editor->control_sel_l->left_color_type ==
PIKA_GRADIENT_COLOR_FIXED);
right_editable = (editor->control_sel_r->right_color_type ==
PIKA_GRADIENT_COLOR_FIXED);
type = editor->control_sel_l->type;
color = editor->control_sel_l->color;
seg = editor->control_sel_l;
do
{
blending_equal = blending_equal && (seg->type == type);
coloring_equal = coloring_equal && (seg->color == color);
aseg = seg;
seg = seg->next;
}
while (aseg != editor->control_sel_r);
selection = (editor->control_sel_l != editor->control_sel_r);
delete = (editor->control_sel_l->prev || editor->control_sel_r->next);
}
if (data_editor->context)
{
pika_context_get_foreground (data_editor->context, &fg);
pika_context_get_background (data_editor->context, &bg);
}
/* pretend the gradient not being editable while the dialog is
* insensitive. prevents the gradient from being modified while a
* dialog is running. bug #161411 --mitch
*/
if (! gtk_widget_is_sensitive (GTK_WIDGET (editor)))
editable = FALSE;
if (! editable)
{
left_editable = FALSE;
right_editable = FALSE;
}
edit_active = pika_data_editor_get_edit_active (data_editor);
#define SET_ACTIVE(action,condition) \
pika_action_group_set_action_active (group, action, (condition) != 0)
#define SET_COLOR(action,color,set_label) \
pika_action_group_set_action_color (group, action, (color), (set_label))
#define SET_LABEL(action,label) \
pika_action_group_set_action_label (group, action, (label))
#define SET_GROUP_LABEL(action,label) \
pika_radio_action_set_group_label (PIKA_RADIO_ACTION (pika_action_group_get_action (group, action)), \
label)
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
#define SET_VISIBLE(action,condition) \
pika_action_group_set_action_visible (group, action, (condition) != 0)
SET_SENSITIVE ("gradient-editor-left-color-fixed", editable);
SET_SENSITIVE ("gradient-editor-left-color-foreground", editable);
SET_SENSITIVE ("gradient-editor-left-color-foreground-transparent", editable);
SET_SENSITIVE ("gradient-editor-left-color-background", editable);
SET_SENSITIVE ("gradient-editor-left-color-background-transparent", editable);
if (gradient)
{
switch (editor->control_sel_l->left_color_type)
{
case PIKA_GRADIENT_COLOR_FIXED:
SET_ACTIVE ("gradient-editor-left-color-fixed", TRUE);
break;
case PIKA_GRADIENT_COLOR_FOREGROUND:
SET_ACTIVE ("gradient-editor-left-color-foreground", TRUE);
break;
case PIKA_GRADIENT_COLOR_FOREGROUND_TRANSPARENT:
SET_ACTIVE ("gradient-editor-left-color-foreground-transparent", TRUE);
break;
case PIKA_GRADIENT_COLOR_BACKGROUND:
SET_ACTIVE ("gradient-editor-left-color-background", TRUE);
break;
case PIKA_GRADIENT_COLOR_BACKGROUND_TRANSPARENT:
SET_ACTIVE ("gradient-editor-left-color-background-transparent", TRUE);
break;
}
}
SET_SENSITIVE ("gradient-editor-left-color", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-left-neighbor", editable);
SET_SENSITIVE ("gradient-editor-load-left-right-endpoint", editable);
if (gradient)
{
SET_COLOR ("gradient-editor-left-color",
&left_color, FALSE);
SET_COLOR ("gradient-editor-load-left-left-neighbor",
&left_seg_color, FALSE);
SET_COLOR ("gradient-editor-load-left-right-endpoint",
&right_color, FALSE);
}
SET_SENSITIVE ("gradient-editor-load-left-fg", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-bg", left_editable);
SET_COLOR ("gradient-editor-load-left-fg",
data_editor->context ? &fg : NULL, FALSE);
SET_COLOR ("gradient-editor-load-left-bg",
data_editor->context ? &bg : NULL, FALSE);
SET_SENSITIVE ("gradient-editor-load-left-01", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-02", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-03", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-04", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-05", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-06", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-07", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-08", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-09", left_editable);
SET_SENSITIVE ("gradient-editor-load-left-10", left_editable);
SET_COLOR ("gradient-editor-load-left-01", &editor->saved_colors[0], TRUE);
SET_COLOR ("gradient-editor-load-left-02", &editor->saved_colors[1], TRUE);
SET_COLOR ("gradient-editor-load-left-03", &editor->saved_colors[2], TRUE);
SET_COLOR ("gradient-editor-load-left-04", &editor->saved_colors[3], TRUE);
SET_COLOR ("gradient-editor-load-left-05", &editor->saved_colors[4], TRUE);
SET_COLOR ("gradient-editor-load-left-06", &editor->saved_colors[5], TRUE);
SET_COLOR ("gradient-editor-load-left-07", &editor->saved_colors[6], TRUE);
SET_COLOR ("gradient-editor-load-left-08", &editor->saved_colors[7], TRUE);
SET_COLOR ("gradient-editor-load-left-09", &editor->saved_colors[8], TRUE);
SET_COLOR ("gradient-editor-load-left-10", &editor->saved_colors[9], TRUE);
SET_SENSITIVE ("gradient-editor-save-left-01", gradient);
SET_SENSITIVE ("gradient-editor-save-left-02", gradient);
SET_SENSITIVE ("gradient-editor-save-left-03", gradient);
SET_SENSITIVE ("gradient-editor-save-left-04", gradient);
SET_SENSITIVE ("gradient-editor-save-left-05", gradient);
SET_SENSITIVE ("gradient-editor-save-left-06", gradient);
SET_SENSITIVE ("gradient-editor-save-left-07", gradient);
SET_SENSITIVE ("gradient-editor-save-left-08", gradient);
SET_SENSITIVE ("gradient-editor-save-left-09", gradient);
SET_SENSITIVE ("gradient-editor-save-left-10", gradient);
SET_COLOR ("gradient-editor-save-left-01", &editor->saved_colors[0], TRUE);
SET_COLOR ("gradient-editor-save-left-02", &editor->saved_colors[1], TRUE);
SET_COLOR ("gradient-editor-save-left-03", &editor->saved_colors[2], TRUE);
SET_COLOR ("gradient-editor-save-left-04", &editor->saved_colors[3], TRUE);
SET_COLOR ("gradient-editor-save-left-05", &editor->saved_colors[4], TRUE);
SET_COLOR ("gradient-editor-save-left-06", &editor->saved_colors[5], TRUE);
SET_COLOR ("gradient-editor-save-left-07", &editor->saved_colors[6], TRUE);
SET_COLOR ("gradient-editor-save-left-08", &editor->saved_colors[7], TRUE);
SET_COLOR ("gradient-editor-save-left-09", &editor->saved_colors[8], TRUE);
SET_COLOR ("gradient-editor-save-left-10", &editor->saved_colors[9], TRUE);
SET_SENSITIVE ("gradient-editor-right-color-fixed", editable);
SET_SENSITIVE ("gradient-editor-right-color-foreground", editable);
SET_SENSITIVE ("gradient-editor-right-color-foreground-transparent", editable);
SET_SENSITIVE ("gradient-editor-right-color-background", editable);
SET_SENSITIVE ("gradient-editor-right-color-background-transparent", editable);
if (gradient)
{
switch (editor->control_sel_r->right_color_type)
{
case PIKA_GRADIENT_COLOR_FIXED:
SET_ACTIVE ("gradient-editor-right-color-fixed", TRUE);
break;
case PIKA_GRADIENT_COLOR_FOREGROUND:
SET_ACTIVE ("gradient-editor-right-color-foreground", TRUE);
break;
case PIKA_GRADIENT_COLOR_FOREGROUND_TRANSPARENT:
SET_ACTIVE ("gradient-editor-right-color-foreground-transparent", TRUE);
break;
case PIKA_GRADIENT_COLOR_BACKGROUND:
SET_ACTIVE ("gradient-editor-right-color-background", TRUE);
break;
case PIKA_GRADIENT_COLOR_BACKGROUND_TRANSPARENT:
SET_ACTIVE ("gradient-editor-right-color-background-transparent", TRUE);
break;
}
}
SET_SENSITIVE ("gradient-editor-right-color", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-right-neighbor", editable);
SET_SENSITIVE ("gradient-editor-load-right-left-endpoint", editable);
if (gradient)
{
SET_COLOR ("gradient-editor-right-color",
&right_color, FALSE);
SET_COLOR ("gradient-editor-load-right-right-neighbor",
&right_seg_color, FALSE);
SET_COLOR ("gradient-editor-load-right-left-endpoint",
&left_color, FALSE);
}
SET_SENSITIVE ("gradient-editor-load-right-fg", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-bg", right_editable);
SET_COLOR ("gradient-editor-load-right-fg",
data_editor->context ? &fg : NULL, FALSE);
SET_COLOR ("gradient-editor-load-right-bg",
data_editor->context ? &bg : NULL, FALSE);
SET_SENSITIVE ("gradient-editor-load-right-01", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-02", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-03", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-04", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-05", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-06", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-07", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-08", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-09", right_editable);
SET_SENSITIVE ("gradient-editor-load-right-10", right_editable);
SET_COLOR ("gradient-editor-load-right-01", &editor->saved_colors[0], TRUE);
SET_COLOR ("gradient-editor-load-right-02", &editor->saved_colors[1], TRUE);
SET_COLOR ("gradient-editor-load-right-03", &editor->saved_colors[2], TRUE);
SET_COLOR ("gradient-editor-load-right-04", &editor->saved_colors[3], TRUE);
SET_COLOR ("gradient-editor-load-right-05", &editor->saved_colors[4], TRUE);
SET_COLOR ("gradient-editor-load-right-06", &editor->saved_colors[5], TRUE);
SET_COLOR ("gradient-editor-load-right-07", &editor->saved_colors[6], TRUE);
SET_COLOR ("gradient-editor-load-right-08", &editor->saved_colors[7], TRUE);
SET_COLOR ("gradient-editor-load-right-09", &editor->saved_colors[8], TRUE);
SET_COLOR ("gradient-editor-load-right-10", &editor->saved_colors[9], TRUE);
SET_SENSITIVE ("gradient-editor-save-right-01", gradient);
SET_SENSITIVE ("gradient-editor-save-right-02", gradient);
SET_SENSITIVE ("gradient-editor-save-right-03", gradient);
SET_SENSITIVE ("gradient-editor-save-right-04", gradient);
SET_SENSITIVE ("gradient-editor-save-right-05", gradient);
SET_SENSITIVE ("gradient-editor-save-right-06", gradient);
SET_SENSITIVE ("gradient-editor-save-right-07", gradient);
SET_SENSITIVE ("gradient-editor-save-right-08", gradient);
SET_SENSITIVE ("gradient-editor-save-right-09", gradient);
SET_SENSITIVE ("gradient-editor-save-right-10", gradient);
SET_COLOR ("gradient-editor-save-right-01", &editor->saved_colors[0], TRUE);
SET_COLOR ("gradient-editor-save-right-02", &editor->saved_colors[1], TRUE);
SET_COLOR ("gradient-editor-save-right-03", &editor->saved_colors[2], TRUE);
SET_COLOR ("gradient-editor-save-right-04", &editor->saved_colors[3], TRUE);
SET_COLOR ("gradient-editor-save-right-05", &editor->saved_colors[4], TRUE);
SET_COLOR ("gradient-editor-save-right-06", &editor->saved_colors[5], TRUE);
SET_COLOR ("gradient-editor-save-right-07", &editor->saved_colors[6], TRUE);
SET_COLOR ("gradient-editor-save-right-08", &editor->saved_colors[7], TRUE);
SET_COLOR ("gradient-editor-save-right-09", &editor->saved_colors[8], TRUE);
SET_COLOR ("gradient-editor-save-right-10", &editor->saved_colors[9], TRUE);
SET_SENSITIVE ("gradient-editor-flip", editable);
SET_SENSITIVE ("gradient-editor-replicate", editable);
SET_SENSITIVE ("gradient-editor-split-midpoint", editable);
SET_SENSITIVE ("gradient-editor-split-uniform", editable);
SET_SENSITIVE ("gradient-editor-delete", editable && delete);
SET_SENSITIVE ("gradient-editor-recenter", editable);
SET_SENSITIVE ("gradient-editor-redistribute", editable);
if (! selection)
{
SET_GROUP_LABEL ("gradient-editor-blending-linear",
_("_Blending Function for Segment"));
SET_GROUP_LABEL ("gradient-editor-coloring-rgb",
_("Coloring _Type for Segment"));
SET_LABEL ("gradient-editor-flip",
_("_Flip Segment"));
SET_LABEL ("gradient-editor-replicate",
_("_Replicate Segment..."));
SET_LABEL ("gradient-editor-split-midpoint",
_("Split Segment at _Midpoint"));
SET_LABEL ("gradient-editor-split-uniform",
_("Split Segment _Uniformly..."));
SET_LABEL ("gradient-editor-delete",
_("_Delete Segment"));
SET_LABEL ("gradient-editor-recenter",
_("Re-_center Segment's Midpoint"));
SET_LABEL ("gradient-editor-redistribute",
_("Re-distribute _Handles in Segment"));
}
else
{
SET_GROUP_LABEL ("gradient-editor-blending-linear",
_("_Blending Function for Selection"));
SET_GROUP_LABEL ("gradient-editor-coloring-rgb",
_("Coloring _Type for Selection"));
SET_LABEL ("gradient-editor-flip",
_("_Flip Selection"));
SET_LABEL ("gradient-editor-replicate",
_("_Replicate Selection..."));
SET_LABEL ("gradient-editor-split-midpoint",
_("Split Segments at _Midpoints"));
SET_LABEL ("gradient-editor-split-uniform",
_("Split Segments _Uniformly..."));
SET_LABEL ("gradient-editor-delete",
_("_Delete Selection"));
SET_LABEL ("gradient-editor-recenter",
_("Re-_center Midpoints in Selection"));
SET_LABEL ("gradient-editor-redistribute",
_("Re-distribute _Handles in Selection"));
}
SET_SENSITIVE ("gradient-editor-blending-varies", FALSE);
SET_VISIBLE ("gradient-editor-blending-varies", ! blending_equal);
SET_SENSITIVE ("gradient-editor-blending-linear", editable);
SET_SENSITIVE ("gradient-editor-blending-curved", editable);
SET_SENSITIVE ("gradient-editor-blending-sine", editable);
SET_SENSITIVE ("gradient-editor-blending-sphere-increasing", editable);
SET_SENSITIVE ("gradient-editor-blending-sphere-decreasing", editable);
SET_SENSITIVE ("gradient-editor-blending-step", editable);
if (blending_equal && gradient)
{
switch (editor->control_sel_l->type)
{
case PIKA_GRADIENT_SEGMENT_LINEAR:
SET_ACTIVE ("gradient-editor-blending-linear", TRUE);
break;
case PIKA_GRADIENT_SEGMENT_CURVED:
SET_ACTIVE ("gradient-editor-blending-curved", TRUE);
break;
case PIKA_GRADIENT_SEGMENT_SINE:
SET_ACTIVE ("gradient-editor-blending-sine", TRUE);
break;
case PIKA_GRADIENT_SEGMENT_SPHERE_INCREASING:
SET_ACTIVE ("gradient-editor-blending-sphere-increasing", TRUE);
break;
case PIKA_GRADIENT_SEGMENT_SPHERE_DECREASING:
SET_ACTIVE ("gradient-editor-blending-sphere-decreasing", TRUE);
break;
case PIKA_GRADIENT_SEGMENT_STEP:
SET_ACTIVE ("gradient-editor-blending-step", TRUE);
break;
}
}
else
{
SET_ACTIVE ("gradient-editor-blending-varies", TRUE);
}
SET_SENSITIVE ("gradient-editor-coloring-varies", FALSE);
SET_VISIBLE ("gradient-editor-coloring-varies", ! coloring_equal);
SET_SENSITIVE ("gradient-editor-coloring-rgb", editable);
SET_SENSITIVE ("gradient-editor-coloring-hsv-ccw", editable);
SET_SENSITIVE ("gradient-editor-coloring-hsv-cw", editable);
if (coloring_equal && gradient)
{
switch (editor->control_sel_l->color)
{
case PIKA_GRADIENT_SEGMENT_RGB:
SET_ACTIVE ("gradient-editor-coloring-rgb", TRUE);
break;
case PIKA_GRADIENT_SEGMENT_HSV_CCW:
SET_ACTIVE ("gradient-editor-coloring-hsv-ccw", TRUE);
break;
case PIKA_GRADIENT_SEGMENT_HSV_CW:
SET_ACTIVE ("gradient-editor-coloring-hsv-cw", TRUE);
break;
}
}
else
{
SET_ACTIVE ("gradient-editor-coloring-varies", TRUE);
}
SET_SENSITIVE ("gradient-editor-blend-color", editable && selection);
SET_SENSITIVE ("gradient-editor-blend-opacity", editable && selection);
SET_SENSITIVE ("gradient-editor-zoom-out", gradient);
SET_SENSITIVE ("gradient-editor-zoom-in", gradient);
SET_SENSITIVE ("gradient-editor-zoom-all", gradient);
SET_ACTIVE ("gradient-editor-edit-active", edit_active);
#undef SET_ACTIVE
#undef SET_COLOR
#undef SET_LABEL
#undef SET_SENSITIVE
#undef SET_VISIBLE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __GRADIENT_EDITOR_ACTIONS_H__
#define __GRADIENT_EDITOR_ACTIONS_H__
void gradient_editor_actions_setup (PikaActionGroup *group);
void gradient_editor_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __GRADIENT_EDITOR_ACTIONS_H__ */

View File

@ -0,0 +1,742 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikacontext.h"
#include "core/pikagradient.h"
#include "widgets/pikagradienteditor.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikauimanager.h"
#include "widgets/pikaviewabledialog.h"
#include "gradient-editor-commands.h"
#include "pika-intl.h"
/* local function prototypes */
static void gradient_editor_split_uniform_response (GtkWidget *widget,
gint response_id,
PikaGradientEditor *editor);
static void gradient_editor_replicate_response (GtkWidget *widget,
gint response_id,
PikaGradientEditor *editor);
/* public functions */
void
gradient_editor_left_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
pika_gradient_editor_edit_left_color (editor);
}
void
gradient_editor_left_color_type_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientColor color_type;
color_type = (PikaGradientColor) g_variant_get_int32 (value);
pika_gradient_editor_get_selection (editor, &gradient, &left, NULL);
if (gradient &&
color_type >= 0 &&
color_type !=
pika_gradient_segment_get_left_color_type (gradient, left))
{
PikaRGB color;
pika_gradient_segment_get_left_flat_color (gradient,
PIKA_DATA_EDITOR (editor)->context,
left, &color);
pika_data_freeze (PIKA_DATA (gradient));
pika_gradient_segment_set_left_color_type (gradient, left, color_type);
if (color_type == PIKA_GRADIENT_COLOR_FIXED)
pika_gradient_segment_set_left_color (gradient, left, &color);
pika_data_thaw (PIKA_DATA (gradient));
}
}
void
gradient_editor_load_left_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
PikaGradientSegment *seg;
PikaRGB color;
PikaGradientColor color_type = PIKA_GRADIENT_COLOR_FIXED;
gint index = g_variant_get_int32 (value);
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
switch (index)
{
case GRADIENT_EDITOR_COLOR_NEIGHBOR_ENDPOINT:
if (left->prev != NULL)
seg = left->prev;
else
seg = pika_gradient_segment_get_last (left);
color = seg->right_color;
color_type = seg->right_color_type;
break;
case GRADIENT_EDITOR_COLOR_OTHER_ENDPOINT:
color = right->right_color;
color_type = right->right_color_type;
break;
case GRADIENT_EDITOR_COLOR_FOREGROUND:
pika_context_get_foreground (data_editor->context, &color);
break;
case GRADIENT_EDITOR_COLOR_BACKGROUND:
pika_context_get_background (data_editor->context, &color);
break;
default: /* Load a color */
color = editor->saved_colors[index - GRADIENT_EDITOR_COLOR_FIRST_CUSTOM];
break;
}
pika_data_freeze (PIKA_DATA (gradient));
pika_gradient_segment_range_blend (gradient, left, right,
&color,
&right->right_color,
TRUE, TRUE);
pika_gradient_segment_set_left_color_type (gradient, left, color_type);
pika_data_thaw (PIKA_DATA (gradient));
}
void
gradient_editor_save_left_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
gint index = g_variant_get_int32 (value);
pika_gradient_editor_get_selection (editor, &gradient, &left, NULL);
pika_gradient_segment_get_left_color (gradient, left,
&editor->saved_colors[index]);
}
void
gradient_editor_right_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
pika_gradient_editor_edit_right_color (editor);
}
void
gradient_editor_right_color_type_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *right;
PikaGradientColor color_type;
color_type = (PikaGradientColor) g_variant_get_int32 (value);
pika_gradient_editor_get_selection (editor, &gradient, NULL, &right);
if (gradient &&
color_type >= 0 &&
color_type !=
pika_gradient_segment_get_right_color_type (gradient, right))
{
PikaRGB color;
pika_gradient_segment_get_right_flat_color (gradient,
PIKA_DATA_EDITOR (editor)->context,
right, &color);
pika_data_freeze (PIKA_DATA (gradient));
pika_gradient_segment_set_right_color_type (gradient, right, color_type);
if (color_type == PIKA_GRADIENT_COLOR_FIXED)
pika_gradient_segment_set_right_color (gradient, right, &color);
pika_data_thaw (PIKA_DATA (gradient));
}
}
void
gradient_editor_load_right_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
PikaGradientSegment *seg;
PikaRGB color;
PikaGradientColor color_type = PIKA_GRADIENT_COLOR_FIXED;
gint index = g_variant_get_int32 (value);
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
switch (index)
{
case GRADIENT_EDITOR_COLOR_NEIGHBOR_ENDPOINT:
if (right->next != NULL)
seg = right->next;
else
seg = pika_gradient_segment_get_first (right);
color = seg->left_color;
color_type = seg->left_color_type;
break;
case GRADIENT_EDITOR_COLOR_OTHER_ENDPOINT:
color = left->left_color;
color_type = left->left_color_type;
break;
case GRADIENT_EDITOR_COLOR_FOREGROUND:
pika_context_get_foreground (data_editor->context, &color);
break;
case GRADIENT_EDITOR_COLOR_BACKGROUND:
pika_context_get_background (data_editor->context, &color);
break;
default: /* Load a color */
color = editor->saved_colors[index - GRADIENT_EDITOR_COLOR_FIRST_CUSTOM];
break;
}
pika_data_freeze (PIKA_DATA (gradient));
pika_gradient_segment_range_blend (gradient, left, right,
&left->left_color,
&color,
TRUE, TRUE);
pika_gradient_segment_set_right_color_type (gradient, left, color_type);
pika_data_thaw (PIKA_DATA (gradient));
}
void
gradient_editor_save_right_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *right;
gint index = g_variant_get_int32 (value);
pika_gradient_editor_get_selection (editor, &gradient, NULL, &right);
pika_gradient_segment_get_right_color (gradient, right,
&editor->saved_colors[index]);
}
void
gradient_editor_blending_func_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
GEnumClass *enum_class = NULL;
PikaGradientSegmentType type;
type = (PikaGradientSegmentType) g_variant_get_int32 (value);
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
enum_class = g_type_class_ref (PIKA_TYPE_GRADIENT_SEGMENT_TYPE);
if (gradient && g_enum_get_value (enum_class, type))
{
pika_gradient_segment_range_set_blending_function (gradient,
left, right,
type);
}
g_type_class_unref (enum_class);
}
void
gradient_editor_coloring_type_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
GEnumClass *enum_class = NULL;
PikaGradientSegmentColor color;
color = (PikaGradientSegmentColor) g_variant_get_int32 (value);
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
enum_class = g_type_class_ref (PIKA_TYPE_GRADIENT_SEGMENT_COLOR);
if (gradient && g_enum_get_value (enum_class, color))
{
pika_gradient_segment_range_set_coloring_type (gradient,
left, right,
color);
}
g_type_class_unref (enum_class);
}
void
gradient_editor_flip_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_flip (gradient,
left, right,
&left, &right);
pika_gradient_editor_set_selection (editor, left, right);
}
void
gradient_editor_replicate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
GtkWidget *dialog;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *scale;
GtkAdjustment *scale_data;
const gchar *title;
const gchar *desc;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
if (left == right)
{
title = _("Replicate Segment");
desc = _("Replicate Gradient Segment");
}
else
{
title = _("Replicate Selection");
desc = _("Replicate Gradient Selection");
}
dialog = pika_viewable_dialog_new (g_list_prepend (NULL, gradient),
data_editor->context,
title,
"pika-gradient-segment-replicate",
PIKA_ICON_GRADIENT, desc,
GTK_WIDGET (editor),
pika_standard_help_func,
PIKA_HELP_GRADIENT_EDITOR_REPLICATE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Replicate"), GTK_RESPONSE_OK,
NULL);
pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
g_signal_connect (dialog, "response",
G_CALLBACK (gradient_editor_replicate_response),
editor);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
/* Instructions */
if (left == right)
label = gtk_label_new (_("Select the number of times\n"
"to replicate the selected segment."));
else
label = gtk_label_new (_("Select the number of times\n"
"to replicate the selection."));
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
/* Scale */
scale_data = gtk_adjustment_new (2.0, 2.0, 21.0, 1.0, 1.0, 1.0);
scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, scale_data);
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 4);
gtk_widget_show (scale);
g_object_set_data (G_OBJECT (dialog), "adjustment", scale_data);
gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
pika_ui_manager_update (pika_editor_get_ui_manager (PIKA_EDITOR (editor)),
pika_editor_get_popup_data (PIKA_EDITOR (editor)));
gtk_widget_show (dialog);
}
void
gradient_editor_split_midpoint_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_split_midpoint (gradient,
data_editor->context,
left, right,
editor->blend_color_space,
&left, &right);
pika_gradient_editor_set_selection (editor, left, right);
}
void
gradient_editor_split_uniformly_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
GtkWidget *dialog;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *scale;
GtkAdjustment *scale_data;
const gchar *title;
const gchar *desc;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
if (left == right)
{
title = _("Split Segment Uniformly");
desc = _("Split Gradient Segment Uniformly");
}
else
{
title = _("Split Segments Uniformly");
desc = _("Split Gradient Segments Uniformly");
}
dialog = pika_viewable_dialog_new (g_list_prepend (NULL, gradient),
data_editor->context,
title,
"pika-gradient-segment-split-uniformly",
PIKA_ICON_GRADIENT, desc,
GTK_WIDGET (editor),
pika_standard_help_func,
PIKA_HELP_GRADIENT_EDITOR_SPLIT_UNIFORM,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Split"), GTK_RESPONSE_OK,
NULL);
pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
g_signal_connect (dialog, "response",
G_CALLBACK (gradient_editor_split_uniform_response),
editor);
/* The main vbox */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
/* Instructions */
if (left == right)
label = gtk_label_new (_("Select the number of uniform parts\n"
"in which to split the selected segment."));
else
label = gtk_label_new (_("Select the number of uniform parts\n"
"in which to split the segments in the selection."));
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
/* Scale */
scale_data = gtk_adjustment_new (2.0, 2.0, 21.0, 1.0, 1.0, 1.0);
scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, scale_data);
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 4);
gtk_widget_show (scale);
g_object_set_data (G_OBJECT (dialog), "adjustment", scale_data);
gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
pika_ui_manager_update (pika_editor_get_ui_manager (PIKA_EDITOR (editor)),
pika_editor_get_popup_data (PIKA_EDITOR (editor)));
gtk_widget_show (dialog);
}
void
gradient_editor_delete_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_delete (gradient,
left, right,
&left, &right);
pika_gradient_editor_set_selection (editor, left, right);
}
void
gradient_editor_recenter_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_recenter_handles (gradient, left, right);
}
void
gradient_editor_redistribute_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_redistribute_handles (gradient, left, right);
}
void
gradient_editor_blend_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_blend (gradient, left, right,
&left->left_color,
&right->right_color,
TRUE, FALSE);
}
void
gradient_editor_blend_opacity_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_blend (gradient, left, right,
&left->left_color,
&right->right_color,
FALSE, TRUE);
}
void
gradient_editor_zoom_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaGradientEditor *editor = PIKA_GRADIENT_EDITOR (data);
PikaZoomType zoom_type = (PikaZoomType) g_variant_get_int32 (value);
pika_gradient_editor_zoom (editor, zoom_type, 1.0, 0.5);
}
/* private functions */
static void
gradient_editor_split_uniform_response (GtkWidget *widget,
gint response_id,
PikaGradientEditor *editor)
{
GtkAdjustment *adjustment;
gint split_parts;
adjustment = g_object_get_data (G_OBJECT (widget), "adjustment");
split_parts = RINT (gtk_adjustment_get_value (adjustment));
gtk_widget_destroy (widget);
gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE);
pika_ui_manager_update (pika_editor_get_ui_manager (PIKA_EDITOR (editor)),
pika_editor_get_popup_data (PIKA_EDITOR (editor)));
if (response_id == GTK_RESPONSE_OK)
{
PikaDataEditor *data_editor = PIKA_DATA_EDITOR (editor);
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_split_uniform (gradient,
data_editor->context,
left, right,
split_parts,
editor->blend_color_space,
&left, &right);
pika_gradient_editor_set_selection (editor, left, right);
}
}
static void
gradient_editor_replicate_response (GtkWidget *widget,
gint response_id,
PikaGradientEditor *editor)
{
GtkAdjustment *adjustment;
gint replicate_times;
adjustment = g_object_get_data (G_OBJECT (widget), "adjustment");
replicate_times = RINT (gtk_adjustment_get_value (adjustment));
gtk_widget_destroy (widget);
gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE);
pika_ui_manager_update (pika_editor_get_ui_manager (PIKA_EDITOR (editor)),
pika_editor_get_popup_data (PIKA_EDITOR (editor)));
if (response_id == GTK_RESPONSE_OK)
{
PikaGradient *gradient;
PikaGradientSegment *left;
PikaGradientSegment *right;
pika_gradient_editor_get_selection (editor, &gradient, &left, &right);
pika_gradient_segment_range_replicate (gradient,
left, right,
replicate_times,
&left, &right);
pika_gradient_editor_set_selection (editor, left, right);
}
}

View File

@ -0,0 +1,103 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __GRADIENT_EDITOR_COMMANDS_H__
#define __GRADIENT_EDITOR_COMMANDS_H__
enum
{
GRADIENT_EDITOR_COLOR_NEIGHBOR_ENDPOINT,
GRADIENT_EDITOR_COLOR_OTHER_ENDPOINT,
GRADIENT_EDITOR_COLOR_FOREGROUND,
GRADIENT_EDITOR_COLOR_BACKGROUND,
GRADIENT_EDITOR_COLOR_FIRST_CUSTOM
};
void gradient_editor_left_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_left_color_type_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_load_left_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_save_left_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_right_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_right_color_type_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_load_right_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_save_right_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_blending_func_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_coloring_type_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_flip_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_replicate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_split_midpoint_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_split_uniformly_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_delete_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_recenter_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_redistribute_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_blend_color_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_blend_opacity_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void gradient_editor_zoom_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __GRADIENT_EDITOR_COMMANDS_H__ */

View File

@ -0,0 +1,150 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikacontext.h"
#include "core/pikadata.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "data-commands.h"
#include "gradients-actions.h"
#include "gradients-commands.h"
#include "pika-intl.h"
static const PikaActionEntry gradients_actions[] =
{
{ "gradients-new", PIKA_ICON_DOCUMENT_NEW,
NC_("gradients-action", "_New Gradient"), NULL, { NULL },
NC_("gradients-action", "Create a new gradient"),
data_new_cmd_callback,
PIKA_HELP_GRADIENT_NEW },
{ "gradients-duplicate", PIKA_ICON_OBJECT_DUPLICATE,
NC_("gradients-action", "D_uplicate Gradient"), NULL, { NULL },
NC_("gradients-action", "Duplicate this gradient"),
data_duplicate_cmd_callback,
PIKA_HELP_GRADIENT_DUPLICATE },
{ "gradients-copy-location", PIKA_ICON_EDIT_COPY,
NC_("gradients-action", "Copy Gradient _Location"), NULL, { NULL },
NC_("gradients-action", "Copy gradient file location to clipboard"),
data_copy_location_cmd_callback,
PIKA_HELP_GRADIENT_COPY_LOCATION },
{ "gradients-show-in-file-manager", PIKA_ICON_FILE_MANAGER,
NC_("gradients-action", "Show in _File Manager"), NULL, { NULL },
NC_("gradients-action", "Show gradient file location in the file manager"),
data_show_in_file_manager_cmd_callback,
PIKA_HELP_GRADIENT_SHOW_IN_FILE_MANAGER },
{ "gradients-save-as-pov", PIKA_ICON_DOCUMENT_SAVE_AS,
NC_("gradients-action", "Save as _POV-Ray..."), NULL, { NULL },
NC_("gradients-action", "Save gradient as POV-Ray"),
gradients_save_as_pov_ray_cmd_callback,
PIKA_HELP_GRADIENT_SAVE_AS_POV },
{ "gradients-delete", PIKA_ICON_EDIT_DELETE,
NC_("gradients-action", "_Delete Gradient"), NULL, { NULL },
NC_("gradients-action", "Delete this gradient"),
data_delete_cmd_callback,
PIKA_HELP_GRADIENT_DELETE },
{ "gradients-refresh", PIKA_ICON_VIEW_REFRESH,
NC_("gradients-action", "_Refresh Gradients"), NULL, { NULL },
NC_("gradients-action", "Refresh gradients"),
data_refresh_cmd_callback,
PIKA_HELP_GRADIENT_REFRESH }
};
static const PikaStringActionEntry gradients_edit_actions[] =
{
{ "gradients-edit", PIKA_ICON_EDIT,
NC_("gradients-action", "_Edit Gradient..."), NULL, { NULL },
NC_("gradients-action", "Edit this gradient"),
"pika-gradient-editor",
PIKA_HELP_GRADIENT_EDIT }
};
void
gradients_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "gradients-action",
gradients_actions,
G_N_ELEMENTS (gradients_actions));
pika_action_group_add_string_actions (group, "gradients-action",
gradients_edit_actions,
G_N_ELEMENTS (gradients_edit_actions),
data_edit_cmd_callback);
}
void
gradients_actions_update (PikaActionGroup *group,
gpointer user_data)
{
PikaContext *context = action_data_get_context (user_data);
PikaGradient *gradient = NULL;
PikaData *data = NULL;
GFile *file = NULL;
if (context)
{
gradient = pika_context_get_gradient (context);
if (action_data_sel_count (user_data) > 1)
{
gradient = NULL;
}
if (gradient)
{
data = PIKA_DATA (gradient);
file = pika_data_get_file (data);
}
}
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("gradients-edit", gradient);
SET_SENSITIVE ("gradients-duplicate", gradient);
SET_SENSITIVE ("gradients-save-as-pov", gradient);
SET_SENSITIVE ("gradients-copy-location", file);
SET_SENSITIVE ("gradients-show-in-file-manager", file);
SET_SENSITIVE ("gradients-delete", gradient && pika_data_is_deletable (data));
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __GRADIENTS_ACTIONS_H__
#define __GRADIENTS_ACTIONS_H__
void gradients_actions_setup (PikaActionGroup *group);
void gradients_actions_update (PikaActionGroup *group,
gpointer user_data);
#endif /* __GRADIENT_ACTIONS_H__ */

View File

@ -0,0 +1,155 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pika.h"
#include "core/pikagradient-save.h"
#include "core/pikacontext.h"
#include "widgets/pikacontainereditor.h"
#include "widgets/pikacontainerview.h"
#include "widgets/pikahelp-ids.h"
#include "dialogs/dialogs.h"
#include "gradients-commands.h"
#include "pika-intl.h"
/* local function prototypes */
static void gradients_save_as_pov_ray_response (GtkWidget *dialog,
gint response_id,
PikaGradient *gradient);
/* public functions */
void
gradients_save_as_pov_ray_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
PikaContainerEditor *editor = PIKA_CONTAINER_EDITOR (data);
PikaContext *context;
PikaGradient *gradient;
GtkWidget *dialog;
context = pika_container_view_get_context (editor->view);
gradient = pika_context_get_gradient (context);
if (! gradient)
return;
#define SAVE_AS_POV_DIALOG_KEY "pika-save-as-pov-ray-dialog"
dialog = dialogs_get_dialog (G_OBJECT (gradient), SAVE_AS_POV_DIALOG_KEY);
if (! dialog)
{
gchar *title = g_strdup_printf (_("Save '%s' as POV-Ray"),
pika_object_get_name (gradient));
dialog = gtk_file_chooser_dialog_new (title, NULL,
GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Save"), GTK_RESPONSE_OK,
NULL);
g_free (title);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
g_object_set_data (G_OBJECT (dialog), "pika", context->pika);
gtk_window_set_screen (GTK_WINDOW (dialog),
gtk_widget_get_screen (GTK_WIDGET (editor)));
gtk_window_set_role (GTK_WINDOW (dialog), "pika-gradient-save-pov");
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
TRUE);
g_signal_connect (dialog, "response",
G_CALLBACK (gradients_save_as_pov_ray_response),
gradient);
g_signal_connect (dialog, "delete-event",
G_CALLBACK (gtk_true),
NULL);
g_signal_connect_object (dialog, "destroy",
G_CALLBACK (g_object_unref),
g_object_ref (gradient),
G_CONNECT_SWAPPED);
pika_help_connect (dialog, pika_standard_help_func,
PIKA_HELP_GRADIENT_SAVE_AS_POV, NULL, NULL);
dialogs_attach_dialog (G_OBJECT (gradient),
SAVE_AS_POV_DIALOG_KEY, dialog);
}
gtk_window_present (GTK_WINDOW (dialog));
}
/* private functions */
static void
gradients_save_as_pov_ray_response (GtkWidget *dialog,
gint response_id,
PikaGradient *gradient)
{
if (response_id == GTK_RESPONSE_OK)
{
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
GError *error = NULL;
if (! pika_gradient_save_pov (gradient, file, &error))
{
pika_message_literal (g_object_get_data (G_OBJECT (dialog), "pika"),
G_OBJECT (dialog), PIKA_MESSAGE_ERROR,
error->message);
g_clear_error (&error);
g_object_unref (file);
return;
}
g_object_unref (file);
}
gtk_widget_destroy (dialog);
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __GRADIENTS_COMMANDS_H__
#define __GRADIENTS_COMMANDS_H__
void gradients_save_as_pov_ray_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __GRADIENTS_COMMANDS_H__ */

View File

@ -0,0 +1,68 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "help-actions.h"
#include "help-commands.h"
#include "pika-intl.h"
static const PikaActionEntry help_actions[] =
{
{ "help-help", "pika-prefs-help-system",
NC_("help-action", "_Help"), NULL, { "F1", NULL },
NC_("help-action", "Open the PIKA user manual"),
help_help_cmd_callback,
PIKA_HELP_HELP },
{ "help-context-help", "pika-prefs-help-system",
NC_("help-action", "_Context Help"), NULL, { "<shift>F1", NULL },
NC_("help-action", "Show the help for a specific user interface item"),
help_context_help_cmd_callback,
PIKA_HELP_HELP_CONTEXT }
};
void
help_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "help-action",
help_actions,
G_N_ELEMENTS (help_actions));
}
void
help_actions_update (PikaActionGroup *group,
gpointer data)
{
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __HELP_ACTIONS_H__
#define __HELP_ACTIONS_H__
void help_actions_setup (PikaActionGroup *group);
void help_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __HELP_ACTIONS_H__ */

View File

@ -0,0 +1,61 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikaprogress.h"
#include "widgets/pikahelp.h"
#include "actions.h"
#include "help-commands.h"
void
help_help_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
Pika *pika;
PikaDisplay *display;
return_if_no_pika (pika, data);
return_if_no_display (display, data);
pika_help_show (pika, PIKA_PROGRESS (display), NULL, NULL);
}
void
help_context_help_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data)
{
GtkWidget *widget;
return_if_no_widget (widget, data);
pika_context_help (widget);
}

View File

@ -0,0 +1,34 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __HELP_COMMANDS_H__
#define __HELP_COMMANDS_H__
void help_help_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void help_context_help_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __HELP_COMMANDS_H__ */

579
app/actions/image-actions.c Normal file
View File

@ -0,0 +1,579 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikaconfig/pikaconfig.h"
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "config/pikaguiconfig.h"
#include "gegl/pika-babl.h"
#include "core/pika.h"
#include "core/pikachannel.h"
#include "core/pikacontext.h"
#include "core/pikaimage.h"
#include "core/pikaimage-color-profile.h"
#include "core/pikaitemstack.h"
#include "display/pikadisplay.h"
#include "display/pikadisplayshell.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "image-actions.h"
#include "image-commands.h"
#include "pika-intl.h"
static const PikaActionEntry image_actions[] =
{
{ "image-new", PIKA_ICON_DOCUMENT_NEW,
NC_("image-action", "_New..."), NULL, { "<primary>N", NULL },
NC_("image-action", "Create a new image"),
image_new_cmd_callback,
PIKA_HELP_FILE_NEW },
{ "image-duplicate", PIKA_ICON_OBJECT_DUPLICATE,
NC_("image-action", "_Duplicate"), NULL, { "<primary>D", NULL },
NC_("image-action", "Create a duplicate of this image"),
image_duplicate_cmd_callback,
PIKA_HELP_IMAGE_DUPLICATE },
{ "image-color-profile-assign", NULL,
NC_("image-action", "_Assign Color Profile..."), NULL, { NULL },
NC_("image-action", "Set a color profile on the image"),
image_color_profile_assign_cmd_callback,
PIKA_HELP_IMAGE_COLOR_PROFILE_ASSIGN },
{ "image-color-profile-convert", NULL,
NC_("image-action", "_Convert to Color Profile..."), NULL, { NULL },
NC_("image-action", "Apply a color profile to the image"),
image_color_profile_convert_cmd_callback,
PIKA_HELP_IMAGE_COLOR_PROFILE_CONVERT },
{ "image-color-profile-discard", NULL,
NC_("image-action", "_Discard Color Profile"), NULL, { NULL },
NC_("image-action", "Remove the image's color profile"),
image_color_profile_discard_cmd_callback,
PIKA_HELP_IMAGE_COLOR_PROFILE_DISCARD },
{ "image-softproof-profile", NULL,
NC_("image-action", "_Soft-proof Profile..."), NULL, { NULL },
NC_("image-action", "Set the soft-proofing profile"),
image_softproof_profile_cmd_callback,
PIKA_HELP_VIEW_COLOR_MANAGEMENT },
{ "image-color-profile-save", NULL,
NC_("image-action", "_Save Color Profile to File..."), NULL, { NULL },
NC_("image-action", "Save the image's color profile to an ICC file"),
image_color_profile_save_cmd_callback,
PIKA_HELP_IMAGE_COLOR_PROFILE_SAVE },
{ "image-resize", PIKA_ICON_OBJECT_RESIZE,
NC_("image-action", "Can_vas Size..."), NULL, { NULL },
NC_("image-action", "Adjust the image dimensions"),
image_resize_cmd_callback,
PIKA_HELP_IMAGE_RESIZE },
{ "image-resize-to-layers", NULL,
NC_("image-action", "Fit Canvas to L_ayers"), NULL, { NULL },
NC_("image-action", "Resize the image to enclose all layers"),
image_resize_to_layers_cmd_callback,
PIKA_HELP_IMAGE_RESIZE_TO_LAYERS },
{ "image-resize-to-selection", NULL,
NC_("image-action", "F_it Canvas to Selection"), NULL, { NULL },
NC_("image-action", "Resize the image to the extents of the selection"),
image_resize_to_selection_cmd_callback,
PIKA_HELP_IMAGE_RESIZE_TO_SELECTION },
{ "image-print-size", PIKA_ICON_DOCUMENT_PRINT_RESOLUTION,
NC_("image-action", "_Print Size..."), NULL, { NULL },
NC_("image-action", "Adjust the print resolution"),
image_print_size_cmd_callback,
PIKA_HELP_IMAGE_PRINT_SIZE },
{ "image-scale", PIKA_ICON_OBJECT_SCALE,
NC_("image-action", "_Scale Image..."), NULL, { NULL },
NC_("image-action", "Change the size of the image content"),
image_scale_cmd_callback,
PIKA_HELP_IMAGE_SCALE },
{ "image-crop-to-selection", PIKA_ICON_TOOL_CROP,
NC_("image-action", "_Crop to Selection"), NULL, { NULL },
NC_("image-action", "Crop the image to the extents of the selection"),
image_crop_to_selection_cmd_callback,
PIKA_HELP_IMAGE_CROP },
{ "image-crop-to-content", PIKA_ICON_TOOL_CROP,
NC_("image-action", "Crop to C_ontent"), NULL, { NULL },
NC_("image-action", "Crop the image to the extents of its content (remove empty borders from the image)"),
image_crop_to_content_cmd_callback,
PIKA_HELP_IMAGE_CROP },
{ "image-merge-layers", NULL,
NC_("image-action", "Merge Visible _Layers..."), NULL, { "<primary>M", NULL },
NC_("image-action", "Merge all visible layers into one layer"),
image_merge_layers_cmd_callback,
PIKA_HELP_IMAGE_MERGE_LAYERS },
{ "image-flatten", NULL,
NC_("image-action", "_Flatten Image"), NULL, { NULL },
NC_("image-action", "Merge all layers into one and remove transparency"),
image_flatten_image_cmd_callback,
PIKA_HELP_IMAGE_FLATTEN },
{ "image-configure-grid", PIKA_ICON_GRID,
NC_("image-action", "Configure G_rid..."), NULL, { NULL },
NC_("image-action", "Configure the grid for this image"),
image_configure_grid_cmd_callback,
PIKA_HELP_IMAGE_GRID },
{ "image-properties", "dialog-information",
NC_("image-action", "Image Pr_operties"), NULL, { "<alt>Return", NULL },
NC_("image-action", "Display information about this image"),
image_properties_cmd_callback,
PIKA_HELP_IMAGE_PROPERTIES }
};
static const PikaToggleActionEntry image_toggle_actions[] =
{
{ "image-color-profile-use-srgb", NULL,
NC_("image-action", "Use _sRGB Profile"), NULL, { NULL },
NC_("image-action", "Temporarily use an sRGB profile for the image. "
"This is the same as discarding the image's color profile, but "
"allows to easily restore the profile."),
image_color_profile_use_srgb_cmd_callback,
TRUE,
PIKA_HELP_IMAGE_COLOR_PROFILE_USE_SRGB },
{ "image-softproof-black-point-compensation", NULL,
NC_("image-action", "_Black Point Compensation"), NULL, { NULL },
NC_("image-action", "Use black point compensation for soft-proofing"),
image_softproof_bpc_cmd_callback,
TRUE,
PIKA_HELP_VIEW_COLOR_MANAGEMENT }
};
static const PikaRadioActionEntry image_convert_base_type_actions[] =
{
{ "image-convert-rgb", PIKA_ICON_CONVERT_RGB,
NC_("image-convert-action", "_RGB"), NULL, { NULL },
NC_("image-convert-action", "Convert the image to the RGB colorspace"),
PIKA_RGB, PIKA_HELP_IMAGE_CONVERT_RGB },
{ "image-convert-grayscale", PIKA_ICON_CONVERT_GRAYSCALE,
NC_("image-convert-action", "_Grayscale"), NULL, { NULL },
NC_("image-convert-action", "Convert the image to grayscale"),
PIKA_GRAY, PIKA_HELP_IMAGE_CONVERT_GRAYSCALE },
{ "image-convert-indexed", PIKA_ICON_CONVERT_INDEXED,
NC_("image-convert-action", "_Indexed..."), NULL, { NULL },
NC_("image-convert-action", "Convert the image to indexed colors"),
PIKA_INDEXED, PIKA_HELP_IMAGE_CONVERT_INDEXED }
};
static const PikaRadioActionEntry image_convert_precision_actions[] =
{
{ "image-convert-u8", NULL,
NC_("image-convert-action", "8-bit integer"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to 8-bit integer"),
PIKA_COMPONENT_TYPE_U8, PIKA_HELP_IMAGE_CONVERT_U8 },
{ "image-convert-u16", NULL,
NC_("image-convert-action", "16-bit integer"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to 16-bit integer"),
PIKA_COMPONENT_TYPE_U16, PIKA_HELP_IMAGE_CONVERT_U16 },
{ "image-convert-u32", NULL,
NC_("image-convert-action", "32-bit integer"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to 32-bit integer"),
PIKA_COMPONENT_TYPE_U32, PIKA_HELP_IMAGE_CONVERT_U32 },
{ "image-convert-half", NULL,
NC_("image-convert-action", "16-bit floating point"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to 16-bit floating point"),
PIKA_COMPONENT_TYPE_HALF, PIKA_HELP_IMAGE_CONVERT_HALF },
{ "image-convert-float", NULL,
NC_("image-convert-action", "32-bit floating point"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to 32-bit floating point"),
PIKA_COMPONENT_TYPE_FLOAT, PIKA_HELP_IMAGE_CONVERT_FLOAT },
{ "image-convert-double", NULL,
NC_("image-convert-action", "64-bit floating point"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to 64-bit floating point"),
PIKA_COMPONENT_TYPE_DOUBLE, PIKA_HELP_IMAGE_CONVERT_DOUBLE }
};
static const PikaRadioActionEntry image_convert_trc_actions[] =
{
{ "image-convert-linear", NULL,
NC_("image-convert-action", "Linear light"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to linear light"),
PIKA_TRC_LINEAR, PIKA_HELP_IMAGE_CONVERT_GAMMA },
{ "image-convert-non-linear", NULL,
NC_("image-convert-action", "Non-Linear"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to non-linear gamma from the color profile"),
PIKA_TRC_NON_LINEAR, PIKA_HELP_IMAGE_CONVERT_GAMMA },
{ "image-convert-perceptual", NULL,
NC_("image-convert-action", "Perceptual (sRGB)"), NULL, { NULL },
NC_("image-convert-action",
"Convert the image to perceptual (sRGB) gamma"),
PIKA_TRC_PERCEPTUAL, PIKA_HELP_IMAGE_CONVERT_GAMMA }
};
static const PikaEnumActionEntry image_flip_actions[] =
{
{ "image-flip-horizontal", PIKA_ICON_OBJECT_FLIP_HORIZONTAL,
NC_("image-action", "Flip _Horizontally"), NULL, { NULL },
NC_("image-action", "Flip image horizontally"),
PIKA_ORIENTATION_HORIZONTAL, FALSE,
PIKA_HELP_IMAGE_FLIP_HORIZONTAL },
{ "image-flip-vertical", PIKA_ICON_OBJECT_FLIP_VERTICAL,
NC_("image-action", "Flip _Vertically"), NULL, { NULL },
NC_("image-action", "Flip image vertically"),
PIKA_ORIENTATION_VERTICAL, FALSE,
PIKA_HELP_IMAGE_FLIP_VERTICAL }
};
static const PikaEnumActionEntry image_rotate_actions[] =
{
{ "image-rotate-90", PIKA_ICON_OBJECT_ROTATE_90,
NC_("image-action", "Rotate 90° _clockwise"), NULL, { NULL },
NC_("image-action", "Rotate the image 90 degrees to the right"),
PIKA_ROTATE_90, FALSE,
PIKA_HELP_IMAGE_ROTATE_90 },
{ "image-rotate-180", PIKA_ICON_OBJECT_ROTATE_180,
NC_("image-action", "Rotate _180°"), NULL, { NULL },
NC_("image-action", "Turn the image upside-down"),
PIKA_ROTATE_180, FALSE,
PIKA_HELP_IMAGE_ROTATE_180 },
{ "image-rotate-270", PIKA_ICON_OBJECT_ROTATE_270,
NC_("image-action", "Rotate 90° counter-clock_wise"), NULL, { NULL },
NC_("image-action", "Rotate the image 90 degrees to the left"),
PIKA_ROTATE_270, FALSE,
PIKA_HELP_IMAGE_ROTATE_270 }
};
static const PikaRadioActionEntry image_softproof_intent_actions[] =
{
{ "image-softproof-intent-perceptual", NULL,
NC_("image-action", "_Perceptual"), NULL, { NULL },
NC_("image-action", "Soft-proofing rendering intent is perceptual"),
PIKA_COLOR_RENDERING_INTENT_PERCEPTUAL,
PIKA_HELP_VIEW_COLOR_MANAGEMENT },
{ "image-softproof-intent-relative-colorimetric", NULL,
NC_("image-action", "_Relative Colorimetric"), NULL, { NULL },
NC_("image-action", "Soft-proofing rendering intent is relative colorimetric"),
PIKA_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
PIKA_HELP_VIEW_COLOR_MANAGEMENT },
{ "image-softproof-intent-saturation", NULL,
NC_("image-action", "_Saturation"), NULL, { NULL },
NC_("image-action", "Soft-proofing rendering intent is saturation"),
PIKA_COLOR_RENDERING_INTENT_SATURATION,
PIKA_HELP_VIEW_COLOR_MANAGEMENT },
{ "image-softproof-intent-absolute-colorimetric", NULL,
NC_("image-action", "_Absolute Colorimetric"), NULL, { NULL },
NC_("image-action", "Soft-proofing rendering intent is absolute colorimetric"),
PIKA_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC,
PIKA_HELP_VIEW_COLOR_MANAGEMENT }
};
void
image_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "image-action",
image_actions,
G_N_ELEMENTS (image_actions));
pika_action_group_add_toggle_actions (group, "image-action",
image_toggle_actions,
G_N_ELEMENTS (image_toggle_actions));
pika_action_group_add_radio_actions (group, "image-action",
image_softproof_intent_actions,
G_N_ELEMENTS (image_softproof_intent_actions),
NULL,
PIKA_COLOR_MANAGEMENT_DISPLAY,
image_softproof_intent_cmd_callback);
pika_action_group_add_radio_actions (group, "image-convert-action",
image_convert_base_type_actions,
G_N_ELEMENTS (image_convert_base_type_actions),
NULL, 0,
image_convert_base_type_cmd_callback);
pika_action_group_add_radio_actions (group, "image-convert-action",
image_convert_precision_actions,
G_N_ELEMENTS (image_convert_precision_actions),
NULL, 0,
image_convert_precision_cmd_callback);
pika_action_group_add_radio_actions (group, "image-convert-action",
image_convert_trc_actions,
G_N_ELEMENTS (image_convert_trc_actions),
NULL, 0,
image_convert_trc_cmd_callback);
pika_action_group_add_enum_actions (group, "image-action",
image_flip_actions,
G_N_ELEMENTS (image_flip_actions),
image_flip_cmd_callback);
pika_action_group_add_enum_actions (group, "image-action",
image_rotate_actions,
G_N_ELEMENTS (image_rotate_actions),
image_rotate_cmd_callback);
#define SET_ALWAYS_SHOW_IMAGE(action,show) \
pika_action_group_set_action_always_show_image (group, action, show)
SET_ALWAYS_SHOW_IMAGE ("image-rotate-90", TRUE);
SET_ALWAYS_SHOW_IMAGE ("image-rotate-180", TRUE);
SET_ALWAYS_SHOW_IMAGE ("image-rotate-270", TRUE);
#undef SET_ALWAYS_SHOW_IMAGE
}
void
image_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaImage *image = action_data_get_image (data);
gboolean is_indexed = FALSE;
gboolean is_u8_gamma = FALSE;
gboolean is_double = FALSE;
gboolean aux = FALSE;
gboolean lp = FALSE;
gboolean sel = FALSE;
gboolean groups = FALSE;
gboolean profile_srgb = FALSE;
gboolean profile_hidden = FALSE;
gboolean profile = FALSE;
gboolean s_bpc = FALSE;
#define SET_LABEL(action,label) \
pika_action_group_set_action_label (group, action, (label))
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
#define SET_ACTIVE(action,condition) \
pika_action_group_set_action_active (group, action, (condition) != 0)
#define SET_VISIBLE(action,condition) \
pika_action_group_set_action_visible (group, action, (condition) != 0)
if (image)
{
PikaContainer *layers;
const gchar *action = NULL;
PikaImageBaseType base_type;
PikaPrecision precision;
PikaComponentType component_type;
PikaTRCType trc;
base_type = pika_image_get_base_type (image);
precision = pika_image_get_precision (image);
component_type = pika_image_get_component_type (image);
trc = pika_babl_format_get_trc
(pika_image_get_layer_format (image, FALSE));
switch (base_type)
{
case PIKA_RGB: action = "image-convert-rgb"; break;
case PIKA_GRAY: action = "image-convert-grayscale"; break;
case PIKA_INDEXED: action = "image-convert-indexed"; break;
}
SET_ACTIVE (action, TRUE);
switch (component_type)
{
case PIKA_COMPONENT_TYPE_U8: action = "image-convert-u8"; break;
case PIKA_COMPONENT_TYPE_U16: action = "image-convert-u16"; break;
case PIKA_COMPONENT_TYPE_U32: action = "image-convert-u32"; break;
case PIKA_COMPONENT_TYPE_HALF: action = "image-convert-half"; break;
case PIKA_COMPONENT_TYPE_FLOAT: action = "image-convert-float"; break;
case PIKA_COMPONENT_TYPE_DOUBLE: action = "image-convert-double"; break;
}
SET_ACTIVE (action, TRUE);
switch (trc)
{
case PIKA_TRC_LINEAR:
action = "image-convert-linear";
SET_VISIBLE ("image-convert-perceptual", FALSE);
break;
case PIKA_TRC_NON_LINEAR:
action = "image-convert-non-linear";
SET_VISIBLE ("image-convert-perceptual", FALSE);
break;
case PIKA_TRC_PERCEPTUAL:
action = "image-convert-perceptual";
SET_VISIBLE ("image-convert-perceptual", TRUE);
break;
}
SET_ACTIVE (action, TRUE);
is_indexed = (base_type == PIKA_INDEXED);
is_u8_gamma = (precision == PIKA_PRECISION_U8_NON_LINEAR);
is_double = (component_type == PIKA_COMPONENT_TYPE_DOUBLE);
aux = (pika_image_get_selected_channels (image) != NULL);
lp = ! pika_image_is_empty (image);
sel = ! pika_channel_is_empty (pika_image_get_mask (image));
layers = pika_image_get_layers (image);
groups = ! pika_item_stack_is_flat (PIKA_ITEM_STACK (layers));
profile_srgb = pika_image_get_use_srgb_profile (image, &profile_hidden);
profile = (pika_image_get_color_profile (image) != NULL);
switch (pika_image_get_simulation_intent (image))
{
case PIKA_COLOR_RENDERING_INTENT_PERCEPTUAL:
action = "image-softproof-intent-perceptual";
break;
case PIKA_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC:
action = "image-softproof-intent-relative-colorimetric";
break;
case PIKA_COLOR_RENDERING_INTENT_SATURATION:
action = "image-softproof-intent-saturation";
break;
case PIKA_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
action = "image-softproof-intent-absolute-colorimetric";
break;
}
pika_action_group_set_action_active (group, action, TRUE);
s_bpc = pika_image_get_simulation_bpc (image);
}
else
{
SET_VISIBLE ("image-convert-perceptual", FALSE);
}
SET_SENSITIVE ("image-duplicate", image);
if (profile)
{
SET_LABEL ("image-convert-rgb",
C_("image-convert-action", "_RGB..."));
SET_LABEL ("image-convert-grayscale",
C_("image-convert-action", "_Grayscale..."));
}
else
{
SET_LABEL ("image-convert-rgb",
C_("image-convert-action", "_RGB"));
SET_LABEL ("image-convert-grayscale",
C_("image-convert-action", "_Grayscale"));
}
SET_SENSITIVE ("image-convert-rgb", image);
SET_SENSITIVE ("image-convert-grayscale", image);
SET_SENSITIVE ("image-convert-indexed", image && !groups && is_u8_gamma);
SET_SENSITIVE ("image-softproof-profile", image);
SET_SENSITIVE ("image-softproof-intent-perceptual", image);
SET_SENSITIVE ("image-softproof-intent-relative-colorimetric", image);
SET_SENSITIVE ("image-softproof-intent-saturation", image);
SET_SENSITIVE ("image-softproof-intent-absolute-colorimetric", image);
SET_SENSITIVE ("image-softproof-black-point-compensation", image);
SET_ACTIVE ("image-softproof-black-point-compensation", s_bpc);
SET_SENSITIVE ("image-convert-u8", image);
SET_SENSITIVE ("image-convert-u16", image && !is_indexed);
SET_SENSITIVE ("image-convert-u32", image && !is_indexed);
SET_SENSITIVE ("image-convert-half", image && !is_indexed);
SET_SENSITIVE ("image-convert-float", image && !is_indexed);
SET_SENSITIVE ("image-convert-double", image && !is_indexed);
SET_VISIBLE ("image-convert-double", is_double);
SET_SENSITIVE ("image-convert-linear", image && !is_indexed);
SET_SENSITIVE ("image-convert-non-linear", image);
SET_SENSITIVE ("image-convert-perceptual", image && !is_indexed);
SET_SENSITIVE ("image-color-profile-use-srgb", image && (profile || profile_hidden));
SET_ACTIVE ("image-color-profile-use-srgb", image && profile_srgb);
SET_SENSITIVE ("image-color-profile-assign", image);
SET_SENSITIVE ("image-color-profile-convert", image);
SET_SENSITIVE ("image-color-profile-discard", image && profile);
SET_SENSITIVE ("image-color-profile-save", image);
SET_SENSITIVE ("image-flip-horizontal", image);
SET_SENSITIVE ("image-flip-vertical", image);
SET_SENSITIVE ("image-rotate-90", image);
SET_SENSITIVE ("image-rotate-180", image);
SET_SENSITIVE ("image-rotate-270", image);
SET_SENSITIVE ("image-resize", image);
SET_SENSITIVE ("image-resize-to-layers", image);
SET_SENSITIVE ("image-resize-to-selection", image && sel);
SET_SENSITIVE ("image-print-size", image);
SET_SENSITIVE ("image-scale", image);
SET_SENSITIVE ("image-crop-to-selection", image && sel);
SET_SENSITIVE ("image-crop-to-content", image);
SET_SENSITIVE ("image-merge-layers", image && !aux && lp);
SET_SENSITIVE ("image-flatten", image && !aux && lp);
SET_SENSITIVE ("image-configure-grid", image);
SET_SENSITIVE ("image-properties", image);
#undef SET_LABEL
#undef SET_SENSITIVE
#undef SET_ACTIVE
#undef SET_VISIBLE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __IMAGE_ACTIONS_H__
#define __IMAGE_ACTIONS_H__
void image_actions_setup (PikaActionGroup *group);
void image_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __IMAGE_ACTIONS_H__ */

1669
app/actions/image-commands.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __IMAGE_COMMANDS_H__
#define __IMAGE_COMMANDS_H__
void image_new_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_duplicate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_convert_base_type_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_convert_precision_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_convert_trc_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_color_profile_use_srgb_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_color_profile_assign_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_color_profile_convert_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_color_profile_discard_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_color_profile_save_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_resize_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_resize_to_layers_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_resize_to_selection_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_print_size_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_scale_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_flip_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_rotate_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_crop_to_selection_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_crop_to_content_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_merge_layers_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_merge_layers_last_vals_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_flatten_image_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_configure_grid_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_properties_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_softproof_profile_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_softproof_intent_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
void image_softproof_bpc_cmd_callback (PikaAction *action,
GVariant *value,
gpointer data);
#endif /* __IMAGE_COMMANDS_H__ */

View File

@ -0,0 +1,98 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "actions-types.h"
#include "core/pikacontext.h"
#include "core/pikaimage.h"
#include "widgets/pikaactiongroup.h"
#include "widgets/pikahelp-ids.h"
#include "actions.h"
#include "images-actions.h"
#include "images-commands.h"
#include "pika-intl.h"
static const PikaActionEntry images_actions[] =
{
{ "images-raise-views", PIKA_ICON_GO_TOP,
NC_("images-action", "_Raise Views"), NULL, { NULL },
NC_("images-action", "Raise this image's displays"),
images_raise_views_cmd_callback,
NULL },
{ "images-new-view", PIKA_ICON_DOCUMENT_NEW,
NC_("images-action", "_New View"), NULL, { NULL },
NC_("images-action", "Create a new display for this image"),
images_new_view_cmd_callback,
NULL },
{ "images-delete", PIKA_ICON_EDIT_DELETE,
NC_("images-action", "_Delete Image"), NULL, { NULL },
NC_("images-action", "Delete this image"),
images_delete_image_cmd_callback,
NULL }
};
void
images_actions_setup (PikaActionGroup *group)
{
pika_action_group_add_actions (group, "images-action",
images_actions,
G_N_ELEMENTS (images_actions));
}
void
images_actions_update (PikaActionGroup *group,
gpointer data)
{
PikaContext *context = action_data_get_context (data);
PikaImage *image = NULL;
gint disp_count = 0;
if (context)
{
image = pika_context_get_image (context);
if (image)
disp_count = pika_image_get_display_count (image);
}
#define SET_SENSITIVE(action,condition) \
pika_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
SET_SENSITIVE ("images-raise-views", image);
SET_SENSITIVE ("images-new-view", image);
SET_SENSITIVE ("images-delete", image && disp_count == 0);
#undef SET_SENSITIVE
}

View File

@ -0,0 +1,31 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __IMAGES_ACTIONS_H__
#define __IMAGES_ACTIONS_H__
void images_actions_setup (PikaActionGroup *group);
void images_actions_update (PikaActionGroup *group,
gpointer data);
#endif /* __IMAGES_ACTIONS_H__ */

Some files were not shown because too many files have changed in this diff Show More