This file is indexed.

/usr/share/pyshared/kiwi/ui/proxywidget.py is in python-kiwi 1.9.22-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
#
# Kiwi: a Framework and Enhanced Widgets for Python
#
# Copyright (C) 2003-2005 Async Open Source
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
# USA
#
# Author(s): Christian Reis <kiko@async.com.br>
#            Lorenzo Gil Sanchez <lgs@sicem.biz>
#            Gustavo Rahal <gustavo@async.com.br>
#            Johan Dahlin <jdahlin@async.com.br>
#            Daniel Saran R. da Cunha <daniel@async.com.br>
#

"""Basic classes for widget support for the Kiwi Framework"""

import gettext

import gobject
import gtk
from gtk import gdk

from kiwi import ValueUnset
from kiwi.component import implements
from kiwi.datatypes import ValidationError, converter, BaseConverter
from kiwi.environ import environ
from kiwi.interfaces import IProxyWidget, IValidatableProxyWidget
from kiwi.log import Logger
from kiwi.ui.gadgets import FadeOut
from kiwi.utils import gsignal, gproperty

log = Logger('widget proxy')

_ = lambda m: gettext.dgettext('kiwi', m)

class _PixbufConverter(BaseConverter):
    type = gdk.Pixbuf
    name = 'Pixbuf'

    def as_string(self, value, format='png'):
        buffer = []
        value.save_to_callback(buffer.append, format)
        string = ''.join(buffer)
        return string

    def from_string(self, value, format='png'):
        loader = gdk.PixbufLoader(format)
        try:
            loader.write(value)
            loader.close()
        except gobject.GError, e:
            raise ValidationError(_("Could not load image: %s") % e)

        pixbuf = loader.get_pixbuf()
        return pixbuf

converter.add(_PixbufConverter)


class ProxyWidgetMixin(object):
    """This class is a mixin that provide a common interface for KiwiWidgets.

    Usually the Proxy class need to set and get data from the widgets. It also
    need a validation framework.

    @cvar allowed_data_types: A list of types which we are allowed to use
      in this class.
    """

    implements(IProxyWidget)

    gsignal('content-changed')
    gsignal('validation-changed', bool)
    gsignal('validate', object, retval=object)

    gproperty('data-type', object, blurb='Data Type')
    gproperty('model-attribute', str, blurb='Model attribute')

    allowed_data_types = ()

    # To be able to call the as/from_string without setting the data_type
    # property and still receiving a good warning.
    _converter = None

    def __init__(self):
        if not type(self.allowed_data_types) == tuple:
            raise TypeError("%s.allowed_data_types must be a tuple" % (
                self.allowed_data_types))
        self._data_format = None
        self._converter_options = {}

    # Properties

    def prop_set_data_type(self, data_type):
        """Set the data type for the widget

        @param data_type: can be None, a type object or a string with the
                          name of the type object, so None, "<type 'str'>"
                          or 'str'
        """
        if data_type is None:
            return data_type

        # This may convert from string to type,
        # A type object will always be returned
        data_type = converter.check_supported(data_type)

        if not issubclass(data_type, self.allowed_data_types):
            raise TypeError(
                "%s only accept %s types, not %r"
                % (self,
                   ' or '.join([t.__name__ for t in self.allowed_data_types]),
                   data_type))

        self._converter = converter.get_converter(data_type)
        return data_type

    # Public API
    def set_data_format(self, format):
        self._data_format = format

    def set_options_for_datatype(self, datatype, **options):
        """Set some options to be passed to the datatype converter.
        Any additional parameter will be passed the the converter when
        converting an object to a string, for displaying in the widget. Note
        that the converter.as_string method should be able to handle such
        parameters.

        @param datatype: the datatype.
        """
        if not options:
            raise ValueError

        self._converter_options[datatype] = options

    def read(self):
        """Get the content of the widget.
        The type of the return value
        @returns: None if the user input a invalid value
        @rtype: Must matche the data-type property.
        """
        raise NotImplementedError

    def update(self, value):
        """
        Update the content value of the widget.
        @param value:
        """
        raise NotImplementedError

    # Private

    def _as_string(self, data):
        """Convert a value to a string
        @param data: data to convert
        """
        conv = self._converter
        if conv is None:
            conv = converter.get_converter(str)

        return conv.as_string(data, format=self._data_format,
                              **self._converter_options.get(conv.type,{}))

    def _from_string(self, data):
        """Convert a string to the data type of the widget
        This may raise a L{kiwi.datatypes.ValidationError} if conversion
        failed
        @param data: data to convert
        """
        conv = self._converter
        if conv is None:
            conv = converter.get_converter(str)

        return conv.from_string(data)

VALIDATION_ICON_WIDTH = 16
MANDATORY_ICON = gtk.STOCK_EDIT
ERROR_ICON = gdk.pixbuf_new_from_file(
    environ.find_resource('pixmap', 'validation-error-16.png'))

class ValidatableProxyWidgetMixin(ProxyWidgetMixin):
    """Class used by some Kiwi Widgets that need to support mandatory
    input and validation features such as custom validation and data-type
    validation.

    Mandatory support provides a way to warn the user when input is necessary.
    The validatation feature provides a way to check the data entered and to
    display information about what is wrong.
    """

    implements(IValidatableProxyWidget)

    gproperty('mandatory', bool, default=False)

    def __init__(self, widget=None):
        ProxyWidgetMixin.__init__(self)

        self._valid = True
        self._fade = FadeOut(self)
        self._fade.connect('color-changed', self._on_fadeout__color_changed)

    # Override in subclass

    def update_background(self, color):
        "Implement in subclass"

    def get_background(self):
        "Implement in subclass"

    def set_pixbuf(self, pixbuf):
        "Implement in subclass"

    def get_icon_window(self):
        "Implement in subclass"

    def set_tooltip(self, text):
        "Implement in subclass"

    # Public API

    def is_valid(self):
        """
        Verify the widget state.
        @returns: True if the widget is in validated state
        """
        return self._valid

    def validate(self, force=False):
        """Checks if the data is valid.
        Validates data-type and custom validation.

        @param force: if True, force validation
        @returns:     validated data or ValueUnset if it failed
        """

        # If we're not visible or sensitive return a blank value, except
        # when forcing the validation
        if not force and (not self.get_property('visible') or
                          not self.get_property('sensitive')):
            return ValueUnset

        try:
            data = self.read()
            log.debug('Read %r for %s' %  (data, self.model_attribute))

            # check if we should draw the mandatory icon
            # this need to be done before any data conversion because we
            # we don't want to end drawing two icons
            if self.mandatory and (data == None or
                                   data == '' or
                                   data == ValueUnset):
                self.set_blank()
                return ValueUnset
            else:

                # The widgets themselves have now valid the data
                # Next step is to call the application specificed
                # checks, which are found in the view.
                if data is not None and data is not ValueUnset:
                    # this signal calls the on_widgetname__validate method
                    # of the view class and gets the exception (if any).
                    error = self.emit("validate", data)
                    if error:
                        raise error

            self.set_valid()
            return data
        except ValidationError, e:
            self.set_invalid(str(e))
            return ValueUnset

    def set_valid(self):
        """Changes the validation state to valid, which will remove icons and
        reset the background color
        """

        log.debug('Setting state for %s to VALID' % self.model_attribute)
        self._set_valid_state(True)

        self._fade.stop()
        self.set_pixbuf(None)

    def set_invalid(self, text=None, fade=True):
        """Changes the validation state to invalid.
        @param text: text of tooltip of None
        @param fade: if we should fade the background
        """
        log.debug('Setting state for %s to INVALID' % self.model_attribute)

        self._set_valid_state(False)

        # If there is no error text, set a generic one so the error icon
        # still have a tooltip
        if not text:
            text = _("'%s' is not a valid value for this field") % self.read()

        self.set_tooltip(text)

        if not fade:
            self.set_pixbuf(ERROR_ICON)
            self.update_background(gtk.gdk.color_parse(self._fade.ERROR_COLOR))
            return

        # When the fading animation is finished, set the error icon
        # We don't need to check if the state is valid, since stop()
        # (which removes this timeout) is called as soon as the user
        # types valid data.
        def done(fadeout, c):
            self.set_pixbuf(ERROR_ICON)
            self.queue_draw()
            fadeout.disconnect(c.signal_id)

        class SignalContainer:
            pass
        c = SignalContainer()
        c.signal_id = self._fade.connect('done', done, c)

        if self._fade.start(self.get_background()):
            self.set_pixbuf(None)

    def set_blank(self):
        """Changes the validation state to blank state, this only applies
        for mandatory widgets, draw an icon and set a tooltip"""

        log.debug('Setting state for %s to BLANK' % self.model_attribute)

        if self.mandatory:
            self._draw_stock_icon(MANDATORY_ICON)
            self.set_tooltip(_('This field is mandatory'))
            self._fade.stop()
            valid = False
        else:
            valid = True

        self._set_valid_state(valid)

    # Private

    def _set_valid_state(self, state):
        """Updates the validation state and emits a signal iff it changed"""

        if self._valid == state:
            return

        self.emit('validation-changed', state)
        self._valid = state

    def _draw_stock_icon(self, stock_id):
        icon = self.render_icon(stock_id, gtk.ICON_SIZE_MENU)
        self.set_pixbuf(icon)
        self.queue_draw()

    # Callbacks

    def _on_fadeout__color_changed(self, fadeout, color):
        self.update_background(color)