Code

Fix [ 1835591 ] Reproducible crash on opening the attached file
[inkscape.git] / src / ui / widget / combo-enums.h
1 /**
2  * \brief Simplified management of enumerations in the UI as combobox.
3  *
4  * Authors:
5  *   Nicholas Bishop <nicholasbishop@gmail.com>
6  *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
7  *
8  * Copyright (C) 2007 Authors
9  *
10  * Released under GNU GPL.  Read the file 'COPYING' for more information.
11  */
13 #ifndef INKSCAPE_UI_WIDGET_COMBO_ENUMS_H
14 #define INKSCAPE_UI_WIDGET_COMBO_ENUMS_H
16 #include <gtkmm/combobox.h>
17 #include <gtkmm/liststore.h>
18 #include "attr-widget.h"
19 #include "util/enums.h"
20 #include "ui/widget/labelled.h"
22 namespace Inkscape {
23 namespace UI {
24 namespace Widget {
26 template<typename E> class ComboBoxEnum : public Gtk::ComboBox, public AttrWidget
27 {
28 public:
29     ComboBoxEnum(const Util::EnumDataConverter<E>& c, const SPAttributeEnum a = SP_ATTR_INVALID)
30         : AttrWidget(a), setProgrammatically(false), _converter(c)
31     {
32         signal_changed().connect(signal_attr_changed().make_slot());
34         _model = Gtk::ListStore::create(_columns);
35         set_model(_model);
37         pack_start(_columns.label);
39         // Initialize list
40         for(int i = 0; i < _converter.end; ++i) {
41             Gtk::TreeModel::Row row = *_model->append();
42             const Util::EnumData<E>* data = &_converter.data(i);
43             row[_columns.data] = data;
44             row[_columns.label] = _( _converter.get_label(data->id).c_str() );
45         }
47         set_active(0);
48     }
50     virtual Glib::ustring get_as_attribute() const
51     {
52         return get_active_data()->key;
53     }
55     virtual void set_from_attribute(SPObject* o)
56     {
57         setProgrammatically = true;
58         const gchar* val = attribute_value(o);
59         if(val)
60             set_active(_converter.get_id_from_key(val));
61         else
62             set_active(0);
63     }
64     
65     const Util::EnumData<E>* get_active_data() const
66     {
67         Gtk::TreeModel::iterator i = this->get_active();
68         if(i)
69             return (*i)[_columns.data];
70         return 0;
71     }
73     void add_row(const Glib::ustring& s)
74     {
75         Gtk::TreeModel::Row row = *_model->append();
76         row[_columns.data] = 0;
77         row[_columns.label] = s;
78     }
80     void set_active_by_id(E id) {
81         setProgrammatically = true;
82         for(Gtk::TreeModel::iterator i = _model->children().begin();
83             i != _model->children().end(); ++i) 
84         {
85             const Util::EnumData<E>* data = (*i)[_columns.data];
86             if(data->id == id) {
87                 set_active(i);
88                 break;
89             }
90         }
91     };
93     void set_active_by_key(const Glib::ustring& key) {
94         setProgrammatically = true;
95         set_active_by_id( _converter.get_id_from_key(key) );
96     };
98     bool setProgrammatically;
100 private:
101     class Columns : public Gtk::TreeModel::ColumnRecord
102     {
103     public:
104         Columns()
105         {
106             add(data);
107             add(label);
108         }
110         Gtk::TreeModelColumn<const Util::EnumData<E>*> data;
111         Gtk::TreeModelColumn<Glib::ustring> label;
112     };
114     Columns _columns;
115     Glib::RefPtr<Gtk::ListStore> _model;
116     const Util::EnumDataConverter<E>& _converter;
117 };
120 template<typename E> class LabelledComboBoxEnum : public Labelled
122 public:
123     LabelledComboBoxEnum( Glib::ustring const &label,
124                           Glib::ustring const &tooltip,
125                           const Util::EnumDataConverter<E>& c,
126                           Glib::ustring const &suffix = "",
127                           Glib::ustring const &icon = "",
128                           bool mnemonic = true)
129         : Labelled(label, tooltip, new ComboBoxEnum<E>(c), suffix, icon, mnemonic)
130     { }
132     ComboBoxEnum<E>* getCombobox() {
133         return static_cast< ComboBoxEnum<E>* > (_widget);
134     }
135 };
141 #endif
143 /*
144   Local Variables:
145   mode:c++
146   c-file-style:"stroustrup"
147   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
148   indent-tabs-mode:nil
149   fill-column:99
150   End:
151 */
152 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :