~ubuntu-branches/ubuntu/utopic/inkscape/utopic-proposed

« back to all changes in this revision

Viewing changes to inkscape-0.47pre1/src/extension/param/radiobutton.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bryce Harrington
  • Date: 2009-07-02 17:09:45 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090702170945-nn6d6zswovbwju1t
Tags: 0.47~pre1-0ubuntu1
* New upstream release.
  - Don't constrain maximization on small resolution devices (pre0)
    (LP: #348842)
  - Fixes segfault on startup (pre0)
    (LP: #391149)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** \file
 
2
 * extension parameter for radiobuttons.
 
3
 *
 
4
 * It uses a Gtk:ComboBoxText widget in the extension UI.
 
5
 */
 
6
 
 
7
/*
 
8
 * Author:
 
9
 *   Johan Engelen <johan@shouraizou.nl>
 
10
 *
 
11
 * Copyright (C) 2006-2007 Johan Engelen
 
12
 * Copyright (C) 2008 Jon A. Cruz
 
13
 *
 
14
 * Released under GNU GPL, read the file 'COPYING' for more information
 
15
 */
 
16
 
 
17
#ifdef HAVE_CONFIG_H
 
18
# include "config.h"
 
19
#endif
 
20
 
 
21
 
 
22
#include <gtkmm/box.h>
 
23
#include <gtkmm/comboboxtext.h>
 
24
#include <gtkmm/radiobutton.h>
 
25
#include <gtkmm/radiobuttongroup.h>
 
26
#include <gtkmm/tooltips.h>
 
27
#include <gtkmm/label.h>
 
28
#include <glibmm/i18n.h>
 
29
 
 
30
#include "xml/node.h"
 
31
#include "extension/extension.h"
 
32
#include "preferences.h"
 
33
#include "document-private.h"
 
34
#include "sp-object.h"
 
35
 
 
36
#include "radiobutton.h"
 
37
 
 
38
/** \brief  The root directory in the preferences database for extension
 
39
            related parameters. */
 
40
#define PREF_DIR "extensions"
 
41
 
 
42
namespace Inkscape {
 
43
namespace Extension {
 
44
 
 
45
/* For internal use only.
 
46
     Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
 
47
class optionentry {
 
48
public:
 
49
    optionentry (Glib::ustring * val, Glib::ustring * text) {
 
50
        value = val;
 
51
        guitext = text;
 
52
    }
 
53
    ~optionentry() {
 
54
        delete value;
 
55
        delete guitext;
 
56
    }
 
57
 
 
58
    Glib::ustring * value;
 
59
    Glib::ustring * guitext;
 
60
};
 
61
 
 
62
ParamRadioButton::ParamRadioButton (const gchar * name,
 
63
                                    const gchar * guitext,
 
64
                                    const gchar * desc,
 
65
                                    const Parameter::_scope_t scope,
 
66
                                    bool gui_hidden,
 
67
                                    const gchar * gui_tip,
 
68
                                    Inkscape::Extension::Extension * ext,
 
69
                                    Inkscape::XML::Node * xml,
 
70
                                    AppearanceMode mode) :
 
71
    Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext),
 
72
    _value(0),
 
73
    _mode(mode),
 
74
    choices(0)
 
75
{
 
76
    // Read XML tree to add enumeration items:
 
77
    // printf("Extension Constructor: ");
 
78
    if (xml != NULL) {
 
79
        Inkscape::XML::Node *child_repr = sp_repr_children(xml);
 
80
        while (child_repr != NULL) {
 
81
            char const * chname = child_repr->name();
 
82
            if (!strcmp(chname, INKSCAPE_EXTENSION_NS "option") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) {
 
83
                Glib::ustring * newguitext = NULL;
 
84
                Glib::ustring * newvalue = NULL;
 
85
                const char * contents = sp_repr_children(child_repr)->content();
 
86
 
 
87
                if (contents != NULL)
 
88
                    // don't translate when 'option' but do translate when '_option'
 
89
                     newguitext = new Glib::ustring( !strcmp(chname, INKSCAPE_EXTENSION_NS "_option") ? _(contents) : contents );
 
90
                else
 
91
                    continue;
 
92
 
 
93
                const char * val = child_repr->attribute("value");
 
94
                if (val != NULL)
 
95
                    newvalue = new Glib::ustring(val);
 
96
                else
 
97
                    newvalue = new Glib::ustring(contents);
 
98
 
 
99
                if ( (newguitext) && (newvalue) ) {   // logical error if this is not true here
 
100
                    choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );
 
101
                }
 
102
            }
 
103
            child_repr = sp_repr_next(child_repr);
 
104
        }
 
105
    }
 
106
 
 
107
    // Initialize _value with the default value from xml
 
108
    // for simplicity : default to the contents of the first xml-child
 
109
    const char * defaultval = NULL;
 
110
    if (choices)
 
111
        defaultval = ((optionentry*) choices->data)->value->c_str();
 
112
 
 
113
    gchar * pref_name = this->pref_name();
 
114
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
115
    Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name);
 
116
    g_free(pref_name);
 
117
 
 
118
    if (!paramval.empty())
 
119
        defaultval = paramval.data();
 
120
    if (defaultval != NULL)
 
121
        _value = g_strdup(defaultval);  // allocate space for _value
 
122
 
 
123
    return;
 
124
}
 
125
 
 
126
ParamRadioButton::~ParamRadioButton (void)
 
127
{
 
128
    //destroy choice strings
 
129
    for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
 
130
        delete (reinterpret_cast<optionentry *>(list->data));
 
131
    }
 
132
    g_slist_free(choices);
 
133
 
 
134
    g_free(_value);
 
135
}
 
136
 
 
137
 
 
138
/** \brief  A function to set the \c _value
 
139
    \param  in   The value to set
 
140
    \param  doc  A document that should be used to set the value.
 
141
    \param  node The node where the value may be placed
 
142
 
 
143
    This function sets ONLY the internal value, but it also sets the value
 
144
    in the preferences structure.  To put it in the right place, \c PREF_DIR
 
145
    and \c pref_name() are used.
 
146
 
 
147
    To copy the data into _value the old memory must be free'd first.
 
148
    It is important to note that \c g_free handles \c NULL just fine.  Then
 
149
    the passed in value is duplicated using \c g_strdup().
 
150
*/
 
151
const gchar *
 
152
ParamRadioButton::set (const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
 
153
{
 
154
    if (in == NULL) return NULL; /* Can't have NULL string */
 
155
 
 
156
    Glib::ustring * settext = NULL;
 
157
    for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
 
158
        optionentry * entr = reinterpret_cast<optionentry *>(list->data);
 
159
        if ( !entr->guitext->compare(in) ) {
 
160
            settext = entr->value;
 
161
            break;  // break out of for loop
 
162
        }
 
163
    }
 
164
    if (settext) {
 
165
        if (_value != NULL) g_free(_value);
 
166
        _value = g_strdup(settext->c_str());
 
167
        gchar * prefname = this->pref_name();
 
168
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
169
        prefs->setString(extension_pref_root + prefname, _value);
 
170
        g_free(prefname);
 
171
    }
 
172
 
 
173
    return _value;
 
174
}
 
175
 
 
176
 
 
177
/**
 
178
    \brief  A function to get the current value of the parameter in a string form
 
179
    \return A string with the 'value' as command line argument
 
180
*/
 
181
void
 
182
ParamRadioButton::string (std::string &string)
 
183
{
 
184
    string += _value;
 
185
    return;
 
186
}
 
187
 
 
188
/** \brief  A special radiobutton class to use in ParamRadioButton */
 
189
class ParamRadioButtonWdg : public Gtk::RadioButton {
 
190
private:
 
191
    ParamRadioButton * _pref;
 
192
    SPDocument * _doc;
 
193
    Inkscape::XML::Node * _node;
 
194
    sigc::signal<void> * _changeSignal;
 
195
public:
 
196
    /** \brief  Build a string preference for the given parameter
 
197
        \param  pref  Where to put the radiobutton's string when it is selected.
 
198
    */
 
199
    ParamRadioButtonWdg ( Gtk::RadioButtonGroup& group, const Glib::ustring& label,
 
200
                          ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal ) :
 
201
        Gtk::RadioButton(group, label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) {
 
202
        add_changesignal();
 
203
    };
 
204
    ParamRadioButtonWdg ( const Glib::ustring& label,
 
205
                          ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node , sigc::signal<void> * changeSignal) :
 
206
        Gtk::RadioButton(label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) {
 
207
        add_changesignal();
 
208
    };
 
209
    void add_changesignal() {
 
210
        this->signal_toggled().connect(sigc::mem_fun(this, &ParamRadioButtonWdg::changed));
 
211
    };
 
212
    void changed (void);
 
213
};
 
214
 
 
215
/** \brief  Respond to the selected radiobutton changing
 
216
 
 
217
    This function responds to the radiobutton selection changing by grabbing the value
 
218
    from the text box and putting it in the parameter.
 
219
*/
 
220
void
 
221
ParamRadioButtonWdg::changed (void)
 
222
{
 
223
    if (this->get_active()) {
 
224
        Glib::ustring data = this->get_label();
 
225
        _pref->set(data.c_str(), _doc, _node);
 
226
    }
 
227
    if (_changeSignal != NULL) {
 
228
        _changeSignal->emit();
 
229
    }
 
230
}
 
231
 
 
232
 
 
233
class ComboWdg : public Gtk::ComboBoxText {
 
234
public:
 
235
    ComboWdg(ParamRadioButton* base, SPDocument * doc, Inkscape::XML::Node * node) :
 
236
        Gtk::ComboBoxText(),
 
237
        base(base),
 
238
        doc(doc),
 
239
        node(node)
 
240
    {
 
241
    }
 
242
    virtual ~ComboWdg() {}
 
243
 
 
244
protected:
 
245
    ParamRadioButton* base;
 
246
    SPDocument* doc;
 
247
    Inkscape::XML::Node* node;
 
248
 
 
249
    virtual void on_changed() {
 
250
        if ( base ) {
 
251
            base->set(get_active_text().c_str(), doc, node);
 
252
        }
 
253
    }
 
254
};
 
255
 
 
256
/**
 
257
    \brief  Creates a combobox widget for an enumeration parameter
 
258
*/
 
259
Gtk::Widget *
 
260
ParamRadioButton::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
 
261
{
 
262
    if (_gui_hidden) return NULL;
 
263
 
 
264
    Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
 
265
    Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox(false, 0));
 
266
 
 
267
    Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT, Gtk::ALIGN_TOP));
 
268
    label->show();
 
269
    hbox->pack_start(*label, false, false);
 
270
 
 
271
    Gtk::ComboBoxText* cbt = 0;
 
272
    bool comboSet = false;
 
273
    if (_mode == MINIMAL) {
 
274
        cbt = Gtk::manage(new ComboWdg(this, doc, node));
 
275
        cbt->show();
 
276
        vbox->pack_start(*cbt, false, false);
 
277
    }
 
278
 
 
279
    // add choice strings as radiobuttons
 
280
    // and select last selected option (_value)
 
281
    Gtk::RadioButtonGroup group;
 
282
    for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
 
283
        optionentry * entr = reinterpret_cast<optionentry *>(list->data);
 
284
        Glib::ustring * text = entr->guitext;
 
285
        switch ( _mode ) {
 
286
            case MINIMAL:
 
287
            {
 
288
                cbt->append_text(*text);
 
289
                if (!entr->value->compare(_value)) {
 
290
                    cbt->set_active_text(*text);
 
291
                    comboSet = true;
 
292
                }
 
293
            }
 
294
            break;
 
295
            case COMPACT:
 
296
            case FULL:
 
297
            {
 
298
                ParamRadioButtonWdg * radio = Gtk::manage(new ParamRadioButtonWdg(group, *text, this, doc, node, changeSignal));
 
299
                radio->show();
 
300
                vbox->pack_start(*radio, true, true);
 
301
                if (!entr->value->compare(_value)) {
 
302
                    radio->set_active();
 
303
                }
 
304
            }
 
305
            break;
 
306
        }
 
307
    }
 
308
 
 
309
    if ( (_mode == MINIMAL) && !comboSet) {
 
310
        cbt->set_active(0);
 
311
    }
 
312
 
 
313
    vbox->show();
 
314
    hbox->pack_end(*vbox, false, false);
 
315
    hbox->show();
 
316
 
 
317
 
 
318
    return dynamic_cast<Gtk::Widget *>(hbox);
 
319
}
 
320
 
 
321
 
 
322
}  /* namespace Extension */
 
323
}  /* namespace Inkscape */
 
324
 
 
325
/*
 
326
  Local Variables:
 
327
  mode:c++
 
328
  c-file-style:"stroustrup"
 
329
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
330
  indent-tabs-mode:nil
 
331
  fill-column:99
 
332
  End:
 
333
*/
 
334
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :