1 /**
2 * Glyph selector dialog.
3 */
5 /* Authors:
6 * Jon A. Cruz
7 *
8 * Copyright (C) 2010 Jon A. Cruz
9 * Released under GNU GPL, read the file 'COPYING' for more information
10 */
12 #include <glib-object.h>
14 #include "desktop-tracker.h"
16 #include "inkscape.h"
17 #include "desktop.h"
18 #include "widgets/desktop-widget.h"
20 namespace Inkscape {
21 namespace UI {
22 namespace Dialog {
24 DesktopTracker::DesktopTracker() :
25 base(0),
26 desktop(0),
27 widget(0),
28 hierID(0),
29 inkID(0),
30 trackActive(false),
31 desktopChangedSig()
32 {
33 }
35 DesktopTracker::~DesktopTracker()
36 {
37 disconnect();
38 }
40 void DesktopTracker::connect(GtkWidget *widget)
41 {
42 disconnect();
44 this->widget = widget;
46 // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues:
47 hierID = g_signal_connect( G_OBJECT(widget), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this );
48 inkID = g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(activateDesktopCB), this );
50 GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET);
51 if (wdgt && !base) {
52 SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt);
53 if (dtw && dtw->desktop) {
54 setBase(dtw->desktop); // may also set desktop
55 }
56 }
57 }
59 void DesktopTracker::disconnect()
60 {
61 if (hierID) {
62 if (widget) {
63 g_signal_handler_disconnect(G_OBJECT(widget), hierID);
64 }
65 hierID = 0;
66 }
67 if (inkID) {
68 if (INKSCAPE) {
69 g_signal_handler_disconnect(G_OBJECT(INKSCAPE), inkID);
70 }
71 inkID = 0;
72 }
73 }
75 void DesktopTracker::setBase(SPDesktop *desktop)
76 {
77 if (this->base != desktop) {
78 base = desktop;
79 // Do not override an existing target desktop
80 if (!this->desktop) {
81 setDesktop(desktop);
82 }
83 }
84 }
86 SPDesktop *DesktopTracker::getBase() const
87 {
88 return base;
89 }
91 SPDesktop *DesktopTracker::getDesktop() const
92 {
93 return desktop;
94 }
96 sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slot<void, SPDesktop*> & slot )
97 {
98 return desktopChangedSig.connect(slot);
99 }
101 gboolean DesktopTracker::activateDesktopCB(Inkscape::Application */*inkscape*/, SPDesktop *desktop, DesktopTracker *self )
102 {
103 if (self && self->trackActive) {
104 self->setDesktop(desktop);
105 }
106 return FALSE;
107 }
109 bool DesktopTracker::hierarchyChangeCB(GtkWidget * /*widget*/, GtkWidget* /*prev*/, DesktopTracker *self)
110 {
111 if (self) {
112 self->handleHierarchyChange();
113 }
114 return false;
115 }
117 void DesktopTracker::handleHierarchyChange()
118 {
119 GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET);
120 bool newFlag = (wdgt == 0); // true means not in an SPDesktopWidget, thus floating.
121 if (wdgt && !base) {
122 SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt);
123 if (dtw && dtw->desktop) {
124 setBase(dtw->desktop); // may also set desktop
125 }
126 }
127 if (newFlag != trackActive) {
128 trackActive = newFlag;
129 if (trackActive) {
130 setDesktop(SP_ACTIVE_DESKTOP);
131 } else if (desktop != base) {
132 setDesktop(getBase());
133 }
134 }
135 }
137 void DesktopTracker::setDesktop(SPDesktop *desktop)
138 {
139 if (desktop != this->desktop) {
140 this->desktop = desktop;
141 desktopChangedSig.emit(desktop);
142 }
143 }
146 } // namespace Dialog
147 } // namespace UI
148 } // namespace Inkscape
150 /*
151 Local Variables:
152 mode:c++
153 c-file-style:"stroustrup"
154 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
155 indent-tabs-mode:nil
156 fill-column:99
157 End:
158 */
159 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :