[solang] Reworked the Editor to work with the EnlargedRenderer



commit e09329c8181a5764cb0953ff5c6abcbed0857033
Author: Debarshi Ray <rishi gnu org>
Date:   Wed Jan 13 17:54:05 2010 +0200

    Reworked the Editor to work with the EnlargedRenderer
    
    There will no longer be a separate EditorRenderer and photos can be
    directly edited in the EnlargedRenderer. Switching to a separate
    renderer to edit a photo and then move back to see it in the browser
    or enlarged mode was inserting too many mouse clicks in the user
    experience. Most photo editing applications (eg., F-Spot, GThumb,
    Shotwell) also take a similar approach.
    
    The flipping and rotating tools have been ported to this new way of
    doing things. They can be accessed from the main menu or the tool bar.
    The EditorToolbar has been removed until the other operations are
    ported.
    
    From now on GEGL is used for all operations. We are hopeful that GEGL
    will sooner than later have fast paths for rotate and reflect special
    cases (GNOME Bugzilla #592106).
    
    Use the "object-flip-horizontal", "object-flip-vertical",
    "object-rotate-left", and "object-rotate-right" icons from the theme
    instead of carrying our own ones.
    
    Dependencies:
    
    Support for GEGL 0.0.x has been dropped. Minimum required version is
    0.1.x and we try to use the C++ bindings as much as possible.
    
    Regressions:
    
    Changes made to photos can not be saved.
    
    The scale, brightness, contrast and saturation operations need to be
    ported.
    
    The undo/redo functionality has not been ported.

 README                                             |    2 +-
 configure.ac                                       |    3 +-
 data/Makefile.am                                   |    5 -
 data/flip-object-horizontal.png                    |  Bin 418 -> 0 bytes
 data/flip-object-vertical.png                      |  Bin 446 -> 0 bytes
 data/object-rotate-left.png                        |  Bin 693 -> 0 bytes
 data/object-rotate-right.png                       |  Bin 712 -> 0 bytes
 data/solang-editor.ui                              |   35 +-
 data/solang-layout.xml                             |    1 -
 data/solang.ui                                     |    9 +-
 data/stock-resize-16.png                           |  Bin 299 -> 0 bytes
 po/POTFILES.in                                     |   20 +-
 src/Makefile.am                                    |    1 -
 src/application/Makefile.am                        |    5 +-
 src/application/application.cpp                    |    4 +
 src/application/main.cpp                           |   28 -
 src/attribute/Makefile.am                          |    1 +
 src/attribute/date-manager.cpp                     |    7 -
 src/attribute/date-manager.h                       |    3 -
 src/attribute/property-manager.cpp                 |    8 -
 src/attribute/property-manager.h                   |    3 -
 src/attribute/search-basket.cpp                    |    7 -
 src/attribute/search-basket.h                      |    3 -
 src/attribute/tag-manager.cpp                      |    7 -
 src/attribute/tag-manager.h                        |    3 -
 src/common/Makefile.am                             |    8 +-
 .../edit-action.cpp => common/i-operation.cpp}     |   15 +-
 src/{edit-engine/filter.h => common/i-operation.h} |   72 +-
 src/common/i-plugin.h                              |    4 -
 src/common/operation.cpp                           |  105 +++
 .../edit-types.h => common/operation.h}            |   31 +-
 src/common/types.h                                 |   39 +-
 src/edit-engine/Makefile.am                        |   38 -
 src/edit-engine/brightness-operation.cpp           |   62 --
 src/edit-engine/buffer.cpp                         |  208 -----
 src/edit-engine/buffer.h                           |  100 --
 src/edit-engine/contrast-operation.cpp             |   63 --
 src/edit-engine/edit-engine.cpp                    |   90 --
 src/edit-engine/edit-engine.h                      |   78 --
 src/edit-engine/edit-utils.h                       |   45 -
 src/edit-engine/filter.cpp                         |   76 --
 src/edit-engine/load-file.cpp                      |   61 --
 src/edit-engine/operation.cpp                      |  110 ---
 src/edit-engine/operation.h                        |   54 --
 src/editor/Makefile.am                             |   57 +-
 src/editor/brightness-widget.cpp                   |   62 --
 src/editor/brightness-widget.h                     |   33 -
 src/editor/buffer-maker.cpp                        |   79 ++
 src/editor/{edit-action.h => buffer-maker.h}       |   36 +-
 src/editor/buffer-pixbuf-converter.cpp             |   83 ++
 .../buffer-pixbuf-converter.h}                     |   39 +-
 src/editor/contrast-widget.cpp                     |   63 --
 src/editor/contrast-widget.h                       |   33 -
 src/editor/desaturate-widget.cpp                   |   52 --
 src/editor/desaturate-widget.h                     |   33 -
 src/editor/desaturate.cpp                          |   92 --
 src/editor/edit-action-history.cpp                 |  136 ---
 src/editor/edit-action-history.h                   |   89 --
 src/editor/edit-action-widget.cpp                  |   36 -
 src/editor/edit-action-widget.h                    |   39 -
 src/editor/editable-photo.cpp                      |  255 ++----
 src/editor/editable-photo.h                        |  142 +---
 src/editor/editor-toolbar.cpp                      |   52 --
 src/editor/editor-toolbar.h                        |   58 --
 src/editor/editor.cpp                              |  602 +++++--------
 src/editor/editor.h                                |  135 +--
 .../{edit-action.cpp => flip-horiz-operation.cpp}  |   32 +-
 .../load-file.h => editor/flip-horiz-operation.h}  |   35 +-
 src/editor/flip-operation.cpp                      |  126 +++
 src/editor/flip-operation.h                        |  100 ++
 .../{desaturate.h => flip-vert-operation.cpp}      |   52 +-
 src/editor/{flip.h => flip-vert-operation.h}       |   34 +-
 src/editor/flip-widget.cpp                         |   63 --
 src/editor/flip-widget.h                           |   49 -
 src/editor/flip.cpp                                |   90 --
 src/editor/gegl-operation.cpp                      |  102 --
 src/editor/gegl-operation.h                        |   54 --
 ...{edit-action.cpp => rotate-clock-operation.cpp} |   32 +-
 src/editor/{scale.h => rotate-clock-operation.h}   |   36 +-
 ...dit-action.cpp => rotate-counter-operation.cpp} |   32 +-
 .../rotate-counter-operation.h}                    |   35 +-
 src/editor/rotate-operation.cpp                    |  117 +++
 src/editor/rotate-operation.h                      |   94 ++
 src/editor/rotate-widget.cpp                       |   63 --
 src/editor/rotate-widget.h                         |   49 -
 src/editor/rotate.cpp                              |  153 ----
 src/editor/rotate.h                                |   59 --
 src/editor/save-photos-window.cpp                  |   94 --
 src/editor/save-photos-window.h                    |   55 --
 src/editor/scale-widget.cpp                        |   52 --
 src/editor/scale-widget.h                          |   33 -
 src/editor/scale.cpp                               |   74 --
 src/editor/stock-button.cpp                        |   21 -
 src/editor/stock-button.h                          |   22 -
 src/exporter/Makefile.am                           |    1 +
 src/exporter/exporter.cpp                          |    6 -
 src/exporter/exporter.h                            |    3 -
 src/importer/importer.cpp                          |    7 -
 src/importer/importer.h                            |    3 -
 src/renderer/Makefile.am                           |    5 +-
 src/renderer/editor-renderer.cpp                   |  963 --------------------
 src/renderer/editor-renderer.h                     |  205 -----
 src/renderer/enlarged-renderer.cpp                 |   14 +-
 103 files changed, 1445 insertions(+), 5140 deletions(-)
---
diff --git a/README b/README
index 941784e..54837a2 100644
--- a/README
+++ b/README
@@ -34,7 +34,7 @@ Also, take a look at: http://en.wikipedia.org/wiki/Solang_valley
 
 Features:
 ---------
-- Browser, editor, enlarged and slideshow renderer for viewing the entire
+- Browser, enlarged and slideshow renderers for viewing the entire
   collection, editing, a single photo and slideshows respectively.
 - Folder exporter to export selected photos to a folder.
 - Date view for showing photo dates.
diff --git a/configure.ac b/configure.ac
index 1af1947..88a1fce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,7 +33,7 @@ fi
 PKG_CHECK_MODULES(BABL, [babl])
 PKG_CHECK_MODULES(DBUS, [dbus-glib-1])
 PKG_CHECK_MODULES(GDL, [gdl-1.0])
-PKG_CHECK_MODULES(GEGL, [gegl])
+PKG_CHECK_MODULES(GEGLMM, [geglmm >= 0.1.0])
 PKG_CHECK_MODULES(GTKIMAGEVIEW, [gtkimageview])
 PKG_CHECK_MODULES(GTKMM, [gtkmm-2.4 >= 2.8])
 PKG_CHECK_MODULES(TRACKER, [tracker-client-0.7])
@@ -56,7 +56,6 @@ src/Makefile
 src/application/Makefile
 src/attribute/Makefile
 src/common/Makefile
-src/edit-engine/Makefile
 src/editor/Makefile
 src/exporter/Makefile
 src/renderer/Makefile
diff --git a/data/Makefile.am b/data/Makefile.am
index fddcbe7..7f5e26a 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -17,10 +17,6 @@ pixmap_DATA = \
 	camera-photo-32.png \
 	camera-photo.svg \
 	flickr.png \
-	flip-object-horizontal.png \
-	flip-object-vertical.png \
-	object-rotate-left.png \
-	object-rotate-right.png \
 	mode-browse-16.png \
 	mode-browse-22.png \
 	mode-browse-24.png \
@@ -29,7 +25,6 @@ pixmap_DATA = \
 	mode-image-edit-16.png \
 	mode-image-edit-22.png \
 	mode-image-edit-24.png \
-	stock-resize-16.png \
 	slideshow-play-16.png \
 	slideshow-play-22.png \
 	slideshow-play-24.png \
diff --git a/data/solang-editor.ui b/data/solang-editor.ui
index 04846d4..ba61a20 100644
--- a/data/solang-editor.ui
+++ b/data/solang-editor.ui
@@ -1,31 +1,22 @@
 <!--*- xml -*-->
 <ui>
 	<menubar name="MenuBar">
-		<menu action="ActionEditMenu">
-			<placeholder name="PlaceholderUndoRedoMenus">
-			<menuitem action="ActionEditUndo"/>
-			<menuitem action="ActionEditRedo"/>
-			</placeholder>
-			<placeholder name="PlaceholderCopyPasteHistory">
-			<menuitem action="ActionCopyHistory"/>
-			<menuitem action="ActionPasteHistory"/>
-			</placeholder>
-			<placeholder name="PlaceholderOtherEditMenus">
-			<menuitem action="ActionEditSaveAs"/>
-			</placeholder>
+		<placeholder name="PlaceholderToolMenus">
+		<menu action="ActionToolsMenu">
+			<menu action="ActionToolsMenuTransformMenu">
+				<menuitem action="ActionToolsFlipHorizontal"/>
+				<menuitem action="ActionToolsFlipVertical"/>
+				<separator name="ToolsTransformSeparator0"/>
+				<menuitem action="ActionToolsRotateClockwise"/>
+				<menuitem action="ActionToolsRotateCounterclockwise"/>
+			</menu>
 		</menu>
+		</placeholder>
 	</menubar>
 	<toolbar name="ToolBar">
-		<placeholder name="PlaceholderEditToolBar">
-			<separator name="EditSeparator0"/>
-			<toolitem action="ActionEditSaveAs"/>
-			<separator name="EditSeparator1"/>
-			<toolitem action="ActionCopyHistory"/>
-			<toolitem action="ActionPasteHistory"/>
-			<separator name="EditSeparator2"/>
-			<toolitem action="ActionEditUndo"/>
-			<toolitem action="ActionEditRedo"/>
+		<placeholder name="PlaceholderToolsToolBar">
+		<toolitem action="ActionToolsRotateCounterclockwise"/>
+		<toolitem action="ActionToolsRotateClockwise"/>
 		</placeholder>
 	</toolbar>
 </ui>
-
diff --git a/data/solang-layout.xml b/data/solang-layout.xml
index 90c6128..1e4d4c6 100644
--- a/data/solang-layout.xml
+++ b/data/solang-layout.xml
@@ -17,7 +17,6 @@
                 <notebook orientation="vertical" locked="no" page="0">
                     <item name="browser-dock-item" orientation="vertical" locked="no"/>
                     <item name="enlarged-dock-item" orientation="vertical" locked="no"/>
-                    <item name="editor-dock-item" orientation="vertical" locked="no"/>
                     <placeholder name="ph-center" next-placement="center"/>
                 </notebook>
             </paned>
diff --git a/data/solang.ui b/data/solang.ui
index 24b1439..e1e22eb 100644
--- a/data/solang.ui
+++ b/data/solang.ui
@@ -17,8 +17,6 @@
 			<placeholder name="PlaceholderFullScreenMenus"/>
 			<separator name="ViewSeparator1"/>
 			<placeholder name="PlaceholderZoomMenus"/>
-			<separator name="ViewSeparator2"/>
-			<placeholder name="PlaceholderToolMenus"/>
 		</menu>
 		<placeholder name="PlaceholderViewMenus"/>
 		<menu action="ActionEditMenu">
@@ -36,6 +34,7 @@
 		<placeholder name="PlaceholderFindMenus"/>
 		<placeholder name="PlaceholderGoMenus"/>
 		<placeholder name="PlaceHolderTagMenus"/>
+		<placeholder name="PlaceholderToolMenus"/>
 		<menu action="ActionHelpMenu">
 			<menuitem action="ActionHelpAbout"/>
 		</menu>
@@ -46,12 +45,12 @@
 		<separator name="ToolBarSeparator0"/>
 		<placeholder name="PlaceholderGoToolBar"/>
 		<separator name="ToolBarSeparator1"/>
-		<placeholder name="PlaceholderEditToolBar"/>
-		<separator name="ToolBarSeparator2"/>
 		<placeholder name="PlaceholderZoomToolBar"/>
-		<separator name="ToolBarSeparator3"/>
+		<separator name="ToolBarSeparator2"/>
 		<toolitem action="ActionViewFullScreen"/>
 		<placeholder name="PlaceholderFullScreenToolBar"/>
+		<separator name="ToolBarSeparator3"/>
+		<placeholder name="PlaceholderToolsToolBar"/>
 		<separator name="ToolBarSeparatorN" expand="true"/>
 		<placeholder name="PlaceholderMiscToolBar"/>
 	</toolbar>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b4dea3a..981eb7b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,24 +12,16 @@ src/attribute/tag-new-dialog.cpp
 src/common/exif-data.cpp
 src/common/histogram-viewer.cpp
 src/common/progress-dialog.cpp
-src/edit-engine/brightness-operation.cpp
-src/edit-engine/buffer.cpp
-src/edit-engine/contrast-operation.cpp
-src/edit-engine/load-file.cpp
-src/edit-engine/operation.cpp
-src/editor/brightness-widget.cpp
-src/editor/contrast-widget.cpp
-src/editor/desaturate-widget.cpp
 src/editor/editor.cpp
-src/editor/editor-toolbar.cpp
-src/editor/flip-widget.cpp
-src/editor/rotate-widget.cpp
-src/editor/save-photos-window.cpp
-src/editor/scale-widget.cpp
+src/editor/flip-horiz-operation.cpp
+src/editor/flip-operation.cpp
+src/editor/flip-vert-operation.cpp
+src/editor/rotate-clock-operation.cpp
+src/editor/rotate-counter-operation.cpp
+src/editor/rotate-operation.cpp
 src/exporter/directory-destination.cpp
 src/exporter/exporter-dialog.cpp
 src/renderer/browser-renderer.cpp
-src/renderer/editor-renderer.cpp
 src/renderer/enlarged-renderer.cpp
 src/renderer/pagination-bar.cpp
 src/renderer/slideshow-renderer.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index c144724..38ad291 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,6 @@
 SUBDIRS = \
 	attribute \
 	common \
-	edit-engine \
 	editor \
 	exporter \
 	renderer \
diff --git a/src/application/Makefile.am b/src/application/Makefile.am
index 56c5fc9..0e0fdc7 100644
--- a/src/application/Makefile.am
+++ b/src/application/Makefile.am
@@ -20,14 +20,13 @@ solang_LDADD = \
 	$(top_builddir)/src/renderer/librenderer.la \
 	$(top_builddir)/src/attribute/libattribute.la \
 	$(top_builddir)/src/editor/libeditor.la \
-	$(top_builddir)/src/edit-engine/libeditengine.la \
 	$(top_builddir)/src/common/libcommon.la \
 	$(DBUS_LIBS) \
 	$(GTKIMAGEVIEW_LIBS) \
 	$(GTKMM_LIBS) \
 	$(GDL_LIBS) \
 	$(BABL_LIBS) \
-	$(GEGL_LIBS) \
+	$(GEGLMM_LIBS) \
 	$(TRACKER_LIBS)
 
 AM_CPPFLAGS = \
@@ -48,7 +47,7 @@ AM_CPPFLAGS = \
 	$(GTKIMAGEVIEW_CFLAGS) \
 	$(GTKMM_CFLAGS) \
 	$(GDL_CFLAGS) \
-	$(GEGL_CFLAGS) \
+	$(GEGLMM_CFLAGS) \
 	$(TRACKER_CFLAGS)
 
 AM_CXXFLAGS = \
diff --git a/src/application/application.cpp b/src/application/application.cpp
index fce913c..b7c3391 100644
--- a/src/application/application.cpp
+++ b/src/application/application.cpp
@@ -36,6 +36,7 @@
 //#include "date-manager.h"
 #include "directory-destination.h"
 //#include "directory-source.h"
+#include "editor.h"
 #include "enlarged-renderer.h"
 #include "exporter.h"
 //#include "flickr-source.h"
@@ -282,6 +283,9 @@ Application::init() throw()
 //    plugins_.insert(std::make_pair("date-manager",
 //                                   date_manager));
 
+    IPluginPtr editor(new Editor());
+    plugins_.insert(std::make_pair("editor", editor));
+
     IPluginPtr property_manager(new PropertyManager());
     plugins_.insert(std::make_pair("property-manager",
                                    property_manager));
diff --git a/src/application/main.cpp b/src/application/main.cpp
index 912ee60..cb05998 100644
--- a/src/application/main.cpp
+++ b/src/application/main.cpp
@@ -23,7 +23,6 @@
 
 #include <cstdlib>
 
-#include <gegl.h>
 #include <giomm.h>
 #include <glibmm.h>
 #include <glibmm/i18n.h>
@@ -44,38 +43,11 @@ main(int argc, char *argv[])
 
     Glib::thread_init();
     Gio::init();
-    gegl_init( &argc, &argv );
 
     Glib::set_prgname(PACKAGE_TARNAME);
     Glib::set_application_name(_(PACKAGE_NAME));
 
     Gtk::Main kit(argc, argv, true);
-#if (GEGL_MINOR_VERSION == 0 )
-    GObject *pConfig = gegl_config();
-#else
-    GeglConfig *pConfig = gegl_config();
-#endif
-    {
-        GValue cacheSize = {0};
-        g_value_init( &cacheSize, G_TYPE_INT );
-        g_value_set_int( &cacheSize, 102400 );
-        g_object_set_property( (GObject *)pConfig, "cache-size", &cacheSize );
-        g_value_unset( &cacheSize );
-    }
-    {
-        GValue quality = {0};
-        g_value_init( &quality, G_TYPE_DOUBLE );
-        g_value_set_double( &quality, 0.1 );
-        g_object_set_property( (GObject *)pConfig, "quality", &quality );
-        g_value_unset( &quality );
-    }
-    {
-        GValue swap = {0};
-        g_value_init( &swap, G_TYPE_STRING );
-        g_value_set_string( &swap, "/tmp" );
-        g_object_set_property( (GObject *)pConfig, "swap", &swap );
-        g_value_unset( &swap );
-    }
     Solang::Application application(argc, argv);
 
     application.init();
diff --git a/src/attribute/Makefile.am b/src/attribute/Makefile.am
index 9c8be7d..d680c04 100644
--- a/src/attribute/Makefile.am
+++ b/src/attribute/Makefile.am
@@ -55,6 +55,7 @@ AM_CPPFLAGS = \
 	$(DBUS_CFLAGS) \
 	$(GTKMM_CFLAGS) \
 	$(GDL_CFLAGS) \
+	$(GEGLMM_CFLAGS) \
 	$(TRACKER_CFLAGS)
 
 AM_CXXFLAGS = \
diff --git a/src/attribute/date-manager.cpp b/src/attribute/date-manager.cpp
index 912466d..5f21580 100644
--- a/src/attribute/date-manager.cpp
+++ b/src/attribute/date-manager.cpp
@@ -26,7 +26,6 @@
 #include "browser-renderer.h"
 #include "console-renderer.h"
 #include "date-manager.h"
-#include "editor-renderer.h"
 #include "engine.h"
 #include "enlarged-renderer.h"
 #include "i-renderer.h"
@@ -125,12 +124,6 @@ DateManager::visit_renderer(ConsoleRenderer & console_renderer)
 }
 
 void
-DateManager::visit_renderer(EditorRenderer & editor_renderer) throw()
-{
-    ui_hide();
-}
-
-void
 DateManager::visit_renderer(EnlargedRenderer & enlarged_renderer)
                             throw()
 {
diff --git a/src/attribute/date-manager.h b/src/attribute/date-manager.h
index 8596a3c..cc2e3b7 100644
--- a/src/attribute/date-manager.h
+++ b/src/attribute/date-manager.h
@@ -54,9 +54,6 @@ class DateManager :
         visit_renderer(ConsoleRenderer & console_renderer) throw();
 
         virtual void
-        visit_renderer(EditorRenderer & editor_renderer) throw();
-
-        virtual void
         visit_renderer(EnlargedRenderer & enlarged_renderer) throw();
 
         virtual void
diff --git a/src/attribute/property-manager.cpp b/src/attribute/property-manager.cpp
index be02919..34ae4e8 100644
--- a/src/attribute/property-manager.cpp
+++ b/src/attribute/property-manager.cpp
@@ -25,7 +25,6 @@
 #include "application.h"
 #include "browser-renderer.h"
 #include "console-renderer.h"
-#include "editor-renderer.h"
 #include "engine.h"
 #include "enlarged-renderer.h"
 #include "i-renderer.h"
@@ -133,13 +132,6 @@ PropertyManager::visit_renderer(ConsoleRenderer & console_renderer)
 }
 
 void
-PropertyManager::visit_renderer(EditorRenderer & editor_renderer)
-                                throw()
-{
-    ui_hide();
-}
-
-void
 PropertyManager::visit_renderer(EnlargedRenderer & enlarged_renderer)
                                 throw()
 {
diff --git a/src/attribute/property-manager.h b/src/attribute/property-manager.h
index 37184cb..c1d8d5c 100644
--- a/src/attribute/property-manager.h
+++ b/src/attribute/property-manager.h
@@ -58,9 +58,6 @@ public:
     visit_renderer(ConsoleRenderer & console_renderer) throw();
 
     virtual void
-    visit_renderer(EditorRenderer & editor_renderer) throw();
-
-    virtual void
     visit_renderer(EnlargedRenderer & enlarged_renderer) throw();
 
     virtual void
diff --git a/src/attribute/search-basket.cpp b/src/attribute/search-basket.cpp
index d87f1ba..b3ea2ae 100644
--- a/src/attribute/search-basket.cpp
+++ b/src/attribute/search-basket.cpp
@@ -28,7 +28,6 @@
 #include "application.h"
 #include "browser-renderer.h"
 #include "console-renderer.h"
-#include "editor-renderer.h"
 #include "engine.h"
 #include "enlarged-renderer.h"
 #include "main-window.h"
@@ -178,12 +177,6 @@ SearchBasket::visit_renderer(ConsoleRenderer & console_renderer)
 }
 
 void
-SearchBasket::visit_renderer(EditorRenderer & editor_renderer) throw()
-{
-    ui_hide();
-}
-
-void
 SearchBasket::visit_renderer(EnlargedRenderer & enlarged_renderer)
                              throw()
 {
diff --git a/src/attribute/search-basket.h b/src/attribute/search-basket.h
index 3b0e395..f9a3701 100644
--- a/src/attribute/search-basket.h
+++ b/src/attribute/search-basket.h
@@ -60,9 +60,6 @@ class SearchBasket :
         visit_renderer(ConsoleRenderer & console_renderer) throw();
 
         virtual void
-        visit_renderer(EditorRenderer & editor_renderer) throw();
-
-        virtual void
         visit_renderer(EnlargedRenderer & enlarged_renderer) throw();
 
         virtual void
diff --git a/src/attribute/tag-manager.cpp b/src/attribute/tag-manager.cpp
index 26fabc5..7be6789 100644
--- a/src/attribute/tag-manager.cpp
+++ b/src/attribute/tag-manager.cpp
@@ -26,7 +26,6 @@
 #include "application.h"
 #include "browser-renderer.h"
 #include "console-renderer.h"
-#include "editor-renderer.h"
 #include "engine.h"
 #include "enlarged-renderer.h"
 #include "i-renderer.h"
@@ -225,12 +224,6 @@ TagManager::visit_renderer(ConsoleRenderer & console_renderer) throw()
 }
 
 void
-TagManager::visit_renderer(EditorRenderer & editor_renderer) throw()
-{
-    ui_hide();
-}
-
-void
 TagManager::visit_renderer(EnlargedRenderer & enlarged_renderer)
                            throw()
 {
diff --git a/src/attribute/tag-manager.h b/src/attribute/tag-manager.h
index c68a0b5..677a8a9 100644
--- a/src/attribute/tag-manager.h
+++ b/src/attribute/tag-manager.h
@@ -56,9 +56,6 @@ public:
     visit_renderer(ConsoleRenderer & console_renderer) throw();
 
     virtual void
-    visit_renderer(EditorRenderer & editor_renderer) throw();
-
-    virtual void
     visit_renderer(EnlargedRenderer & enlarged_renderer) throw();
 
     virtual void
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 2567dd4..e0af9d4 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -37,6 +37,8 @@ libcommon_la_SOURCES = \
 	id-base.h \
 	id-repo.cpp \
 	id-repo.h \
+	i-operation.cpp \
+	i-operation.h \
 	i-photo-destination.cpp \
 	i-photo-destination.h \
 	i-photo-source.cpp \
@@ -51,6 +53,8 @@ libcommon_la_SOURCES = \
 	i-storage.h \
 	non-copyable.cpp \
 	non-copyable.h \
+	operation.cpp \
+	operation.h \
 	photo.cpp \
 	photo.h \
 	photo-search-criteria.cpp \
@@ -92,7 +96,7 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/attribute \
 	-I$(top_srcdir)/src/common \
 	-I$(top_srcdir)/src/database \
-	-I$(top_srcdir)/src/edit-engine \
+	-I$(top_srcdir)/src/editor \
 	-I$(top_srcdir)/src/importer \
 	-I$(top_srcdir)/src/renderer \
 	-I$(top_srcdir)/src/storage \
@@ -100,7 +104,7 @@ AM_CPPFLAGS = \
 	$(DBUS_CFLAGS) \
 	$(GTKMM_CFLAGS) \
 	$(GDL_CFLAGS) \
-	$(GEGL_CFLAGS) \
+	$(GEGLMM_CFLAGS) \
 	$(BABL_CFLAGS) \
 	$(TRACKER_CFLAGS)
 
diff --git a/src/editor/edit-action.cpp b/src/common/i-operation.cpp
similarity index 77%
copy from src/editor/edit-action.cpp
copy to src/common/i-operation.cpp
index 02ff1ab..d1bba6a 100644
--- a/src/editor/edit-action.cpp
+++ b/src/common/i-operation.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -18,20 +18,21 @@
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif // HAVE_CONFIG_H
 
-#include "edit-action.h"
+#include "i-operation.h"
 
 namespace Solang
 {
 
-EditAction::EditAction()
-    :NonCopyable()
+IOperation::IOperation() throw() :
+    NonCopyable(),
+    sigc::trackable()
 {
 }
 
-EditAction::~EditAction() throw()
+IOperation::~IOperation() throw()
 {
 }
 
-} //namespace Solang
+} // namespace Solang
diff --git a/src/edit-engine/filter.h b/src/common/i-operation.h
similarity index 52%
rename from src/edit-engine/filter.h
rename to src/common/i-operation.h
index 52dd570..eec9227 100644
--- a/src/edit-engine/filter.h
+++ b/src/common/i-operation.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,61 +16,57 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef SOLANG_FILTER_H
-#define SOLANG_FILTER_H
+#ifndef SOLANG_I_OPERATION_H
+#define SOLANG_I_OPERATION_H
 
 #include <glibmm.h>
+#include <sigc++/sigc++.h>
 
 #include "non-copyable.h"
-#include "edit-types.h"
+#include "types.h"
 
-namespace Solang
+namespace Gtk
 {
 
-class Filter
-    : public NonCopyable
+class Widget;
+
+} // namespace Gtk
+
+namespace Solang
 {
-    protected:
-        Filter( const EditEnginePtr &engine );
-        Filter( const EditEnginePtr &engine,
-                const Glib::ustring &xmlPath );
 
+class IOperation :
+    public NonCopyable,
+    public sigc::trackable
+{
     public:
-        virtual ~Filter() throw();
+        typedef sigc::signal<void> SignalReady;
 
-        virtual void
-        dumpXml( const Glib::ustring &path );
+        virtual
+        ~IOperation() throw() = 0;
 
-        inline GeglNodePtr
-        get_execution_node();
+        virtual BufferPtr
+        apply(const BufferPtr & buffer,
+              const ProgressObserverPtr & observer) throw() = 0;
 
-        inline EditEnginePtr
-        get_engine();
+        virtual Glib::ustring
+        get_description() const throw() = 0;
 
-        void
-        set_execution_node( GeglNodePtr node );
+        virtual Gtk::Widget *
+        get_widget() throw() = 0;
 
-        virtual Glib::ustring
-        get_name() const throw() = 0;
+        virtual SignalReady &
+        signal_ready() throw() = 0;
 
-        virtual Glib::ustring
-        get_description() const throw() = 0;
+    protected:
+        IOperation() throw();
+
+        virtual NodePtr
+        get_node(const NodePtr & root) const throw() = 0;
 
     private:
-        GeglNodePtr node_;
-        EditEnginePtr engine_;
 };
 
-inline GeglNodePtr
-Filter::get_execution_node()
-{
-    return node_;
-}
-inline EditEnginePtr
-Filter::get_engine()
-{
-    return engine_;
-}
-
 } // namespace Solang
-#endif //SOLANG_FILTER_H
+
+#endif // SOLANG_I_OPERATION_H
diff --git a/src/common/i-plugin.h b/src/common/i-plugin.h
index 6204be7..9a56154 100644
--- a/src/common/i-plugin.h
+++ b/src/common/i-plugin.h
@@ -30,7 +30,6 @@ namespace Solang
 class Application;
 class BrowserRenderer;
 class ConsoleRenderer;
-class EditorRenderer;
 class EnlargedRenderer;
 class SlideshowRenderer;
 
@@ -62,9 +61,6 @@ class IPlugin :
                        throw() = 0;
 
         virtual void
-        visit_renderer(EditorRenderer & editor_renderer) throw() = 0;
-
-        virtual void
         visit_renderer(EnlargedRenderer & editor_renderer)
                        throw() = 0;
 
diff --git a/src/common/operation.cpp b/src/common/operation.cpp
new file mode 100644
index 0000000..5de003f
--- /dev/null
+++ b/src/common/operation.cpp
@@ -0,0 +1,105 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+extern "C"
+{
+#include <babl/babl.h>
+}
+
+#include <geglmm.h>
+#include <geglmm/buffer.h>
+#include <geglmm/processor.h>
+
+#include "operation.h"
+#include "progress-observer.h"
+
+namespace Solang
+{
+
+Operation::Operation() throw() :
+    IOperation()
+{
+}
+
+Operation::~Operation() throw()
+{
+}
+
+BufferPtr
+Operation::apply(const BufferPtr & buffer,
+                 const ProgressObserverPtr & observer) throw()
+{
+    if (0 != observer)
+    {
+        observer->set_event_description(get_description());
+        observer->set_num_events(100);
+        observer->set_current_events(0);
+    }
+
+    const NodePtr root = Gegl::Node::create();
+    root->set("format", babl_format("RGB u8"));
+
+    const NodePtr buffer_source = root->new_child(
+                                      "operation",
+                                      "gegl:buffer-source");
+    gegl_node_set(buffer_source->gobj(),
+                  "buffer", buffer->gobj(),
+                  NULL);
+
+    const NodePtr operation = get_node(root);
+
+    const NodePtr buffer_sink = root->new_child("operation",
+                                                "gegl:buffer-sink");
+    GeglBuffer * output_buffer;
+    gegl_node_set(buffer_sink->gobj(),
+                  "buffer", &output_buffer,
+                  NULL);
+
+    buffer_source->link(operation)->link(buffer_sink);
+
+    gdouble progress;
+    GeglProcessor * const processor = gegl_node_new_processor(
+                                          buffer_sink->gobj(), 0);
+
+    while (true == gegl_processor_work(processor, &progress))
+    {
+        if (0 != observer)
+        {
+            observer->set_current_events(static_cast<guint64>(
+                                             progress * 100.0));
+            if (true == observer->get_stop())
+            {
+                break;
+            }
+        }
+    }
+    g_object_unref(processor);
+
+    if (0 != observer)
+    {
+        observer->reset();
+    }
+
+    return Glib::wrap(output_buffer, false);
+}
+
+} // namespace Solang
diff --git a/src/edit-engine/edit-types.h b/src/common/operation.h
similarity index 62%
rename from src/edit-engine/edit-types.h
rename to src/common/operation.h
index ab6ef8b..6af154e 100644
--- a/src/edit-engine/edit-types.h
+++ b/src/common/operation.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,26 +16,29 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef SOLANG_EDIT_TYPES_H
-#define SOLANG_EDIT_TYPES_H
+#ifndef SOLANG_OPERATION_H
+#define SOLANG_OPERATION_H
 
-#include <gegl.h>
-#include <tr1/memory>
+#include "i-operation.h"
 
 namespace Solang
 {
 
-enum EditBits
+class Operation :
+    public IOperation
 {
-    EDIT_16_BITS = 0,
-    EDIT_8_BITS
-};
+    public:
+        virtual BufferPtr
+        apply(const BufferPtr & buffer,
+              const ProgressObserverPtr & observer) throw();
 
+    protected:
+        virtual
+        ~Operation() throw() = 0;
 
-//Gegl
-typedef GeglNode * GeglNodePtr;
-typedef GeglBuffer * GeglBufferPtr;
+        Operation() throw();
+};
 
-} //namespace Solang
+} // namespace Solang
 
-#endif //SOLANG_EDIT_TYPES_H
+#endif // SOLANG_OPERATION_H
diff --git a/src/common/types.h b/src/common/types.h
index a36958e..08b8872 100644
--- a/src/common/types.h
+++ b/src/common/types.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Debarshi Ray <rishi gnu org>
+ * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
  * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
  *
  * Solang is free software: you can redistribute it and/or modify it
@@ -30,6 +30,15 @@
 #include <glibmm.h>
 #include <gtkmm.h>
 
+namespace Gegl
+{
+
+class Buffer;
+class Node;
+class Processor;
+
+} // namespace Gegl
+
 namespace Solang
 {
 
@@ -77,6 +86,7 @@ typedef std::tr1::shared_ptr<const EditablePhoto>
                                     ConstEditablePhotoPtr;
 typedef std::tr1::shared_ptr<EditablePhoto> EditablePhotoPtr;
 typedef std::vector<EditablePhotoPtr> EditablePhotoList;
+typedef std::map<Glib::ustring, EditablePhotoPtr> EditablePhotoMap;
 
 class ExifDataKey;
 typedef std::tr1::shared_ptr<ExifDataKey> ExifDataKeyPtr;
@@ -122,6 +132,11 @@ typedef std::tr1::shared_ptr<const ImporterDialog>
     ConstImporterDialogPtr;
 typedef std::tr1::shared_ptr<ImporterDialog> ImporterDialogPtr;
 
+class IOperation;
+typedef std::tr1::shared_ptr<const IOperation> ConstIOperationPtr;
+typedef std::tr1::shared_ptr<IOperation> IOperationPtr;
+typedef std::vector<IOperationPtr> OperationList;
+
 class IPhotoSource;
 typedef std::tr1::shared_ptr<const IPhotoSource> ConstIPhotoSourcePtr;
 typedef std::tr1::shared_ptr<IPhotoSource> IPhotoSourcePtr;
@@ -217,6 +232,15 @@ typedef Glib::RefPtr<Gdk::Window> WindowPtr;
 typedef GdlDockObject * DockObjectPtr;
 typedef const GdlDockObject * ConstDockObjectPtr;
 
+typedef Glib::RefPtr<const Gegl::Buffer> ConstBufferPtr;
+typedef Glib::RefPtr<Gegl::Buffer> BufferPtr;
+
+typedef Glib::RefPtr<const Gegl::Node> ConstNodePtr;
+typedef Glib::RefPtr<Gegl::Node> NodePtr;
+
+typedef Glib::RefPtr<const Gegl::Processor> ConstProcessorPtr;
+typedef Glib::RefPtr<Gegl::Processor> ProcessorPtr;
+
 typedef Glib::RefPtr<const Gio::DataInputStream>
     ConstDataInputStreamPtr;
 typedef Glib::RefPtr<Gio::DataInputStream> DataInputStreamPtr;
@@ -226,6 +250,8 @@ typedef Glib::RefPtr<Gio::File> FilePtr;
 
 typedef Glib::RefPtr<const Gtk::Action> ConstActionPtr;
 typedef Glib::RefPtr<Gtk::Action> ActionPtr;
+typedef std::vector<ConstActionPtr> ConstActionList;
+typedef std::vector<ActionPtr> ActionList;
 
 typedef Glib::RefPtr<const Gtk::ActionGroup> ConstActionGroupPtr;
 typedef Glib::RefPtr<Gtk::ActionGroup> ActionGroupPtr;
@@ -267,20 +293,9 @@ typedef std::vector<Gtk::TreeModel::Path> TreePathList;
 typedef Glib::RefPtr<const Gtk::UIManager> ConstUIManagerPtr;
 typedef Glib::RefPtr<Gtk::UIManager> UIManagerPtr;
 
-//Editing engine
-class Buffer;
-typedef std::tr1::shared_ptr<Buffer> BufferPtr;
-
 class EditEngine;
 typedef EditEngine *EditEnginePtr;
 
-class Filter;
-typedef std::tr1::shared_ptr<Filter> FilterPtr;
-
-class Operation;
-typedef std::tr1::shared_ptr<Operation> OperationPtr;
-
-
 } // namespace Solang
 
 #endif // SOLANG_TYPES_H
diff --git a/src/editor/Makefile.am b/src/editor/Makefile.am
index b2fda7f..c6b2252 100644
--- a/src/editor/Makefile.am
+++ b/src/editor/Makefile.am
@@ -1,44 +1,26 @@
 noinst_LTLIBRARIES =	libeditor.la
 
 libeditor_la_SOURCES = \
-	brightness-widget.cpp \
-	brightness-widget.h \
-	contrast-widget.cpp \
-	contrast-widget.h \
-	desaturate.cpp \
-	desaturate.h \
-	desaturate-widget.cpp \
-	desaturate-widget.h \
-	edit-action.cpp \
-	edit-action.h \
-	edit-action-history.cpp \
-	edit-action-history.h \
-	edit-action-widget.cpp \
-	edit-action-widget.h \
+	buffer-maker.cpp \
+	buffer-maker.h \
+	buffer-pixbuf-converter.cpp \
+	buffer-pixbuf-converter.h \
 	editable-photo.cpp \
 	editable-photo.h \
-	editor-toolbar.cpp \
-	editor-toolbar.h \
 	editor.cpp \
 	editor.h \
-	flip.cpp \
-	flip.h \
-	flip-widget.cpp \
-	flip-widget.h \
-	gegl-operation.cpp \
-	gegl-operation.h \
-	rotate-widget.cpp \
-	rotate-widget.h \
-	rotate.cpp \
-	rotate.h \
-	save-photos-window.cpp \
-	save-photos-window.h \
-	scale.cpp \
-	scale.h \
-	scale-widget.cpp \
-	scale-widget.h \
-	stock-button.cpp \
-	stock-button.h
+	flip-horiz-operation.cpp \
+	flip-horiz-operation.h \
+	flip-operation.cpp \
+	flip-operation.h \
+	flip-vert-operation.cpp \
+	flip-vert-operation.h \
+	rotate-clock-operation.cpp \
+	rotate-clock-operation.h \
+	rotate-counter-operation.cpp \
+	rotate-counter-operation.h \
+	rotate-operation.cpp \
+	rotate-operation.h
 
 AM_CPPFLAGS = \
 	-DPACKAGE_LOCALE_DIR=\""${datadir}/locale"\" \
@@ -48,17 +30,14 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/application \
 	-I$(top_srcdir)/src/attribute \
 	-I$(top_srcdir)/src/common \
-	-I$(top_srcdir)/src/database \
-	-I$(top_srcdir)/src/edit-engine \
 	-I$(top_srcdir)/src/editor \
-	-I$(top_srcdir)/src/importer \
+	-I$(top_srcdir)/src/exporter \
 	-I$(top_srcdir)/src/renderer \
-	-I$(top_srcdir)/src/storage \
 	$(SOLANG_CFLAGS) \
 	$(DBUS_CFLAGS) \
 	$(GTKMM_CFLAGS) \
 	$(GDL_CFLAGS) \
-	$(GEGL_CFLAGS) \
+	$(GEGLMM_CFLAGS) \
 	$(TRACKER_CFLAGS)
 
 AM_CXXFLAGS = \
diff --git a/src/editor/buffer-maker.cpp b/src/editor/buffer-maker.cpp
new file mode 100644
index 0000000..78c54ce
--- /dev/null
+++ b/src/editor/buffer-maker.cpp
@@ -0,0 +1,79 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include <geglmm.h>
+#include <geglmm/buffer.h>
+
+#include "buffer-maker.h"
+
+namespace Solang
+{
+
+BufferMaker::BufferMaker() throw() :
+    std::unary_function<const std::string &, BufferPtr>()
+{
+}
+
+BufferMaker::BufferMaker(
+    const BufferMaker & source) throw() :
+    std::unary_function<const std::string &, BufferPtr>(source)
+{
+}
+
+BufferMaker::~BufferMaker() throw()
+{
+}
+
+BufferMaker &
+BufferMaker::operator=(const BufferMaker & source) throw()
+{
+    if (this != &source)
+    {
+        std::unary_function<const std::string &, BufferPtr>
+            ::operator=(source);
+    }
+
+    return *this;
+}
+
+BufferPtr
+BufferMaker::operator()(const std::string & path) throw()
+{
+    const NodePtr root = Gegl::Node::create();
+    root->set("format", babl_format("RGB u8"));
+
+    const NodePtr load = root->new_child("operation",
+                                         "gegl:load");
+    gegl_node_set(load->gobj(), "path", path.c_str(), NULL);
+
+    const NodePtr buffer_sink = root->new_child("operation",
+                                                "gegl:buffer-sink");
+    GeglBuffer * buffer;
+    gegl_node_set(buffer_sink->gobj(), "buffer", &buffer, NULL);
+
+    load->link(buffer_sink);
+    buffer_sink->process();
+
+    return Glib::wrap(buffer, false);
+}
+
+} // namespace Solang
diff --git a/src/editor/edit-action.h b/src/editor/buffer-maker.h
similarity index 57%
rename from src/editor/edit-action.h
rename to src/editor/buffer-maker.h
index fd25eeb..4e85fdf 100644
--- a/src/editor/edit-action.h
+++ b/src/editor/buffer-maker.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,34 +16,34 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef SOLANG_I_EDIT_ACTION_H
-#define SOLANG_I_EDIT_ACTION_H
+#ifndef SOLANG_BUFFER_MAKER_H
+#define SOLANG_BUFFER_MAKER_H
+
+#include <functional>
+#include <string>
 
-#include "error.h"
-#include "non-copyable.h"
 #include "types.h"
 
 namespace Solang
 {
 
-class EditAction :
-        public NonCopyable
+class BufferMaker :
+    public std::unary_function<const std::string &, BufferPtr>
 {
-    protected:
-        EditAction();
-
     public:
-        virtual ~EditAction() throw();
+        BufferMaker() throw();
+
+        BufferMaker(const BufferMaker & source) throw();
 
-        virtual void execute(
-                    EditablePhoto &photo) throw(Error) = 0;
+        ~BufferMaker() throw();
 
-        virtual void reverse(
-                    EditablePhoto &photo) throw(Error) = 0;
+        BufferMaker &
+        operator=(const BufferMaker & source) throw();
 
-        virtual EditActionPtr clone() = 0;
+        BufferPtr
+        operator()(const std::string & path) throw();
 };
 
-} //namespace Solang
+} // namespace Solang
 
-#endif // SOLANG_I_EDIT_ACTION_H
+#endif // SOLANG_BUFFER_MAKER_H
diff --git a/src/editor/buffer-pixbuf-converter.cpp b/src/editor/buffer-pixbuf-converter.cpp
new file mode 100644
index 0000000..306a8b9
--- /dev/null
+++ b/src/editor/buffer-pixbuf-converter.cpp
@@ -0,0 +1,83 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include <geglmm.h>
+#include <geglmm/buffer.h>
+
+#include "buffer-pixbuf-converter.h"
+
+namespace Solang
+{
+
+BufferPixbufConverter::BufferPixbufConverter() throw() :
+    std::unary_function<const BufferPtr &, PixbufPtr>()
+{
+}
+
+BufferPixbufConverter::BufferPixbufConverter(
+    const BufferPixbufConverter & source) throw() :
+    std::unary_function<const BufferPtr &, PixbufPtr>(source)
+{
+}
+
+BufferPixbufConverter::~BufferPixbufConverter() throw()
+{
+}
+
+BufferPixbufConverter &
+BufferPixbufConverter::operator=(const BufferPixbufConverter & source)
+                                 throw()
+{
+    if (this != &source)
+    {
+        std::unary_function<const BufferPtr &, PixbufPtr>
+            ::operator=(source);
+    }
+
+    return *this;
+}
+
+PixbufPtr
+BufferPixbufConverter::operator()(const BufferPtr & buffer) throw()
+{
+    const NodePtr root = Gegl::Node::create();
+    root->set("format", babl_format("RGB u8"));
+
+    const NodePtr buffer_source = root->new_child(
+                                      "operation",
+                                      "gegl:buffer-source");
+    gegl_node_set(buffer_source->gobj(),
+                  "buffer", buffer->gobj(),
+                  NULL);
+
+    const NodePtr save_pixbuf = root->new_child("operation",
+                                         "gegl:save-pixbuf");
+    GdkPixbuf * pixbuf;
+    gegl_node_set(save_pixbuf->gobj(), "pixbuf", &pixbuf, NULL);
+
+    buffer_source->link(save_pixbuf);
+    save_pixbuf->process();
+
+    return Glib::wrap(pixbuf, false);
+}
+
+} // namespace Solang
diff --git a/src/edit-engine/brightness-operation.h b/src/editor/buffer-pixbuf-converter.h
similarity index 52%
rename from src/edit-engine/brightness-operation.h
rename to src/editor/buffer-pixbuf-converter.h
index f20606a..34ce363 100644
--- a/src/edit-engine/brightness-operation.h
+++ b/src/editor/buffer-pixbuf-converter.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,37 +16,34 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "filter.h"
+#ifndef SOLANG_BUFFER_PIXBUF_CONVERTER_H
+#define SOLANG_BUFFER_PIXBUF_CONVERTER_H
 
-#ifndef SOLANG_BRIGHTNESS_OPERATION_H
-#define SOLANG_BRIGHTNESS_OPERATION_H
+#include <functional>
+
+#include "types.h"
 
 namespace Solang
 {
 
-class BrightnessOperation
-        : public Filter
+class BufferPixbufConverter :
+    public std::unary_function<const BufferPtr &, PixbufPtr>
 {
     public:
-        BrightnessOperation( const EditEnginePtr &engine,
-                  double fraction );
-
-        BrightnessOperation( const EditEnginePtr &engine,
-                  const Glib::ustring &xmlPath );
+        BufferPixbufConverter() throw();
 
-        ~BrightnessOperation() throw();
+        BufferPixbufConverter(const BufferPixbufConverter & source)
+                              throw();
 
-        virtual Glib::ustring
-        get_name() const throw();
+        ~BufferPixbufConverter() throw();
 
-        virtual Glib::ustring
-        get_description() const throw();
+        BufferPixbufConverter &
+        operator=(const BufferPixbufConverter & source) throw();
 
-    private:
-       double fraction_;
+        PixbufPtr
+        operator()(const BufferPtr & buffer) throw();
 };
 
+} // namespace Solang
 
-}//namespace Solang
-
-#endif //SOLANG_BRIGHTNESS_OPERATION_H
+#endif // SOLANG_BUFFER_PIXBUF_CONVERTER_H
diff --git a/src/editor/editable-photo.cpp b/src/editor/editable-photo.cpp
index 214c990..5108586 100644
--- a/src/editor/editable-photo.cpp
+++ b/src/editor/editable-photo.cpp
@@ -1,5 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
  *
  * Solang is free software: you can redistribute it and/or modify it
@@ -18,233 +19,121 @@
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif // HAVE_CONFIG_H
 
-extern "C"
-{
-#include <babl/babl.h>
-}
-
-
-#include <iostream>
-#include <gegl.h>
-#include <glibmm/i18n.h>
-#include <giomm.h>
+#include <geglmm.h>
+#include <geglmm/buffer.h>
 
-#include "buffer.h"
-#include "edit-action.h"
+#include "buffer-maker.h"
+#include "buffer-pixbuf-converter.h"
 #include "editable-photo.h"
+#include "i-operation.h"
+#include "photo.h"
 
 namespace Solang
 {
 
-EditablePhoto::EditablePhoto( const PhotoPtr &photo ) throw()
-    :photo_( photo ),
-    buffer_( 0 ),
-    editBuffer_( ),
-    isDirty_( false ),
-//    image_(),
-    toSave_( false )
+EditablePhoto::EditablePhoto(const PhotoPtr & photo,
+                             const ProgressObserverPtr & observer) throw() :
+    buffer_(0),
+    photo_(photo),
+    pixbuf_(0),
+    pending_(),
+    observer_(observer),
+    applyEnd_(),
+    threadPool_(1, false)
 {
-    setup_photo_for_edit();
+    applyEnd_.connect(sigc::mem_fun(*this,
+                                    &EditablePhoto::on_apply_end));
 }
 
-EditablePhoto::~EditablePhoto()
+EditablePhoto::~EditablePhoto() throw()
 {
 }
 
 void
-EditablePhoto::set_photo( const PhotoPtr &photo ) throw()
-{
-    photo_ = photo;
-    setup_photo_for_edit();
-}
-
-const PixbufPtr
-EditablePhoto::get_buffer() const throw()
+EditablePhoto::apply_async(const IOperationPtr & operation,
+                           const SlotAsyncReady & slot) throw()
 {
-#ifdef FULL_GEGL
-    if( !editBuffer_->is_empty()
-        && isDirty_ )
-    {
-        buffer_ = editBuffer_->get_pixbuf();
-        isDirty_ = false;
-    }
-#endif
-    return buffer_;
-}
+    const SlotAsyncReadyPtr slot_copy(new SlotAsyncReady(slot));
 
-void
-EditablePhoto::set_buffer(const PixbufPtr &buffer, bool sync )
-{
-    buffer_ = buffer;
-//    if( photo_->get_buffer() )
-    {
-        photo_->set_buffer( buffer_ );
-    }
-    if( sync && editBuffer_ && !isDirty_ )
+    pending_.push(std::make_pair(operation, slot_copy));
+    if (1 < pending_.size())
     {
-        editBuffer_ = pixbuf_to_edit_buffer();
+        return;
     }
-}
 
-void
-EditablePhoto::set_edit_buffer( const BufferPtr &buffer ) throw()
-{
-    editBuffer_ = buffer;
-    //isDirty_ = true;
+    apply_begin();
 }
 
-void
-EditablePhoto::save( Engine &engine ) throw(Error)
-{
-    if( photo_->get_content_type().find("jpeg") != 0 ) //JPEG
-    {
-        std::vector<Glib::ustring> keys;
-        keys.push_back("quality");
-        std::vector<Glib::ustring> values;
-        values.push_back("100");
-
-        gchar *buf = NULL;
-        gsize size = 0L;
-
-        buffer_->save_to_buffer( buf, size, "jpeg", keys, values );
-
-//        Exiv2::Image::AutoPtr target = Exiv2::ImageFactory::open(
-//                                         (Exiv2::byte *)buf, size );
-//        target->setMetadata( *image_ );
-//        target->writeMetadata();
-
-//        Exiv2::FileIo file( "/tmp/test.jpg" );
-//        file.open("w");
-//        file.write( target->io() );
-//        file.close();
-
-//        Glib::RefPtr<Gio::File> src = Gio::File::create_for_path(
-//                                            "/tmp/test.jpg");
-//        Glib::RefPtr<Gio::File> dest = Gio::File::create_for_uri(
-//                                           photo_->get_uri());
-//        src->copy( dest, Gio::FILE_COPY_OVERWRITE );
-    }
-}
 
 void
-EditablePhoto::setup_photo_for_edit( ) throw()
+EditablePhoto::apply_begin() throw()
 {
-    if( !photo_ )
-        return;
-
-//    image_ = Exiv2::ImageFactory::open(
-//                 Glib::filename_from_uri(photo_->get_uri()));
-
-//    image_->readMetadata();
-
-#if 0
+    const std::pair<IOperationPtr, SlotAsyncReadyPtr> & current
+        = pending_.front();
 
-    gchar *buf;
-
-//    image_->io()->read( (Exiv2::byte *)buf, image_->io()->size());
-
-    Glib::Ref<Gdk::PixbufLoader> loader = Gdk::PixbufLoader::create();
-
-//    loader->write( buf, image_->io()->size() );
-
-    buffer_ = loader->get_pixbuf();
-#endif
-
-//CREATE
-    buffer_ = photo_->get_buffer();
-    if( ! buffer_ )
-    {
-        buffer_ = Gdk::Pixbuf::create_from_file(
-                      Glib::filename_from_uri(photo_->get_uri()));
-    }
+    threadPool_.push(sigc::bind(
+                         sigc::mem_fun(*this,
+                                       &EditablePhoto::apply_worker),
+                         current.first));
 }
 
 void
-EditablePhoto::set_to_save( bool value ) throw()
+EditablePhoto::apply_worker(const IOperationPtr & operation)
+                            throw(Glib::Thread::Exit)
 {
-    toSave_ = value;
-}
-
-void
-EditablePhoto::apply_action( const EditActionPtr &action ) throw(Error)
-{
-    try
+    if (0 == buffer_)
     {
-        action->execute( *this );
+        std::string path;
+        try
+        {
+            path = Glib::filename_from_uri(photo_->get_uri());
+        }
+        catch (const Glib::ConvertError & e)
+        {
+            g_warning("%s", e.what().c_str());
+            throw Glib::Thread::Exit();
+        }
+
+        BufferMaker buffer_maker;
+        buffer_ = buffer_maker(path);
     }
-    catch( Error & e )
-    {
-        e.add_call_info( __FUNCTION__, __FILE__, __LINE__ );
-        throw;
-    }
-    appliedActions_.insert( action );
-}
 
-void
-EditablePhoto::undo_last_action( ) throw(Error)
-{
-    if( !appliedActions_.is_undo_possible() )
-        return;
-
-    EditActionList actions = appliedActions_.undo_actions( 1 );
-
-    EditActionPtr action = *actions.begin();
-    try
-    {
-        action->reverse( *this );
-    }
-    catch( Error & e )
-    {
-        e.add_call_info( __FUNCTION__, __FILE__, __LINE__ );
-        throw;
-    }
-    if( actions.empty() )
-        photo_->set_has_unsaved_data( false );
+    buffer_ = operation->apply(buffer_, observer_);
+g_warning("done op");
+    BufferPixbufConverter buffer_pixbuf_converter;
+    pixbuf_ = buffer_pixbuf_converter(buffer_);
+g_warning("done pixbuf");
+    applyEnd_.emit();
 }
 
 void
-EditablePhoto::redo_last_action( ) throw(Error)
+EditablePhoto::on_apply_end() throw()
 {
-    if( !appliedActions_.is_redo_possible() )
-        return;
+    const std::pair<IOperationPtr, SlotAsyncReadyPtr> current
+        = pending_.front();
 
-    EditActionList actions = appliedActions_.redo_actions( 1 );
+    pending_.pop();
+    photo_->set_buffer(pixbuf_);
 
-    EditActionPtr action = *actions.begin();
-    try
+    if (0 != current.second && 0 != *current.second)
     {
-        action->execute( *this );
+        (*current.second)();
     }
-    catch( Error & e )
+
+    if (true == pending_.empty())
     {
-        e.add_call_info( __FUNCTION__, __FILE__, __LINE__ );
-        throw;
+        return;
     }
+
+    apply_begin();
 }
 
-BufferPtr
-EditablePhoto::pixbuf_to_edit_buffer() throw()
+PhotoPtr &
+EditablePhoto::get_photo() throw()
 {
-    bool hasAlpha = buffer_->get_has_alpha();
-    const guint8 channels = 3;//(hasAlpha)?4:3;
-    GeglRectangle rect;
-    rect.width = buffer_->get_width();
-    rect.height = buffer_->get_height();
-    rect.x = rect.y = 0;
-    Babl *fmt = babl_format( "RGB u8" );
-                //(hasAlpha) ?"RGBA u8" : "RGB u8" );
-    size_t size = rect.width * rect.height *channels;
-    gpointer pMem = g_new0( guint8,  size );
-    ::memcpy( pMem, (void *)(buffer_->get_pixels()), size );
-    GeglBufferPtr gBuf = gegl_buffer_new( &rect, fmt );
-    gegl_buffer_set( gBuf, //gegl buffer
-                    &rect, //extent
-                    fmt, //format
-                    pMem,
-                    buffer_->get_rowstride() );
-    return BufferPtr ( new Buffer( gBuf ) );
+    return photo_;
 }
 
-} //namespace Solang
+} // namespace Solang
diff --git a/src/editor/editable-photo.h b/src/editor/editable-photo.h
index b9b2adb..43c45e8 100644
--- a/src/editor/editable-photo.h
+++ b/src/editor/editable-photo.h
@@ -1,5 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
  *
  * Solang is free software: you can redistribute it and/or modify it
@@ -19,10 +20,13 @@
 #ifndef SOLANG_EDITABLE_PHOTO_H
 #define SOLANG_EDITABLE_PHOTO_H
 
-#include <gdkmm.h>
+#include <queue>
+#include <utility>
+#include <tr1/memory>
+
+#include <glibmm.h>
+#include <sigc++/sigc++.h>
 
-#include "edit-action-history.h"
-#include "engine.h"
 #include "types.h"
 
 namespace Solang
@@ -31,131 +35,53 @@ namespace Solang
 class EditablePhoto
 {
     public:
-        class Searcher
-        {
-            public:
-                Searcher( const PhotoPtr &photo )
-                    :photo_( photo )
-                {
-                }
-
-                bool operator ()( const EditablePhotoPtr &lhs )
-                {
-                    return lhs->get_photo()->get_uri()
-                                == photo_->get_uri();
-                }
-
-            private:
-                PhotoPtr photo_;
-        };
-
-    public:
-        EditablePhoto( const PhotoPtr &photo ) throw();
-        ~EditablePhoto();
+        typedef sigc::slot<void> SlotAsyncReady;
 
-        inline const PhotoPtr &
-        get_photo() const throw();
+        typedef std::tr1::shared_ptr<SlotAsyncReady>
+            SlotAsyncReadyPtr;
 
-        void
-        set_photo( const PhotoPtr & ) throw();
-
-        const PixbufPtr
-        get_buffer() const throw();
+        typedef std::queue<std::pair<IOperationPtr,
+                                     SlotAsyncReadyPtr> >
+            PendingOperationQueue;
 
-        void
-        set_buffer(const PixbufPtr &, bool sync = true);
+        EditablePhoto(const PhotoPtr & photo,
+                      const ProgressObserverPtr & observer) throw();
 
-        inline const BufferPtr
-        get_edit_buffer() throw();
+        ~EditablePhoto() throw();
 
         void
-        set_edit_buffer( const BufferPtr &buffer ) throw();
+        apply_async(const IOperationPtr & operation,
+                    const SlotAsyncReady & slot) throw();
 
-//        inline Exiv2::ExifData &  //Modifiable
-//        get_exif_data() throw();
-
-//        inline Exiv2::XmpData &  //Modifiable
-//        get_xmp_data() throw();
+        PhotoPtr &
+        get_photo() throw();
 
+    private:
         void
-        save( Engine &engine ) throw(Error);
-
-        inline bool
-        get_to_save() const throw();
+        apply_begin() throw();
 
         void
-        set_to_save( bool ) throw();
+        apply_worker(const IOperationPtr & operation)
+                     throw(Glib::Thread::Exit);
 
         void
-        apply_action( const EditActionPtr &action ) throw(Error);
+        on_apply_end() throw();
 
-        void
-        undo_last_action( ) throw(Error);
+        BufferPtr buffer_;
 
-        void
-        redo_last_action( ) throw(Error);
+        PhotoPtr photo_;
 
-        inline const EditActionHistory &
-        get_history() const throw();
+        PixbufPtr pixbuf_;
 
-    private:
+        PendingOperationQueue pending_;
 
-        void
-        setup_photo_for_edit() throw();
+        ProgressObserverPtr observer_;
 
-        BufferPtr
-        pixbuf_to_edit_buffer() throw();
+        Glib::Dispatcher applyEnd_;
 
-        PhotoPtr photo_;
-        mutable PixbufPtr buffer_;
-        mutable BufferPtr editBuffer_;
-        mutable bool isDirty_;
-//        Exiv2::Image::AutoPtr image_;
-        bool toSave_;
-        EditActionHistory appliedActions_;
+        Glib::ThreadPool threadPool_;
 };
 
-inline const PhotoPtr &
-EditablePhoto::get_photo() const throw()
-{
-    return photo_;
-}
-
-inline const BufferPtr
-EditablePhoto::get_edit_buffer() throw()
-{
-#if 0
-    if( !editBuffer_ )
-    {
-        editBuffer_ = pixbuf_to_edit_buffer();
-    }
-#endif
-    return pixbuf_to_edit_buffer();
-}
-
-//inline Exiv2::ExifData &  //Modifiable
-//EditablePhoto::get_exif_data() throw()
-//{
-//    return image_->exifData();
-//}
-
-//inline Exiv2::XmpData &  //Modifiable
-//EditablePhoto::get_xmp_data() throw()
-//{
-//    return image_->xmpData();
-//}
-
-inline bool
-EditablePhoto::get_to_save() const throw()
-{
-    return toSave_;
-}
-
-inline const EditActionHistory &
-EditablePhoto::get_history() const throw()
-{
-    return appliedActions_;
-}
+} // namespace Solang
 
-} //namespace Solang
-#endif
+#endif // SOLANG_EDITABLE_PHOTO_H
diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp
index 0c22dab..a2c2892 100644
--- a/src/editor/editor.cpp
+++ b/src/editor/editor.cpp
@@ -1,5 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
  *
  * Solang is free software: you can redistribute it and/or modify it
@@ -18,483 +19,348 @@
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif // HAVE_CONFIG_H
 
-#include <algorithm>
+#include <geglmm.h>
 #include <glibmm/i18n.h>
-#include <iostream>
 
 #include "application.h"
-#include "buffer.h"
-#include "cursor-changer.h"
-#include "edit-action.h"
-#include "edit-engine.h"
 #include "editable-photo.h"
 #include "editor.h"
-#include "flip.h"
-#include "gegl-operation.h"
-#include "main-window.h"
-#include "operation.h"
-#include "rotate.h"
-#include "save-photos-window.h"
+#include "flip-horiz-operation.h"
+#include "flip-vert-operation.h"
+#include "i-renderer.h"
+#include "non-copyable.h"
+#include "rotate-clock-operation.h"
+#include "rotate-counter-operation.h"
 
 namespace Solang
 {
 
-static const std::string uiFile
-    = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/ui/"
-          PACKAGE_TARNAME"-editor.ui";
+class IOperationFactory :
+    public NonCopyable
+{
+    public:
+        virtual
+        ~IOperationFactory() throw() = 0;
 
-static const std::string flipHorzImageFile
-    = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/pixmaps/flip-object-horizontal.png";
+        virtual IOperation *
+        create() throw() = 0;
 
-static const std::string flipVertImageFile
-    = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/pixmaps/flip-object-vertical.png";
+    protected:
+        IOperationFactory() throw();
+};
 
-static const std::string rotateLeftFile
-    = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/pixmaps/object-rotate-left.png";
+IOperationFactory::IOperationFactory() throw() :
+    NonCopyable()
+{
+}
 
-static const std::string rotateRightFile
-    = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/pixmaps/object-rotate-right.png";
+IOperationFactory::~IOperationFactory() throw()
+{
+}
 
-static const std::string scaleFile
-    = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/pixmaps/stock-resize-16.png";
+template <typename T>
+class OperationFactory :
+    public IOperationFactory
+{
+    public:
+        OperationFactory() throw();
+
+        virtual
+        ~OperationFactory() throw();
+
+        virtual T *
+        create() throw();
+};
+
+template <typename T>
+OperationFactory<T>::OperationFactory() throw() :
+    IOperationFactory()
+{
+}
 
-Editor::Editor( )
-    :application_( NULL ),
-    modifiedPhotos_(),
-    mutex_(),
-    actionGroup_( Gtk::ActionGroup::create(
+template <typename T>
+OperationFactory<T>::~OperationFactory() throw()
+{
+}
+
+template <typename T>
+T *
+OperationFactory<T>::create() throw()
+{
+    return new T();
+}
+
+const std::string Editor::uiFile_
+    = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/ui/"
+          PACKAGE_TARNAME"-editor.ui";
+
+Editor::Editor() throw() :
+    Plugin(),
+    application_(),
+    actionGroup_(Gtk::ActionGroup::create(
                      Glib::ustring::compose("%1:%2",
                                             __FILE__,
                                             __LINE__))),
-    iconFactory_( Gtk::IconFactory::create()),
-    uiID_( 0 ),
-    actionPerformed_(),
+    uiID_(0),
+    editablePhotos_(),
     currentPhoto_(),
-    engine_( NULL )
+    signalRendererChanged_()
 {
-    Gtk::IconSource icon_source;
-
-    Gtk::IconSet icon_set_flip_horz;
-    icon_source.set_filename( flipHorzImageFile );
-    icon_source.set_size(Gtk::IconSize(16));
-    icon_set_flip_horz.add_source(icon_source);
-    iconFactory_->add(Gtk::StockID(PACKAGE_TARNAME"-flip-horz"),
-                    icon_set_flip_horz);
-
-    Gtk::IconSet icon_set_flip_vert;
-    icon_source.set_filename( flipVertImageFile );
-    icon_source.set_size(Gtk::IconSize(16));
-    icon_set_flip_vert.add_source(icon_source);
-    iconFactory_->add(Gtk::StockID(PACKAGE_TARNAME"-flip-vert"),
-                    icon_set_flip_vert);
-
-    Gtk::IconSet icon_set_rotate_left;
-    icon_source.set_filename( rotateLeftFile );
-    icon_source.set_size(Gtk::IconSize(16));
-    icon_set_rotate_left.add_source(icon_source);
-    iconFactory_->add(Gtk::StockID(PACKAGE_TARNAME"-rotate-left"),
-                    icon_set_rotate_left);
-
-    Gtk::IconSet icon_set_rotate_right;
-    icon_source.set_filename( rotateRightFile );
-    icon_source.set_size(Gtk::IconSize(16));
-    icon_set_rotate_right.add_source(icon_source);
-    iconFactory_->add(Gtk::StockID(PACKAGE_TARNAME"-rotate-right"),
-                    icon_set_rotate_right);
-
-    Gtk::IconSet icon_set_scale;
-    icon_source.set_filename( scaleFile );
-    icon_source.set_size(Gtk::IconSize(16));
-    icon_set_scale.add_source(icon_source);
-    iconFactory_->add(Gtk::StockID(PACKAGE_TARNAME"-scale"),
-                    icon_set_scale);
-
-    iconFactory_->add_default();
-
     actionGroup_->add(
         Gtk::Action::create(
-            "ActionEditMenu", _("_Edit")));
-
-     actionGroup_->add(
-         Gtk::Action::create(
-            "ActionEditUndo",
-            Gtk::Stock::UNDO,
-            _("Undo"),
-            _("Undo last action")),
-            Gtk::AccelKey("<control>z"),
-            sigc::mem_fun(*this, &Editor::on_action_undo));
-
-     actionGroup_->add(
-         Gtk::Action::create(
-            "ActionEditRedo",
-            Gtk::Stock::REDO,
-            _("Redo"),
-            _("Redo last action")),
-            Gtk::AccelKey("<control>y"),
-            sigc::mem_fun(*this, &Editor::on_action_redo));
+            "ActionToolsMenu", _("T_ools")));
 
     actionGroup_->add(
-         Gtk::Action::create(
-            "ActionCopyHistory",
-            Gtk::Stock::COPY,
-            _("Copy Actions"),
-            _("Copy actions applied to this photo")),
-            Gtk::AccelKey("<control>c"),
-            sigc::mem_fun(*this, &Editor::on_action_copy_actions));
+        Gtk::Action::create(
+            "ActionToolsMenuTransformMenu", _("_Transform")));
 
     actionGroup_->add(
-         Gtk::Action::create(
-            "ActionPasteHistory",
-            Gtk::Stock::PASTE,
-            _("Paste Actions"),
-            _("Paste copied actions")),
-            Gtk::AccelKey("<control>v"),
-            sigc::mem_fun(*this, &Editor::on_action_paste_actions));
-
-#if 0
+        Gtk::Action::create_with_icon_name(
+            "ActionToolsFlipHorizontal",
+            "object-flip-horizontal",
+            _("Flip _Horizontal"),
+            _("Mirror the photo horizontally")),
+        Gtk::AccelKey(""),
+        sigc::bind(
+            sigc::mem_fun(*this, &Editor::on_action_edit_photo),
+            IOperationFactoryPtr(
+                new OperationFactory<FlipHorizOperation>)));
 
     actionGroup_->add(
-         Gtk::Action::create(
-            "ActionEditFlipHorizontal",
-            Gtk::StockID(PACKAGE_TARNAME"-flip-horz"),
-            _("Flip _Horizontally"),
-            _("Flip the selected image(s) horizontally")),
-            Gtk::AccelKey(""),
-            sigc::mem_fun(*this, &Editor::on_action_flip_horz));
-
-     actionGroup_->add(
-         Gtk::Action::create(
-            "ActionEditFlipVertical",
-            Gtk::StockID(PACKAGE_TARNAME"-flip-vert"),
-            _("Flip _Vertically"),
-            _("Flip the selected image(s) vertically")),
-            Gtk::AccelKey(""),
-            sigc::mem_fun(*this, &Editor::on_action_flip_vert));
-
-     actionGroup_->add(
-         Gtk::Action::create(
-            "ActionEditRotateClockwise",
-            Gtk::StockID(PACKAGE_TARNAME"-rotate-right"),
-            _("Rotate _Clockwise"),
-            _("Rotate the selected image(s) clockwise")),
-            Gtk::AccelKey(""),
-            sigc::mem_fun(*this, &Editor::on_action_rotate_right));
-
-     actionGroup_->add(
-         Gtk::Action::create(
-            "ActionEditRotateCounterClockwise",
-            Gtk::StockID(PACKAGE_TARNAME"-rotate-left"),
-            _("Rotate C_ounter Clockwise"),
-            _("Rotate the selected image(s) counter-clockwise")),
-            Gtk::AccelKey(""),
-            sigc::mem_fun(*this, &Editor::on_action_rotate_left));
-
-     actionGroup_->add(
-         Gtk::Action::create(
-             "ActionEditScale",
-            Gtk::StockID(PACKAGE_TARNAME"-scale"),
-            _("Sca_le"),
-            _("Scale/resize the selected image(s)")),
-            Gtk::AccelKey(""),
-            sigc::mem_fun(*this, &Editor::on_action_scale));
-#endif
-     actionGroup_->add(
-         Gtk::Action::create(
-             "ActionEditSaveAs", Gtk::Stock::SAVE,
-            _("_Save")),
-            Gtk::AccelKey(""),
-            sigc::mem_fun(*this, &Editor::on_action_save));
+        Gtk::Action::create_with_icon_name(
+            "ActionToolsFlipVertical",
+            "object-flip-vertical",
+            _("Flip _Vertical"),
+            _("Mirror the photo vertically")),
+        Gtk::AccelKey(""),
+        sigc::bind(
+            sigc::mem_fun(*this, &Editor::on_action_edit_photo),
+            IOperationFactoryPtr(
+                new OperationFactory<FlipVertOperation>)));
 
+    actionGroup_->add(
+        Gtk::Action::create_with_icon_name(
+            "ActionToolsRotateClockwise",
+            "object-rotate-right",
+            _("_Rotate Clockwise"),
+            _("Rotate the photo 90 degrees to the right")),
+        Gtk::AccelKey("<control>R"),
+        sigc::bind(
+            sigc::mem_fun(*this, &Editor::on_action_edit_photo),
+            IOperationFactoryPtr(
+                new OperationFactory<RotateClockOperation>)));
 
+    actionGroup_->add(
+        Gtk::Action::create_with_icon_name(
+            "ActionToolsRotateCounterclockwise",
+            "object-rotate-left",
+            _("Rotate Counterc_lockwise"),
+            _("Rotate the photo 90 degrees to the left")),
+        Gtk::AccelKey("<control><shift>R"),
+        sigc::bind(
+            sigc::mem_fun(*this, &Editor::on_action_edit_photo),
+            IOperationFactoryPtr(
+                new OperationFactory<RotateCounterOperation>)));
 }
 
 Editor::~Editor() throw()
 {
-    iconFactory_->remove_default();
+    //g_object_unref(dockItem_);
 }
 
 void
-Editor::apply( const EditActionPtr &action,
-                const EditablePhotoPtr &photo) throw(Error)
+Editor::init(Application & application) throw()
 {
-    if( !currentPhoto_ )
-        return;
-
+    Gegl::init(0, 0);
+    application_ = &application;
+
+    Engine & engine = application.get_engine();
+    signalSelectionChanged_
+        = engine.selection_changed().connect(
+              sigc::mem_fun(*this,
+                            &Editor::on_selection_changed));
+
+    RendererRegistry & renderer_registry
+                           = application.get_renderer_registry();
+    signalRendererChanged_
+        = renderer_registry.changed().connect(
+              sigc::mem_fun(*this,
+                            &Editor::on_renderer_changed));
+
+    MainWindow & main_window = application.get_main_window();
+    const UIManagerPtr & ui_manager = main_window.get_ui_manager();
+
+    uiID_ = ui_manager->add_ui_from_file(uiFile_);
+    if (0 == uiID_)
     {
-        currentPhoto_->apply_action( action );
-
-        Glib::Mutex::Lock lock( mutex_ );
-        if( !photo->get_photo()->get_has_unsaved_data() )
-        {
-            EditablePhotoList::iterator ptr = std::find_if(
-                    modifiedPhotos_.begin(), modifiedPhotos_.end(),
-                    EditablePhoto::Searcher( photo->get_photo() ) );
-            if( ptr == modifiedPhotos_.end() )
-                modifiedPhotos_.push_back( currentPhoto_ );
-            currentPhoto_->get_photo()->set_has_unsaved_data( true );
-        }
+        // FIXME: error condition.
     }
-    actionPerformed_.emit();
-}
 
-void
-Editor::apply( const EditActionPtr &action)
-{
-    Glib::ThreadPool & thread_pool
-                    = application_->get_thread_pool();
-    thread_pool.push(sigc::bind(
-            sigc::mem_fun2( *this,
-                &Editor::apply_action),
-                    action, currentPhoto_ ));
-    //apply( action, currentPhoto_ );
+    ui_manager->insert_action_group(actionGroup_);
+
+    initialized_.emit(*this);
 }
 
 void
-Editor::apply( const EditActionPtr &action,
-               const EditablePhotoList &photos) throw(Error)
+Editor::final(Application & application) throw()
 {
-    for( EditablePhotoList::const_iterator photo = photos.begin();
-                            photo != photos.end(); photo++ )
-    {
-        apply( action, *photo );
-    }
+    MainWindow & main_window = application.get_main_window();
+    const UIManagerPtr & ui_manager = main_window.get_ui_manager();
+
+    ui_manager->remove_action_group(actionGroup_);
+    ui_manager->remove_ui(uiID_);
+
+    signalRendererChanged_.disconnect();
+    editablePhotos_.clear();
+    Gegl::exit();
+
+    finalized_.emit(*this);
 }
 
 void
-Editor::init( Application &app )
+Editor::visit_renderer(BrowserRenderer & browser_renderer) throw()
 {
-    application_ = &app;
-    engine_ = new EditEngine();
-    engine_->init( application_->get_engine().get_default_observer() );
+    ui_hide();
 }
 
 void
-Editor::register_ui() throw()
+Editor::visit_renderer(ConsoleRenderer & browser_renderer) throw()
 {
-    MainWindow & main_window = application_->get_main_window();
-
-    const Glib::RefPtr<Gtk::UIManager> & ui_manager
-        = main_window.get_ui_manager();
-
-    uiID_ = ui_manager->add_ui_from_file(uiFile);
-    if (0 == uiID_)
-    {
-        // FIXME: error condition.
-    }
-
-    ui_manager->insert_action_group(actionGroup_);
-
-    return;
+    ui_hide();
 }
 
 void
-Editor::unregister_ui() throw()
+Editor::visit_renderer(EnlargedRenderer & editor_renderer) throw()
 {
-    if( 0 == uiID_ )
-        return;
-
-    MainWindow & main_window = application_->get_main_window();
-    const Glib::RefPtr<Gtk::UIManager> & ui_manager
-        = main_window.get_ui_manager();
-    ui_manager->remove_action_group(actionGroup_);
-    ui_manager->remove_ui(uiID_);
-    uiID_ = 0;
+    ui_show();
 }
 
 void
-Editor::final( Application &app )
+Editor::visit_renderer(SlideshowRenderer & editor_renderer) throw()
 {
-    unregister_ui();
-    delete engine_;
+    ui_hide();
 }
 
 void
-Editor::save()
+Editor::apply_async(const IOperationPtr & operation) throw()
 {
-    if( modifiedPhotos_.empty() )
+    const Glib::ustring current_uri = currentPhoto_->get_uri();
+    EditablePhotoMap::const_iterator iter = editablePhotos_.find(
+                                                current_uri);
+
+    EditablePhotoPtr editable_photo;
+
+    if (editablePhotos_.end() == iter)
     {
-        return;
+        Engine & engine = application_->get_engine();
+        const ProgressObserverPtr & observer = engine.get_default_observer();
+
+        editable_photo = EditablePhotoPtr(new EditablePhoto(
+                                              currentPhoto_,
+                                              observer));
+        editablePhotos_.insert(std::make_pair(current_uri,
+                                              editable_photo));
     }
-    bool hasUnsavedData = false;
-    for( EditablePhotoList::iterator photo = modifiedPhotos_.begin();
-                    photo != modifiedPhotos_.end(); photo++ )
+    else
     {
-        hasUnsavedData = hasUnsavedData
-                    || (*photo)->get_photo()->get_has_unsaved_data();
+        editable_photo = iter->second;
     }
-    if( !hasUnsavedData )
-        return;
-    SavePhotosWindow saveWindow(
-                        application_->get_engine(), modifiedPhotos_ );
-    const gint response = saveWindow.run();
-    if( Gtk::RESPONSE_OK == response )
-    {
-        for( EditablePhotoList::iterator photo = modifiedPhotos_.begin();
-                    photo != modifiedPhotos_.end(); photo++ )
-        {
-            if( (*photo)->get_photo()->get_has_unsaved_data()
-                && (*photo)->get_to_save() )
-            {
-                (*photo)->save( application_->get_engine() );
-            }
-        }
-    }
-
-    modifiedPhotos_.clear();
 
-    return;
+    editable_photo->apply_async(
+        operation,
+        sigc::bind(sigc::mem_fun(*this,
+                                 &Editor::on_action_edit_photo_end),
+                   editable_photo));
 }
 
 void
-Editor::set_current_photo( const EditablePhotoPtr &photo )
+Editor::on_action_edit_photo_end(
+            const EditablePhotoPtr & editable_photo) throw()
 {
-    currentPhoto_ = photo;
-
-    if( !currentPhoto_ )
+    const PhotoPtr & photo = editable_photo->get_photo();
+    if (currentPhoto_->get_uri() != photo->get_uri())
+    {
         return;
+    }
 
-#if 0
-    buffer->open_image_file(
-                photo->get_photo()->get_disk_file_path(),
-                engine_);
-#endif
-
-#ifdef SS_LATER
-    Glib::ThreadPool & thread_pool
-                    = application_->get_thread_pool();
-    thread_pool.push(sigc::bind(
-            sigc::mem_fun2( *(photo->get_edit_buffer()),
-                &Buffer::open_image_file),
-                    photo->get_photo()->get_disk_file_path(),
-                    engine_ ));
-#endif
-
-#if 0
-    Glib::Thread * const loader = Glib::Thread::create(
-            sigc::bind(
-                sigc::mem_fun2( *buffer,
-                    &Buffer::open_image_file),
-                    photo->get_photo()->get_disk_file_path(),
-                    engine_ ), true );
-    loader->join();
-#endif
-    return;
-}
+    RendererRegistry & renderer_registry
+                           = application_->get_renderer_registry();
+    const IRendererPtr & current_renderer
+                             = renderer_registry.get_current();
+    const IRendererPtr enlarged_renderer
+        = renderer_registry.select<EnlargedRenderer>();
 
-void
-Editor::apply_action( const EditActionPtr &action,
-               const EditablePhotoPtr &photo ) throw()
-{
-	static Glib::Mutex lock;
-    CursorChanger tmp( application_->get_main_window() );
-	Glib::Mutex::Lock l(lock);
-    apply( action, photo );
-}
+    if (current_renderer != enlarged_renderer
+        || 0 == enlarged_renderer)
+    {
+        return;
+    }
 
-void
-Editor::on_action_flip_horz() throw()
-{
-    EditActionPtr action( new Flip( true ) );
-    apply( action );
-
-#if 0
-    FilterPtr filter( new FlipOperation( engine_,
-                        FlipOperation::HORIZONTAL ) );
-    BufferPtr buffer = currentPhoto_->get_edit_buffer();
-    OperationPtr op( new Operation(
-                            engine_, filter, buffer ) );
-    EditActionPtr action( new GeglOperation( op,
-                        application_->get_engine().get_default_observer() ) );
-    apply( action );
-#endif
+    enlarged_renderer->render(photo);
 }
 
 void
-Editor::on_action_flip_vert() throw()
+Editor::on_action_edit_photo(const IOperationFactoryPtr & factory)
+                             throw()
 {
-#if 0
-    FilterPtr filter( new FlipOperation( engine_,
-                        FlipOperation::VERTICAL) );
-    BufferPtr buffer = currentPhoto_->get_edit_buffer();
-    OperationPtr op( new Operation(
-                            engine_, filter, buffer ) );
-    EditActionPtr action( new GeglOperation( op,
-                        application_->get_engine().get_default_observer() ) );
-    apply( action );
-#endif
-    EditActionPtr action( new Flip( false ) );
-    apply( action );
-}
+    const IOperationPtr operation(factory->create());
+    Gtk::Widget * const widget = operation->get_widget();
 
-void
-Editor::on_action_rotate_left() throw()
-{
-    EditActionPtr action(
-        new Rotate( Rotate::ROTATE_COUNTERCLOCKWISE ) );
-    apply( action );
-}
+    if (0 != widget)
+    {
+        widget->show_all();
+    }
 
-void
-Editor::on_action_rotate_right() throw()
-{
-    EditActionPtr action(
-        new Rotate( Rotate::ROTATE_CLOCKWISE ) );
-    apply( action );
+    operation->signal_ready().connect(
+        sigc::bind(
+            sigc::mem_fun(*this,
+                          &Editor::apply_async),
+            operation));
 }
 
 void
-Editor::on_action_scale() throw()
+Editor::on_renderer_changed(RendererRegistry & renderer_registry)
+                            throw()
 {
+    const IRendererPtr & renderer = renderer_registry.get_current();
+    renderer->receive_plugin(*this);
 }
 
 void
-Editor::on_action_save() throw()
+Editor::on_selection_changed() throw()
 {
-    save();
-}
+    RendererRegistry & renderer_registry
+                           = application_->get_renderer_registry();
+    const IRendererPtr renderer = renderer_registry.get_current();
 
-void
-Editor::on_action_undo() throw()
-{
-    CursorChanger tmp( application_->get_main_window() );
-    if( !currentPhoto_ )
+    if (0 == renderer)
     {
         return;
     }
-    currentPhoto_->undo_last_action( );
-    actionPerformed_.emit();
-}
 
-void
-Editor::on_action_redo() throw()
-{
-    CursorChanger tmp( application_->get_main_window() );
-    if( !currentPhoto_ )
+    PhotoList photos = renderer->get_current_selection();
+
+    if (true == photos.empty())
     {
         return;
     }
-    currentPhoto_->redo_last_action( );
-    actionPerformed_.emit();
+
+    currentPhoto_ = *photos.begin();
+    return;
 }
 
 void
-Editor::on_action_copy_actions() throw()
+Editor::ui_hide() throw()
 {
-    copiedActions_ = currentPhoto_->get_history()
-                                .get_actions_for_copy();
+    actionGroup_->set_visible(false);
 }
 
 void
-Editor::on_action_paste_actions() throw()
+Editor::ui_show() throw()
 {
-    for( EditActionList::iterator it = copiedActions_.begin();
-                it != copiedActions_.end(); it++ )
-    {
-        apply( *it );
-    }
+    actionGroup_->set_visible(true);
 }
 
-
 } // namespace Solang
diff --git a/src/editor/editor.h b/src/editor/editor.h
index 6b98350..f97903b 100644
--- a/src/editor/editor.h
+++ b/src/editor/editor.h
@@ -1,5 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
  *
  * Solang is free software: you can redistribute it and/or modify it
@@ -19,138 +20,90 @@
 #ifndef SOLANG_EDITOR_H
 #define SOLANG_EDITOR_H
 
+#include <string>
+#include <tr1/memory>
+
 #include <glibmm.h>
 #include <gtkmm.h>
 
-#include "error.h"
+#include "plugin.h"
 #include "types.h"
 
 namespace Solang
 {
 
-class Editor
+class IOperationFactory;
+typedef std::tr1::shared_ptr<IOperationFactory> IOperationFactoryPtr;
+
+class Editor :
+    public Plugin
 {
     public:
-        Editor();
+        Editor() throw();
 
+        virtual
         ~Editor() throw();
 
-        void
-        init( Application &app );
-
-        void
-        final( Application &app );
-
-        void
-        apply( const EditActionPtr &action);
-
-        void
-        apply( const EditActionPtr &action,
-                const EditablePhotoPtr &photo ) throw(Error);
-
-        void
-        apply( const EditActionPtr &action,
-               const EditablePhotoList &photo) throw(Error);
+        virtual void
+        init(Application & application) throw();
 
-        void
-        register_ui() throw();
+        virtual void
+        final(Application & application) throw();
 
-        void
-        unregister_ui() throw();
+        virtual void
+        visit_renderer(BrowserRenderer & browser_renderer) throw();
 
-        void
-        save();
+        virtual void
+        visit_renderer(ConsoleRenderer & browser_renderer) throw();
 
-        inline Glib::Dispatcher &
-        edit_action_performed() throw();
-
-        inline EditEnginePtr &
-        get_engine() throw();
-
-        inline EditablePhotoPtr
-        get_current_photo() throw();
-
-        void
-        set_current_photo( const EditablePhotoPtr &photo );
+        virtual void
+        visit_renderer(EnlargedRenderer & editor_renderer) throw();
 
-        inline ApplicationPtr
-        get_application() throw();
+        virtual void
+        visit_renderer(SlideshowRenderer & editor_renderer) throw();
 
     private:
-
-        void
-        set_target_photo( const EditablePhotoPtr &photo );
-
-        void
-        on_action_flip_horz() throw();
-
-        void
-        on_action_flip_vert() throw();
-
-        void
-        on_action_rotate_left() throw();
-
         void
-        on_action_rotate_right() throw();
+        apply_async(const IOperationPtr & operation) throw();
 
         void
-        on_action_scale() throw();
+        on_action_edit_photo_end(
+            const EditablePhotoPtr & editable_photo) throw();
 
         void
-        on_action_save() throw();
+        on_action_edit_photo(const IOperationFactoryPtr & factory)
+                             throw();
 
         void
-        on_action_undo() throw();
+        on_renderer_changed(RendererRegistry & renderer_registry)
+                            throw();
 
         void
-        on_action_redo() throw();
+        on_selection_changed() throw();
 
         void
-        on_action_copy_actions() throw();
+        ui_hide() throw();
 
         void
-        on_action_paste_actions() throw();
+        ui_show() throw();
 
-        void
-        apply_action( const EditActionPtr &action,
-               const EditablePhotoPtr &photo ) throw();
+        static const std::string uiFile_;
 
         ApplicationPtr application_;
-        EditablePhotoList modifiedPhotos_;
-        Glib::Mutex mutex_;
+
         ActionGroupPtr actionGroup_;
-        Glib::RefPtr<Gtk::IconFactory> iconFactory_;
+
         Gtk::UIManager::ui_merge_id uiID_;
-        Glib::Dispatcher actionPerformed_;
-        EditablePhotoPtr currentPhoto_;
-        EditActionList copiedActions_;
-        EditEnginePtr engine_;
-};
 
-inline Glib::Dispatcher &
-Editor::edit_action_performed() throw()
-{
-    return actionPerformed_;
-}
+        EditablePhotoMap editablePhotos_;
 
-inline EditEnginePtr &
-Editor::get_engine() throw()
-{
-    return engine_;
-}
+        PhotoPtr currentPhoto_;
 
-inline EditablePhotoPtr
-Editor::get_current_photo() throw()
-{
-    return currentPhoto_;
-}
+        sigc::connection signalRendererChanged_;
 
-inline ApplicationPtr
-Editor::get_application() throw()
-{
-    return application_;
-}
+        sigc::connection signalSelectionChanged_;
+};
 
-} //namespace solang
+} // namespace solang
 
-#endif
+#endif // SOLANG_EDITOR_H
diff --git a/src/editor/edit-action.cpp b/src/editor/flip-horiz-operation.cpp
similarity index 56%
copy from src/editor/edit-action.cpp
copy to src/editor/flip-horiz-operation.cpp
index 02ff1ab..7fa8389 100644
--- a/src/editor/edit-action.cpp
+++ b/src/editor/flip-horiz-operation.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -18,20 +18,38 @@
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif // HAVE_CONFIG_H
 
-#include "edit-action.h"
+#include <glibmm/i18n.h>
+
+#include "flip-horiz-operation.h"
 
 namespace Solang
 {
 
-EditAction::EditAction()
-    :NonCopyable()
+FlipHorizOperation::FlipHorizOperation() throw() :
+    FlipOperation()
+{
+    set_y(-1.0);
+}
+
+FlipHorizOperation::~FlipHorizOperation() throw()
+{
+}
+
+Glib::ustring
+FlipHorizOperation::get_description() const throw()
 {
+    return Glib::ustring(_("Flipping horizontally..."));
 }
 
-EditAction::~EditAction() throw()
+Gtk::Widget *
+FlipHorizOperation::get_widget() throw()
 {
+    Glib::signal_idle().connect_once(
+        sigc::mem_fun(signal_ready(),
+                      &SignalReady::emit));
+    return 0;
 }
 
-} //namespace Solang
+} // namespace Solang
diff --git a/src/edit-engine/load-file.h b/src/editor/flip-horiz-operation.h
similarity index 62%
rename from src/edit-engine/load-file.h
rename to src/editor/flip-horiz-operation.h
index 3f87f5c..6c6e47e 100644
--- a/src/edit-engine/load-file.h
+++ b/src/editor/flip-horiz-operation.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,35 +16,34 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "filter.h"
+#ifndef SOLANG_FLIP_HORIZ_OPERATION_H
+#define SOLANG_FLIP_HORIZ_OPERATION_H
 
-#ifndef SOLANG_LOAD_FILE_H
-#define SOLANG_LOAD_FILE_H
+#include "flip-operation.h"
 
 namespace Solang
 {
 
-class LoadFile
-        : public Filter
+class FlipHorizOperation :
+    public FlipOperation
 {
     public:
-        LoadFile( const EditEnginePtr &engine,
-                  const char *path);
+        FlipHorizOperation() throw();
 
-        LoadFile( const EditEnginePtr &engine,
-                  const Glib::ustring &xmlPath );
-
-        ~LoadFile() throw();
-
-        virtual Glib::ustring
-        get_name() const throw();
+        virtual
+        ~FlipHorizOperation() throw();
 
         virtual Glib::ustring
         get_description() const throw();
 
-};
+        virtual Gtk::Widget *
+        get_widget() throw();
+
+    protected:
 
+    private:
+};
 
-}//namespace Solang
+} // namespace Solang
 
-#endif //SOLANG_LOAD_FILE_H
+#endif // SOLANG_FLIP_HORIZ_OPERATION_H
diff --git a/src/editor/flip-operation.cpp b/src/editor/flip-operation.cpp
new file mode 100644
index 0000000..29dfc6a
--- /dev/null
+++ b/src/editor/flip-operation.cpp
@@ -0,0 +1,126 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include <geglmm.h>
+#include <glibmm/i18n.h>
+
+#include "flip-operation.h"
+
+namespace Solang
+{
+
+FlipOperation::FlipOperation(gdouble origin_x,
+                             gdouble origin_y,
+                             const std::string & filter,
+                             bool hard_edges,
+                             gint lanczos_width,
+                             gdouble x,
+                             gdouble y) throw() :
+    Operation(),
+    hardEdges_(hard_edges),
+    originX_(origin_x),
+    originY_(origin_y),
+    x_(x),
+    y_(y),
+    lanczosWidth_(lanczos_width),
+    filter_(filter),
+    signalReady_()
+{
+}
+
+FlipOperation::~FlipOperation() throw()
+{
+}
+
+Glib::ustring
+FlipOperation::get_description() const throw()
+{
+    return Glib::ustring(_("Flipping..."));
+}
+
+NodePtr
+FlipOperation::get_node(const NodePtr & root) const throw()
+{
+    const NodePtr operation = root->new_child("operation",
+                                              "gegl:reflect");
+    gegl_node_set(operation->gobj(),
+                  "origin-x", originX_,
+                  "origin-y", originY_,
+                  "filter", filter_.c_str(),
+                  "hard-edges", hardEdges_,
+                  "lanczos-width", lanczosWidth_,
+                  "x", x_,
+                  "y", y_,
+                  NULL);
+
+    return operation;
+}
+
+FlipOperation::SignalReady &
+FlipOperation::signal_ready() throw()
+{
+    return signalReady_;
+}
+
+void
+FlipOperation::set_hard_edges(bool hard_edges) throw()
+{
+    hardEdges_ = hard_edges;
+}
+
+void
+FlipOperation::set_origin_x(gdouble origin_x) throw()
+{
+    originX_ = origin_x;
+}
+
+void
+FlipOperation::set_origin_y(gdouble origin_y) throw()
+{
+    originY_ = origin_y;
+}
+
+void
+FlipOperation::set_x(gdouble x) throw()
+{
+    x_ = x;
+}
+
+void
+FlipOperation::set_y(gdouble y) throw()
+{
+    y_ = y;
+}
+
+void
+FlipOperation::set_lanczos_width(gdouble lanczos_width) throw()
+{
+    lanczosWidth_ = lanczos_width;
+}
+
+void
+FlipOperation::set_filter(const std::string & filter) throw()
+{
+    filter_ = filter;
+}
+
+} // namespace Solang
diff --git a/src/editor/flip-operation.h b/src/editor/flip-operation.h
new file mode 100644
index 0000000..67284a9
--- /dev/null
+++ b/src/editor/flip-operation.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SOLANG_FLIP_OPERATION_H
+#define SOLANG_FLIP_OPERATION_H
+
+#include <string>
+
+#include <glibmm.h>
+
+#include "operation.h"
+
+namespace Solang
+{
+
+class FlipOperation :
+    public Operation
+{
+    public:
+        FlipOperation(gdouble origin_x = 0.0,
+                      gdouble origin_y = 0.0,
+                      const std::string & filter = "linear",
+                      bool hard_edges = false,
+                      gint lanczos_width = 3,
+                      gdouble x = 0.0,
+                      gdouble y = 0.0) throw();
+
+        virtual
+        ~FlipOperation() throw();
+
+        virtual Glib::ustring
+        get_description() const throw();
+
+        virtual Gtk::Widget *
+        get_widget() throw() = 0;
+
+        virtual SignalReady &
+        signal_ready() throw();
+
+    protected:
+        virtual NodePtr
+        get_node(const NodePtr & root) const throw();
+
+        void
+        set_hard_edges(bool hard_edges) throw();
+
+        void
+        set_origin_x(gdouble origin_x) throw();
+
+        void
+        set_origin_y(gdouble origin_y) throw();
+
+        void
+        set_x(gdouble x) throw();
+
+        void
+        set_y(gdouble y) throw();
+
+        void
+        set_lanczos_width(gdouble lanczos_width) throw();
+
+        void
+        set_filter(const std::string & filter) throw();
+
+    private:
+        bool hardEdges_;
+
+        gdouble originX_;
+
+        gdouble originY_;
+
+        gdouble x_;
+
+        gdouble y_;
+
+        gint lanczosWidth_;
+
+        std::string filter_;
+
+        SignalReady signalReady_;
+};
+
+} // namespace Solang
+
+#endif // SOLANG_FLIP_OPERATION_H
diff --git a/src/editor/desaturate.h b/src/editor/flip-vert-operation.cpp
similarity index 53%
rename from src/editor/desaturate.h
rename to src/editor/flip-vert-operation.cpp
index 0f98541..21d3cf0 100644
--- a/src/editor/desaturate.h
+++ b/src/editor/flip-vert-operation.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,36 +16,40 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef SOLANG_DESATURATE_H
-#define SOLANG_DESATURATE_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
 
-#include "edit-action.h"
+#include <glibmm/i18n.h>
+
+#include "flip-vert-operation.h"
 
 namespace Solang
 {
 
-class Desaturate :
-        public EditAction
+FlipVertOperation::FlipVertOperation() throw() :
+    FlipOperation()
 {
-    public:
-        Desaturate( double fraction );
-        virtual ~Desaturate() throw();
-
-        virtual void
-        execute( EditablePhoto &photo) throw(Error);
-
-        virtual void
-        reverse( EditablePhoto &photo) throw(Error);
-
-        virtual EditActionPtr
-        clone();
+    set_x(-1.0);
+}
 
-    private:
-        double fraction_;
-        PixbufPtr oldBuf_;
+FlipVertOperation::~FlipVertOperation() throw()
+{
+}
 
-};
+Glib::ustring
+FlipVertOperation::get_description() const throw()
+{
+    return Glib::ustring(_("Flipping vertically..."));
+}
 
-} //namespace Solang
+Gtk::Widget *
+FlipVertOperation::get_widget() throw()
+{
+    Glib::signal_idle().connect_once(
+        sigc::mem_fun(signal_ready(),
+                      &SignalReady::emit));
+    return 0;
+}
 
-#endif // SOLANG_DESATURATE_H
+} // namespace Solang
diff --git a/src/editor/flip.h b/src/editor/flip-vert-operation.h
similarity index 60%
rename from src/editor/flip.h
rename to src/editor/flip-vert-operation.h
index 84e7424..e8dae64 100644
--- a/src/editor/flip.h
+++ b/src/editor/flip-vert-operation.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,34 +16,34 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef SOLANG_FLIP_H
-#define SOLANG_FLIP_H
+#ifndef SOLANG_FLIP_VERT_OPERATION_H
+#define SOLANG_FLIP_VERT_OPERATION_H
 
-#include "edit-action.h"
+#include "flip-operation.h"
 
 namespace Solang
 {
 
-class Flip :
-        public EditAction
+class FlipVertOperation :
+    public FlipOperation
 {
     public:
-        Flip( bool horizontal );
-        virtual ~Flip() throw();
+        FlipVertOperation() throw();
 
-        virtual void
-        execute( EditablePhoto &photo) throw(Error);
+        virtual
+        ~FlipVertOperation() throw();
 
-        virtual void
-        reverse( EditablePhoto &photo) throw(Error);
+        virtual Glib::ustring
+        get_description() const throw();
 
-        virtual EditActionPtr
-        clone();
+        virtual Gtk::Widget *
+        get_widget() throw();
+
+    protected:
 
     private:
-        bool horizontal_;
 };
 
-} //namespace Solang
+} // namespace Solang
 
-#endif // SOLANG_FLIP_H
+#endif // SOLANG_FLIP_VERT_OPERATION_H
diff --git a/src/editor/edit-action.cpp b/src/editor/rotate-clock-operation.cpp
similarity index 55%
copy from src/editor/edit-action.cpp
copy to src/editor/rotate-clock-operation.cpp
index 02ff1ab..330e576 100644
--- a/src/editor/edit-action.cpp
+++ b/src/editor/rotate-clock-operation.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -18,20 +18,38 @@
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif // HAVE_CONFIG_H
 
-#include "edit-action.h"
+#include <glibmm/i18n.h>
+
+#include "rotate-clock-operation.h"
 
 namespace Solang
 {
 
-EditAction::EditAction()
-    :NonCopyable()
+RotateClockOperation::RotateClockOperation() throw() :
+    RotateOperation()
+{
+    set_degrees(-90.0);
+}
+
+RotateClockOperation::~RotateClockOperation() throw()
+{
+}
+
+Glib::ustring
+RotateClockOperation::get_description() const throw()
 {
+    return Glib::ustring(_("Rotating clockwise..."));
 }
 
-EditAction::~EditAction() throw()
+Gtk::Widget *
+RotateClockOperation::get_widget() throw()
 {
+    Glib::signal_idle().connect_once(
+        sigc::mem_fun(signal_ready(),
+                      &SignalReady::emit));
+    return 0;
 }
 
-} //namespace Solang
+} // namespace Solang
diff --git a/src/editor/scale.h b/src/editor/rotate-clock-operation.h
similarity index 59%
rename from src/editor/scale.h
rename to src/editor/rotate-clock-operation.h
index 51fa051..ed34594 100644
--- a/src/editor/scale.h
+++ b/src/editor/rotate-clock-operation.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,36 +16,34 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef SOLANG_SCALE_H
-#define SOLANG_SCALE_H
+#ifndef SOLANG_ROTATE_CLOCK_OPERATION_H
+#define SOLANG_ROTATE_CLOCK_OPERATION_H
 
-#include "edit-action.h"
+#include "rotate-operation.h"
 
 namespace Solang
 {
 
-class Scale :
-        public EditAction
+class RotateClockOperation :
+    public RotateOperation
 {
     public:
-        Scale( double fraction );
-        virtual ~Scale() throw();
+        RotateClockOperation() throw();
 
-        virtual void
-        execute( EditablePhoto &photo) throw(Error);
+        virtual
+        ~RotateClockOperation() throw();
 
-        virtual void
-        reverse( EditablePhoto &photo) throw(Error);
+        virtual Glib::ustring
+        get_description() const throw();
 
-        virtual EditActionPtr
-        clone();
+        virtual Gtk::Widget *
+        get_widget() throw();
 
-    private:
-        double fraction_;
-        PixbufPtr oldBuf_;
+    protected:
 
+    private:
 };
 
-} //namespace Solang
+} // namespace Solang
 
-#endif // SOLANG_SCALE_H
+#endif // SOLANG_ROTATE_CLOCK_OPERATION_H
diff --git a/src/editor/edit-action.cpp b/src/editor/rotate-counter-operation.cpp
similarity index 54%
rename from src/editor/edit-action.cpp
rename to src/editor/rotate-counter-operation.cpp
index 02ff1ab..c6a26b7 100644
--- a/src/editor/edit-action.cpp
+++ b/src/editor/rotate-counter-operation.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -18,20 +18,38 @@
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif // HAVE_CONFIG_H
 
-#include "edit-action.h"
+#include <glibmm/i18n.h>
+
+#include "rotate-counter-operation.h"
 
 namespace Solang
 {
 
-EditAction::EditAction()
-    :NonCopyable()
+RotateCounterOperation::RotateCounterOperation() throw() :
+    RotateOperation()
+{
+    set_degrees(90.0);
+}
+
+RotateCounterOperation::~RotateCounterOperation() throw()
+{
+}
+
+Glib::ustring
+RotateCounterOperation::get_description() const throw()
 {
+    return Glib::ustring(_("Rotating counterclockwise..."));
 }
 
-EditAction::~EditAction() throw()
+Gtk::Widget *
+RotateCounterOperation::get_widget() throw()
 {
+    Glib::signal_idle().connect_once(
+        sigc::mem_fun(signal_ready(),
+                      &SignalReady::emit));
+    return 0;
 }
 
-} //namespace Solang
+} // namespace Solang
diff --git a/src/edit-engine/contrast-operation.h b/src/editor/rotate-counter-operation.h
similarity index 59%
rename from src/edit-engine/contrast-operation.h
rename to src/editor/rotate-counter-operation.h
index 5abdfe7..46cb7bd 100644
--- a/src/edit-engine/contrast-operation.h
+++ b/src/editor/rotate-counter-operation.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
  *
  * Solang is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,37 +16,34 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "filter.h"
+#ifndef SOLANG_ROTATE_COUNTER_OPERATION_H
+#define SOLANG_ROTATE_COUNTER_OPERATION_H
 
-#ifndef SOLANG_CONTRAST_OPERATION_H
-#define SOLANG_CONTRAST_OPERATION_H
+#include "rotate-operation.h"
 
 namespace Solang
 {
 
-class ContrastOperation
-        : public Filter
+class RotateCounterOperation :
+    public RotateOperation
 {
     public:
-        ContrastOperation( const EditEnginePtr &engine,
-                  double contrast );
+        RotateCounterOperation() throw();
 
-        ContrastOperation( const EditEnginePtr &engine,
-                  const Glib::ustring &xmlPath );
-
-        ~ContrastOperation() throw();
-
-        virtual Glib::ustring
-        get_name() const throw();
+        virtual
+        ~RotateCounterOperation() throw();
 
         virtual Glib::ustring
         get_description() const throw();
 
+        virtual Gtk::Widget *
+        get_widget() throw();
+
+    protected:
+
     private:
-       double contrast_;
 };
 
+} // namespace Solang
 
-}//namespace Solang
-
-#endif //SOLANG_CONTRAST_OPERATION_H
+#endif // SOLANG_ROTATE_COUNTER_OPERATION_H
diff --git a/src/editor/rotate-operation.cpp b/src/editor/rotate-operation.cpp
new file mode 100644
index 0000000..8c55750
--- /dev/null
+++ b/src/editor/rotate-operation.cpp
@@ -0,0 +1,117 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include <geglmm.h>
+#include <glibmm/i18n.h>
+
+#include "rotate-operation.h"
+
+namespace Solang
+{
+
+RotateOperation::RotateOperation(gdouble origin_x,
+                                 gdouble origin_y,
+                                 const std::string & filter,
+                                 bool hard_edges,
+                                 gint lanczos_width,
+                                 gdouble degrees) throw() :
+    Operation(),
+    hardEdges_(hard_edges),
+    originX_(origin_x),
+    originY_(origin_y),
+    degrees_(degrees),
+    lanczosWidth_(lanczos_width),
+    filter_(filter),
+    signalReady_()
+{
+}
+
+RotateOperation::~RotateOperation() throw()
+{
+}
+
+Glib::ustring
+RotateOperation::get_description() const throw()
+{
+    return Glib::ustring(_("Rotating..."));
+}
+
+NodePtr
+RotateOperation::get_node(const NodePtr & root) const throw()
+{
+    const NodePtr operation = root->new_child("operation",
+                                              "gegl:rotate");
+    gegl_node_set(operation->gobj(),
+                  "origin-x", originX_,
+                  "origin-y", originY_,
+                  "filter", filter_.c_str(),
+                  "hard-edges", hardEdges_,
+                  "lanczos-width", lanczosWidth_,
+                  "degrees", degrees_,
+                  NULL);
+
+    return operation;
+}
+
+RotateOperation::SignalReady &
+RotateOperation::signal_ready() throw()
+{
+    return signalReady_;
+}
+
+void
+RotateOperation::set_hard_edges(bool hard_edges) throw()
+{
+    hardEdges_ = hard_edges;
+}
+
+void
+RotateOperation::set_origin_x(gdouble origin_x) throw()
+{
+    originX_ = origin_x;
+}
+
+void
+RotateOperation::set_origin_y(gdouble origin_y) throw()
+{
+    originY_ = origin_y;
+}
+
+void
+RotateOperation::set_degrees(gdouble degrees) throw()
+{
+    degrees_ = degrees;
+}
+
+void
+RotateOperation::set_lanczos_width(gdouble lanczos_width) throw()
+{
+    lanczosWidth_ = lanczos_width;
+}
+
+void
+RotateOperation::set_filter(const std::string & filter) throw()
+{
+    filter_ = filter;
+}
+
+} // namespace Solang
diff --git a/src/editor/rotate-operation.h b/src/editor/rotate-operation.h
new file mode 100644
index 0000000..d961bf5
--- /dev/null
+++ b/src/editor/rotate-operation.h
@@ -0,0 +1,94 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SOLANG_ROTATE_OPERATION_H
+#define SOLANG_ROTATE_OPERATION_H
+
+#include <string>
+
+#include <glibmm.h>
+
+#include "operation.h"
+
+namespace Solang
+{
+
+class RotateOperation :
+    public Operation
+{
+    public:
+        RotateOperation(gdouble origin_x = 0.0,
+                        gdouble origin_y = 0.0,
+                        const std::string & filter = "linear",
+                        bool hard_edges = false,
+                        gint lanczos_width = 3,
+                        gdouble degrees = 0.0) throw();
+
+        virtual
+        ~RotateOperation() throw();
+
+        virtual Glib::ustring
+        get_description() const throw();
+
+        virtual Gtk::Widget *
+        get_widget() throw() = 0;
+
+        virtual SignalReady &
+        signal_ready() throw();
+
+    protected:
+        virtual NodePtr
+        get_node(const NodePtr & root) const throw();
+
+        void
+        set_hard_edges(bool hard_edges) throw();
+
+        void
+        set_degrees(gdouble degrees) throw();
+
+        void
+        set_origin_x(gdouble origin_x) throw();
+
+        void
+        set_origin_y(gdouble origin_y) throw();
+
+        void
+        set_lanczos_width(gdouble lanczos_width) throw();
+
+        void
+        set_filter(const std::string & filter) throw();
+
+    private:
+        bool hardEdges_;
+
+        gdouble degrees_;
+
+        gdouble originX_;
+
+        gdouble originY_;
+
+        gint lanczosWidth_;
+
+        std::string filter_;
+
+        SignalReady signalReady_;
+};
+
+} // namespace Solang
+
+#endif // SOLANG_ROTATE_OPERATION_H
diff --git a/src/exporter/Makefile.am b/src/exporter/Makefile.am
index 40bc380..d9f05b3 100644
--- a/src/exporter/Makefile.am
+++ b/src/exporter/Makefile.am
@@ -27,6 +27,7 @@ AM_CPPFLAGS = \
 	$(DBUS_CFLAGS) \
 	$(GTKMM_CFLAGS) \
 	$(GDL_CFLAGS) \
+	$(GEGLMM_CFLAGS) \
 	$(TRACKER_CFLAGS)
 
 AM_CXXFLAGS = \
diff --git a/src/exporter/exporter.cpp b/src/exporter/exporter.cpp
index 19c6714..081a04e 100644
--- a/src/exporter/exporter.cpp
+++ b/src/exporter/exporter.cpp
@@ -161,12 +161,6 @@ Exporter::visit_renderer(ConsoleRenderer & console_renderer) throw()
 }
 
 void
-Exporter::visit_renderer(EditorRenderer & editor_renderer) throw()
-{
-    ui_show();
-}
-
-void
 Exporter::visit_renderer(EnlargedRenderer & enlarged_renderer) throw()
 {
     ui_show();
diff --git a/src/exporter/exporter.h b/src/exporter/exporter.h
index de9d04a..63814ab 100644
--- a/src/exporter/exporter.h
+++ b/src/exporter/exporter.h
@@ -57,9 +57,6 @@ class Exporter :
         visit_renderer(ConsoleRenderer & console_renderer) throw();
 
         virtual void
-        visit_renderer(EditorRenderer & editor_renderer) throw();
-
-        virtual void
         visit_renderer(EnlargedRenderer & enlarged_renderer) throw();
 
         virtual void
diff --git a/src/importer/importer.cpp b/src/importer/importer.cpp
index 6267c6a..3e20c7d 100644
--- a/src/importer/importer.cpp
+++ b/src/importer/importer.cpp
@@ -27,7 +27,6 @@
 #include "browser-renderer.h"
 #include "console-renderer.h"
 #include "directory-storage.h"
-#include "editor-renderer.h"
 #include "engine.h"
 #include "enlarged-renderer.h"
 #include "i-photo-source.h"
@@ -187,12 +186,6 @@ Importer::visit_renderer(ConsoleRenderer & console_renderer) throw()
 }
 
 void
-Importer::visit_renderer(EditorRenderer & editor_renderer) throw()
-{
-    ui_show();
-}
-
-void
 Importer::visit_renderer(EnlargedRenderer & enlarged_renderer) throw()
 {
     ui_show();
diff --git a/src/importer/importer.h b/src/importer/importer.h
index a9a8b51..775e835 100644
--- a/src/importer/importer.h
+++ b/src/importer/importer.h
@@ -57,9 +57,6 @@ class Importer :
         visit_renderer(ConsoleRenderer & console_renderer) throw();
 
         virtual void
-        visit_renderer(EditorRenderer & editor_renderer) throw();
-
-        virtual void
         visit_renderer(EnlargedRenderer & enlarged_renderer) throw();
 
         virtual void
diff --git a/src/renderer/Makefile.am b/src/renderer/Makefile.am
index 250c35e..ad449c0 100644
--- a/src/renderer/Makefile.am
+++ b/src/renderer/Makefile.am
@@ -5,8 +5,6 @@ librenderer_la_SOURCES = \
 	browser-renderer.h \
 	console-renderer.cpp \
 	console-renderer.h \
-	editor-renderer.cpp \
-	editor-renderer.h \
 	enlarged-renderer.cpp \
 	enlarged-renderer.h \
 	browser-model-column-record.cpp \
@@ -32,7 +30,6 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/common \
 	-I$(top_srcdir)/src/database \
 	-I$(top_srcdir)/src/editor \
-	-I$(top_srcdir)/src/edit-engine \
 	-I$(top_srcdir)/src/importer \
 	-I$(top_srcdir)/src/renderer \
 	-I$(top_srcdir)/src/storage \
@@ -42,7 +39,7 @@ AM_CPPFLAGS = \
 	$(GTKMM_CFLAGS) \
 	$(GDL_CFLAGS) \
 	$(BABL_CFLAGS) \
-	$(GEGL_CFLAGS) \
+	$(GEGLMM_CFLAGS) \
 	$(TRACKER_CFLAGS)
 
 AM_CXXFLAGS = \
diff --git a/src/renderer/enlarged-renderer.cpp b/src/renderer/enlarged-renderer.cpp
index 93b6ef6..e5a53f4 100644
--- a/src/renderer/enlarged-renderer.cpp
+++ b/src/renderer/enlarged-renderer.cpp
@@ -76,7 +76,7 @@ EnlargedRenderer::EnlargedRenderer() throw() :
     imageView_(0),
     imageScrollWin_(0),
     pageNum_(-1),
-    pixbufMaker_(),
+    pixbufMaker_(PixbufMaker::create(true)),
     signalMainWindowStateEvent_(),
     signalSwitchPage_()
 {
@@ -121,13 +121,13 @@ EnlargedRenderer::init(Application & application) throw()
 void
 EnlargedRenderer::render(const PhotoPtr & photo) throw()
 {
-    if (0 == pixbufMaker_)
-    {
-        pixbufMaker_ = PixbufMaker::create(true);
-    }
-    else
+    pixbufMaker_->stop_async();
+
+    const PixbufPtr & pixbuf = photo->get_buffer();
+    if (0 != pixbuf)
     {
-        pixbufMaker_->stop_async();
+        on_pixbuf_maker_async_ready(pixbuf);
+        return;
     }
 
     try



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]