~ubuntu-branches/debian/experimental/inkscape/experimental

« back to all changes in this revision

Viewing changes to src/extension/paramradiobutton.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-09-09 23:29:02 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080909232902-c50iujhk1w79u8e7
Tags: 0.46-2.1
* Non-maintainer upload.
* Add upstream patch fixing a crash in the open dialog
  in the zh_CN.utf8 locale. Closes: #487623.
  Thanks to Luca Bruno for the patch.

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
 *
 
13
 * Released under GNU GPL, read the file 'COPYING' for more information
 
14
 */
 
15
 
 
16
#ifdef HAVE_CONFIG_H
 
17
# include "config.h"
 
18
#endif
 
19
 
 
20
 
 
21
#include <gtkmm/box.h>
 
22
#include <gtkmm/radiobutton.h>
 
23
#include <gtkmm/radiobuttongroup.h>
 
24
#include <gtkmm/tooltips.h>
 
25
#include <gtkmm/label.h>
 
26
 
 
27
#include <glibmm/i18n.h>
 
28
 
 
29
#include <xml/node.h>
 
30
 
 
31
#include "extension.h"
 
32
#include "prefs-utils.h"
 
33
#include "document-private.h"
 
34
#include "sp-object.h"
 
35
 
 
36
#include "paramradiobutton.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, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
 
63
    Parameter(name, guitext, desc, scope, ext)
 
64
{
 
65
    choices = NULL;
 
66
    _value = NULL;
 
67
 
 
68
    // Read XML tree to add enumeration items:
 
69
    // printf("Extension Constructor: ");
 
70
    if (xml != NULL) {
 
71
        Inkscape::XML::Node *child_repr = sp_repr_children(xml);
 
72
        while (child_repr != NULL) {
 
73
            char const * chname = child_repr->name();
 
74
            if (!strcmp(chname, "option") || !strcmp(chname, "_option")) {
 
75
                Glib::ustring * newguitext = NULL;
 
76
                Glib::ustring * newvalue = NULL;
 
77
                const char * contents = sp_repr_children(child_repr)->content();
 
78
                if (contents != NULL)
 
79
                    // don't translate when 'option' but do translate when '_option'
 
80
                     newguitext = new Glib::ustring( !strcmp(chname, "_option") ? _(contents) : contents );
 
81
                else
 
82
                    continue;  
 
83
                    
 
84
                const char * val = child_repr->attribute("value");
 
85
                if (val != NULL)
 
86
                    newvalue = new Glib::ustring(val);
 
87
                else
 
88
                    newvalue = new Glib::ustring(contents);
 
89
                            
 
90
                if ( (newguitext) && (newvalue) ) {   // logical error if this is not true here
 
91
                    choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );
 
92
                }
 
93
            }
 
94
            child_repr = sp_repr_next(child_repr);
 
95
        }
 
96
    }
 
97
 
 
98
    // Initialize _value with the default value from xml
 
99
    // for simplicity : default to the contents of the first xml-child
 
100
    const char * defaultval = NULL;
 
101
    if (choices)
 
102
        defaultval = ((optionentry*) choices->data)->value->c_str();
 
103
 
 
104
    gchar * pref_name = this->pref_name();
 
105
    const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
 
106
    g_free(pref_name);
 
107
 
 
108
    if (paramval != NULL)
 
109
        defaultval = paramval;
 
110
    if (defaultval != NULL)
 
111
        _value = g_strdup(defaultval);  // allocate space for _value
 
112
 
 
113
    return;
 
114
}
 
115
 
 
116
ParamRadioButton::~ParamRadioButton (void)
 
117
{
 
118
    //destroy choice strings
 
119
    for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
 
120
        delete (reinterpret_cast<optionentry *>(list->data));
 
121
    }
 
122
    g_slist_free(choices);
 
123
 
 
124
    g_free(_value);
 
125
}
 
126
 
 
127
 
 
128
/** \brief  A function to set the \c _value
 
129
    \param  in   The value to set
 
130
    \param  doc  A document that should be used to set the value.
 
131
    \param  node The node where the value may be placed
 
132
 
 
133
    This function sets ONLY the internal value, but it also sets the value
 
134
    in the preferences structure.  To put it in the right place, \c PREF_DIR
 
135
    and \c pref_name() are used.
 
136
 
 
137
    To copy the data into _value the old memory must be free'd first.
 
138
    It is important to note that \c g_free handles \c NULL just fine.  Then
 
139
    the passed in value is duplicated using \c g_strdup().
 
140
*/
 
141
const gchar *
 
142
ParamRadioButton::set (const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
 
143
{
 
144
    if (in == NULL) return NULL; /* Can't have NULL string */
 
145
 
 
146
    Glib::ustring * settext = NULL;
 
147
    for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
 
148
        optionentry * entr = reinterpret_cast<optionentry *>(list->data);
 
149
        if ( !entr->guitext->compare(in) ) {
 
150
            settext = entr->value;
 
151
            break;  // break out of for loop
 
152
        }
 
153
    }
 
154
    if (settext) {
 
155
        if (_value != NULL) g_free(_value);
 
156
        _value = g_strdup(settext->c_str());
 
157
        gchar * prefname = this->pref_name();
 
158
        prefs_set_string_attribute(PREF_DIR, prefname, _value);
 
159
        g_free(prefname);
 
160
    }
 
161
 
 
162
    return _value;
 
163
}
 
164
 
 
165
 
 
166
/**
 
167
    \brief  A function to get the current value of the parameter in a string form
 
168
    \return A string with the 'value' as command line argument
 
169
*/
 
170
void
 
171
ParamRadioButton::string (std::string &string)
 
172
{
 
173
    string += _value;
 
174
    return;
 
175
}
 
176
 
 
177
/** \brief  A special radiobutton class to use in ParamRadioButton */
 
178
class ParamRadioButtonWdg : public Gtk::RadioButton {
 
179
private:
 
180
    ParamRadioButton * _pref;
 
181
    SPDocument * _doc;
 
182
    Inkscape::XML::Node * _node;
 
183
    sigc::signal<void> * _changeSignal;
 
184
public:
 
185
    /** \brief  Build a string preference for the given parameter
 
186
        \param  pref  Where to put the radiobutton's string when it is selected.
 
187
    */
 
188
    ParamRadioButtonWdg ( Gtk::RadioButtonGroup& group, const Glib::ustring& label,
 
189
                          ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal ) :
 
190
        Gtk::RadioButton(group, label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) {
 
191
        add_changesignal();
 
192
    };
 
193
    ParamRadioButtonWdg ( const Glib::ustring& label,
 
194
                          ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node , sigc::signal<void> * changeSignal) :
 
195
        Gtk::RadioButton(label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) {
 
196
        add_changesignal();
 
197
    };
 
198
    void add_changesignal() {
 
199
        this->signal_toggled().connect(sigc::mem_fun(this, &ParamRadioButtonWdg::changed));
 
200
    };
 
201
    void changed (void);
 
202
};
 
203
 
 
204
/** \brief  Respond to the selected radiobutton changing
 
205
 
 
206
    This function responds to the radiobutton selection changing by grabbing the value
 
207
    from the text box and putting it in the parameter.
 
208
*/
 
209
void
 
210
ParamRadioButtonWdg::changed (void)
 
211
{
 
212
    if (this->get_active()) {
 
213
        Glib::ustring data = this->get_label();
 
214
        _pref->set(data.c_str(), _doc, _node);
 
215
    }
 
216
    if (_changeSignal != NULL) {
 
217
        _changeSignal->emit();
 
218
    }
 
219
}
 
220
 
 
221
 
 
222
 
 
223
/**
 
224
    \brief  Creates a combobox widget for an enumeration parameter
 
225
*/
 
226
Gtk::Widget *
 
227
ParamRadioButton::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
 
228
{
 
229
    Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
 
230
    Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox(false, 0));
 
231
 
 
232
    Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT, Gtk::ALIGN_TOP));
 
233
    label->show();
 
234
    hbox->pack_start(*label, false, false);
 
235
 
 
236
    // add choice strings as radiobuttons
 
237
    // and select last selected option (_value)
 
238
    bool first = true;
 
239
    ParamRadioButtonWdg * radio;
 
240
    Gtk::RadioButtonGroup group;
 
241
    for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
 
242
        optionentry * entr = reinterpret_cast<optionentry *>(list->data);
 
243
        Glib::ustring * text = entr->guitext;
 
244
        if (first) {
 
245
            radio = Gtk::manage(new ParamRadioButtonWdg(*text, this, doc, node, changeSignal));
 
246
            group = radio->get_group();
 
247
            first = false;
 
248
        } else {
 
249
            radio = Gtk::manage(new ParamRadioButtonWdg(group, *text, this, doc, node, changeSignal));
 
250
        }
 
251
        radio->show();
 
252
        vbox->pack_start(*radio, true, true);
 
253
        if (!entr->value->compare(_value)) {
 
254
            radio->set_active();
 
255
        }
 
256
    }
 
257
 
 
258
    vbox->show();
 
259
    hbox->pack_end(*vbox, false, false);
 
260
    hbox->show();
 
261
 
 
262
 
 
263
    return dynamic_cast<Gtk::Widget *>(hbox);
 
264
}
 
265
 
 
266
 
 
267
}  /* namespace Extension */
 
268
}  /* namespace Inkscape */
 
269