### Navigation

- index
- modules |
- Camelot documentation »
- Module code »

# Source code for camelot.core.utils

    #  ============================================================================
    #
    #  Copyright (C) 2007-2011 Conceptive Engineering bvba. All rights reserved.
    #  www.conceptive.be / project-camelot@conceptive.be
    #
    #  This file is part of the Camelot Library.
    #
    #  This file may be used under the terms of the GNU General Public
    #  License version 2.0 as published by the Free Software Foundation
    #  and appearing in the file license.txt included in the packaging of
    #  this file.  Please review this information to ensure GNU
    #  General Public Licensing requirements will be met.
    #
    #  If you are unsure which license is appropriate for your use, please
    #  visit www.python-camelot.com or contact project-camelot@conceptive.be
    #
    #  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    #  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    #
    #  For use of this library in commercial applications, please contact
    #  project-camelot@conceptive.be
    #
    #  ============================================================================

    """Utility functions"""

    from PyQt4 import QtGui
    from PyQt4 import QtCore

    import logging
    logger = logging.getLogger('camelot.core.utils')

    def is_deleted_pyqt( qobj ):
        """
        :param qobj: a :class:`QtCore.QObject`
        :return: :keyword:`True` if the qobj was deleted, :keyword:`False`
            otherwise
        """
        import sip
        return sip.isdeleted( qobj )

    def is_deleted_pyside( qobj ):
        """
        :param qobj: a :class:`QtCore.QObject`
        :return: :keyword:`True` if the qobj was deleted, :keyword:`False`
            otherwise
        """
        return False

    if hasattr(QtCore, 'PYQT_VERSION_STR'):
        pyqt = True
        is_deleted = is_deleted_pyqt
    else:
        pyqt = False
        is_deleted = is_deleted_pyside

    def create_constant_function(constant):
        return lambda:constant

    class CollectionGetterFromObjectGetter(object):
        """Convert an object getter to a collection getter.  The resulting
        class is callable and will make sure object_getter is only called
        once, even if collection getter is called multiple times.
        """

        def __init__(self, object_getter):
            """:param object_getter: a function that returns the object to
            be put in the collection.
            """
            self._object_getter = object_getter
            self._collection = None

        def __call__(self):
            if not self._collection:
                self._collection = [self._object_getter()]
            return self._collection

    """
    A Note on GUI Types

    Because QVariant is part of the QtCore library, it cannot provide conversion
    functions to data types defined in QtGui, such as QColor, QImage, and QPixmap.
    In other words, there is no toColor() function. Instead, you can use the
    QVariant.value() or the qVariantValue() template function. For example:

     QVariant variant;
     ...
     QColor color = variant.value<QColor>();

    The inverse conversion (e.g., from QColor to QVariant) is automatic for all
    data types supported by QVariant, including GUI-related types:

     QColor color = palette().background().color();
     QVariant variant = color;
    """
    def variant_to_pyobject(qvariant=None):
        """Try to convert a QVariant to a python object as good as possible"""
        if not pyqt:
            return qvariant
        import datetime
        if not qvariant:
            return None
        if qvariant.isNull():
            return None
        type = qvariant.type()
        if type == QtCore.QVariant.String:
            value = unicode(qvariant.toString())
        elif type == QtCore.QVariant.Date:
            value = qvariant.toDate()
            value = datetime.date(year=value.year(),
                                  month=value.month(),
                                  day=value.day())
        elif type == QtCore.QVariant.Int:
            value = int(qvariant.toInt()[0])
        elif type == QtCore.QVariant.LongLong:
            value = int(qvariant.toLongLong()[0])
        elif type == QtCore.QVariant.Double:
            value = float(qvariant.toDouble()[0])
        elif type == QtCore.QVariant.Bool:
            value = bool(qvariant.toBool())
        elif type == QtCore.QVariant.Time:
            value = qvariant.toTime()
            value = datetime.time(hour = value.hour(),
                                  minute = value.minute(),
                                  second = value.second())
        elif type == QtCore.QVariant.DateTime:
            value = qvariant.toDateTime()
            value = value.toPyDateTime ()
        elif type == QtCore.QVariant.Color:
            value = QtGui.QColor(qvariant)
        else:
            value = qvariant.toPyObject()

        return value

    #
    # Global dictionary containing all user defined translations in the
    # current locale
    #
    _translations_ = {}

    #
    # Encoding used when transferring translation strings from
    # python to qt
    #
    _encoding=QtCore.QCoreApplication.UnicodeUTF8

    def set_translation(source, value):
        """Store a tranlation in the global translation dictionary"""
        _translations_[source] = value

    def load_translations():
        """Fill the global dictionary of translations with all data from the
        database, to be able to do fast gui thread lookups of translations"""
        language = unicode(QtCore.QLocale().name())
        from sqlalchemy import sql
        from camelot.model.i18n import Translation
        # only load translations when the camelot model is active
        if not hasattr(Translation, 'query'):
            return
        query = sql.select( [Translation.source, Translation.value],
                            whereclause = sql.and_(Translation.language==language,
                                                   Translation.value!=None,
                                                   Translation.value!=u'') )
        for source, value in Translation.query.session.execute(query):
            _translations_[source] = value

    def _qtranslate(string_to_translate):
        """Translate a string using the QCoreApplication translation framework
        :param string_to_translate: a unicode string
        :return: the translated unicode string if it was possible to translate
        """
        return unicode(QtCore.QCoreApplication.translate('',
                                                         string_to_translate.encode('utf-8'),
                                                         encoding=_encoding))

    def ugettext(string_to_translate):
        """Translate the string_to_translate to the language of the current locale.
        This is a two step process.  First the function will try to get the
        translation out of the Translation entity, if this is not successfull, the
        function will ask QCoreApplication to translate string_to_translate (which
        tries to get the translation from the .qm files)"""
        assert isinstance(string_to_translate, basestring)
        result = _translations_.get(string_to_translate, None)
        if not result:
            result = _qtranslate( string_to_translate )
            #print string_to_translate, result
            # try one more time with string_to_translate capitalized
            if result is string_to_translate:
                result2 = _qtranslate( string_to_translate.capitalize() )
                if result2 is not string_to_translate.capitalize():
                    result = result2

        return result

    def dgettext(domain, message):
        """Like ugettext but look the message up in the specified domain.
        This uses the Translation table.
        """
        assert isinstance(message, basestring)
        from camelot.model.i18n import Translation
        from sqlalchemy import sql
        query = sql.select( [Translation.value],
                              whereclause = sql.and_(Translation.language.like('%s%%'%domain),
                                                     Translation.source==message) ).limit(1)
        for translation in Translation.query.session.execute(query):
            return translation[0]
        return message

    class ugettext_lazy(object):
        """Like :function:`ugettext`, but delays the translation until the string
        is shown to the user.  This makes it possible for the user to translate
        the string.
        """

        def __init__(self, string_to_translate):
            assert isinstance(string_to_translate, basestring)
            self._string_to_translate = string_to_translate

        def __str__(self):
            return ugettext(self._string_to_translate)

        def __unicode__(self):
            return ugettext(self._string_to_translate)

        def __eq__(self, other_string):
            if isinstance(other_string, basestring):
                return other_string == self._string_to_translate
            if isinstance(other_string, ugettext_lazy):
                return other_string._string_to_translate == self._string_to_translate
            return False

        def __ne__(self, other_string):
            return not self.__eq__( other_string )

        def __repr__(self):
            return u"_('%s')"%self._string_to_translate

    def xls2list(xf):
        import xlrd
        matrix = []
        s = xlrd.open_workbook(xf).sheets()[0] # assume a single sheet xls doc
        for r in range(s.nrows):
            vector = []
            for c in range(s.ncols):
                cell = s.cell(r, c)
                type = xlrd.sheet.ctype_text[cell.ctype]
                if type == 'xldate':
                    t = xlrd.xldate_as_tuple(cell.value, datemode=0)
                    value = '%02d/%02d/%d' % (t[2], t[1], t[0])
                else:
                    value = cell.value
                #vector.append((type, value))
                vector.append(value)
            matrix.append(vector)
        return matrix

    def format_float(value, precision=3):
        return QtCore.QString("%L1").arg(float(value), 0, 'f', precision)

### Navigation

- index
- modules |
- Camelot documentation »
- Module code »

Comments
blog comments powered by Disqus