1 /**
2 * \brief Filter Effects dialog
3 *
4 * Authors:
5 * Nicholas Bishop <nicholasbishop@gmail.org>
6 *
7 * Copyright (C) 2007 Authors
8 *
9 * Released under GNU GPL. Read the file 'COPYING' for more information.
10 */
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
16 #include <gtk/gtktreeview.h>
17 #include <gtkmm/cellrenderertext.h>
18 #include <gtkmm/paned.h>
19 #include <gtkmm/scale.h>
20 #include <gtkmm/scrolledwindow.h>
21 #include <gtkmm/spinbutton.h>
22 #include <gtkmm/stock.h>
23 #include <glibmm/i18n.h>
25 #include "application/application.h"
26 #include "application/editor.h"
27 #include "desktop.h"
28 #include "desktop-handles.h"
29 #include "dialog-manager.h"
30 #include "document.h"
31 #include "filter-chemistry.h"
32 #include "filter-effects-dialog.h"
33 #include "inkscape.h"
34 #include "sp-filter-primitive.h"
35 #include "sp-gaussian-blur.h"
36 #include "sp-feoffset.h"
37 #include "verbs.h"
38 #include "xml/node.h"
39 #include "xml/repr.h"
40 #include <sstream>
42 #include <iostream>
44 namespace Inkscape {
45 namespace UI {
46 namespace Dialog {
48 Glib::RefPtr<Gtk::Menu> create_popup_menu(Gtk::Widget& parent, sigc::slot<void> dup,
49 sigc::slot<void> rem)
50 {
51 Glib::RefPtr<Gtk::Menu> menu(new Gtk::Menu);
53 menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Duplicate"), dup));
54 Gtk::MenuItem* mi = Gtk::manage(new Gtk::ImageMenuItem(Gtk::Stock::REMOVE));
55 menu->append(*mi);
56 mi->signal_activate().connect(rem);
57 mi->show();
58 menu->accelerate(parent);
60 return menu;
61 }
63 static void try_id_change(SPObject* ob, const Glib::ustring& text)
64 {
65 // FIXME: this needs more serious error checking...
66 if(ob && !SP_ACTIVE_DOCUMENT->getObjectById(text.c_str())) {
67 SPException ex;
68 SP_EXCEPTION_INIT(&ex);
69 sp_object_setAttribute(ob, "id", text.c_str(), &ex);
70 sp_document_done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILTER_EFFECTS, _("Set object ID"));
71 }
72 }
74 /*** FilterModifier ***/
75 FilterEffectsDialog::FilterModifier::FilterModifier()
76 : _add(Gtk::Stock::ADD)
77 {
78 Gtk::ScrolledWindow* sw = Gtk::manage(new Gtk::ScrolledWindow);
79 pack_start(*sw);
80 pack_start(_add, false, false);
81 sw->add(_list);
83 _list.set_model(_model);
84 _list.append_column_editable(_("_Filter"), _columns.id);
85 ((Gtk::CellRendererText*)_list.get_column(0)->get_first_cell_renderer())->
86 signal_edited().connect(sigc::mem_fun(*this, &FilterEffectsDialog::FilterModifier::filter_name_edited));
88 sw->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
89 sw->set_shadow_type(Gtk::SHADOW_IN);
90 show_all_children();
91 _add.signal_clicked().connect(sigc::mem_fun(*this, &FilterModifier::add_filter));
92 _list.signal_button_press_event().connect_notify(
93 sigc::mem_fun(*this, &FilterModifier::filter_list_button_press));
94 _menu = create_popup_menu(*this, sigc::mem_fun(*this, &FilterModifier::duplicate_filter),
95 sigc::mem_fun(*this, &FilterModifier::remove_filter));
97 update_filters();
98 }
100 Glib::SignalProxy0<void> FilterEffectsDialog::FilterModifier::signal_selection_changed()
101 {
102 return _list.get_selection()->signal_changed();
103 }
105 SPFilter* FilterEffectsDialog::FilterModifier::get_selected_filter()
106 {
107 if(_list.get_selection()) {
108 Gtk::TreeModel::iterator i = _list.get_selection()->get_selected();
110 if(i)
111 return (*i)[_columns.filter];
112 }
114 return 0;
115 }
117 void FilterEffectsDialog::FilterModifier::select_filter(const SPFilter* filter)
118 {
119 if(filter) {
120 for(Gtk::TreeModel::iterator i = _model->children().begin();
121 i != _model->children().end(); ++i) {
122 if((*i)[_columns.filter] == filter) {
123 _list.get_selection()->select(i);
124 break;
125 }
126 }
127 }
128 }
130 void FilterEffectsDialog::FilterModifier::filter_list_button_press(GdkEventButton* event)
131 {
132 if((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) {
133 const bool sensitive = get_selected_filter() != NULL;
134 _menu->items()[0].set_sensitive(sensitive);
135 _menu->items()[1].set_sensitive(sensitive);
136 _menu->popup(event->button, event->time);
137 }
138 }
140 void FilterEffectsDialog::FilterModifier::add_filter()
141 {
142 SPDocument* doc = sp_desktop_document(SP_ACTIVE_DESKTOP);
143 SPFilter* filter = new_filter(doc);
145 update_filters();
147 select_filter(filter);
149 sp_document_done(doc, SP_VERB_DIALOG_FILTER_EFFECTS, _("Add filter"));
150 }
152 void FilterEffectsDialog::FilterModifier::remove_filter()
153 {
154 SPFilter *filter = get_selected_filter();
156 if(filter) {
157 SPDocument* doc = filter->document;
158 sp_repr_unparent(filter->repr);
160 sp_document_done(doc, SP_VERB_DIALOG_FILTER_EFFECTS, _("Remove filter"));
162 update_filters();
163 }
164 }
166 void FilterEffectsDialog::FilterModifier::duplicate_filter()
167 {
168 SPFilter *filter = get_selected_filter();
170 if(filter) {
171 //SPFilter *dupfilter = filter_duplicate(sp_desktop_document(SP_ACTIVE_DESKTOP), filter);
173 sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Duplicate filter"));
175 update_filters();
176 }
177 }
179 void FilterEffectsDialog::FilterModifier::filter_name_edited(const Glib::ustring& path, const Glib::ustring& text)
180 {
181 Gtk::TreeModel::iterator i = _model->get_iter(path);
183 if(i)
184 try_id_change((SPObject*)(*i)[_columns.filter], text);
185 }
187 /*** SettingsFrame ***/
188 FilterEffectsDialog::SettingsFrame::SettingsFrame()
189 : _where(0)
190 {
191 set_col_spacings(12);
192 show();
193 }
195 void FilterEffectsDialog::SettingsFrame::init(Gtk::VBox& box)
196 {
197 box.pack_start(*this, false, false);
198 }
200 void FilterEffectsDialog::SettingsFrame::add_setting(Gtk::Widget& w, const Glib::ustring& label)
201 {
202 Gtk::Label *lbl = new Gtk::Label(label + ":", Gtk::ALIGN_LEFT);
204 attach(*Gtk::manage(lbl), 0, 1, _where, _where + 1, Gtk::FILL, Gtk::FILL);
205 attach(w, 1, 2, _where, _where + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL);
207 lbl->show();
208 w.show();
210 ++_where;
211 }
213 /*** FilterEffectsDialog ***/
215 FilterEffectsDialog::FilterEffectsDialog()
216 : Dialog ("dialogs.filtereffects", SP_VERB_DIALOG_FILTER_EFFECTS),
217 _add_primitive_type(FPConverter),
218 _add_primitive(Gtk::Stock::ADD),
219 _empty_settings("No primitive selected", Gtk::ALIGN_LEFT),
220 _blend_mode(BlendModeConverter),
221 _gaussianblur_stddeviation(1, 0, 100, 1, 0.01, 1),
222 _morphology_radius(1, 0, 100, 1, 0.01, 1),
223 _offset_dx(0, -100, 100, 1, 0.01, 1),
224 _offset_dy(0, -100, 100, 1, 0.01, 1),
225 _turbulence_basefrequency(1, 0, 100, 1, 0.01, 1),
226 _turbulence_numoctaves(1, 0, 100, 1, 0.01, 1),
227 _turbulence_seed(1, 0, 100, 1, 0.01, 1)
228 {
229 // Initialize widget hierarchy
230 Gtk::HPaned* hpaned = Gtk::manage(new Gtk::HPaned);
231 Gtk::VBox* vb_prims = Gtk::manage(new Gtk::VBox);
232 Gtk::ScrolledWindow* sw_prims = Gtk::manage(new Gtk::ScrolledWindow);
233 Gtk::HBox* hb_prims = Gtk::manage(new Gtk::HBox);
234 Gtk::Frame* fr_settings = Gtk::manage(new Gtk::Frame("<b>Settings</b>"));
235 Gtk::Alignment* al_settings = Gtk::manage(new Gtk::Alignment);
236 get_vbox()->add(*hpaned);
237 hpaned->pack1(_filter_modifier);
238 hpaned->pack2(*vb_prims);
239 vb_prims->pack_start(*sw_prims);
240 vb_prims->pack_start(*hb_prims, false, false);
241 sw_prims->add(_primitive_list);
242 hb_prims->pack_end(_add_primitive, false, false);
243 hb_prims->pack_end(_add_primitive_type, false, false);
244 get_vbox()->pack_start(*fr_settings, false, false);
245 fr_settings->add(*al_settings);
246 al_settings->add(_settings);
248 // Primitive list
249 _primitive_model = Gtk::ListStore::create(_primitive_columns);
250 _primitive_list.set_reorderable(true);
251 _primitive_list.set_model(_primitive_model);
252 //_primitive_list.append_column_editable(_("_Primitive"), _primitive_columns.id);
253 _primitive_list.append_column("Type", _primitive_columns.type);
254 ((Gtk::CellRendererText*)_primitive_list.get_column(0)->get_first_cell_renderer())->
255 signal_edited().connect(sigc::mem_fun(*this, &FilterEffectsDialog::primitive_name_edited));
256 _filter_modifier.signal_selection_changed().connect(
257 sigc::mem_fun(*this, &FilterEffectsDialog::update_primitive_list));
258 _primitive_list.get_selection()->signal_changed().connect(
259 sigc::mem_fun(*this, &FilterEffectsDialog::update_settings_view));
260 _primitive_list.signal_button_press_event().connect_notify(
261 sigc::mem_fun(*this, &FilterEffectsDialog::primitive_list_button_press));
262 _primitive_list.signal_drag_end().connect(
263 sigc::mem_fun(*this, &FilterEffectsDialog::primitive_list_drag_end));
265 // Other widgets
266 sw_prims->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
267 sw_prims->set_shadow_type(Gtk::SHADOW_IN);
268 al_settings->set_padding(0, 0, 12, 0);
269 fr_settings->set_shadow_type(Gtk::SHADOW_NONE);
270 ((Gtk::Label*)fr_settings->get_label_widget())->set_use_markup();
271 _add_primitive.signal_clicked().connect(sigc::mem_fun(*this, &FilterEffectsDialog::add_primitive));
272 _primitive_menu = create_popup_menu(*this, sigc::mem_fun(*this, &FilterEffectsDialog::duplicate_primitive),
273 sigc::mem_fun(*this, &FilterEffectsDialog::remove_primitive));
275 show_all_children();
276 init_settings_widgets();
277 update_primitive_list();
278 update_settings_view();
279 }
281 FilterEffectsDialog::~FilterEffectsDialog()
282 {
283 }
285 void FilterEffectsDialog::primitive_list_button_press(GdkEventButton* event)
286 {
287 if((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) {
288 const bool sensitive = get_selected_primitive() != NULL;
289 _primitive_menu->items()[0].set_sensitive(sensitive);
290 _primitive_menu->items()[1].set_sensitive(sensitive);
291 _primitive_menu->popup(event->button, event->time);
292 }
293 }
295 // Reorder the filter primitives to match the list order
296 void FilterEffectsDialog::primitive_list_drag_end(const Glib::RefPtr<Gdk::DragContext>&)
297 {
298 int ndx = 0;
299 SPFilter* filter = _filter_modifier.get_selected_filter();
301 for(Gtk::TreeModel::iterator iter = _primitive_model->children().begin();
302 iter != _primitive_model->children().end(); ++iter) {
303 SPFilterPrimitive* prim = (*iter)[_primitive_columns.primitive];
304 if(prim)
305 ;//reorder_primitive(filter, prim->repr->position(), ndx); /* FIXME */
306 std::cout << prim->repr->position();
307 }
309 sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Reorder filter primitive"));
310 }
312 void FilterEffectsDialog::init_settings_widgets()
313 {
314 _empty_settings.set_sensitive(false);
315 _settings.pack_start(_empty_settings);
317 _blend.init(_settings);
318 _blend.add_setting(_blend_mode, "Mode");
319 _blend_mode.signal_changed().connect(
320 sigc::bind(sigc::mem_fun(*this, &FilterEffectsDialog::set_attr), SP_ATTR_MODE));
322 _colormatrix.init(_settings);
323 _colormatrix.add_setting(_colormatrix_type, "Type");
325 _componenttransfer.init(_settings);
327 _composite.init(_settings);
329 _convolvematrix.init(_settings);
331 _diffuselighting.init(_settings);
333 _displacementmap.init(_settings);
335 _flood.init(_settings);
337 _gaussianblur.init(_settings);
338 _gaussianblur.add_setting(_gaussianblur_stddeviation, "Standard Deviation");
339 _gaussianblur_stddeviation.signal_value_changed().connect(
340 sigc::bind(sigc::mem_fun(*this, &FilterEffectsDialog::set_attr), SP_ATTR_STDDEVIATION));
342 _image.init(_settings);
344 _merge.init(_settings);
346 _morphology.init(_settings);
347 _morphology.add_setting(_morphology_operator, "Operator");
348 _morphology.add_setting(_morphology_radius, "Radius");
350 _offset.init(_settings);
351 _offset.add_setting(_offset_dx, "Delta X");
352 _offset_dx.signal_value_changed().connect(
353 sigc::bind(sigc::mem_fun(*this, &FilterEffectsDialog::set_attr), SP_ATTR_DX));
354 _offset.add_setting(_offset_dy, "Delta Y");
355 _offset_dy.signal_value_changed().connect(
356 sigc::bind(sigc::mem_fun(*this, &FilterEffectsDialog::set_attr), SP_ATTR_DY));
358 _specularlighting.init(_settings);
360 _tile.init(_settings);
362 _turbulence.init(_settings);
363 _turbulence.add_setting(_turbulence_basefrequency, "Base Frequency");
364 _turbulence.add_setting(_turbulence_numoctaves, "Octaves");
365 _turbulence.add_setting(_turbulence_seed, "Seed");
366 _turbulence.add_setting(_turbulence_stitchtiles, "Stitch Tiles");
367 _turbulence.add_setting(_turbulence_type, "Type");
368 }
370 void FilterEffectsDialog::add_primitive()
371 {
372 SPFilter* filter = _filter_modifier.get_selected_filter();
373 const EnumData<NR::FilterPrimitiveType>* data = _add_primitive_type.get_active_data();
375 if(filter && data) {
376 SPFilterPrimitive* prim = filter_add_primitive(filter, data->name.c_str());
378 // Set default values
379 switch(data->id) {
380 case NR::NR_FILTER_BLEND:
381 sp_object_set(prim, SP_ATTR_MODE, BlendModeConverter.get_name(NR::BLEND_NORMAL).c_str());
382 break;
383 case NR::NR_FILTER_COLORMATRIX:
384 break;
385 case NR::NR_FILTER_COMPONENTTRANSFER:
386 break;
387 case NR::NR_FILTER_COMPOSITE:
388 break;
389 case NR::NR_FILTER_CONVOLVEMATRIX:
390 break;
391 case NR::NR_FILTER_DIFFUSELIGHTING:
392 break;
393 case NR::NR_FILTER_DISPLACEMENTMAP:
394 break;
395 case NR::NR_FILTER_FLOOD:
396 break;
397 case NR::NR_FILTER_GAUSSIANBLUR:
398 sp_object_set(prim, SP_ATTR_STDDEVIATION, "1");
399 break;
400 case NR::NR_FILTER_IMAGE:
401 break;
402 case NR::NR_FILTER_MERGE:
403 break;
404 case NR::NR_FILTER_MORPHOLOGY:
405 break;
406 case NR::NR_FILTER_OFFSET:
407 sp_object_set(prim, SP_ATTR_DX, "0");
408 sp_object_set(prim, SP_ATTR_DY, "0");
409 break;
410 case NR::NR_FILTER_SPECULARLIGHTING:
411 break;
412 case NR::NR_FILTER_TILE:
413 break;
414 case NR::NR_FILTER_TURBULENCE:
415 break;
416 default:
417 break;
418 }
420 update_primitive_list();
421 select_primitive(prim);
423 sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Add filter primitive"));
424 }
425 }
427 void FilterEffectsDialog::remove_primitive()
428 {
429 Gtk::TreeModel::iterator i = _primitive_list.get_selection()->get_selected();
431 if(i) {
432 SPFilterPrimitive* prim = (*i)[_primitive_columns.primitive];
434 sp_repr_unparent(prim->repr);
436 sp_document_done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_FILTER_EFFECTS,
437 _("Remove filter primitive"));
439 update_primitive_list();
440 }
441 }
443 void FilterEffectsDialog::duplicate_primitive()
444 {
445 SPFilter* filter = _filter_modifier.get_selected_filter();
446 SPFilterPrimitive* origprim = get_selected_primitive();
448 if(filter && origprim) {
449 Inkscape::XML::Node *repr;
450 repr = SP_OBJECT_REPR(origprim)->duplicate(SP_OBJECT_REPR(origprim)->document());
451 SP_OBJECT_REPR(filter)->appendChild(repr);
453 sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Duplicate filter primitive"));
455 update_primitive_list();
456 }
457 }
459 // Edits the id of the primitive at path
460 void FilterEffectsDialog::primitive_name_edited(const Glib::ustring& path, const Glib::ustring& text)
461 {
462 Gtk::TreeModel::iterator i = _primitive_model->get_iter(path);
464 if(i)
465 try_id_change((*i)[_primitive_columns.primitive], text);
466 }
468 void FilterEffectsDialog::set_attr(const SPAttributeEnum attr)
469 {
470 Gtk::TreeModel::iterator i = _primitive_list.get_selection()->get_selected();
472 if(i) {
473 SPFilter *filter = _filter_modifier.get_selected_filter();
474 SPFilterPrimitive* prim = (*i)[_primitive_columns.primitive];
475 std::ostringstream os;
476 Glib::ustring val;
478 if(attr == SP_ATTR_MODE) {
479 val = _blend_mode.get_active_data()->name;
480 }
481 else if(attr == SP_ATTR_STDDEVIATION) {
482 os << _gaussianblur_stddeviation.get_value();
483 val = os.str();
484 }
485 else if(attr == SP_ATTR_DX) {
486 os << _offset_dx.get_value();
487 val = os.str();
488 }
489 else if(attr == SP_ATTR_DY) {
490 os << _offset_dy.get_value();
491 val = os.str();
492 }
494 sp_object_set(prim, attr, val.c_str());
495 filter->requestModified(SP_OBJECT_MODIFIED_FLAG);
497 sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Set filter primitive attribute"));
498 }
499 }
501 /* Add all filter primitives in the current to the list.
502 Keeps the same selection if possible, otherwise selects the first element */
503 void FilterEffectsDialog::update_primitive_list()
504 {
505 SPFilter* f = _filter_modifier.get_selected_filter();
506 const SPFilterPrimitive* active_prim = get_selected_primitive();
507 bool active_found = false;
509 _primitive_model->clear();
511 if(f) {
512 _primitive_box.set_sensitive(true);
514 for(SPObject *prim_obj = f->children;
515 prim_obj && SP_IS_FILTER_PRIMITIVE(prim_obj);
516 prim_obj = prim_obj->next) {
517 SPFilterPrimitive *prim = SP_FILTER_PRIMITIVE(prim_obj);
518 if(prim) {
519 Gtk::TreeModel::Row row = *_primitive_model->append();
520 row[_primitive_columns.primitive] = prim;
521 row[_primitive_columns.type_id] = FPConverter.get_id_from_name(prim->repr->name());
522 row[_primitive_columns.type] = FPConverter.get_label(row[_primitive_columns.type_id]);
523 row[_primitive_columns.id] = SP_OBJECT_ID(prim);
525 if(prim == active_prim) {
526 _primitive_list.get_selection()->select(row);
527 active_found = true;
528 }
529 }
530 }
532 if(!active_found && _primitive_model->children().begin())
533 _primitive_list.get_selection()->select(_primitive_model->children().begin());
534 }
535 else {
536 _primitive_box.set_sensitive(false);
537 }
538 }
540 void FilterEffectsDialog::update_settings_view()
541 {
542 SPFilterPrimitive* prim = get_selected_primitive();
544 // Hide all the settings except for common
545 Glib::ListHandle<Widget*> c = _settings.get_children();
546 for(Glib::ListHandle<Widget*>::iterator iter = c.begin();
547 iter != c.end(); ++iter) {
548 (*iter)->hide();
549 }
551 _settings.set_sensitive(false);
552 _empty_settings.show();
554 if(prim) {
555 const NR::FilterPrimitiveType tid = FPConverter.get_id_from_name(prim->repr->name());
556 if(tid == NR::NR_FILTER_BLEND) {
557 _blend.show();
558 const gchar* val = prim->repr->attribute("mode");
559 if(val)
560 _blend_mode.set_active(BlendModeConverter.get_id_from_name(val));
561 }
562 else if(tid == NR::NR_FILTER_COLORMATRIX)
563 _colormatrix.show();
564 else if(tid == NR::NR_FILTER_COMPONENTTRANSFER)
565 _componenttransfer.show();
566 else if(tid == NR::NR_FILTER_COMPOSITE)
567 _composite.show();
568 else if(tid == NR::NR_FILTER_CONVOLVEMATRIX)
569 _convolvematrix.show();
570 else if(tid == NR::NR_FILTER_DIFFUSELIGHTING)
571 _diffuselighting.show();
572 else if(tid == NR::NR_FILTER_DISPLACEMENTMAP)
573 _displacementmap.show();
574 else if(tid == NR::NR_FILTER_FLOOD)
575 _flood.show();
576 else if(tid == NR::NR_FILTER_GAUSSIANBLUR) {
577 _gaussianblur.show();
578 _gaussianblur_stddeviation.set_value(((SPGaussianBlur*)prim)->stdDeviation.getNumber());
579 }
580 else if(tid == NR::NR_FILTER_IMAGE)
581 _image.show();
582 else if(tid == NR::NR_FILTER_MERGE)
583 _merge.show();
584 else if(tid == NR::NR_FILTER_MORPHOLOGY)
585 _morphology.show();
586 else if(tid == NR::NR_FILTER_OFFSET) {
587 _offset.show();
588 _offset_dx.set_value(((SPFeOffset*)prim)->dx);
589 _offset_dy.set_value(((SPFeOffset*)prim)->dy);
590 }
591 else if(tid == NR::NR_FILTER_SPECULARLIGHTING)
592 _specularlighting.show();
593 else if(tid == NR::NR_FILTER_TILE)
594 _tile.show();
595 else if(tid == NR::NR_FILTER_TURBULENCE)
596 _turbulence.show();
598 _settings.set_sensitive(true);
599 _empty_settings.hide();
600 }
601 }
603 SPFilterPrimitive* FilterEffectsDialog::get_selected_primitive()
604 {
605 if(_filter_modifier.get_selected_filter()) {
606 Gtk::TreeModel::iterator i = _primitive_list.get_selection()->get_selected();
607 if(i)
608 return (*i)[_primitive_columns.primitive];
609 }
611 return 0;
612 }
614 void FilterEffectsDialog::select_primitive(SPFilterPrimitive* prim)
615 {
616 for(Gtk::TreeIter i = _primitive_model->children().begin();
617 i != _primitive_model->children().end(); ++i) {
618 if((*i)[_primitive_columns.primitive] == prim)
619 _primitive_list.get_selection()->select(i);
620 }
621 }
623 } // namespace Dialog
624 } // namespace UI
625 } // namespace Inkscape
627 /*
628 Local Variables:
629 mode:c++
630 c-file-style:"stroustrup"
631 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
632 indent-tabs-mode:nil
633 fill-column:99
634 End:
635 */
636 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :