Commit 5a38bb1e authored by Wolfgang Steitz's avatar Wolfgang Steitz Committed by Jim Nelson

Copy and paste color adjustments: Closes #2517

Color adjustments now have a "clipboard" that can be copied to and
pasted from.
parent 379a3ba9
......@@ -108,6 +108,9 @@ public abstract class CollectionPage : MediaPage {
group.add_separator();
group.add_menu_item("Enhance");
group.add_menu_item("Revert");
group.add_separator();
group.add_menu_item("CopyColorAdjustments");
group.add_menu_item("PasteColorAdjustments");
return group;
}
......@@ -178,6 +181,18 @@ public abstract class CollectionPage : MediaPage {
enhance.tooltip = Resources.ENHANCE_TOOLTIP;
actions += enhance;
Gtk.ActionEntry copy_adjustments = { "CopyColorAdjustments", null, TRANSLATABLE,
"<Ctrl><Shift>C", TRANSLATABLE, on_copy_adjustments};
copy_adjustments.label = Resources.COPY_ADJUSTMENTS_MENU;
copy_adjustments.tooltip = Resources.COPY_ADJUSTMENTS_TOOLTIP;
actions += copy_adjustments;
Gtk.ActionEntry paste_adjustments = { "PasteColorAdjustments", null, TRANSLATABLE,
"<Ctrl><Shift>V", TRANSLATABLE, on_paste_adjustments};
paste_adjustments.label = Resources.PASTE_ADJUSTMENTS_MENU;
paste_adjustments.tooltip = Resources.PASTE_ADJUSTMENTS_TOOLTIP;
actions += paste_adjustments;
Gtk.ActionEntry revert = { "Revert", Gtk.Stock.REVERT_TO_SAVED, TRANSLATABLE, null,
TRANSLATABLE, on_revert };
revert.label = Resources.REVERT_MENU;
......@@ -284,6 +299,10 @@ public abstract class CollectionPage : MediaPage {
&& !is_string_empty(Config.Facade.get_instance().get_external_raw_app()));
set_action_sensitive("Revert", (!selection_has_videos) && can_revert_selected());
set_action_sensitive("Enhance", (!selection_has_videos) && has_selected);
set_action_sensitive("CopyColorAdjustments", (!selection_has_videos) && one_selected &&
((Photo) get_view().get_selected_at(0).get_source()).has_color_adjustments());
set_action_sensitive("PasteColorAdjustments", (!selection_has_videos) && has_selected &&
PixelTransformationBundle.has_copied_color_adjustments());
set_action_sensitive("RotateClockwise", (!selection_has_videos) && has_selected);
set_action_sensitive("RotateCounterclockwise", (!selection_has_videos) && has_selected);
set_action_sensitive("FlipHorizontally", (!selection_has_videos) && has_selected);
......@@ -580,6 +599,23 @@ public abstract class CollectionPage : MediaPage {
get_command_manager().execute(command);
}
public void on_copy_adjustments() {
if (get_view().get_selected_count() != 1)
return;
Photo photo = (Photo) get_view().get_selected_at(0).get_source();
PixelTransformationBundle.set_copied_color_adjustments(photo.get_color_adjustments());
}
public void on_paste_adjustments() {
PixelTransformationBundle? copied_adjustments = PixelTransformationBundle.get_copied_color_adjustments();
if (get_view().get_selected_count() == 0 || copied_adjustments == null)
return;
AdjustColorsMultipleCommand command = new AdjustColorsMultipleCommand(get_view().get_selected(),
copied_adjustments, Resources.PASTE_ADJUSTMENTS_LABEL, Resources.PASTE_ADJUSTMENTS_TOOLTIP);
get_command_manager().execute(command);
}
private void on_enhance() {
if (get_view().get_selected_count() == 0)
return;
......
......@@ -231,12 +231,26 @@ public enum PixelTransformationType {
}
public class PixelTransformationBundle {
private static PixelTransformationBundle? copied_color_adjustments = null;
private Gee.HashMap<int, PixelTransformation> map = new Gee.HashMap<int, PixelTransformation>(
Gee.Functions.get_hash_func_for(typeof(int)), Gee.Functions.get_equal_func_for(typeof(int)));
public PixelTransformationBundle() {
}
public static PixelTransformationBundle? get_copied_color_adjustments() {
return copied_color_adjustments;
}
public static void set_copied_color_adjustments(PixelTransformationBundle adjustments) {
copied_color_adjustments = adjustments;
}
public static bool has_copied_color_adjustments() {
return copied_color_adjustments != null;
}
public void set(PixelTransformation transformation) {
map.set((int) transformation.get_transformation_type(), transformation);
}
......
......@@ -814,10 +814,10 @@ public class CropCommand : GenericPhotoTransformationCommand {
}
}
public class AdjustColorsCommand : GenericPhotoTransformationCommand {
public class AdjustColorsSingleCommand : GenericPhotoTransformationCommand {
private PixelTransformationBundle transformations;
public AdjustColorsCommand(Photo photo, PixelTransformationBundle transformations,
public AdjustColorsSingleCommand(Photo photo, PixelTransformationBundle transformations,
string name, string explanation) {
base(photo, name, explanation);
......@@ -833,7 +833,23 @@ public class AdjustColorsCommand : GenericPhotoTransformationCommand {
}
public override bool can_compress(Command command) {
return command is AdjustColorsCommand;
return command is AdjustColorsSingleCommand;
}
}
public class AdjustColorsMultipleCommand : MultiplePhotoTransformationCommand {
private PixelTransformationBundle transformations;
public AdjustColorsMultipleCommand(Gee.Iterable<DataView> iter,
PixelTransformationBundle transformations, string name, string explanation) {
base(iter, _("Applying Color Transformations"), _("Undoing Color Transformations"),
name, explanation);
this.transformations = transformations;
}
public override void execute_on_source(DataSource source) {
((Photo) source).set_color_adjustments(transformations);
}
}
......
......@@ -19,6 +19,7 @@ public class InjectionGroup {
private string path;
private Gee.ArrayList<Element?> elements = new Gee.ArrayList<Element?>();
private int separator_id = 0;
public InjectionGroup(string path) {
this.path = path;
......@@ -41,7 +42,7 @@ public class InjectionGroup {
}
public void add_separator() {
elements.add(new Element("", null, Gtk.UIManagerItemType.SEPARATOR));
elements.add(new Element("%d-separator".printf(separator_id++), null, Gtk.UIManagerItemType.SEPARATOR));
}
}
......
......@@ -2143,6 +2143,22 @@ public abstract class EditingHostPage : SinglePhotoPage {
EnhanceSingleCommand command = new EnhanceSingleCommand(get_photo());
get_command_manager().execute(command);
}
public void on_copy_adjustments() {
if (!has_photo())
return;
PixelTransformationBundle.set_copied_color_adjustments(get_photo().get_color_adjustments());
}
public void on_paste_adjustments() {
PixelTransformationBundle? copied_adjustments = PixelTransformationBundle.get_copied_color_adjustments();
if (!has_photo() || copied_adjustments == null)
return;
AdjustColorsSingleCommand command = new AdjustColorsSingleCommand(get_photo(), copied_adjustments,
Resources.PASTE_ADJUSTMENTS_LABEL, Resources.PASTE_ADJUSTMENTS_TOOLTIP);
get_command_manager().execute(command);
}
private void place_tool_window() {
if (current_tool == null)
......@@ -2431,6 +2447,18 @@ public class LibraryPhotoPage : EditingHostPage {
enhance.tooltip = Resources.ENHANCE_TOOLTIP;
actions += enhance;
Gtk.ActionEntry copy_adjustments = { "CopyColorAdjustments", null, TRANSLATABLE,
"<Ctrl><Shift>C", TRANSLATABLE, on_copy_adjustments};
copy_adjustments.label = Resources.COPY_ADJUSTMENTS_MENU;
copy_adjustments.tooltip = Resources.COPY_ADJUSTMENTS_TOOLTIP;
actions += copy_adjustments;
Gtk.ActionEntry paste_adjustments = { "PasteColorAdjustments", null, TRANSLATABLE,
"<Ctrl><Shift>V", TRANSLATABLE, on_paste_adjustments};
paste_adjustments.label = Resources.PASTE_ADJUSTMENTS_MENU;
paste_adjustments.tooltip = Resources.PASTE_ADJUSTMENTS_TOOLTIP;
actions += paste_adjustments;
Gtk.ActionEntry crop = { "Crop", Resources.CROP, TRANSLATABLE, "<Ctrl>O",
TRANSLATABLE, toggle_crop };
crop.label = Resources.CROP_MENU;
......@@ -2703,6 +2731,9 @@ public class LibraryPhotoPage : EditingHostPage {
set_action_sensitive("SetBackground", has_photo());
set_action_sensitive("CopyColorAdjustments", (has_photo() && get_photo().has_color_adjustments()));
set_action_sensitive("PasteColorAdjustments", PixelTransformationBundle.has_copied_color_adjustments());
set_action_sensitive("PrevPhoto", multiple);
set_action_sensitive("NextPhoto", multiple);
set_action_sensitive("RotateClockwise", rotate_possible);
......
......@@ -158,6 +158,14 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc.,
public const string ENHANCE_LABEL = _("Enhance");
public const string ENHANCE_TOOLTIP = _("Automatically improve the photo's appearance");
public const string COPY_ADJUSTMENTS_MENU = _("_Copy Color Adjustments");
public const string COPY_ADJUSTMENTS_LABEL = _("Copy Color Adjustments");
public const string COPY_ADJUSTMENTS_TOOLTIP = _("Copy the color adjustments applied to the photo");
public const string PASTE_ADJUSTMENTS_MENU = _("_Paste Color Adjustments");
public const string PASTE_ADJUSTMENTS_LABEL = _("Paste Color Adjustments");
public const string PASTE_ADJUSTMENTS_TOOLTIP = _("Apply copied color adjustments to the selected photos");
public const string CROP_MENU = _("_Crop");
public const string CROP_LABEL = _("Crop");
public const string CROP_TOOLTIP = _("Crop the photo's size");
......
......@@ -2623,7 +2623,7 @@ public class AdjustTool : EditingTool {
get_tool_window().hide();
applied(new AdjustColorsCommand(canvas.get_photo(), transformations,
applied(new AdjustColorsSingleCommand(canvas.get_photo(), transformations,
Resources.ADJUST_LABEL, Resources.ADJUST_TOOLTIP), draw_to_pixbuf,
canvas.get_photo().get_dimensions(), false);
}
......
......@@ -73,6 +73,9 @@
</menu>
<menuitem name="Revert" action="Revert" />
<separator />
<menuitem name="CopyColorAdjustments" action="CopyColorAdjustments" />
<menuitem name="PasteColorAdjustments" action="PasteColorAdjustments" />
<separator/>
<menuitem name="Flag" action="Flag" />
<menu name="Rate" action="Rate">
<menuitem name="RateFive" action="RateFive" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment