Code

Fix handle for LPERotateCopies
[inkscape.git] / src / desktop.cpp
index 3ff4bf2f590df2376e7078d35ac7d04317a97229..932d79ff2e7dadfe24d1c6e3cee85e5db55c0d79 100644 (file)
 #include "ui/dialog/dialog-manager.h"
 #include "xml/repr.h"
 #include "message-context.h"
+#include "device-manager.h"
+#include "layer-fns.h"
 #include "layer-manager.h"
 #include "event-log.h"
 #include "display/canvas-grid.h"
 #include "widgets/desktop-widget.h"
+#include "box3d-context.h"
 
 #include "display/sp-canvas.h"
 
@@ -145,6 +148,8 @@ SPDesktop::SPDesktop() :
     gr_fill_or_stroke( true ),
     _layer_hierarchy( 0 ),
     _reconstruction_old_layer_id( 0 ),
+    _display_mode(Inkscape::RENDERMODE_NORMAL),
+    _saved_display_mode(Inkscape::RENDERMODE_NORMAL),
     _widget( 0 ),
     _inkscape( 0 ),
     _guides_message_context( 0 ),
@@ -163,6 +168,9 @@ SPDesktop::SPDesktop() :
 void
 SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
 {
+    // Temporary workaround for link order issues:
+    Inkscape::DeviceManager::getManager().getDevices();
+
     _guides_message_context = new Inkscape::MessageContext(const_cast<Inkscape::MessageStack*>(messageStack()));
 
     current = sp_repr_css_attr_inherited (inkscape_get_repr (INKSCAPE, "desktop"), "style");
@@ -387,13 +395,26 @@ SPDesktop::~SPDesktop() {}
 /* Public methods */
 
 
+/* These methods help for temporarily showing things on-canvas.
+ * The *only* valid use of the TemporaryItem* that you get from add_temporary_canvasitem
+ * is when you want to prematurely remove the item from the canvas, by calling
+ * desktop->remove_temporary_canvasitem(tempitem).
+ */
 /** Note that lifetime is measured in milliseconds
-* it is perfectly safe to ignore the returned pointer: the object is deleted by itself, so don't delete it elsewhere!
-* The return value should only be used as argument for SPDesktop::remove_temporary_canvasitem, because the object might be deleted already.
-*/
+ * One should *not* keep a reference to the SPCanvasItem, the temporary item code will
+ * delete the object for you and the reference will become invalid without you knowing it.
+ * It is perfectly safe to ignore the returned pointer: the object is deleted by itself, so don't delete it elsewhere!
+ * The *only* valid use of the returned TemporaryItem* is as argument for SPDesktop::remove_temporary_canvasitem,
+ * because the object might be deleted already without you knowing it.
+ * move_to_bottom = true by default so the item does not interfere with handling of other items on the canvas like nodes.
+ */
 Inkscape::Display::TemporaryItem *
-SPDesktop::add_temporary_canvasitem (SPCanvasItem *item, guint lifetime)
+SPDesktop::add_temporary_canvasitem (SPCanvasItem *item, guint lifetime, bool move_to_bottom)
 {
+    if (move_to_bottom) {
+        sp_canvas_item_move_to_z(item, 0);
+    }
+
     return temporary_item_list->add_item(item, lifetime);
 }
 
@@ -408,30 +429,23 @@ SPDesktop::remove_temporary_canvasitem (Inkscape::Display::TemporaryItem * tempi
     }
 }
 
-void SPDesktop::setDisplayModeNormal()
-{
-    SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_NORMAL;
-    canvas->rendermode = RENDERMODE_NORMAL; // canvas needs that for choosing the best buffer size
-    displayMode = RENDERMODE_NORMAL;
-    sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw
-    _widget->setTitle(SP_DOCUMENT_NAME(sp_desktop_document(this)));
-}
-
-void SPDesktop::setDisplayModeOutline()
-{
-    SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_OUTLINE;
-    canvas->rendermode = RENDERMODE_OUTLINE; // canvas needs that for choosing the best buffer size
-    displayMode = RENDERMODE_OUTLINE;
+void SPDesktop::_setDisplayMode(Inkscape::RenderMode mode) {
+    SP_CANVAS_ARENA (drawing)->arena->rendermode = mode;
+    canvas->rendermode = mode;
+    _display_mode = mode;
+    if (mode != Inkscape::RENDERMODE_OUTLINE) {
+        _saved_display_mode = _display_mode;
+    }
     sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw
     _widget->setTitle(SP_DOCUMENT_NAME(sp_desktop_document(this)));
 }
 
-void SPDesktop::displayModeToggle()
-{
-    if (displayMode == RENDERMODE_OUTLINE)
-        setDisplayModeNormal();
-    else
-        setDisplayModeOutline();
+void SPDesktop::displayModeToggle() {
+    if (_display_mode == Inkscape::RENDERMODE_OUTLINE) {
+        _setDisplayMode(_saved_display_mode);
+    } else {
+        _setDisplayMode(Inkscape::RENDERMODE_OUTLINE);
+    }
 }
 
 /**
@@ -462,6 +476,31 @@ void SPDesktop::setCurrentLayer(SPObject *object) {
     _layer_hierarchy->setBottom(object);
 }
 
+void SPDesktop::toggleLayerSolo(SPObject *object) {
+    g_return_if_fail(SP_IS_GROUP(object));
+    g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) );
+
+    bool othersShowing = false;
+    std::vector<SPObject*> layers;
+    for ( SPObject* obj = Inkscape::next_layer(currentRoot(), object); obj; obj = Inkscape::next_layer(currentRoot(), obj) ) {
+        layers.push_back(obj);
+        othersShowing |= !SP_ITEM(obj)->isHidden();
+    }
+    for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), object); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) {
+        layers.push_back(obj);
+        othersShowing |= !SP_ITEM(obj)->isHidden();
+    }
+
+
+    if ( SP_ITEM(object)->isHidden() ) {
+        SP_ITEM(object)->setHidden(false);
+    }
+
+    for ( std::vector<SPObject*>::iterator it = layers.begin(); it != layers.end(); ++it ) {
+        SP_ITEM(*it)->setHidden(othersShowing);
+    }
+}
+
 /**
  * Return layer that contains \a object.
  */
@@ -741,6 +780,9 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
     /* Scroll */
     sp_canvas_scroll_to (canvas, x0 * newscale - border, y1 * -newscale - border, clear);
 
+    /*  update perspective lines if we are in the 3D box tool (so that infinite ones are shown correctly) */
+    sp_box3d_context_update_lines(event_context);
+
     _widget->updateRulers();
     _widget->updateScrollbars(expansion(_d2w));
     _widget->updateZoom();
@@ -967,6 +1009,16 @@ SPDesktop::zoom_drawing()
     set_display_area(*d, 10);
 }
 
+/**
+ * Scroll canvas by specific coordinate amount in svg coordinates.
+ */
+void
+SPDesktop::scroll_world_in_svg_coords (double dx, double dy, bool is_scrolling)
+{
+    double scale = expansion(_d2w);
+    scroll_world(dx*scale, dy*scale, is_scrolling);
+}
+
 /**
  * Scroll canvas by specific coordinate amount.
  */
@@ -979,6 +1031,9 @@ SPDesktop::scroll_world (double dx, double dy, bool is_scrolling)
 
     sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::Y] - dy, FALSE, is_scrolling);
 
+    /*  update perspective lines if we are in the 3D box tool (so that infinite ones are shown correctly) */
+    sp_box3d_context_update_lines(event_context);
+
     _widget->updateRulers();
     _widget->updateScrollbars(expansion(_d2w));
 }