2
* Widgets.EditorPage.cs
5
* Ruben Vermeersch <ruben@savanne.be>
7
* This is free software. See COPYING for details.
12
using FSpot.UI.Dialog;
21
using System.Collections.Generic;
23
namespace FSpot.Widgets {
24
public class EditorPage : SidebarPage {
25
internal bool InPhotoView;
26
private readonly EditorPageWidget EditorPageWidget;
28
public EditorPage () : base (new EditorPageWidget (),
29
Catalog.GetString ("Edit"),
31
// TODO: Somebody might need to change the icon to something more suitable.
32
// FIXME: The icon isn't shown in the menu, are we missing a size?
33
EditorPageWidget = SidebarWidget as EditorPageWidget;
34
EditorPageWidget.Page = this;
37
protected override void AddedToSidebar () {
38
Sidebar.SelectionChanged += delegate (IBrowsableCollection collection) { EditorPageWidget.ShowTools (); };
39
Sidebar.ContextChanged += HandleContextChanged;
42
private void HandleContextChanged (object sender, EventArgs args)
44
InPhotoView = (Sidebar.Context == ViewContext.Edit);
45
EditorPageWidget.ChangeButtonVisibility ();
49
public class EditorPageWidget : ScrolledWindow {
51
private VButtonBox buttons;
52
private Widget active_editor;
54
private List<Editor> editors;
55
private Editor current_editor;
57
// Used to make buttons insensitive when selecting multiple images.
58
private Dictionary<Editor, Button> editor_buttons;
60
private EditorPage page;
61
internal EditorPage Page {
63
set { page = value; ChangeButtonVisibility (); }
66
public EditorPageWidget () {
67
editors = new List<Editor> ();
68
editor_buttons = new Dictionary<Editor, Button> ();
70
AddinManager.AddExtensionNodeHandler ("/FSpot/Editors", OnExtensionChanged);
74
private void OnExtensionChanged (object s, ExtensionNodeEventArgs args) {
75
// FIXME: We do not do run-time removal of editors yet!
76
if (args.Change == ExtensionChange.Add) {
77
Editor editor = (args.ExtensionNode as EditorNode).GetEditor ();
78
editor.ProcessingStarted += OnProcessingStarted;
79
editor.ProcessingStep += OnProcessingStep;
80
editor.ProcessingFinished += OnProcessingFinished;
86
private ProgressDialog progress;
88
private void OnProcessingStarted (string name, int count) {
89
progress = new ProgressDialog (name, ProgressDialog.CancelButtonType.None, count, MainWindow.Toplevel.Window);
92
private void OnProcessingStep (int done) {
94
progress.Update (String.Empty);
97
private void OnProcessingFinished () {
98
if (progress != null) {
104
internal void ChangeButtonVisibility () {
105
foreach (Editor editor in editors) {
107
if (editor_buttons.TryGetValue (editor, out button))
108
button.Visible = Page.InPhotoView || editor.CanHandleMultiple;
112
void PackButton (Editor editor)
114
Button button = new Button (editor.Label);
115
if (editor.IconName != null)
116
button.Image = new Image (GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, editor.IconName, 22, (Gtk.IconLookupFlags)0));
117
button.Clicked += delegate (object o, EventArgs e) { ChooseEditor (editor); };
119
buttons.Add (button);
120
editor_buttons.Add (editor, button);
123
public void ShowTools () {
124
// Remove any open editor, if present.
125
if (current_editor != null) {
126
active_editor.Hide ();
127
widgets.Remove (active_editor);
128
active_editor = null;
129
current_editor.Restore ();
130
current_editor = null;
133
// No need to build the widget twice.
134
if (buttons != null) {
139
if (widgets == null) {
140
widgets = new VBox (false, 0);
141
widgets.NoShowAll = true;
143
Viewport widgets_port = new Viewport ();
144
widgets_port.Add (widgets);
146
widgets_port.ShowAll ();
149
// Build the widget (first time we call this method).
150
buttons = new VButtonBox ();
151
buttons.BorderWidth = 5;
153
buttons.LayoutStyle = ButtonBoxStyle.Start;
155
foreach (Editor editor in editors)
159
widgets.Add (buttons);
162
private void ChooseEditor (Editor editor) {
163
SetupEditor (editor);
165
if (!editor.CanBeApplied || editor.HasSettings)
168
Apply (editor); // Instant apply
171
private bool SetupEditor (Editor editor) {
172
EditorState state = editor.CreateState ();
174
EditorSelection selection = new EditorSelection ();
175
PhotoImageView photo_view = MainWindow.Toplevel.PhotoView.View;
177
if (Page.InPhotoView && photo_view != null) {
178
if (photo_view.GetSelection (out selection.x, out selection.y,
179
out selection.width, out selection.height))
180
state.Selection = selection;
182
state.Selection = null;
183
state.PhotoImageView = photo_view;
185
state.Selection = null;
186
state.PhotoImageView = null;
188
if (Page.Sidebar.Selection == null)
190
state.Items = Page.Sidebar.Selection.Items;
192
editor.Initialize (state);
196
private void Apply (Editor editor) {
197
if (!SetupEditor (editor))
200
if (!editor.CanBeApplied) {
201
string msg = Catalog.GetString ("No selection available");
202
string desc = Catalog.GetString ("This tool requires an active selection. Please select a region of the photo and try the operation again");
204
HigMessageDialog md = new HigMessageDialog (MainWindow.Toplevel.Window,
205
DialogFlags.DestroyWithParent,
206
Gtk.MessageType.Error, ButtonsType.Ok,
215
// TODO: Might need to do some nicer things for multiple selections (progress?)
218
} catch (Exception e) {
219
string msg = Catalog.GetPluralString ("Error saving adjusted photo", "Error saving adjusted photos",
220
editor.State.Items.Length);
221
string desc = String.Format (Catalog.GetString ("Received exception \"{0}\". Note that you have to develop RAW files into JPEG before you can edit them."),
224
HigMessageDialog md = new HigMessageDialog (MainWindow.Toplevel.Window,
225
DialogFlags.DestroyWithParent,
226
Gtk.MessageType.Error, ButtonsType.Ok,
235
private void ShowEditor (Editor editor) {
236
SetupEditor (editor);
237
current_editor = editor;
242
VBox vbox = new VBox (false, 4);
243
Label label = new Label ();
244
label.Markup = String.Format("<big><b>{0}</b></big>", editor.Label);
245
vbox.PackStart (label, false, false, 5);
247
// Optional config widget
248
Widget config = editor.ConfigurationWidget ();
249
if (config != null) {
250
vbox.PackStart (config, false, false, 0);
253
// Apply / Cancel buttons
254
HButtonBox tool_buttons = new HButtonBox ();
255
tool_buttons.LayoutStyle = ButtonBoxStyle.End;
256
tool_buttons.Spacing = 5;
257
tool_buttons.BorderWidth = 5;
258
tool_buttons.Homogeneous = false;
260
Button cancel = new Button (Stock.Cancel);
261
cancel.Clicked += HandleCancel;
262
tool_buttons.Add (cancel);
264
Button apply = new Button (editor.ApplyLabel);
265
apply.Image = new Image (GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, editor.IconName, 22, (Gtk.IconLookupFlags)0));
266
apply.Clicked += delegate { Apply (editor); };
267
tool_buttons.Add (apply);
269
// Pack it all together
270
vbox.PackEnd (tool_buttons, false, false, 0);
271
active_editor = vbox;
272
widgets.Add (active_editor);
273
active_editor.ShowAll ();
276
void HandleCancel (object sender, System.EventArgs args) {