X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdesktop.cpp;h=0b17fb385aead21accff281c1d3cc646cdf92955;hb=8a2e76b7021b9b960d7c30801a1a14461d9b5939;hp=1f2baccbba2ed61559eb7d0ef70362dd9832accf;hpb=6debf70683e9b0f2787a5341a9e186903962d54e;p=inkscape.git diff --git a/src/desktop.cpp b/src/desktop.cpp index 1f2baccbb..0b17fb385 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1,5 +1,3 @@ -#define __SP_DESKTOP_C__ - /** \file * Editable view implementation * @@ -10,6 +8,8 @@ * Ralf Stephan * John Bintz * Johan Engelen + * Jon A. Cruz + * Abhishek Sharma * * Copyright (C) 2007 Jon A. Cruz * Copyright (C) 2006-2008 Johan Engelen @@ -90,6 +90,11 @@ #include "display/canvas-grid.h" #include "widgets/desktop-widget.h" #include "box3d-context.h" +#include "desktop-style.h" + +// TODO those includes are only for node tool quick zoom. Remove them after fixing it. +#include "ui/tool/node-tool.h" +#include "ui/tool/control-point-selection.h" #include "display/sp-canvas.h" @@ -148,7 +153,6 @@ SPDesktop::SPDesktop() : _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 ), @@ -165,8 +169,10 @@ SPDesktop::SPDesktop() : } void -SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) +SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWidgetInterface *widget) { + _widget = widget; + // Temporary workaround for link order issues: Inkscape::DeviceManager::getManager().getDevices(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -180,12 +186,12 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) SPDocument *document = SP_OBJECT_DOCUMENT (namedview); /* Kill flicker */ - sp_document_ensure_up_to_date (document); + document->ensureUpToDate(); /* Setup Dialog Manager */ _dlg_mgr = &Inkscape::UI::Dialog::DialogManager::getInstance(); - dkey = sp_item_display_key_new (1); + dkey = SPItem::display_key_new(1); /* Connect document */ setDocument (document); @@ -226,11 +232,18 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) setDisplayModeNormal(); } + // The order in which these canvas items are added determines the z-order. It's therefore + // important to add the tempgroup (which will contain the snapindicator) before adding the + // controls. Only this way one will be able to quickly (before the snap indicator has + // disappeared) reselect a node after snapping it. If the z-order is wrong however, this + // will not work (the snap indicator is on top of the node handler; is the snapindicator + // being selected? or does it intercept some of the events that should have gone to the + // node handler? see bug https://bugs.launchpad.net/inkscape/+bug/414142) gridgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); - controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); tempgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); + controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); /* Push select tool to the bottom of stack */ /** \todo @@ -243,7 +256,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) // display rect and zoom are now handled in sp_desktop_widget_realize() Geom::Rect const d(Geom::Point(0.0, 0.0), - Geom::Point(sp_document_width(document), sp_document_height(document))); + Geom::Point(document->getWidth(), document->getHeight())); SP_CTRLRECT(page)->setRectangle(d); SP_CTRLRECT(page_border)->setRectangle(d); @@ -260,12 +273,12 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) /* Connect event for page resize */ - _doc2dt[5] = sp_document_height (document); + _doc2dt[5] = document->getHeight(); sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt); _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this)); - NRArenaItem *ai = sp_item_invoke_show (SP_ITEM (sp_document_root (document)), + NRArenaItem *ai = SP_ITEM(document->getRoot())->invoke_show( SP_CANVAS_ARENA (drawing)->arena, dkey, SP_ITEM_SHOW_DISPLAY); @@ -382,7 +395,7 @@ void SPDesktop::destroy() } if (drawing) { - sp_item_invoke_hide (SP_ITEM (sp_document_root (doc())), dkey); + SP_ITEM(doc()->getRoot())->invoke_hide(dkey); drawing = NULL; } @@ -437,18 +450,24 @@ 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))); + _widget->setTitle( sp_desktop_document(this)->getName() ); } void SPDesktop::displayModeToggle() { - if (_display_mode == Inkscape::RENDERMODE_OUTLINE) { - _setDisplayMode(_saved_display_mode); - } else { + switch (_display_mode) { + case Inkscape::RENDERMODE_NORMAL: + _setDisplayMode(Inkscape::RENDERMODE_NO_FILTERS); + break; + case Inkscape::RENDERMODE_NO_FILTERS: _setDisplayMode(Inkscape::RENDERMODE_OUTLINE); + break; + case Inkscape::RENDERMODE_OUTLINE: + _setDisplayMode(Inkscape::RENDERMODE_NORMAL); + break; +// case Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW: + default: + _setDisplayMode(Inkscape::RENDERMODE_NORMAL); } } @@ -476,7 +495,7 @@ SPObject *SPDesktop::currentLayer() const void SPDesktop::setCurrentLayer(SPObject *object) { g_return_if_fail(SP_IS_GROUP(object)); g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) ); - // printf("Set Layer to ID: %s\n", SP_OBJECT_ID(object)); + // printf("Set Layer to ID: %s\n", object->getId()); _layer_hierarchy->setBottom(object); } @@ -534,7 +553,7 @@ bool SPDesktop::isLayer(SPObject *object) const { bool SPDesktop::isWithinViewport (SPItem *item) const { Geom::Rect const viewport = get_display_area(); - Geom::OptRect const bbox = sp_item_bbox_desktop(item); + Geom::OptRect const bbox = item->getBboxDesktop(); if (bbox) { return viewport.contains(*bbox); } else { @@ -591,8 +610,10 @@ SPDesktop::change_document (SPDocument *theDocument) Gtk::Window *parent = this->getToplevel(); g_assert(parent != NULL); SPDesktopWidget *dtw = (SPDesktopWidget *) parent->get_data("desktopwidget"); - if (dtw) dtw->desktop = this; - sp_desktop_widget_update_namedview(dtw); + if (dtw) { + dtw->desktop = this; + } + dtw->updateNamedview(); _namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this); _document_replaced_signal.emit (this, theDocument); @@ -608,14 +629,23 @@ SPDesktop::set_event_context (GtkType type, const gchar *config) while (event_context) { ec = event_context; sp_event_context_deactivate (ec); - event_context = ec->next; + // we have to keep event_context valid during destruction - otherwise writing + // destructors is next to impossible + SPEventContext *next = ec->next; sp_event_context_finish (ec); g_object_unref (G_OBJECT (ec)); + event_context = next; } + // The event_context will be null. This means that it will be impossible + // to process any event invoked by the lines below. See for example bug + // LP #622350. Cutting and undoing again in the node tool resets the event + // context to the node tool. In this bug the line bellow invokes GDK_LEAVE_NOTIFY + // events which cannot be handled and must be discarded. ec = sp_event_context_new (type, this, config, SP_EVENT_CONTEXT_STATIC); ec->next = event_context; event_context = ec; + // Now the event_context has been set again and we can process all events again sp_event_context_activate (ec); _event_context_changed_signal.emit (this, ec); } @@ -655,33 +685,30 @@ SPDesktop::set_coordinate_status (Geom::Point p) { } /** - * \see sp_document_item_from_list_at_point_bottom() + * \see SPDocument::getItemFromListAtPointBottom() */ -SPItem * -SPDesktop::item_from_list_at_point_bottom (const GSList *list, Geom::Point const p) const +SPItem *SPDesktop::getItemFromListAtPointBottom(const GSList *list, Geom::Point const p) const { g_return_val_if_fail (doc() != NULL, NULL); - return sp_document_item_from_list_at_point_bottom (dkey, SP_GROUP (doc()->root), list, p); + return SPDocument::getItemFromListAtPointBottom(dkey, SP_GROUP (doc()->root), list, p); } /** - * \see sp_document_item_at_point() + * \see SPDocument::getItemAtPoint() */ -SPItem * -SPDesktop::item_at_point (Geom::Point const p, bool into_groups, SPItem *upto) const +SPItem *SPDesktop::getItemAtPoint(Geom::Point const p, bool into_groups, SPItem *upto) const { g_return_val_if_fail (doc() != NULL, NULL); - return sp_document_item_at_point (doc(), dkey, p, into_groups, upto); + return doc()->getItemAtPoint( dkey, p, into_groups, upto); } /** - * \see sp_document_group_at_point() + * \see SPDocument::getGroupAtPoint() */ -SPItem * -SPDesktop::group_at_point (Geom::Point const p) const +SPItem *SPDesktop::getGroupAtPoint(Geom::Point const p) const { g_return_val_if_fail (doc() != NULL, NULL); - return sp_document_group_at_point (doc(), dkey, p); + return doc()->getGroupAtPoint(dkey, p); } /** @@ -769,11 +796,12 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double int clear = FALSE; if (!NR_DF_TEST_CLOSE (newscale, scale, 1e-4 * scale)) { - /* Set zoom factors */ + // zoom changed - set new zoom factors _d2w = Geom::Scale(newscale, -newscale); _w2d = Geom::Scale(1/newscale, 1/-newscale); sp_canvas_item_affine_absolute(SP_CANVAS_ITEM(main), _d2w); clear = TRUE; + signal_zoom_changed.emit(_d2w.descrim()); } /* Calculate top left corner (in document pixels) */ @@ -859,11 +887,6 @@ SPDesktop::next_zoom() zooms_future = g_list_remove (zooms_future, ((NRRect *) zooms_future->data)); } -#include "tools-switch.h" -#include "node-context.h" -#include "shape-editor.h" -#include "nodepath.h" - /** \brief Performs a quick zoom into what the user is working on \param enable Whether we're going in or out of quick zoom @@ -879,57 +902,18 @@ SPDesktop::zoom_quick (bool enable) _quick_zoom_stored_area = get_display_area(); bool zoomed = false; - if (!zoomed) { - SPItem * singleItem = selection->singleItem(); - if (singleItem != NULL && tools_isactive(this, TOOLS_NODES)) { - - Inkscape::NodePath::Path * nodepath = event_context->shape_editor->get_nodepath(); - // printf("I've got a nodepath, crazy\n"); - - Geom::Rect nodes; - bool firstnode = true; - - if (nodepath->selected) { - for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) { - Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data; - for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) { - Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data; - if (node->selected) { - // printf("\tSelected node\n"); - if (firstnode) { - nodes = Geom::Rect(node->pos, node->pos); - firstnode = false; - } else { - nodes.expandTo(node->pos); - } - - if (node->p.other != NULL) { - /* Include previous node pos */ - nodes.expandTo(node->p.other->pos); - - /* Include previous handle */ - if (!sp_node_side_is_line(node, &node->p)) { - nodes.expandTo(node->p.pos); - } - } - - if (node->n.other != NULL) { - /* Include previous node pos */ - nodes.expandTo(node->n.other->pos); - - /* Include previous handle */ - if (!sp_node_side_is_line(node, &node->n)) { - nodes.expandTo(node->n.pos); - } - } - } - } - } - - if (!firstnode && nodes.area() * 2.0 < _quick_zoom_stored_area.area()) { - set_display_area(nodes, 10); - zoomed = true; - } + // TODO This needs to migrate into the node tool, but currently the design + // of this method is sufficiently wrong to prevent this. + if (!zoomed && INK_IS_NODE_TOOL(event_context)) { + InkNodeTool *nt = static_cast(event_context); + if (!nt->_selected_nodes->empty()) { + Geom::Rect nodes = *nt->_selected_nodes->bounds(); + double area = nodes.area(); + // do not zoom if a single cusp node is selected aand the bounds + // have zero area. + if (!Geom::are_near(area, 0) && area * 2.0 < _quick_zoom_stored_area.area()) { + set_display_area(nodes, true); + zoomed = true; } } } @@ -937,7 +921,7 @@ SPDesktop::zoom_quick (bool enable) if (!zoomed) { Geom::OptRect const d = selection->bounds(); if (d && d->area() * 2.0 < _quick_zoom_stored_area.area()) { - set_display_area(*d, 10); + set_display_area(*d, true); zoomed = true; } } @@ -947,7 +931,7 @@ SPDesktop::zoom_quick (bool enable) zoomed = true; } } else { - set_display_area(_quick_zoom_stored_area, 0); + set_display_area(_quick_zoom_stored_area, false); } _quick_zoom_enabled = enable; @@ -980,6 +964,26 @@ SPDesktop::zoom_absolute_keep_point (double cx, double cy, double px, double py, 0.0); } +/** + * Apply the desktop's current style or the tool style to the object. + */ +void SPDesktop::applyCurrentOrToolStyle(SPObject *obj, Glib::ustring const &tool_path, bool with_text) +{ + SPCSSAttr *css_current = sp_desktop_get_style(this, with_text); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + if (prefs->getBool(tool_path + "/usecurrent") && css_current) { + obj->setCSS(css_current,"style"); + } else { + SPCSSAttr *css = prefs->getInheritedStyle(tool_path + "/style"); + obj->setCSS(css,"style"); + sp_repr_css_attr_unref(css); + } + if (css_current) { + sp_repr_css_attr_unref(css_current); + } +} + /** * Zoom to center with absolute zoom factor. */ @@ -1034,7 +1038,7 @@ void SPDesktop::zoom_page() { Geom::Rect d(Geom::Point(0, 0), - Geom::Point(sp_document_width(doc()), sp_document_height(doc()))); + Geom::Point(doc()->getWidth(), doc()->getHeight())); if (d.minExtent() < 1.0) { return; @@ -1051,12 +1055,12 @@ SPDesktop::zoom_page_width() { Geom::Rect const a = get_display_area(); - if (sp_document_width(doc()) < 1.0) { + if (doc()->getWidth() < 1.0) { return; } Geom::Rect d(Geom::Point(0, a.midpoint()[Geom::Y]), - Geom::Point(sp_document_width(doc()), a.midpoint()[Geom::Y])); + Geom::Point(doc()->getWidth(), a.midpoint()[Geom::Y])); set_display_area(d, 10); } @@ -1092,10 +1096,10 @@ void SPDesktop::zoom_drawing() { g_return_if_fail (doc() != NULL); - SPItem *docitem = SP_ITEM (sp_document_root (doc())); + SPItem *docitem = SP_ITEM(doc()->getRoot()); g_return_if_fail (docitem != NULL); - Geom::OptRect d = sp_item_bbox_desktop(docitem); + Geom::OptRect d = docitem->getBboxDesktop(); /* Note that the second condition here indicates that ** there are no items in the drawing. @@ -1387,7 +1391,7 @@ SPDesktop::emitToolSubselectionChanged(gpointer data) void SPDesktop::updateNow() { - sp_canvas_update_now(canvas); + sp_canvas_update_now(canvas); } void @@ -1430,8 +1434,7 @@ void SPDesktop::toggleGrids() } } else { //there is no grid present at the moment. add a rectangular grid and make it visible - Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview); - Inkscape::CanvasGrid::writeNewGridToRepr(repr, sp_desktop_document(this), Inkscape::GRID_RECTANGULAR); + namedview->writeNewGrid(sp_desktop_document(this), Inkscape::GRID_RECTANGULAR); showGrids(true); } } @@ -1449,9 +1452,8 @@ void SPDesktop::showGrids(bool show, bool dirty_document) void SPDesktop::toggleSnapGlobal() { - bool v = namedview->snap_manager.snapprefs.getSnapEnabledGlobally(); - Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview); - sp_repr_set_boolean(repr, "inkscape:snap-global", !v); + bool v = namedview->getSnapGlobal(); + namedview->setSnapGlobal(!v); } //---------------------------------------------------------------------- @@ -1494,7 +1496,7 @@ SPDesktop::setDocument (SPDocument *doc) { if (this->doc() && doc) { namedview->hide(this); - sp_item_invoke_hide (SP_ITEM (sp_document_root (this->doc())), dkey); + SP_ITEM(this->doc()->getRoot())->invoke_hide(dkey); } if (_layer_hierarchy) { @@ -1505,7 +1507,7 @@ SPDesktop::setDocument (SPDocument *doc) _layer_hierarchy->connectAdded(sigc::bind(sigc::ptr_fun(_layer_activated), this)); _layer_hierarchy->connectRemoved(sigc::bind(sigc::ptr_fun(_layer_deactivated), this)); _layer_hierarchy->connectChanged(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this)); - _layer_hierarchy->setTop(SP_DOCUMENT_ROOT(doc)); + _layer_hierarchy->setTop(doc->getRoot()); /* setup EventLog */ event_log = new Inkscape::EventLog(doc); @@ -1525,7 +1527,7 @@ SPDesktop::setDocument (SPDocument *doc) _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this)); number = namedview->getViewCount(); - ai = sp_item_invoke_show (SP_ITEM (sp_document_root (doc)), + ai = SP_ITEM(doc->getRoot())->invoke_show( SP_CANVAS_ARENA (drawing)->arena, dkey, SP_ITEM_SHOW_DISPLAY); @@ -1655,7 +1657,7 @@ static void _reconstruction_start (SPDesktop * desktop) { // printf("Desktop, starting reconstruction\n"); - desktop->_reconstruction_old_layer_id = g_strdup(SP_OBJECT_ID(desktop->currentLayer())); + desktop->_reconstruction_old_layer_id = g_strdup(desktop->currentLayer()->getId()); desktop->_layer_hierarchy->setBottom(desktop->currentRoot()); /* @@ -1788,7 +1790,7 @@ Geom::Point SPDesktop::dt2doc(Geom::Point const &p) const } -/** +/* * Pop event context from desktop's context stack. Never used. */ // void @@ -1830,4 +1832,4 @@ Geom::Point SPDesktop::dt2doc(Geom::Point const &p) const fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :