6a2218a06014018645e2917b2d8e74615e6774d1
1 /**
2 * \brief A panel holding dialog
3 *
4 * Authors:
5 * Gustav Broberg <broberg@kth.se>
6 *
7 * Copyright (C) 2007 Authors
8 *
9 * Released under GNU GPL. Read the file 'COPYING' for more information.
10 */
12 #ifndef INKSCAPE_PANEL_DIALOG_H
13 #define INKSCAPE_PANEL_DIALOG_H
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
19 #include <gtkmm/stock.h>
21 #include "verbs.h"
22 #include "dialog.h"
23 #include "dialogs/swatches.h"
24 #include "ui/dialog/floating-behavior.h"
25 #include "ui/dialog/dock-behavior.h"
26 #include "prefs-utils.h"
28 namespace Inkscape {
29 namespace UI {
30 namespace Dialog {
32 class PanelDialogBase {
33 public:
34 PanelDialogBase(Panel &panel, char const */*prefs_path*/, int const /*verb_num*/,
35 Glib::ustring const &/*apply_label*/) :
36 _panel (panel) { }
38 virtual void present() = 0;
39 virtual ~PanelDialogBase() {}
41 virtual Panel &getPanel() { return _panel; }
43 protected:
44 static void handle_deactivate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) {
45 g_return_if_fail(data != NULL);
46 static_cast<PanelDialogBase *>(data)->_propagateDesktopDeactivated(application, desktop);
47 }
49 static void _handle_activate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) {
50 g_return_if_fail(data != NULL);
51 static_cast<PanelDialogBase *>(data)->_propagateDesktopActivated(application, desktop);
52 }
54 inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document);
55 inline virtual void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *);
56 inline virtual void _propagateDesktopDeactivated(Inkscape::Application *, SPDesktop *);
58 Panel &_panel;
59 sigc::connection _document_replaced_connection;
60 };
62 template <typename Behavior>
63 class PanelDialog : public PanelDialogBase, public Inkscape::UI::Dialog::Dialog {
65 public:
66 PanelDialog(Panel &contents, char const *prefs_path, int const verb_num,
67 Glib::ustring const &apply_label);
69 virtual ~PanelDialog() {}
71 template <typename T>
72 static PanelDialog<Behavior> *create();
74 inline virtual void present();
76 private:
77 PanelDialog(); // no constructor without params
78 PanelDialog(PanelDialog<Behavior> const &d); // no copy
79 PanelDialog<Behavior>& operator=(PanelDialog<Behavior> const &d); // no assign
80 };
83 template <>
84 class PanelDialog<Behavior::FloatingBehavior> :
85 public PanelDialogBase, public Inkscape::UI::Dialog::Dialog {
87 public:
88 inline PanelDialog(Panel &contents, char const *prefs_path, int const verb_num,
89 Glib::ustring const &apply_label);
91 virtual ~PanelDialog() {}
93 template <typename T>
94 static PanelDialog<Behavior::FloatingBehavior> *create();
96 inline virtual void present();
98 private:
99 PanelDialog(); // no constructor without params
100 PanelDialog(PanelDialog<Behavior::FloatingBehavior> const &d); // no copy
101 PanelDialog<Behavior::FloatingBehavior>&
102 operator=(PanelDialog<Behavior::FloatingBehavior> const &d); // no assign
103 };
107 void
108 PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument *document)
109 {
110 _panel.signalDocumentReplaced().emit(desktop, document);
111 }
113 void
114 PanelDialogBase::_propagateDesktopActivated(Inkscape::Application *application, SPDesktop *desktop)
115 {
116 _document_replaced_connection =
117 desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced));
118 _panel.signalActivateDesktop().emit(application, desktop);
119 }
121 void
122 PanelDialogBase::_propagateDesktopDeactivated(Inkscape::Application *application, SPDesktop *desktop)
123 {
124 _document_replaced_connection.disconnect();
125 _panel.signalDeactiveDesktop().emit(application, desktop);
126 }
129 template <typename B>
130 PanelDialog<B>::PanelDialog(Panel &panel, char const *prefs_path, int const verb_num,
131 Glib::ustring const &apply_label) :
132 PanelDialogBase(panel, prefs_path, verb_num, apply_label),
133 Dialog(&B::create, prefs_path, verb_num, apply_label)
134 {
135 Gtk::VBox *vbox = get_vbox();
136 _panel.signalResponse().connect(sigc::mem_fun(*this, &PanelDialog::_handleResponse));
138 vbox->pack_start(_panel, true, true, 0);
140 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
142 _propagateDesktopActivated(INKSCAPE, desktop);
144 _document_replaced_connection =
145 desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced));
147 if (prefs_get_int_attribute ("dialogs", "showclose", 0) || !apply_label.empty()) {
148 // TODO: make the order of buttons obey the global preference
149 if (!apply_label.empty()) {
150 panel.addResponseButton(apply_label, Gtk::RESPONSE_APPLY);
151 panel.setDefaultResponse(Gtk::RESPONSE_APPLY);
152 }
153 panel.addResponseButton(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
154 }
156 show_all_children();
157 }
159 template <typename B> template <typename P>
160 PanelDialog<B> *
161 PanelDialog<B>::create()
162 {
163 Panel &panel = P::getInstance();
164 return new PanelDialog<B>(panel, panel.getPrefsPath(), panel.getVerb(), panel.getApplyLabel());
165 }
167 template <typename B>
168 void
169 PanelDialog<B>::present()
170 {
171 Dialog::present();
172 _panel.present();
173 }
175 PanelDialog<Behavior::FloatingBehavior>::PanelDialog(Panel &panel, char const *prefs_path,
176 int const verb_num, Glib::ustring const &apply_label) :
177 PanelDialogBase(panel, prefs_path, verb_num, apply_label),
178 Dialog(&Behavior::FloatingBehavior::create, prefs_path, verb_num, apply_label)
179 {
180 Gtk::VBox *vbox = get_vbox();
181 _panel.signalResponse().connect(sigc::mem_fun(*this, &PanelDialog::_handleResponse));
183 vbox->pack_start(_panel, true, true, 0);
185 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
187 _propagateDesktopActivated(INKSCAPE, desktop);
189 _document_replaced_connection =
190 desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced));
192 if (prefs_get_int_attribute ("dialogs", "showclose", 0) || !apply_label.empty()) {
193 // TODO: make the order of buttons obey the global preference
194 if (!apply_label.empty()) {
195 panel.addResponseButton(apply_label, Gtk::RESPONSE_APPLY);
196 panel.setDefaultResponse(Gtk::RESPONSE_APPLY);
197 }
198 panel.addResponseButton(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
199 }
201 show_all_children();
202 }
204 void
205 PanelDialog<Behavior::FloatingBehavior>::present()
206 {
207 Dialog::present();
208 _panel.present();
209 }
211 /**
212 * Specialize factory method for panel dialogs with floating behavior in order to make them work as
213 * singletons, i.e. allow them track the current active desktop.
214 */
215 template <typename P>
216 PanelDialog<Behavior::FloatingBehavior> *
217 PanelDialog<Behavior::FloatingBehavior>::create()
218 {
219 Panel &panel = P::getInstance();
220 PanelDialog<Behavior::FloatingBehavior> *instance =
221 new PanelDialog<Behavior::FloatingBehavior>(panel, panel.getPrefsPath(),
222 panel.getVerb(), panel.getApplyLabel());
224 g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(_handle_activate_desktop), instance);
225 g_signal_connect(G_OBJECT(INKSCAPE), "deactivate_desktop", G_CALLBACK(handle_deactivate_desktop), instance);
227 return instance;
228 }
230 } // namespace Dialog
231 } // namespace UI
232 } // namespace Inkscape
234 #endif //INKSCAPE_PANEL_DIALOG_H
236 /*
237 Local Variables:
238 mode:c++
239 c-file-style:"stroustrup"
240 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
241 indent-tabs-mode:nil
242 fill-column:99
243 End:
244 */
245 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :