1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2007 MenTaLguY <mental@rydia.net>
4  *   Abhishek Sharma
5  *
6  * Released under GNU GPL v2+, read the file 'COPYING' for more information.
7  */
8 
9 #include "style-subject.h"
10 
11 #include "desktop.h"
12 #include "desktop-style.h"
13 #include "selection.h"
14 
15 #include "xml/sp-css-attr.h"
16 
17 namespace Inkscape {
18 namespace UI {
19 namespace Widget {
20 
StyleSubject()21 StyleSubject::StyleSubject() : _desktop(nullptr) {
22 }
23 
~StyleSubject()24 StyleSubject::~StyleSubject() {
25     setDesktop(nullptr);
26 }
27 
setDesktop(SPDesktop * desktop)28 void StyleSubject::setDesktop(SPDesktop *desktop) {
29     if (desktop != _desktop) {
30         if (desktop) {
31             GC::anchor(desktop);
32         }
33         if (_desktop) {
34             GC::release(_desktop);
35         }
36         _desktop = desktop;
37         _afterDesktopSwitch(desktop);
38         _emitChanged();
39     }
40 }
41 
42 StyleSubject::Selection::Selection() = default;
43 
44 StyleSubject::Selection::~Selection() = default;
45 
_getSelection() const46 Inkscape::Selection *StyleSubject::Selection::_getSelection() const {
47     SPDesktop *desktop = getDesktop();
48     if (desktop) {
49         return desktop->getSelection();
50     } else {
51         return nullptr;
52     }
53 }
54 
list()55 std::vector<SPObject*> StyleSubject::Selection::list() {
56     Inkscape::Selection *selection = _getSelection();
57     if(selection) {
58         return std::vector<SPObject *>(selection->objects().begin(), selection->objects().end());
59     }
60 
61     return std::vector<SPObject*>();
62 }
63 
getBounds(SPItem::BBoxType type)64 Geom::OptRect StyleSubject::Selection::getBounds(SPItem::BBoxType type) {
65     Inkscape::Selection *selection = _getSelection();
66     if (selection) {
67         return selection->bounds(type);
68     } else {
69         return Geom::OptRect();
70     }
71 }
72 
queryStyle(SPStyle * query,int property)73 int StyleSubject::Selection::queryStyle(SPStyle *query, int property) {
74     SPDesktop *desktop = getDesktop();
75     if (desktop) {
76         return sp_desktop_query_style(desktop, query, property);
77     } else {
78         return QUERY_STYLE_NOTHING;
79     }
80 }
81 
_afterDesktopSwitch(SPDesktop * desktop)82 void StyleSubject::Selection::_afterDesktopSwitch(SPDesktop *desktop) {
83     _sel_changed.disconnect();
84     _subsel_changed.disconnect();
85     _sel_modified.disconnect();
86     if (desktop) {
87         _subsel_changed = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &Selection::_emitChanged)));
88         Inkscape::Selection *selection = desktop->getSelection();
89         if (selection) {
90             _sel_changed = selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &Selection::_emitChanged)));
91             _sel_modified = selection->connectModified(sigc::mem_fun(*this, &Selection::_emitModified));
92         }
93     }
94 }
95 
setCSS(SPCSSAttr * css)96 void StyleSubject::Selection::setCSS(SPCSSAttr *css) {
97     SPDesktop *desktop = getDesktop();
98     if (desktop) {
99         sp_desktop_set_style(desktop, css);
100     }
101 }
102 
CurrentLayer()103 StyleSubject::CurrentLayer::CurrentLayer() {
104     _element = nullptr;
105 }
106 
107 StyleSubject::CurrentLayer::~CurrentLayer() = default;
108 
_setLayer(SPObject * layer)109 void StyleSubject::CurrentLayer::_setLayer(SPObject *layer) {
110     _layer_release.disconnect();
111     _layer_modified.disconnect();
112     if (_element) {
113         sp_object_unref(_element, nullptr);
114     }
115     _element = layer;
116     if (layer) {
117         sp_object_ref(layer, nullptr);
118         _layer_release = layer->connectRelease(sigc::hide(sigc::bind(sigc::mem_fun(*this, &CurrentLayer::_setLayer), (SPObject *)nullptr)));
119         _layer_modified = layer->connectModified(sigc::hide(sigc::hide(sigc::mem_fun(*this, &CurrentLayer::_emitChanged))));
120     }
121     _emitChanged();
122 }
123 
_getLayer() const124 SPObject *StyleSubject::CurrentLayer::_getLayer() const {
125     return _element;
126 }
127 
_getLayerSList() const128 SPObject *StyleSubject::CurrentLayer::_getLayerSList() const {
129         return _element;
130 
131 }
132 
list()133 std::vector<SPObject*> StyleSubject::CurrentLayer::list(){
134     std::vector<SPObject*> list;
135     list.push_back(_element);
136     return list;
137 }
138 
getBounds(SPItem::BBoxType type)139 Geom::OptRect StyleSubject::CurrentLayer::getBounds(SPItem::BBoxType type) {
140     SPObject *layer = _getLayer();
141     if (layer && SP_IS_ITEM(layer)) {
142         return SP_ITEM(layer)->desktopBounds(type);
143     } else {
144         return Geom::OptRect();
145     }
146 }
147 
queryStyle(SPStyle * query,int property)148 int StyleSubject::CurrentLayer::queryStyle(SPStyle *query, int property) {
149 	std::vector<SPItem*> list;
150     SPObject* i=_getLayerSList();
151     if (i) {
152 		list.push_back((SPItem*)i);
153         return sp_desktop_query_style_from_list(list, query, property);
154     } else {
155         return QUERY_STYLE_NOTHING;
156     }
157 }
158 
setCSS(SPCSSAttr * css)159 void StyleSubject::CurrentLayer::setCSS(SPCSSAttr *css) {
160     SPObject *layer = _getLayer();
161     if (layer) {
162         sp_desktop_apply_css_recursive(layer, css, true);
163     }
164 }
165 
_afterDesktopSwitch(SPDesktop * desktop)166 void StyleSubject::CurrentLayer::_afterDesktopSwitch(SPDesktop *desktop) {
167     _layer_switched.disconnect();
168     if (desktop) {
169         _layer_switched = desktop->connectCurrentLayerChanged(sigc::mem_fun(*this, &CurrentLayer::_setLayer));
170         _setLayer(desktop->currentLayer());
171     } else {
172         _setLayer(nullptr);
173     }
174 }
175 
176 }
177 }
178 }
179 
180 /*
181   Local Variables:
182   mode:c++
183   c-file-style:"stroustrup"
184   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
185   indent-tabs-mode:nil
186   fill-column:99
187   End:
188 */
189 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
190