1 /*
2 * Authors:
3 * Ted Gould <ted@gould.cx>
4 *
5 * Copyright (C) 2005-2008 Authors
6 *
7 * Released under GNU GPL, read the file 'COPYING' for more information
8 */
10 #include <gtkmm/stock.h>
11 #include <gtkmm/checkbutton.h>
12 #include <gtkmm/separator.h>
13 #include <glibmm/i18n.h>
15 #include "../dialogs/dialog-events.h"
16 #include "xml/repr.h"
18 // Used to get SP_ACTIVE_DESKTOP
19 #include "inkscape.h"
20 #include "desktop.h"
22 #include "preferences.h"
23 #include "effect.h"
24 #include "implementation/implementation.h"
26 #include "prefdialog.h"
29 namespace Inkscape {
30 namespace Extension {
33 /** \brief Creates a new preference dialog for extension preferences
34 \param name Name of the Extension who's dialog this is
35 \param help The help string for the extension (NULL if none)
36 \param controls The extension specific widgets in the dialog
38 This function initializes the dialog with the name of the extension
39 in the title. It adds a few buttons and sets up handlers for
40 them. It also places the passed in widgets into the dialog.
41 */
42 PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * controls, Effect * effect) :
43 Gtk::Dialog::Dialog(_(name.c_str()), true, true),
44 _help(help),
45 _name(name),
46 _button_ok(NULL),
47 _button_cancel(NULL),
48 _button_preview(NULL),
49 _param_preview(NULL),
50 _effect(effect),
51 _exEnv(NULL)
52 {
53 Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
54 if (controls == NULL) {
55 if (_effect == NULL) {
56 std::cout << "AH!!! No controls and no effect!!!" << std::endl;
57 return;
58 }
59 controls = _effect->get_imp()->prefs_effect(_effect, SP_ACTIVE_DESKTOP, &_signal_param_change, NULL);
60 _signal_param_change.connect(sigc::mem_fun(this, &PrefDialog::param_change));
61 }
63 hbox->pack_start(*controls, true, true, 6);
64 hbox->show();
65 this->get_vbox()->pack_start(*hbox, true, true, 6);
67 /*
68 Gtk::Button * help_button = add_button(Gtk::Stock::HELP, Gtk::RESPONSE_HELP);
69 if (_help == NULL)
70 help_button->set_sensitive(false);
71 */
72 _button_cancel = add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CANCEL);
73 _button_cancel->set_use_stock(true);
75 _button_ok = add_button(Gtk::Stock::APPLY, Gtk::RESPONSE_OK);
76 _button_ok->set_use_stock(true);
77 set_default_response(Gtk::RESPONSE_OK);
78 _button_ok->grab_focus();
80 if (_effect != NULL) {
81 if (_param_preview == NULL) {
82 XML::Document * doc = sp_repr_read_mem(live_param_xml, strlen(live_param_xml), NULL);
83 _param_preview = Parameter::make(doc->root(), _effect);
84 }
86 Gtk::HSeparator * sep = Gtk::manage(new Gtk::HSeparator());
87 sep->show();
88 this->get_vbox()->pack_start(*sep, true, true, 4);
90 hbox = Gtk::manage(new Gtk::HBox());
91 _button_preview = _param_preview->get_widget(NULL, NULL, &_signal_preview);
92 _button_preview->show();
93 hbox->pack_start(*_button_preview, true, true,6);
94 hbox->show();
95 this->get_vbox()->pack_start(*hbox, true, true, 6);
97 Gtk::HBox * hbox = dynamic_cast<Gtk::HBox *>(_button_preview);
98 if (hbox != NULL) {
99 Gtk::Widget * back = hbox->children().back().get_widget();
100 Gtk::CheckButton * cb = dynamic_cast<Gtk::CheckButton *>(back);
101 _checkbox_preview = cb;
102 }
104 preview_toggle();
105 _signal_preview.connect(sigc::mem_fun(this, &PrefDialog::preview_toggle));
106 }
108 GtkWidget *dlg = GTK_WIDGET(gobj());
109 sp_transientize(dlg);
111 return;
112 }
114 PrefDialog::~PrefDialog ( )
115 {
116 if (_param_preview != NULL) {
117 delete _param_preview;
118 _param_preview = NULL;
119 }
121 if (_exEnv != NULL) {
122 _exEnv->cancel();
123 delete _exEnv;
124 _exEnv = NULL;
125 }
127 if (_effect != NULL) {
128 _effect->set_pref_dialog(NULL);
129 }
131 return;
132 }
134 #if 0
135 /** \brief Runs the dialog
136 \return The response to the dialog
138 This function overrides the run function in the GTKmm dialog
139 class, but basically it only calls it. This function only
140 handles the \c Gtk::RESPONSE_HELP return, and in that case it
141 brings up the help window. All other return values are returned
142 to the calling function.
143 */
144 int
145 PrefDialog::run (void) {
146 int resp = Gtk::RESPONSE_HELP;
147 while (resp == Gtk::RESPONSE_HELP) {
148 resp = Gtk::Dialog::run();
149 if (resp == Gtk::RESPONSE_HELP) {
150 /*
151 if (_helpDialog == NULL) {
152 _helpDialog = new HelpDialog(_help);
153 }
154 */
155 }
156 }
157 return resp;
158 }
159 #endif
161 void
162 PrefDialog::preview_toggle (void) {
163 if(_param_preview->get_bool(NULL, NULL)) {
164 set_modal(true);
165 if (_exEnv == NULL) {
166 _exEnv = new ExecutionEnv(_effect, SP_ACTIVE_DESKTOP, NULL, false, false);
167 _exEnv->run();
168 }
169 } else {
170 set_modal(false);
171 if (_exEnv != NULL) {
172 _exEnv->cancel();
173 _exEnv->undo();
174 delete _exEnv;
175 _exEnv = NULL;
176 }
177 }
178 }
180 void
181 PrefDialog::param_change (void) {
182 if (_exEnv != NULL) {
183 _timersig.disconnect();
184 _timersig = Glib::signal_timeout().connect(sigc::mem_fun(this, &PrefDialog::param_timer_expire),
185 250, /* ms */
186 Glib::PRIORITY_DEFAULT_IDLE);
187 }
189 return;
190 }
192 bool
193 PrefDialog::param_timer_expire (void) {
194 if (_exEnv != NULL) {
195 _exEnv->cancel();
196 _exEnv->undo();
197 _exEnv->run();
198 }
200 return false;
201 }
203 void
204 PrefDialog::on_response (int signal) {
205 if (signal == Gtk::RESPONSE_OK) {
206 if (_exEnv == NULL) {
207 if (_effect != NULL) {
208 _effect->effect(SP_ACTIVE_DESKTOP);
209 } else {
210 // Shutdown run()
211 return;
212 }
213 } else {
214 if (_exEnv->wait()) {
215 _exEnv->commit();
216 } else {
217 _exEnv->undo();
218 }
219 delete _exEnv;
220 _exEnv = NULL;
221 }
222 }
224 if (_param_preview != NULL) {
225 _checkbox_preview->set_active(false);
226 }
228 if ((signal == Gtk::RESPONSE_CANCEL || signal == Gtk::RESPONSE_DELETE_EVENT) && _effect != NULL) {
229 delete this;
230 }
232 return;
233 }
235 #include "internal/clear-n_.h"
237 const char * PrefDialog::live_param_xml = "<param name=\"__live_effect__\" type=\"boolean\" gui-text=\"" N_("Live Preview") "\" gui-description=\"" N_("Controls whether the effect settings are rendered live on canvas") "\" scope=\"user\">false</param>";
239 }; }; /* namespace Inkscape, Extension */
241 /*
242 Local Variables:
243 mode:c++
244 c-file-style:"stroustrup"
245 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
246 indent-tabs-mode:nil
247 fill-column:99
248 End:
249 */
250 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :