1 /**
2 * \brief Inkscape Preferences dialog
3 *
4 * Authors:
5 * Marco Scholten
6 * Bruno Dilly <bruno.dilly@gmail.com>
7 *
8 * Copyright (C) 2004, 2006, 2007 Authors
9 *
10 * Released under GNU GPL. Read the file 'COPYING' for more information.
11 */
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
17 #include <gtkmm/frame.h>
18 #include <gtkmm/alignment.h>
19 #include <gtkmm/box.h>
21 #include "prefs-utils.h"
22 #include "ui/widget/preferences-widget.h"
23 #include "verbs.h"
24 #include "selcue.h"
25 #include <iostream>
26 #include "enums.h"
27 #include "inkscape.h"
28 #include "desktop-handles.h"
29 #include "message-stack.h"
30 #include "style.h"
31 #include "selection.h"
32 #include "selection-chemistry.h"
33 #include "xml/repr.h"
35 using namespace Inkscape::UI::Widget;
37 namespace Inkscape {
38 namespace UI {
39 namespace Widget {
41 DialogPage::DialogPage()
42 {
43 this->set_border_width(12);
44 this->set_col_spacings(12);
45 this->set_row_spacings(6);
46 }
48 void DialogPage::add_line(bool indent, const Glib::ustring label, Gtk::Widget& widget, const Glib::ustring suffix, const Glib::ustring& tip, bool expand_widget)
49 {
50 int start_col;
51 int row = this->property_n_rows();
52 Gtk::Widget* w;
53 if (expand_widget)
54 {
55 w = &widget;
56 }
57 else
58 {
59 Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
60 hb->set_spacing(12);
61 hb->pack_start(widget,false,false);
62 w = (Gtk::Widget*) hb;
63 }
64 if (label != "")
65 {
66 Gtk::Label* label_widget;
67 label_widget = Gtk::manage(new Gtk::Label(label , Gtk::ALIGN_LEFT , Gtk::ALIGN_CENTER, true));
68 label_widget->set_mnemonic_widget(widget);
69 if (indent)
70 {
71 Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment());
72 alignment->set_padding(0, 0, 12, 0);
73 alignment->add(*label_widget);
74 this->attach(*alignment , 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
75 }
76 else
77 this->attach(*label_widget , 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
78 start_col = 1;
79 }
80 else
81 start_col = 0;
83 if (start_col == 0 && indent) //indent this widget
84 {
85 Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment());
86 alignment->set_padding(0, 0, 12, 0);
87 alignment->add(*w);
88 this->attach(*alignment, start_col, 2, row, row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::AttachOptions(), 0, 0);
89 }
90 else
91 {
92 this->attach(*w, start_col, 2, row, row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::AttachOptions(), 0, 0);
93 }
95 if (suffix != "")
96 {
97 Gtk::Label* suffix_widget = Gtk::manage(new Gtk::Label(suffix , Gtk::ALIGN_LEFT , Gtk::ALIGN_CENTER, true));
98 if (expand_widget)
99 this->attach(*suffix_widget, 2, 3, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
100 else
101 ((Gtk::HBox*)w)->pack_start(*suffix_widget,false,false);
102 }
104 if (tip != "")
105 {
106 _tooltips.set_tip (widget, tip);
107 }
109 }
111 void DialogPage::add_group_header(Glib::ustring name)
112 {
113 int row = this->property_n_rows();
114 if (name != "")
115 {
116 Gtk::Label* label_widget = Gtk::manage(new Gtk::Label(Glib::ustring(/*"<span size='large'>*/"<b>") + name +
117 Glib::ustring("</b>"/*</span>"*/) , Gtk::ALIGN_LEFT , Gtk::ALIGN_CENTER, true));
118 label_widget->set_use_markup(true);
119 this->attach(*label_widget , 0, 4, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
120 if (row != 1)
121 this->set_row_spacing(row - 1, 18);
122 }
123 }
125 void DialogPage::set_tip(Gtk::Widget& widget, const Glib::ustring& tip)
126 {
127 _tooltips.set_tip (widget, tip);
128 }
130 void PrefCheckButton::init(const Glib::ustring& label, const std::string& prefs_path, const std::string& attr,
131 bool default_value)
132 {
133 _prefs_path = prefs_path;
134 _attr = attr;
135 this->set_label(label);
136 this->set_active( prefs_get_int_attribute (_prefs_path.c_str(), _attr.c_str(), (int)default_value) );
137 }
139 void PrefCheckButton::on_toggled()
140 {
141 if (this->is_visible()) //only take action if the user toggled it
142 {
143 prefs_set_int_attribute (_prefs_path.c_str(), _attr.c_str(), (int) this->get_active());
144 }
145 }
147 void PrefRadioButton::init(const Glib::ustring& label, const std::string& prefs_path, const std::string& attr,
148 const std::string& string_value, bool default_value, PrefRadioButton* group_member)
149 {
150 _value_type = VAL_STRING;
151 _prefs_path = prefs_path;
152 _attr = attr;
153 _string_value = string_value;
154 this->set_label(label);
155 if (group_member)
156 {
157 Gtk::RadioButtonGroup rbg = group_member->get_group();
158 this->set_group(rbg);
159 }
160 const gchar* val = prefs_get_string_attribute( _prefs_path.c_str(), _attr.c_str() );
161 if ( val )
162 this->set_active( std::string( val ) == _string_value);
163 else
164 this->set_active( false );
165 }
167 void PrefRadioButton::init(const Glib::ustring& label, const std::string& prefs_path, const std::string& attr,
168 int int_value, bool default_value, PrefRadioButton* group_member)
169 {
170 _value_type = VAL_INT;
171 _prefs_path = prefs_path;
172 _attr = attr;
173 _int_value = int_value;
174 this->set_label(label);
175 if (group_member)
176 {
177 Gtk::RadioButtonGroup rbg = group_member->get_group();
178 this->set_group(rbg);
179 }
180 if (default_value)
181 this->set_active( prefs_get_int_attribute( _prefs_path.c_str(), _attr.c_str(), int_value ) == _int_value);
182 else
183 this->set_active( prefs_get_int_attribute( _prefs_path.c_str(), _attr.c_str(), int_value + 1 )== _int_value);
184 }
186 void PrefRadioButton::on_toggled()
187 {
188 this->changed_signal.emit(this->get_active());
189 if (this->is_visible() && this->get_active() ) //only take action if toggled by user (to active)
190 {
191 if ( _value_type == VAL_STRING )
192 prefs_set_string_attribute ( _prefs_path.c_str(), _attr.c_str(), _string_value.c_str());
193 else if ( _value_type == VAL_INT )
194 prefs_set_int_attribute ( _prefs_path.c_str(), _attr.c_str(), _int_value);
195 }
196 }
198 void PrefSpinButton::init(const std::string& prefs_path, const std::string& attr,
199 double lower, double upper, double step_increment, double page_increment,
200 double default_value, bool is_int, bool is_percent)
201 {
202 _prefs_path = prefs_path;
203 _attr = attr;
204 _is_int = is_int;
205 _is_percent = is_percent;
207 double value;
208 if (is_int)
209 if (is_percent)
210 value = 100 * prefs_get_double_attribute_limited (prefs_path.c_str(), attr.c_str(), default_value, lower/100.0, upper/100.0);
211 else
212 value = (double) prefs_get_int_attribute_limited (prefs_path.c_str(), attr.c_str(), (int) default_value, (int) lower, (int) upper);
213 else
214 value = prefs_get_double_attribute_limited (prefs_path.c_str(), attr.c_str(), default_value, lower, upper);
216 this->set_range (lower, upper);
217 this->set_increments (step_increment, page_increment);
218 this->set_numeric();
219 this->set_value (value);
220 this->set_width_chars(6);
221 if (is_int)
222 this->set_digits(0);
223 else if (step_increment < 0.1)
224 this->set_digits(4);
225 else
226 this->set_digits(2);
228 }
230 void PrefSpinButton::on_value_changed()
231 {
232 if (this->is_visible()) //only take action if user changed value
233 {
234 if (_is_int)
235 if (_is_percent)
236 prefs_set_double_attribute(_prefs_path.c_str(), _attr.c_str(), this->get_value()/100.0);
237 else
238 prefs_set_int_attribute(_prefs_path.c_str(), _attr.c_str(), (int) this->get_value());
239 else
240 prefs_set_double_attribute (_prefs_path.c_str(), _attr.c_str(), this->get_value());
241 }
242 }
244 void PrefCombo::init(const std::string& prefs_path, const std::string& attr,
245 Glib::ustring labels[], int values[], int num_items, int default_value)
246 {
247 _prefs_path = prefs_path;
248 _attr = attr;
249 int row = 0;
250 int value = prefs_get_int_attribute (_prefs_path.c_str(), _attr.c_str(), default_value);
252 for (int i = 0 ; i < num_items; ++i)
253 {
254 this->append_text(labels[i]);
255 _values.push_back(values[i]);
256 if (value == values[i])
257 row = i;
258 }
259 this->set_active(row);
260 }
262 void PrefCombo::on_changed()
263 {
264 if (this->is_visible()) //only take action if user changed value
265 {
266 prefs_set_int_attribute (_prefs_path.c_str(), _attr.c_str(), _values[this->get_active_row_number()]);
267 }
268 }
270 void PrefEntryButtonHBox::init(const std::string& prefs_path, const std::string& attr,
271 bool visibility, gchar* default_string)
272 {
273 _prefs_path = prefs_path;
274 _attr = attr;
275 _default_string = default_string;
276 relatedEntry = new Gtk::Entry();
277 relatedButton = new Gtk::Button("Reset");
278 relatedEntry->set_invisible_char('*');
279 relatedEntry->set_visibility(visibility);
280 relatedEntry->set_text(prefs_get_string_attribute(_prefs_path.c_str(), _attr.c_str()));
281 this->pack_start(*relatedEntry);
282 this->pack_start(*relatedButton);
283 relatedButton->signal_clicked().connect(
284 sigc::mem_fun(*this, &PrefEntryButtonHBox::onRelatedButtonClickedCallback));
285 relatedEntry->signal_changed().connect(
286 sigc::mem_fun(*this, &PrefEntryButtonHBox::onRelatedEntryChangedCallback));
287 }
289 void PrefEntryButtonHBox::onRelatedEntryChangedCallback()
290 {
291 if (this->is_visible()) //only take action if user changed value
292 {
293 prefs_set_string_attribute(_prefs_path.c_str(), _attr.c_str(),
294 relatedEntry->get_text().c_str());
295 }
296 }
298 void PrefEntryButtonHBox::onRelatedButtonClickedCallback()
299 {
300 if (this->is_visible()) //only take action if user changed value
301 {
302 prefs_set_string_attribute(_prefs_path.c_str(), _attr.c_str(),
303 _default_string);
304 relatedEntry->set_text(_default_string);
305 }
306 }
310 void PrefEntry::init(const std::string& prefs_path, const std::string& attr,
311 bool visibility)
312 {
313 _prefs_path = prefs_path;
314 _attr = attr;
315 this->set_invisible_char('*');
316 this->set_visibility(visibility);
317 this->set_text(prefs_get_string_attribute(_prefs_path.c_str(), _attr.c_str()));
318 }
320 void PrefEntry::on_changed()
321 {
322 if (this->is_visible()) //only take action if user changed value
323 {
324 prefs_set_string_attribute(_prefs_path.c_str(), _attr.c_str(), this->get_text().c_str());
325 }
326 }
328 } // namespace Widget
329 } // namespace UI
330 } // namespace Inkscape
332 /*
333 Local Variables:
334 mode:c++
335 c-file-style:"stroustrup"
336 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
337 indent-tabs-mode:nil
338 fill-column:99
339 End:
340 */
341 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :