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 /* local desktop event handlers */
33 static void handle_activate_desktop(Inkscape::Application *, SPDesktop *, void *);
34 static void handle_deactivate_desktop(Inkscape::Application *, SPDesktop *, void *);
36 struct PanelDialogBase {
37 virtual void present() =0;
38 virtual Panel &getPanel() =0;
39 virtual ~PanelDialogBase() {}
41 private:
42 virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document) =0;
43 virtual void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *) =0;
44 virtual void _propagateDesktopDeactivated(Inkscape::Application *, SPDesktop *) =0;
46 friend void handle_activate_desktop(Inkscape::Application *, SPDesktop *, void *);
47 friend void handle_deactivate_desktop(Inkscape::Application *, SPDesktop *, void *);
48 };
50 template <typename Behavior>
51 class PanelDialog : public PanelDialogBase, public Inkscape::UI::Dialog::Dialog {
53 public:
54 PanelDialog(Panel &contents, char const *prefs_path, int const verb_num,
55 Glib::ustring const &apply_label);
57 virtual ~PanelDialog() {}
59 template <typename T>
60 static PanelDialog<Behavior> *create();
62 virtual void present();
64 Panel &getPanel() { return _panel; }
66 private:
67 void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document);
68 void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *);
69 void _propagateDesktopDeactivated(Inkscape::Application *, SPDesktop *);
71 Panel &_panel;
72 sigc::connection _document_replaced_connection;
74 PanelDialog(); // no constructor without params
75 PanelDialog(PanelDialog<Behavior> const &d); // no copy
76 PanelDialog<Behavior>& operator=(PanelDialog<Behavior> const &d); // no assign
78 };
80 template <typename B>
81 PanelDialog<B>::PanelDialog(Panel &panel, char const *prefs_path, int const verb_num, Glib::ustring const &apply_label) :
82 Dialog(&B::create, prefs_path, verb_num, apply_label),
83 _panel (panel)
84 {
85 Gtk::VBox *vbox = get_vbox();
86 _panel.signalResponse().connect(sigc::mem_fun(*this, &PanelDialog::_handleResponse));
87 _panel.signalPresent().connect(sigc::mem_fun(*this, &PanelDialog::present));
89 vbox->pack_start(_panel, true, true, 0);
91 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
93 _propagateDesktopActivated(INKSCAPE, desktop);
95 _document_replaced_connection =
96 desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced));
98 if (prefs_get_int_attribute ("dialogs", "showclose", 0) || !apply_label.empty()) {
99 // TODO: make the order of buttons obey the global preference
100 if (!apply_label.empty()) {
101 panel.addResponseButton(apply_label, Gtk::RESPONSE_APPLY);
102 panel.setDefaultResponse(Gtk::RESPONSE_APPLY);
103 }
104 panel.addResponseButton(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
105 }
107 show_all_children();
108 }
110 template <typename B> template <typename P>
111 PanelDialog<B> *
112 PanelDialog<B>::create()
113 {
114 Panel &panel = P::getInstance();
115 return new PanelDialog<B>(panel, panel.getPrefsPath(), panel.getVerb(), panel.getApplyLabel());
116 }
118 /**
119 * Specialize factory method for panel dialogs with floating behavior in order to make them work as
120 * singletons, i.e. allow them track the current active desktop.
121 */
122 template <> template <typename P>
123 PanelDialog<Behavior::FloatingBehavior> *
124 PanelDialog<Behavior::FloatingBehavior>::create()
125 {
126 Panel &panel = P::getInstance();
127 PanelDialog<Behavior::FloatingBehavior> *instance =
128 new PanelDialog<Behavior::FloatingBehavior>(panel, panel.getPrefsPath(),
129 panel.getVerb(), panel.getApplyLabel());
131 g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(handle_activate_desktop), instance);
132 g_signal_connect(G_OBJECT(INKSCAPE), "deactivate_desktop", G_CALLBACK(handle_deactivate_desktop), instance);
134 return instance;
135 }
137 template <typename B>
138 void
139 PanelDialog<B>::present()
140 {
141 Dialog::present();
142 }
144 template <typename B>
145 void
146 PanelDialog<B>::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument *document)
147 {
148 _panel.signalDocumentReplaced().emit(desktop, document);
149 }
151 template <typename B>
152 void
153 PanelDialog<B>::_propagateDesktopActivated(Inkscape::Application *application, SPDesktop *desktop)
154 {
155 _document_replaced_connection =
156 desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced));
157 _panel.signalActivateDesktop().emit(application, desktop);
158 }
160 template <typename B>
161 void
162 PanelDialog<B>::_propagateDesktopDeactivated(Inkscape::Application *application, SPDesktop *desktop)
163 {
164 _document_replaced_connection.disconnect();
165 _panel.signalDeactiveDesktop().emit(application, desktop);
166 }
169 static void
170 handle_activate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data)
171 {
172 g_return_if_fail(data != NULL);
173 static_cast<PanelDialogBase *>(data)->_propagateDesktopActivated(application, desktop);
174 }
176 static void
177 handle_deactivate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data)
178 {
179 g_return_if_fail(data != NULL);
180 static_cast<PanelDialogBase *>(data)->_propagateDesktopDeactivated(application, desktop);
181 }
183 } // namespace Dialog
184 } // namespace UI
185 } // namespace Inkscape
187 #endif //INKSCAPE_PANEL_DIALOG_H
189 /*
190 Local Variables:
191 mode:c++
192 c-file-style:"stroustrup"
193 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
194 indent-tabs-mode:nil
195 fill-column:99
196 End:
197 */
198 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :