예제 #1
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        if source_index.isValid():
            source_data = self.sourceModel().data(source_index, role)
            publication_col = CertifiersTableModel.columns_ids.index('publication')
            publication_index = self.sourceModel().index(source_index.row(), publication_col)
            expiration_col = CertifiersTableModel.columns_ids.index('expiration')
            expiration_index = self.sourceModel().index(source_index.row(), expiration_col)
            written_col = CertifiersTableModel.columns_ids.index('written')
            written_index = self.sourceModel().index(source_index.row(), written_col)

            publication_data = self.sourceModel().data(publication_index, Qt.DisplayRole)
            expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole)
            written_data = self.sourceModel().data(written_index, Qt.DisplayRole)
            current_time = QDateTime().currentDateTime().toMSecsSinceEpoch()
            warning_expiration_time = int((expiration_data - publication_data) / 3)
            #logging.debug("{0} > {1}".format(current_time, expiration_data))

            if role == Qt.DisplayRole:
                if source_index.column() == CertifiersTableModel.columns_ids.index('expiration'):
                    if source_data:
                        ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data)
                        return QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(ts),
                            QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                        ) + " BAT"
                    else:
                        return ""
                if source_index.column() == CertifiersTableModel.columns_ids.index('publication'):
                    if source_data:
                        ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data)
                        return QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(ts),
                            QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                        ) + " BAT"
                    else:
                        return ""
                if source_index.column() == CertifiersTableModel.columns_ids.index('pubkey'):
                    return source_data

            if role == Qt.FontRole:
                font = QFont()
                if not written_data:
                    font.setItalic(True)
                return font

            if role == Qt.ForegroundRole:
                if current_time > ((expiration_data*1000) - (warning_expiration_time*1000)):
                    return QColor("darkorange").darker(120)

            return source_data
예제 #2
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        source_data = self.sourceModel().data(source_index, role)
        expiration_col = self.sourceModel().columns_ids.index('expiration')
        expiration_index = self.sourceModel().index(source_index.row(), expiration_col)
        expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole)
        current_time = QDateTime().currentDateTime().toMSecsSinceEpoch()
        sig_validity = self.community.parameters['sigValidity']
        warning_expiration_time = int(sig_validity / 3)
        #logging.debug("{0} > {1}".format(current_time, expiration_data))
        if expiration_data is not None:
            will_expire_soon = (current_time > expiration_data*1000 - warning_expiration_time*1000)
        if role == Qt.DisplayRole:
            if source_index.column() == self.sourceModel().columns_ids.index('renewed') \
                    or source_index.column() == self.sourceModel().columns_ids.index('expiration'):
                if source_data is not None:
                    return QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(source_data).date(),
                        QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                    )
                else:
                    return ""
            if source_index.column() == self.sourceModel().columns_ids.index('pubkey'):
                return "pub:{0}".format(source_data[:5])

        if role == Qt.ForegroundRole:
            if expiration_data:
                if will_expire_soon:
                    return QColor(Qt.red)
            else:
                return QColor(Qt.blue)
        return source_data
예제 #3
0
파일: base_graph.py 프로젝트: eliadem/sakia
    def add_certified_node(self, identity, certified, certification,
                           node_status):
        metadata = {
            'text': certified.uid if certified.uid else certified.pubkey[:12],
            'tooltip': certified.pubkey,
            'identity': certified,
            'status': node_status
        }
        self.nx_graph.add_node(certified.pubkey, attr_dict=metadata)

        arc_status = self.arc_status(certification.timestamp)
        sig_validity = self.blockchain_service.parameters().sig_validity
        arc = {
            'status':
            arc_status,
            'tooltip':
            QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(certification.timestamp +
                                     sig_validity).date(),
                QLocale.dateFormat(QLocale(), QLocale.ShortFormat)),
            'cert_time':
            certification.timestamp,
            'confirmation_text':
            self.confirmation_text(certification.written_on)
        }

        self.nx_graph.add_edge(identity.pubkey,
                               certified.pubkey,
                               attr_dict=arc)
예제 #4
0
 async def exec_test():
     value = await referential.localized(units=True, international_system=True)
     self.assertEqual(value, "1.011000 mUD({0}) TC".format(QLocale.toString(
                     QLocale(),
                     QDateTime.fromTime_t(1452663088792).date(),
                     QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                 )))
예제 #5
0
 async def exec_test():
     value = await referential.diff_localized(units=True)
     self.assertEqual(value, "0.101100 UD({0}) TC".format(QLocale.toString(
                     QLocale(),
                     QDateTime.fromTime_t(1452663088792).date(),
                     QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                 )))
예제 #6
0
    def message(cls, string, server_port=0):
        if cls._last_client_name and cls._last_client_name != 'daemon':
            sys.stderr.write('\n')

        sys.stderr.write('[\033[90mray-daemon\033[0m]\033[92m%s\033[0m\n' %
                         string)

        log_dir = "%s/logs" % get_app_config_path()
        if server_port:
            log_file_path = "%s/%i" % (log_dir, server_port)
        else:
            log_file_path = "%s/dummy" % log_dir

        if not os.path.exists(log_dir):
            os.makedirs(log_dir)

        log_file = open(log_file_path, 'a')

        date_time = QDateTime.currentDateTime()
        locale = QLocale(QLocale.English)
        date_format = locale.toString(date_time, "ddd MMM d hh:mm:ss yyyy")

        log_file.write("%s: %s\n" % (date_format, string))

        cls._last_client_name = 'daemon'
예제 #7
0
    def add_certifier_node(self, certifier, identity, certification,
                           node_status):
        sentry_symbol, sentry_text = sentry_display(certifier)
        name_text = certifier.uid if certifier.uid else certifier.pubkey[:12]
        metadata = {
            'text': sentry_symbol + name_text,
            'tooltip': sentry_text + certifier.pubkey,
            'identity': certifier,
            'status': node_status
        }
        self.nx_graph.add_node(certifier.pubkey, attr_dict=metadata)

        arc_status = self.arc_status(certification.timestamp)
        sig_validity = self.blockchain_service.parameters().sig_validity
        expiration = self.blockchain_service.adjusted_ts(
            certification.timestamp + sig_validity)
        arc = {
            'status':
            arc_status,
            'tooltip':
            QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(expiration).date(),
                QLocale.dateFormat(QLocale(), QLocale.ShortFormat)) + " BAT",
            'cert_time':
            certification.timestamp,
            'confirmation_text':
            self.confirmation_text(certification.written_on)
        }
        self.nx_graph.add_edge(certifier.pubkey,
                               identity.pubkey,
                               attr_dict=arc)
예제 #8
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        model = self.sourceModel()
        source_data = model.data(source_index, role)
        state_col = model.columns_types.index('state')
        state_index = model.index(source_index.row(), state_col)
        state_data = model.data(state_index, Qt.DisplayRole)
        if role == Qt.DisplayRole:
            if source_index.column() == model.columns_types.index('uid'):
                return source_data
            if source_index.column() == model.columns_types.index('date'):
                return QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(source_data).date(),
                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                )
            if source_index.column() == model.columns_types.index('payment') or \
                    source_index.column() == model.columns_types.index('deposit'):
                if source_data is not "":
                    amount_ref = self.account.units_to_diff_ref(source_data,
                                                                self.community)
                    # if referential type is quantitative...
                    if self.account.ref_type() == 'q':
                        # display int values
                        return QLocale().toString(float(amount_ref), 'f', 0)
                    else:
                        # display float values
                        return QLocale().toString(amount_ref, 'f', 6)

        if role == Qt.FontRole:
            font = QFont()
            if state_data == Transfer.AWAITING:
                font.setItalic(True)
            elif state_data == Transfer.REFUSED:
                font.setItalic(True)
            elif state_data == Transfer.TO_SEND:
                font.setBold(True)
            else:
                font.setItalic(False)
            return font

        if role == Qt.ForegroundRole:
            if state_data == Transfer.REFUSED:
                return QColor(Qt.red)
            elif state_data == Transfer.TO_SEND:
                return QColor(Qt.blue)

        if role == Qt.TextAlignmentRole:
            if source_index.column() == self.sourceModel().columns_types.index(
                    'deposit') or source_index.column() == self.sourceModel().columns_types.index('payment'):
                return Qt.AlignRight | Qt.AlignVCenter
            if source_index.column() == self.sourceModel().columns_types.index('date'):
                return Qt.AlignCenter

        if role == Qt.ToolTipRole:
            if source_index.column() == self.sourceModel().columns_types.index('date'):
                return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate)

        return source_data
예제 #9
0
 async def exec_test():
     value = await referential.localized(units=True)
     self.assertEqual(
         value, "0.101000 UD({0}) TC".format(
             QLocale.toString(
                 QLocale(),
                 QDateTime.fromTime_t(1452663088792).date(),
                 QLocale.dateFormat(QLocale(), QLocale.ShortFormat))))
예제 #10
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        source_model = self.sourceModel()
        if not source_index.isValid():
            return QVariant()
        source_data = source_model.data(source_index, role)

        if role == Qt.DisplayRole:
            if index.column() == NetworkTableModel.columns_types.index('is_member'):
                value = {True: QT_TRANSLATE_NOOP("NetworkTableModel", 'yes'),
                         False: QT_TRANSLATE_NOOP("NetworkTableModel", 'no'),
                         None: QT_TRANSLATE_NOOP("NetworkTableModel", 'offline')}
                return value[source_data]

            if index.column() == NetworkTableModel.columns_types.index('pubkey'):
                return source_data[:5]

            if index.column() == NetworkTableModel.columns_types.index('current_block'):
                if source_data == -1:
                    return ""
                else:
                    return source_data

            if index.column() == NetworkTableModel.columns_types.index('address') \
                    or index.column() == NetworkTableModel.columns_types.index('port') \
                    or index.column() == NetworkTableModel.columns_types.index('api'):
                    return "<p>" + source_data.replace('\n', "<br>") + "</p>"

            if index.column() == NetworkTableModel.columns_types.index('current_hash'):
                return source_data[:10]

            if index.column() == NetworkTableModel.columns_types.index('current_time') and source_data:
                ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data)
                return QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(ts),
                            QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                        ) + " BAT"

        if role == Qt.TextAlignmentRole:
            if source_index.column() == NetworkTableModel.columns_types.index('address') \
                    or source_index.column() == self.sourceModel().columns_types.index('current_block'):
                return Qt.AlignRight | Qt.AlignVCenter
            if source_index.column() == NetworkTableModel.columns_types.index('is_member'):
                return Qt.AlignCenter

        if role == Qt.FontRole:
            is_root_col = NetworkTableModel.columns_types.index('is_root')
            index_root_col = source_model.index(source_index.row(), is_root_col)
            if source_model.data(index_root_col, Qt.DisplayRole):
                font = QFont()
                font.setBold(True)
                return font

        if role == Qt.BackgroundColorRole and self.app.parameters.dark_theme:
            return source_data.darker()

        return source_data
예제 #11
0
파일: controller.py 프로젝트: florck/sakia
 def new_blocks_handled(self):
     current_block = self.model.current_block()
     current_time = self.model.current_time()
     str_time = QLocale.toString(
                     QLocale(),
                     QDateTime.fromTime_t(current_time),
                     QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
                 )
     self.view.status_label.setText(self.tr("Blockchain sync : {0} ({1})").format(str_time, str(current_block)[:15]))
예제 #12
0
 async def exec_test():
     value = await referential.diff_localized(units=False,
                                              international_system=True)
     self.assertEqual(
         value, "1.011000 mUD({0}) ".format(
             QLocale.toString(
                 QLocale(),
                 QDateTime.fromTime_t(1452663088792).date(),
                 QLocale.dateFormat(QLocale(), QLocale.ShortFormat))))
예제 #13
0
 def update_time(self):
     dateTime = QDateTime.currentDateTime()
     self.label_time.setText("{0}".format(
         QLocale.toString(
             QLocale(), QDateTime.currentDateTime(),
             QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat))))
     timer = QTimer()
     timer.timeout.connect(self.update_time)
     timer.start(1000)
예제 #14
0
    def refresh_status(self):
        """
        Refresh status bar
        """
        logging.debug("Refresh status")
        if self.community:
            text = ""

            current_block_number = self.community.network.current_blockid.number
            if current_block_number:
                text += self.tr(" Block {0}").format(current_block_number)
                try:
                    block = yield from self.community.get_block(current_block_number)
                    text += " ({0})".format(QLocale.toString(
                                QLocale(),
                                QDateTime.fromTime_t(block['medianTime']),
                                QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
                            ))
                except NoPeerAvailable as e:
                    logging.debug(str(e))
                    text += " ( ### ) "
                except ValueError as e:
                    logging.debug(str(e))

            if len(self.community.network.synced_nodes) == 0:
                self.button_membership.setEnabled(False)
                self.button_certification.setEnabled(False)
                self.button_send_money.setEnabled(False)
            else:
                self.button_membership.setEnabled(True)
                self.button_certification.setEnabled(True)
                self.button_send_money.setEnabled(True)

            if self.community.network.quality > 0.66:
                icon = '<img src=":/icons/connected" width="12" height="12"/>'
            elif self.community.network.quality > 0.33:
                icon = '<img src=":/icons/weak_connect" width="12" height="12"/>'
            else:
                icon = '<img src=":/icons/disconnected" width="12" height="12"/>'

            status_infotext = " - ".join([self.app.notifications[info][0] for info in self.status_info])
            label_text = "{0}{1}".format(icon, text)
            if status_infotext != "":
                label_text += " - {0}".format(status_infotext)

            if self.app.preferences['expert_mode']:
                try:
                    members_pubkeys = yield from self.community.members_pubkeys()
                    label_text += self.tr(" - Median fork window : {0}")\
                        .format(self.community.network.fork_window(members_pubkeys))
                except NoPeerAvailable as e:
                    logging.debug(str(e))
                    label_text += self.tr(" - Median fork window : {0}")\
                        .format("#")

            self.status_label.setText(label_text)
예제 #15
0
 def update_time(self):
     dateTime = QDateTime.currentDateTime()
     self.label_time.setText("{0}".format(QLocale.toString(
                     QLocale(),
                     QDateTime.currentDateTime(),
                     QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
                 )))
     timer = QTimer()
     timer.timeout.connect(self.update_time)
     timer.start(1000)
예제 #16
0
파일: identities.py 프로젝트: c-geek/sakia
    def data(self, index, role):
        source_index = self.mapToSource(index)
        if source_index.isValid():
            source_data = self.sourceModel().data(source_index, role)
            expiration_col = self.sourceModel().columns_ids.index('expiration')
            expiration_index = self.sourceModel().index(source_index.row(), expiration_col)

            STATUS_NOT_MEMBER = 0
            STATUS_MEMBER = 1
            STATUS_EXPIRE_SOON = 3
            status = STATUS_NOT_MEMBER
            expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole)
            current_time = QDateTime().currentDateTime().toMSecsSinceEpoch()
            sig_validity = self.sourceModel().sig_validity()
            warning_expiration_time = int(sig_validity / 3)
            #logging.debug("{0} > {1}".format(current_time, expiration_data))

            if expiration_data is not None:
                status = STATUS_MEMBER
                if current_time > (expiration_data*1000):
                    status = STATUS_NOT_MEMBER
                elif current_time > ((expiration_data*1000) - (warning_expiration_time*1000)):
                    status = STATUS_EXPIRE_SOON

            if role == Qt.DisplayRole:
                if source_index.column() in (self.sourceModel().columns_ids.index('renewed'),
                                             self.sourceModel().columns_ids.index('expiration'),
                                             self.sourceModel().columns_ids.index('publication')):
                    if source_data is not None:
                        return QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(source_data).date(),
                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                        )
                    else:
                        return ""
                if source_index.column() == self.sourceModel().columns_ids.index('pubkey'):
                    return "pub:{0}".format(source_data[:5])

            if role == Qt.ForegroundRole:
                if status == STATUS_EXPIRE_SOON:
                    return QColor("darkorange").darker(120)
                elif status == STATUS_NOT_MEMBER:
                    return QColor(Qt.red)
                else:
                    return QColor(Qt.blue)
            if role == Qt.DecorationRole and source_index.column() == self.sourceModel().columns_ids.index('uid'):
                if status == STATUS_NOT_MEMBER:
                    return QIcon(":/icons/not_member")
                elif status == STATUS_MEMBER:
                    return QIcon(":/icons/member")
                elif status == STATUS_EXPIRE_SOON:
                    return QIcon(":/icons/member_warning")

            return source_data
예제 #17
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        source_model = self.sourceModel()
        if not source_index.isValid():
            return QVariant()
        source_data = source_model.data(source_index, role)

        if role == Qt.DisplayRole:
            if index.column() == source_model.columns_types.index('is_member'):
                value = {
                    True: self.tr('yes'),
                    False: self.tr('no'),
                    None: self.tr('offline')
                }
                return value[source_data]

            if index.column() == source_model.columns_types.index('pubkey'):
                return source_data[:5]

            if index.column() == source_model.columns_types.index(
                    'current_block'):
                if source_data == -1:
                    return ""
                else:
                    return source_data

            if index.column() == source_model.columns_types.index(
                    'current_hash'):
                return source_data[:10]

            if index.column() == source_model.columns_types.index(
                    'current_time') and source_data:
                return QLocale.toString(
                    QLocale(), QDateTime.fromTime_t(source_data),
                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat))

        if role == Qt.TextAlignmentRole:
            if source_index.column() == source_model.columns_types.index(
                    'address') or source_index.column() == self.sourceModel(
                    ).columns_types.index('current_block'):
                return Qt.AlignRight | Qt.AlignVCenter
            if source_index.column() == source_model.columns_types.index(
                    'is_member'):
                return Qt.AlignCenter

        if role == Qt.FontRole:
            is_root_col = source_model.columns_types.index('is_root')
            index_root_col = source_model.index(source_index.row(),
                                                is_root_col)
            if source_model.data(index_root_col, Qt.DisplayRole):
                font = QFont()
                font.setBold(True)
                return font

        return source_data
예제 #18
0
    async def refresh_status(self):
        """
        Refresh status bar
        """
        logging.debug("Refresh status")
        if self.community:
            text = ""

            current_block_number = self.community.network.current_blockUID.number
            if current_block_number:
                text += self.tr("Block {0}").format(current_block_number)
                try:
                    block = await self.community.get_block(current_block_number
                                                           )
                    text += " ({0})".format(
                        QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(block['medianTime']),
                            QLocale.dateTimeFormat(QLocale(),
                                                   QLocale.NarrowFormat)))
                except NoPeerAvailable as e:
                    logging.debug(str(e))
                    text += " ( ### ) "
                except errors.DuniterError as e:
                    if e.ucode == errors.BLOCK_NOT_FOUND:
                        logging.debug(str(e))

            if len(self.community.network.synced_nodes) == 0:
                self.button_membership.setEnabled(False)
                self.button_certification.setEnabled(False)
                self.button_send_money.setEnabled(False)
            else:
                self.button_send_money.setEnabled(True)
                self.refresh_quality_buttons()

            if self.community.network.quality > 0.66:
                icon = ':/icons/connected'
            elif self.community.network.quality > 0.33:
                icon = ':/icons/weak_connect'
            else:
                icon = ':/icons/disconnected'

            status_infotext = " - ".join([
                self.account.notifications[info][0]
                for info in self.status_info
            ])
            label_text = text
            if status_infotext != "":
                label_text += " - {0}".format(status_infotext)

            self.status_label.setText(label_text)
            self.label_icon.setPixmap(
                QPixmap(icon).scaled(24, 24, Qt.KeepAspectRatio,
                                     Qt.SmoothTransformation))
예제 #19
0
    def add_certifier_list(self, certifier_list, person, person_account):
        """
        Add list of certifiers to graph
        :param list certifier_list: List of certifiers from api
        :param Person person:   Person instance which is certified
        :param Person person_account:   Account person instance
        :return:
        """
        #  add certifiers of uid
        for certifier in tuple(certifier_list):
            # add only valid certification...
            if (time.time() - certifier['cert_time']['medianTime']) > self.signature_validity:
                continue
            # new node
            if certifier['pubkey'] not in self._graph.keys():
                node_status = 0
                if certifier['pubkey'] == person_account.pubkey:
                    node_status += NODE_STATUS_HIGHLIGHTED
                if certifier['isMember'] is False:
                    node_status += NODE_STATUS_OUT
                self._graph[certifier['pubkey']] = {
                    'id': certifier['pubkey'],
                    'arcs': list(),
                    'text': certifier['uid'],
                    'tooltip': certifier['pubkey'],
                    'status': node_status,
                    'connected': [person.pubkey]
                }

            # keep only the latest certification
            if self._graph[certifier['pubkey']]['arcs']:
                if certifier['cert_time']['medianTime'] < self._graph[certifier['pubkey']]['arcs'][0]['cert_time']:
                    continue
            # display validity status
            if (time.time() - certifier['cert_time']['medianTime']) > self.ARC_STATUS_STRONG_time:
                arc_status = ARC_STATUS_WEAK
            else:
                arc_status = ARC_STATUS_STRONG
            arc = {
                'id': person.pubkey,
                'status': arc_status,
                'tooltip': QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(certifier['cert_time']['medianTime'] + self.signature_validity).date(),
                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                ),
                'cert_time': certifier['cert_time']['medianTime']
            }
            #  add arc to certifier
            self._graph[certifier['pubkey']]['arcs'].append(arc)
            # if certifier node not in person nodes
            if certifier['pubkey'] not in tuple(self._graph[person.pubkey]['connected']):
                # add certifier node to person node
                self._graph[person.pubkey]['connected'].append(certifier['pubkey'])
예제 #20
0
파일: base_graph.py 프로젝트: mmuman/sakia
    async def add_certified_list(self, certified_list, identity,
                                 account_identity):
        """
        Add list of certified from api to graph
        :param list certified_list: List of certified from api
        :param identity identity:   identity instance which is certifier
        :param identity account_identity:   Account identity instance
        :return:
        """

        if self.community:
            try:
                # add certified by uid
                for certified in tuple(certified_list):
                    node_status = await self.node_status(
                        certified['identity'], account_identity)
                    metadata = {
                        'text': certified['identity'].uid,
                        'tooltip': certified['identity'].pubkey,
                        'status': node_status
                    }
                    self.nx_graph.add_node(certified['identity'].pubkey,
                                           attr_dict=metadata)

                    arc_status = await self.arc_status(certified['cert_time'])
                    sig_validity = (await
                                    self.community.parameters())['sigValidity']
                    arc = {
                        'status':
                        arc_status,
                        'tooltip':
                        QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(certified['cert_time'] +
                                                 sig_validity).date(),
                            QLocale.dateFormat(QLocale(),
                                               QLocale.ShortFormat)),
                        'cert_time':
                        certified['cert_time'],
                        'confirmation_text':
                        self.confirmation_text(certified['block_number'])
                    }

                    self.nx_graph.add_edge(identity.pubkey,
                                           certified['identity'].pubkey,
                                           attr_dict=arc,
                                           weight=len(certified_list))

            except NoPeerAvailable as e:
                logging.debug(str(e))
예제 #21
0
파일: member.py 프로젝트: pierreloicq/sakia
    async def refresh(self):
        if self.identity and self.identity.local_state != LocalState.NOT_FOUND:
            self.ui.busy.show()
            self.ui.label_uid.setText(self.identity.uid)
            self.ui.label_properties.setText("")
            try:
                identity_selfcert = await self.identity.selfcert(self.community)
                publish_time = await self.community.time(identity_selfcert.timestamp.number)

                join_date = await self.identity.get_join_date(self.community)
                if join_date is None:
                    join_date = self.tr('not a member')
                else:
                    join_date = datetime.datetime.fromtimestamp(join_date).strftime("%d/%m/%Y %I:%M")

            except MembershipNotFoundError:
                join_date = "###"
            except (LookupFailureError, NoPeerAvailable):
                publish_time = None
                join_date = "###"

            if publish_time:
                uid_publish_date = QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(publish_time),
                        QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                    )
            else:
                uid_publish_date = "###"

            text = self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                """).format(
                self.tr('Public key'),
                self.identity.pubkey,
                self.tr('UID Published on'),
                uid_publish_date,
                self.tr('Join date'),
                join_date
            )
            # close html text
            text += "</table>"

            # set text in label
            self.ui.label_properties.setText(text)
            self.ui.busy.hide()
예제 #22
0
    def write_csv_row(self, file_ptr, elems):
        """ Writes list of values as a CSV row, converting values as cencessary (if value contains a character used
        as a CSV ddelimiter).  """

        delim = self.app_config.csv_delimiter if self.app_config else ';'
        delim_replacement = '_' if delim != '_' else '-'
        # elems = [str(elem if elem is not None else '').replace(delim, delim_replacement) for elem in elems]
        csv_row = []
        for elem in elems:
            if elem is None:
                elem = ''
            elif not isinstance(elem, str):
                elem = QLocale.toString(self.app_config.get_default_locale(), elem if elem is not None else '')
            csv_row.append(elem.replace(delim, delim_replacement))
        file_ptr.write(delim.join(csv_row) + '\n')
예제 #23
0
    async def refresh_status(self):
        """
        Refresh status bar
        """
        logging.debug("Refresh status")
        if self.community:
            text = ""

            current_block_number = self.community.network.current_blockid.number
            if current_block_number:
                text += self.tr("Block {0}").format(current_block_number)
                try:
                    block = await self.community.get_block(current_block_number)
                    text += " ({0})".format(QLocale.toString(
                                QLocale(),
                                QDateTime.fromTime_t(block['medianTime']),
                                QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
                            ))
                except NoPeerAvailable as e:
                    logging.debug(str(e))
                    text += " ( ### ) "
                except ValueError as e:
                    logging.debug(str(e))

            if len(self.community.network.synced_nodes) == 0:
                self.button_membership.setEnabled(False)
                self.button_certification.setEnabled(False)
                self.button_send_money.setEnabled(False)
            else:
                self.button_membership.setEnabled(True)
                self.button_certification.setEnabled(True)
                self.button_send_money.setEnabled(True)

            if self.community.network.quality > 0.66:
                icon = ':/icons/connected'
            elif self.community.network.quality > 0.33:
                icon = ':/icons/weak_connect'
            else:
                icon = ':/icons/disconnected'

            status_infotext = " - ".join([self.account.notifications[info][0] for info in self.status_info])
            label_text = text
            if status_infotext != "":
                label_text += " - {0}".format(status_infotext)

            self.status_label.setText(label_text)
            self.label_icon.setPixmap(QPixmap(icon).scaled(24, 24, Qt.KeepAspectRatio, Qt.SmoothTransformation))
예제 #24
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        source_model = self.sourceModel()
        if not source_index.isValid():
            return QVariant()
        source_data = source_model.data(source_index, role)

        if role == Qt.DisplayRole:
            if index.column() == source_model.columns_types.index('is_member'):
                value = {True: self.tr('yes'), False: self.tr('no'), None: self.tr('offline')}
                return value[source_data]

            if index.column() == source_model.columns_types.index('pubkey'):
                return source_data[:5]

            if index.column() == source_model.columns_types.index('current_block'):
                if source_data == -1:
                    return ""
                else:
                    return source_data

            if index.column() == source_model.columns_types.index('current_hash') :
                return source_data[:10]

            if index.column() == source_model.columns_types.index('current_time') and source_data:
                return QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(source_data),
                            QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                        )

        if role == Qt.TextAlignmentRole:
            if source_index.column() == source_model.columns_types.index('address') or source_index.column() == self.sourceModel().columns_types.index('current_block'):
                return Qt.AlignRight | Qt.AlignVCenter
            if source_index.column() == source_model.columns_types.index('is_member'):
                return Qt.AlignCenter

        if role == Qt.FontRole:
            is_root_col = source_model.columns_types.index('is_root')
            index_root_col = source_model.index(source_index.row(), is_root_col)
            if source_model.data(index_root_col, Qt.DisplayRole):
                font = QFont()
                font.setBold(True)
                return font

        return source_data
예제 #25
0
파일: member.py 프로젝트: mmuman/sakia
    async def refresh(self):
        if self.identity and self.identity.local_state != LocalState.NOT_FOUND:
            self.ui.busy.show()
            self.ui.label_uid.setText(self.identity.uid)
            self.ui.label_properties.setText("")
            try:
                identity_selfcert = await self.identity.selfcert(self.community
                                                                 )
                publish_time = await self.community.time(
                    identity_selfcert.timestamp.number)

                join_date = await self.identity.get_join_date(self.community)
                if join_date is None:
                    join_date = self.tr('not a member')
                else:
                    join_date = datetime.datetime.fromtimestamp(
                        join_date).strftime("%d/%m/%Y %I:%M")

            except MembershipNotFoundError:
                join_date = "###"
            except (LookupFailureError, NoPeerAvailable):
                publish_time = None
                join_date = "###"

            if publish_time:
                uid_publish_date = QLocale.toString(
                    QLocale(), QDateTime.fromTime_t(publish_time),
                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat))
            else:
                uid_publish_date = "###"

            text = self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                """).format(self.tr('Public key'), self.identity.pubkey,
                            self.tr('UID Published on'), uid_publish_date,
                            self.tr('Join date'), join_date)
            # close html text
            text += "</table>"

            # set text in label
            self.ui.label_properties.setText(text)
            self.ui.busy.hide()
예제 #26
0
파일: member.py 프로젝트: c-geek/sakia
    async def refresh(self):
        if self.identity:
            self.ui.busy.show()
            self.ui.label_uid.setText(self.identity.uid)
            self.ui.label_properties.setText("")
            try:
                join_date = await self.identity.get_join_date(self.community)
            except MembershipNotFoundError:
                join_date = None

            if join_date is None:
                join_date = self.tr('not a member')
            else:
                join_date = datetime.datetime.fromtimestamp(join_date).strftime("%d/%m/%Y %I:%M")


            identity_selfcert = await self.identity.selfcert(self.community)
            uid_publish_date = QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(identity_selfcert.timestamp),
                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                )

            text = self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
                """).format(
                self.tr('Public key'),
                self.identity.pubkey,
                self.tr('UID Published on'),
                uid_publish_date,
                self.tr('Join date'),
                join_date
            )
            # close html text
            text += "</table>"

            # set text in label
            self.ui.label_properties.setText(text)
            self.ui.busy.hide()
예제 #27
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        model = self.sourceModel()
        source_data = model.data(source_index, role)
        state_col = model.columns_types.index('state')
        state_index = model.index(source_index.row(), state_col)
        state_data = model.data(state_index, Qt.DisplayRole)
        if role == Qt.DisplayRole:
            if source_index.column() == model.columns_types.index('uid'):
                return source_data
            if source_index.column() == model.columns_types.index('date'):
                return QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(source_data).date(),
                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat))
            if source_index.column() == model.columns_types.index('payment') or \
                    source_index.column() == model.columns_types.index('deposit'):
                return source_data

        if role == Qt.FontRole:
            font = QFont()
            return font

        if role == Qt.ForegroundRole:
            if state_data == TransferState.REFUSED:
                return QColor(Qt.red)
            elif state_data == TransferState.TO_SEND:
                return QColor(Qt.blue)

        if role == Qt.TextAlignmentRole:
            if source_index.column() == self.sourceModel().columns_types.index(
                    'date'):
                return Qt.AlignCenter

        if role == Qt.ToolTipRole:
            if source_index.column() == self.sourceModel().columns_types.index(
                    'date'):
                return QDateTime.fromTime_t(source_data).toString(
                    Qt.SystemLocaleLongDate)
            return None

        return source_data
예제 #28
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        model = self.sourceModel()
        source_data = model.data(source_index, role)
        state_col = model.columns_types.index('state')
        state_index = model.index(source_index.row(), state_col)
        state_data = model.data(state_index, Qt.DisplayRole)
        if role == Qt.DisplayRole:
            if source_index.column() == model.columns_types.index('uid'):
                return source_data
            if source_index.column() == model.columns_types.index('date'):
                return QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(source_data).date(),
                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                )
            if source_index.column() == model.columns_types.index('payment') or \
                    source_index.column() == model.columns_types.index('deposit'):
                return source_data

        if role == Qt.FontRole:
            font = QFont()
            return font

        if role == Qt.ForegroundRole:
            if state_data == TransferState.REFUSED:
                return QColor(Qt.red)
            elif state_data == TransferState.TO_SEND:
                return QColor(Qt.blue)

        if role == Qt.TextAlignmentRole:
            if source_index.column() == self.sourceModel().columns_types.index('date'):
                return Qt.AlignCenter

        if role == Qt.ToolTipRole:
            if source_index.column() == self.sourceModel().columns_types.index('date'):
                return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate)
            return None

        return source_data
예제 #29
0
    async def diff_localized(self, units=False, international_system=False):
        from . import Relative
        value = await self.differential()
        block = await self.community.get_ud_block(0, self._block_number)
        prefix = ""
        if international_system and value != 0:
            localized_value, prefix = Relative.to_si(value, self.app.preferences['digits_after_comma'])
        else:
            localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma'])

        if units or international_system:
            return QCoreApplication.translate("RelativeToPast", RelativeToPast._REF_STR_)\
                .format(localized_value,
                    prefix,
                    QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(block['medianTime']).date(),
                        QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                    ),
                    self.community.short_currency if units else "")
        else:
            return localized_value
예제 #30
0
    async def localized(self, units=False, international_system=False):
        from . import Relative
        value = await self.value()
        block = await self.community.get_ud_block()
        prefix = ""
        if international_system:
            localized_value, prefix = Relative.to_si(value, self.app.preferences['digits_after_comma'])
        else:
            localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma'])

        if units or international_system:
            return QCoreApplication.translate("RelativeToPast", RelativeToPast._REF_STR_) \
                .format(localized_value,
                        prefix,
                        QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(block['medianTime']).date(),
                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                        ),
                        self.community.short_currency if units else "")
        else:
            return localized_value
예제 #31
0
파일: base_graph.py 프로젝트: c-geek/sakia
    async def add_certified_list(self, certified_list, identity, account_identity):
        """
        Add list of certified from api to graph
        :param list certified_list: List of certified from api
        :param identity identity:   identity instance which is certifier
        :param identity account_identity:   Account identity instance
        :return:
        """

        if self.community:
            try:
                # add certified by uid
                for certified in tuple(certified_list):
                    node_status = await self.node_status(certified['identity'], account_identity)
                    metadata = {
                        'text': certified['identity'].uid,
                        'tooltip': certified['identity'].pubkey,
                        'status': node_status
                    }
                    self.nx_graph.add_node(certified['identity'].pubkey, attr_dict=metadata)

                    arc_status = await self.arc_status(certified['cert_time'])
                    sig_validity = (await self.community.parameters())['sigValidity']
                    arc = {
                        'status': arc_status,
                        'tooltip': QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(certified['cert_time'] + sig_validity).date(),
                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                        ),
                        'cert_time': certified['cert_time'],
                        'confirmation_text': self.confirmation_text(certified['cert_time'])
                    }

                    self.nx_graph.add_edge(identity.pubkey, certified['identity'].pubkey, attr_dict=arc,
                                           weight=len(certified_list))

            except NoPeerAvailable as e:
                logging.debug(str(e))
예제 #32
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        source_data = self.sourceModel().data(source_index, role)
        expiration_col = self.sourceModel().columns_ids.index('expiration')
        expiration_index = self.sourceModel().index(source_index.row(),
                                                    expiration_col)
        expiration_data = self.sourceModel().data(expiration_index,
                                                  Qt.DisplayRole)
        current_time = QDateTime().currentDateTime().toMSecsSinceEpoch()
        sig_validity = self.community.parameters['sigValidity']
        warning_expiration_time = int(sig_validity / 3)
        #logging.debug("{0} > {1}".format(current_time, expiration_data))
        if expiration_data is not None:
            will_expire_soon = (current_time > expiration_data * 1000 -
                                warning_expiration_time * 1000)
        if role == Qt.DisplayRole:
            if source_index.column() == self.sourceModel().columns_ids.index('renewed') \
                    or source_index.column() == self.sourceModel().columns_ids.index('expiration'):
                if source_data is not None:
                    return QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(source_data).date(),
                        QLocale.dateFormat(QLocale(), QLocale.ShortFormat))
                else:
                    return ""
            if source_index.column() == self.sourceModel().columns_ids.index(
                    'pubkey'):
                return "pub:{0}".format(source_data[:5])

        if role == Qt.ForegroundRole:
            if expiration_data:
                if will_expire_soon:
                    return QColor(Qt.red)
            else:
                return QColor(Qt.blue)
        return source_data
예제 #33
0
    def refresh_labels(self):
        self.busy.show()
        #  try to request money parameters
        try:
            params = yield from self.community.parameters()
        except NoPeerAvailable as e:
            logging.debug('community parameters error : ' + str(e))
            return False

        #  try to request money variables from last ud block
        try:
            block_ud = yield from self.community.get_ud_block()
        except NoPeerAvailable as e:
            logging.debug('community get_ud_block error : ' + str(e))
            return False
        try:
            block_ud_minus_1 = yield from self.community.get_ud_block(1)
        except NoPeerAvailable as e:
            logging.debug('community get_ud_block error : ' + str(e))
            return False

        if block_ud:
            # display float values
            localized_ud = yield from self.account.current_ref(block_ud['dividend'],
                                                               self.community,
                                                               self.app)\
                .diff_localized(True, self.app.preferences['international_system_of_units'])

            computed_dividend = yield from self.community.computed_dividend()
            # display float values
            localized_ud_plus_1 = yield from self.account.current_ref(computed_dividend,
                                                    self.community, self.app)\
                .diff_localized(True, self.app.preferences['international_system_of_units'])

            localized_mass = yield from self.account.current_ref(block_ud['monetaryMass'],
                                                    self.community, self.app)\
                .diff_localized(True, self.app.preferences['international_system_of_units'])
            if block_ud_minus_1:
                mass_minus_1 = (float(0) if block_ud['membersCount'] == 0 else
                        block_ud_minus_1['monetaryMass'] / block_ud['membersCount'])
                localized_mass_minus_1_per_member = yield from self.account.current_ref(mass_minus_1,
                                                                  self.community, self.app)\
                    .diff_localized(True, self.app.preferences['international_system_of_units'])
                localized_mass_minus_1 = yield from self.account.current_ref(block_ud_minus_1['monetaryMass'],
                                                                  self.community, self.app)\
                    .diff_localized(True, self.app.preferences['international_system_of_units'])

            else:
                localized_mass_minus_1_per_member = QLocale().toString(
                    float(0), 'f', self.app.preferences['digits_after_comma']
                )
                localized_mass_minus_1 = QLocale().toString(
                    float(0), 'f', self.app.preferences['digits_after_comma']
                )

            # set infos in label
            self.label_general.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:2.2%} / {:} days</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    localized_ud,
                    self.tr('Universal Dividend UD(t) in'),
                    self.account.current_ref.diff_units(self.community.currency),
                    localized_mass_minus_1,
                    self.tr('Monetary Mass M(t-1) in'),
                    self.account.current_ref.diff_units(self.community.currency),
                    block_ud['membersCount'],
                    self.tr('Members N(t)'),
                    localized_mass_minus_1_per_member,
                    self.tr('Monetary Mass per member M(t-1)/N(t) in'),
                    self.account.current_ref.diff_units(self.community.currency),
                    float(0) if block_ud['membersCount'] == 0 or block_ud_minus_1['monetaryMass'] == 0 else
                    block_ud['dividend'] / (block_ud_minus_1['monetaryMass'] / block_ud['membersCount']),

                    params['dt'] / 86400,
                    self.tr('Actual growth c = UD(t)/[M(t-1)/N(t)]'),
                    QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(block_ud_minus_1['medianTime']),
                        QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                    ),
                    self.tr('Penultimate UD date and time (t-1)'),
                    QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(block_ud['medianTime']),
                        QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                    ),
                    self.tr('Last UD date and time (t)'),
                    QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(block_ud['medianTime'] + params['dt']),
                        QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                    ),
                    self.tr('Next UD date and time (t+1)')
                )
            )
        else:
            self.label_general.setText(self.tr('No Universal Dividend created yet.'))

        if block_ud:
            # set infos in label
            self.label_rules.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.tr('{:2.0%} / {:} days').format(params['c'], params['dt'] / 86400),
                    self.tr('Fundamental growth (c) / Delta time (dt)'),
                    self.tr('UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }'),
                    self.tr('Universal Dividend (formula)'),
                    self.tr('{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}').format(
                        localized_ud_plus_1,
                        localized_ud,
                        self.account.current_ref.diff_units(self.community.currency),
                        params['c'],
                        localized_mass,
                        self.account.current_ref.diff_units(self.community.currency),
                        block_ud['membersCount']
                    ),
                    self.tr('Universal Dividend (computed)')
                )
            )
        else:
            self.label_rules.setText(self.tr('No Universal Dividend created yet.'))

        # set infos in label
        self.label_money.setText(
            self.tr("""
            <table cellpadding="5">
            <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr>
            </table>
            """).format(
                params['c'],
                params['dt'] / 86400,
                self.tr('Fundamental growth (c)'),
                params['ud0'],
                self.tr('Initial Universal Dividend UD(0) in'),
                self.community.short_currency,
                params['dt'] / 86400,
                self.tr('Time period (dt) in days (86400 seconds) between two UD'),
                params['medianTimeBlocks'],
                self.tr('Number of blocks used for calculating median time'),
                params['avgGenTime'],
                self.tr('The average time in seconds for writing 1 block (wished time)'),
                params['dtDiffEval'],
                self.tr('The number of blocks required to evaluate again PoWMin value'),
                params['blocksRot'],
                self.tr('The number of previous blocks to check for personalized difficulty'),
                params['percentRot'],
                self.tr('The percent of previous issuers to reach for personalized difficulty')
            )
        )

        # set infos in label
        self.label_wot.setText(
            self.tr("""
            <table cellpadding="5">
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            </table>
            """).format(
                params['sigDelay'] / 86400,
                self.tr('Minimum delay between 2 identical certifications (in days)'),
                params['sigValidity'] / 86400,
                self.tr('Maximum age of a valid signature (in days)'),
                params['sigQty'],
                self.tr('Minimum quantity of signatures to be part of the WoT'),
                params['sigWoT'],
                self.tr('Minimum quantity of valid made certifications to be part of the WoT for distance rule'),
                params['msValidity'] / 86400,
                self.tr('Maximum age of a valid membership (in days)'),
                params['stepMax'],
                self.tr('Maximum distance between each WoT member and a newcomer'),
            )
        )
        self.busy.hide()
예제 #34
0
class ImapServer(QObject):
    socket.setdefaulttimeout(1)
    imap_signal = pyqtSignal()
    imap_signal_log = pyqtSignal(str)
    imap_signal_button_color = pyqtSignal(bool)
    imap_status_next_connection = pyqtSignal(int)
    imap_update_dt = 5  # in sec

    def __init__(self,
                 send_mail_sleep,
                 send_mail_parameters,
                 send_mail_mission,
                 imap_signal_stop_server,
                 test_send_mission=None):
        super().__init__()
        self.serverIMAP = None
        self.mailbox = 'Inbox'  # change function of imap server
        self.is_connected = False
        self.is_first_connection = True
        self.running = False
        self.imap_signal_log.emit("?")
        self.server_id = -1
        self.thread = None
        self.db = DataBaseConnection(init_table=True)
        self.locale = QLocale(QLocale.English, QLocale.UnitedStates)
        self.start_sync = None

        send_mail_sleep.connect(self.send_mail_sleep)
        send_mail_parameters.connect(self.send_mail_parameters)

        send_mail_mission.connect(self.send_mail_mission)

        imap_signal_stop_server.connect(self.stop_server)
        if (test_send_mission != None):
            test_send_mission.connect(self.test_mission_file)

    def __del__(self):
        # with self.lock:
        self.running = False
        if (threading.active_count() != 0 and self.thread != None):
            self.thread.join()
        self.close_server()

    def send_mail_sleep(self, imei, duration):
        parser = IridiumMessageParser(DataBaseConnection(init_table=False))
        data, type = parser.serialize_cmd_sleep(duration)
        print(data)
        if parser.flag_msg_ok:
            self.send_mail(imei, data, type)
        return

    def send_mail_parameters(self, imei, enable_mission, enable_flash,
                             enable_depth, enable_engine, period_message):
        parser = IridiumMessageParser(DataBaseConnection(init_table=False))
        data, type = parser.serialize_cmd_parameters(enable_mission,
                                                     enable_flash,
                                                     enable_depth,
                                                     enable_engine,
                                                     period_message)
        print(data)
        if parser.flag_msg_ok:
            self.send_mail(imei, data, type)
        return

    def test_mission_file(self, imei, mission, keep_old_mission):
        parser = IridiumMessageParser(DataBaseConnection(init_table=False))
        data, msg_type = parser.serialize_cmd_mission(mission,
                                                      keep_old_mission)
        if data == None:
            return
        print(data)
        if (len(data) > 270 or mission.get_nb_wp() > 256):
            msgBox = QMessageBox()
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Mission is too heavy " + str(len(data)) +
                           "/270bytes " + str(mission.get_nb_wp()) + "/256 wp")
            msgBox.setWindowTitle("Seabot")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()
            return
        debug_path = expanduser("~") + '/sbd_message.sbd'
        filename = QFileDialog.getSaveFileName(None, "Save file", debug_path,
                                               "SBD File (*.sbd)")
        if (filename[0] != ''):
            local_file_sbd = open(filename[0], 'wb')
            local_file_sbd.write(data)
            local_file_sbd.close()

        db = DataBaseConnection(init_table=False)
        filename = imei + "_" + str(int(
            datetime.datetime.utcnow().timestamp())) + '.sbd'
        db.add_sbd_sent_to_icu(imei, filename, msg_type, data,
                               datetime.datetime.utcnow().timestamp())

    def send_mail_mission(self, imei, mission, keep_old_mission):
        parser = IridiumMessageParser(DataBaseConnection(init_table=False))
        data, type = parser.serialize_cmd_mission(mission, keep_old_mission)
        if data == None:
            return
        print(data)

        # Check the length of the message
        if (len(data) > 270 or mission.get_nb_wp() > 256):
            msgBox = QMessageBox()
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Mission is too heavy " + str(len(data)) +
                           "/270bytes " + str(mission.get_nb_wp()) + "/256 wp")
            msgBox.setWindowTitle("Seabot")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()
            return

        if parser.flag_msg_ok:
            self.send_mail(imei, data, type)
        return

    def send_mail(self, imei, data, msg_type):
        if (self.is_connected):
            db = DataBaseConnection(init_table=False)
            login_data = db.get_server_data(self.server_id)

            sbd_msg = MIMEBase("application",
                               "octet-stream")  # x-zip-compressed

            filename = imei + "_" + str(
                int(datetime.datetime.utcnow().timestamp())) + ".sbd"

            sbd_msg.set_payload(base64.b64encode(data))
            sbd_msg.add_header('Content-Disposition',
                               'attachment',
                               filename=filename)
            sbd_msg.add_header('Content-Transfer-Encoding', 'base64')

            # encoders.encode_base64(sbd_msg)

            msg = MIMEMultipart('alternative')
            msg['Subject'] = imei
            msg['From'] = "<Seabot> <" + login_data["email"] + ">"
            msg['To'] = login_data["iridium_server_mail"]
            msg.attach(sbd_msg)

            msgBox = QMessageBox()
            msgBox.setIcon(QMessageBox.Question)
            msgBox.setText("Are you sure you want to send the CMD " +
                           str(msg_type))
            msgBox.setWindowTitle("Seabot")
            msgBox.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok)
            msgBox.setDefaultButton(QMessageBox.Cancel)
            ret = msgBox.exec()
            if (ret != QMessageBox.Ok):
                return

            # Send message
            try:
                s = smtplib.SMTP(login_data["server_smtp_ip"],
                                 login_data["server_smtp_port"])
                s.ehlo()
                context = ssl.SSLContext(ssl.PROTOCOL_TLS)
                s.starttls(context=context)
                s.ehlo()
                s.login(login_data["email"], login_data["password"])
                s.sendmail(login_data["email"],
                           login_data["iridium_server_mail"], msg.as_string())
                s.close()
            except socket.error as e:
                print(e, flush=True)
                return

            print("Message sent to ", imei)
            db.add_sbd_sent_to_icu(imei, filename, msg_type, data,
                                   datetime.datetime.utcnow().timestamp())

            msgBox = QMessageBox()
            msgBox.setText("The message was send to iridium server")
            msgBox.setWindowTitle("Seabot")
            msgBox.exec()
        else:
            print("Server Down")

    def start_server(self):
        # with self.lock:
        self.running = True
        self.thread = threading.Thread(target=self.update_imap, daemon=True)
        self.thread.start()

    def stop_server(self):
        print("STOP SERVER RECEIVED")
        # with self.lock:
        if (self.running == True):
            self.running = False
        self.close_server()
        if (self.thread != None):
            self.thread.join()

    def close_server(self):
        if self.is_connected == True:
            self.is_connected = False
            self.is_first_connection = True
            try:
                self.serverIMAP.close()
                self.serverIMAP.logout()
                self.imap_signal_log.emit("Disconnected")
                print("Server disconnected")
            except imaplib.IMAP4.error as err:
                print(err, flush=True)

    def update_imap(self):
        self.db = DataBaseConnection(init_table=False)
        time_counter = 0
        freq = 2  # Hz
        while self.running:
            if (not self.is_connected):
                self.imap_signal_button_color.emit(False)
                self.connect_imap()
            if (time_counter == 0):
                if (self.is_connected and self.is_first_connection):
                    self.update_first_connection()
                if (self.is_connected and not self.is_first_connection):
                    self.update_recent()
                time_counter = freq * self.imap_update_dt
            time.sleep(1. / freq)
            time_counter -= 1
            self.imap_status_next_connection.emit(
                math.ceil(time_counter / freq))
        self.imap_status_next_connection.emit(0)

    def set_server_id(self, server_id):
        self.server_id = server_id

    def connect_imap(self):
        print("Try connect")
        try:
            rsp = None
            # Retreive data from DB
            login_data = self.db.get_server_data(self.server_id)
            if (len(login_data) == 0):
                raise Exception('wrong server_id ', self.server_id)
            print("Try Login")
            self.serverIMAP = imaplib.IMAP4_SSL(login_data["server_imap_ip"],
                                                login_data["server_imap_port"])
            rsp = self.serverIMAP.login(login_data["email"],
                                        login_data["password"])
            print(self.serverIMAP.list())
            if (rsp[1][0].decode() == "LOGIN completed." or re.search(
                    "Logged in", rsp[1][0].decode()).group(0) == "Logged in"):
                self.is_connected = True
                self.is_first_connection = True
                self.imap_signal_button_color.emit(True)
                rsp, nb_message_inbox = self.serverIMAP.select(
                    mailbox=self.mailbox, readonly=False)
                print("select rsp = ", rsp, " nb_message = ",
                      nb_message_inbox[0].decode())
                self.imap_signal_log.emit("Connected")
            else:
                raise Exception('Failed to select')

            return True

        except imaplib.IMAP4.error as err:
            print("Error imap ", err)
            self.imap_signal_log.emit("Error IMAP\n" + str(err))
            self.close_server()
            return False
        except sqlite3.Error as error:
            print("Error sqlite ", error)
            self.imap_signal_log.emit("Error SQLITE")
            self.close_server()
            return False
        except:
            print("Error ", sys.exc_info())
            self.imap_signal_log.emit("Error - No connection\n" +
                                      str(sys.exc_info()[1]))
            self.close_server()
            return False

    def process_msg(self, msgnums):
        if (msgnums[0] != None):
            k = 1
            list_msg_num = msgnums[0].split()
            for num in list_msg_num:
                if (not self.download_msg(num.decode())):
                    return False
                self.imap_signal_log.emit("Update " + str(k) + "/" +
                                          str(len(list_msg_num)) + " (" +
                                          str(num.decode()) + ")")
                k += 1
                if (k % 10 == 0):
                    self.imap_signal.emit()
            self.imap_signal.emit()
            return True

    def update_recent(self):
        self.imap_signal_log.emit("Update " +
                                  str(datetime.datetime.now().replace(
                                      microsecond=0)))
        try:
            t = datetime.datetime.now()
            rsp, msgnums = self.serverIMAP.recent()
            if (not self.process_msg(msgnums)):
                return False

            self.db.update_last_sync(
                self.server_id,
                t.replace(microsecond=0).isoformat())  # without microsecond
            return True
        except imaplib.IMAP4.error as err:
            self.close_server()
            print(err, flush=True)
            self.imap_signal_log.emit("Error imaplib")
            return False
        except:
            print("Error ", sys.exc_info())
            self.close_server()
            self.imap_signal_log.emit("Error (timeout)")
            return False

    def update_first_connection(self):
        print("Try update_first_connection")
        t = datetime.datetime.now()

        try:
            # Search for email since last sync date
            self.start_sync = self.db.get_last_sync(self.server_id)
            date_string = self.locale.toString(self.start_sync, "dd-MMM-yyyy")
            print(date_string)
            typ, msgnums = self.serverIMAP.search(
                None, 'SINCE {date}'.format(date=date_string),
                'FROM "*****@*****.**"')
            if (not self.process_msg(msgnums)):
                return False

            self.is_first_connection = False
            self.db.update_last_sync(self.server_id, t)
            self.log = "Connected"
            return True
        except imaplib.IMAP4.error as err:
            self.close_server()
            self.imap_signal_log.emit("Error IMAP")
            print(err)
            return False
        except sqlite3.Error as error:
            self.close_server()
            self.imap_signal_log.emit("Error SQLITE")
            print(error)
            return False
        except:
            print("Error ", sys.exc_info())
            self.close_server()
            self.imap_signal_log.emit("Error - No connection")
            return False

    def download_msg(self, msgnum):
        if (msgnum == "0"):
            return True
        print("Download msg ", msgnum)
        try:
            typ, data_msg = self.serverIMAP.fetch(msgnum, '(BODY.PEEK[])')

        except imaplib.IMAP4.error as err:
            self.close_server()
            self.imap_signal_log.emit("Error IMAP")
            print(err)
            return False

        # Parse received part (starting with "Received: ")
        mail = email.message_from_bytes(data_msg[0][1], policy=default)

        if (mail["From"] == "*****@*****.**"):
            # imei = mail["Subject"].split(": ")[1]

            # Determine type of mail
            sbd_received = mail["Subject"].startswith('SBD Msg From Unit: ')
            sbd_sent = mail["Subject"].startswith(
                'SBD Mobile Terminated Message Queued for Unit: ')

            print(mail["Subject"])
            imei = re.search("Unit: (.*)", mail["Subject"]).group(1)
            time_connection = calendar.timegm(parsedate(mail["Date"]))

            if (sbd_received):
                return self.process_received_sbd(imei, mail, time_connection)

            if (sbd_sent):
                return self.process_sent_sbd(imei, mail, time_connection)

        return True

    def process_received_sbd(self, imei, mail, time_connection):
        self.db.add_new_robot(imei)  # Add new robot if not existing

        mail_message = mail.get_body('plain').get_content()
        momsn = int(re.search("MOMSN: (.*)", mail_message).group(1))
        mtmsn = int(re.search("MTMSN: (.*)", mail_message).group(1))
        print("momsn =", momsn, "mtmsn =", mtmsn)

        # Check if mtmsn validate previous sent message
        self.db.update_sbd_last_mtmsn(imei, mtmsn, time_connection)

        if mail.get_content_maintype() != 'multipart':
            print("No attachment")
            return True

        ## Extract enclosed file
        for part in mail.iter_attachments():
            if part.get_content_maintype() == 'application':
                #print(part.get_content_maintype(), part.get_content_subtype())
                # Extract momsn from attached file
                print(part.get_filename())

                # Add new entry to the database with the association of the imei and momsn
                message_id = self.db.add_sbd_received(imei, momsn, mtmsn,
                                                      time_connection)

                # Test if message is already saved
                if (message_id != None):
                    msg_data = part.get_payload(decode=True)
                    ip = IridiumMessageParser(self.db)
                    ip.save_log_state(msg_data, message_id, time_connection)

        return True

    def process_sent_sbd(self, imei, mail, time_connection):
        mail_message = mail.get_body('plain').get_content()
        mtmsn = int(re.search("The MTMSN is (.*),", mail_message).group(1))
        queue = int(
            re.search("the message is number (.*) in the queue",
                      mail_message).group(1))
        filename = re.search("Attachment Filename: (.*).sbd",
                             mail_message).group(1) + '.sbd'
        print(len(filename))
        print(filename)
        self.db.update_sbd_received_by_icu(imei, filename, mtmsn, queue,
                                           time_connection)
        return True
예제 #35
0
class SnapWidget(QWidget, Ui_SnapWidget):
    """
    Class implementing the snapshot widget.
    """
    ModeFullscreen = 0
    ModeScreen = 1
    ModeRectangle = 2
    ModeFreehand = 3
    ModeEllipse = 4

    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(SnapWidget, self).__init__(parent)
        self.setupUi(self)

        self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSaveAs.png"))
        self.takeButton.setIcon(UI.PixmapCache.getIcon("cameraPhoto.png"))
        self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
        self.copyPreviewButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
        self.setWindowIcon(UI.PixmapCache.getIcon("ericSnap.png"))

        self.modeCombo.addItem(self.tr("Fullscreen"),
                               SnapWidget.ModeFullscreen)
        self.modeCombo.addItem(self.tr("Rectangular Selection"),
                               SnapWidget.ModeRectangle)
        self.modeCombo.addItem(self.tr("Ellipical Selection"),
                               SnapWidget.ModeEllipse)
        self.modeCombo.addItem(self.tr("Freehand Selection"),
                               SnapWidget.ModeFreehand)
        if QApplication.desktop().screenCount() > 1:
            self.modeCombo.addItem(self.tr("Current Screen"),
                                   SnapWidget.ModeScreen)
        self.__mode = int(Preferences.Prefs.settings.value("Snapshot/Mode", 0))
        index = self.modeCombo.findData(self.__mode)
        if index == -1:
            index = 0
        self.modeCombo.setCurrentIndex(index)

        self.__delay = int(
            Preferences.Prefs.settings.value("Snapshot/Delay", 0))
        self.delaySpin.setValue(self.__delay)

        if PYQT_VERSION_STR >= "5.0.0":
            from PyQt5.QtCore import QStandardPaths
            picturesLocation = QStandardPaths.writableLocation(
                QStandardPaths.PicturesLocation)
        else:
            from PyQt5.QtGui import QDesktopServices
            picturesLocation = QDesktopServices.storageLocation(
                QDesktopServices.PicturesLocation)
        self.__filename = Preferences.Prefs.settings.value(
            "Snapshot/Filename",
            os.path.join(picturesLocation,
                         self.tr("snapshot") + "1.png"))

        self.__grabber = None
        self.__snapshot = QPixmap()
        self.__savedPosition = QPoint()
        self.__modified = False
        self.__locale = QLocale()

        self.__grabberWidget = QWidget(None, Qt.X11BypassWindowManagerHint)
        self.__grabberWidget.move(-10000, -10000)
        self.__grabberWidget.installEventFilter(self)

        self.__initFileFilters()

        self.__initShortcuts()

        self.preview.startDrag.connect(self.__dragSnapshot)

        from .SnapshotTimer import SnapshotTimer
        self.__grabTimer = SnapshotTimer()
        self.__grabTimer.timeout.connect(self.__grabTimerTimeout)
        self.__updateTimer = QTimer()
        self.__updateTimer.setSingleShot(True)
        self.__updateTimer.timeout.connect(self.__updatePreview)

        self.__updateCaption()
        self.takeButton.setFocus()

    def __initFileFilters(self):
        """
        Private method to define the supported image file filters.
        """
        filters = {
            'bmp': self.tr("Windows Bitmap File (*.bmp)"),
            'gif': self.tr("Graphic Interchange Format File (*.gif)"),
            'ico': self.tr("Windows Icon File (*.ico)"),
            'jpg': self.tr("JPEG File (*.jpg)"),
            'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"),
            'pbm': self.tr("Portable Bitmap File (*.pbm)"),
            'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"),
            'pgm': self.tr("Portable Graymap File (*.pgm)"),
            'png': self.tr("Portable Network Graphics File (*.png)"),
            'ppm': self.tr("Portable Pixmap File (*.ppm)"),
            'sgi': self.tr("Silicon Graphics Image File (*.sgi)"),
            'svg': self.tr("Scalable Vector Graphics File (*.svg)"),
            'tga': self.tr("Targa Graphic File (*.tga)"),
            'tif': self.tr("TIFF File (*.tif)"),
            'xbm': self.tr("X11 Bitmap File (*.xbm)"),
            'xpm': self.tr("X11 Pixmap File (*.xpm)"),
        }

        outputFormats = []
        writeFormats = QImageWriter.supportedImageFormats()
        for writeFormat in writeFormats:
            try:
                outputFormats.append(filters[bytes(writeFormat).decode()])
            except KeyError:
                pass
        outputFormats.sort()
        self.__outputFilter = ';;'.join(outputFormats)

        self.__defaultFilter = filters['png']

    def __initShortcuts(self):
        """
        Private method to initialize the keyboard shortcuts.
        """
        self.__quitShortcut = QShortcut(QKeySequence(QKeySequence.Quit), self,
                                        self.close)

        self.__copyShortcut = QShortcut(QKeySequence(QKeySequence.Copy), self,
                                        self.copyButton.animateClick)

        self.__quickSaveShortcut = QShortcut(QKeySequence(Qt.Key_Q), self,
                                             self.__quickSave)

        self.__save1Shortcut = QShortcut(QKeySequence(QKeySequence.Save), self,
                                         self.saveButton.animateClick)
        self.__save2Shortcut = QShortcut(QKeySequence(Qt.Key_S), self,
                                         self.saveButton.animateClick)

        self.__grab1Shortcut = QShortcut(QKeySequence(QKeySequence.New), self,
                                         self.takeButton.animateClick)
        self.__grab2Shortcut = QShortcut(QKeySequence(Qt.Key_N), self,
                                         self.takeButton.animateClick)
        self.__grab3Shortcut = QShortcut(QKeySequence(Qt.Key_Space), self,
                                         self.takeButton.animateClick)

    def __quickSave(self):
        """
        Private slot to save the snapshot bypassing the file selection dialog.
        """
        if not self.__snapshot.isNull():
            while os.path.exists(self.__filename):
                self.__autoIncFilename()

            if self.__saveImage(self.__filename):
                self.__modified = False
                self.__autoIncFilename()
                self.__updateCaption()

    @pyqtSlot()
    def on_saveButton_clicked(self):
        """
        Private slot to save the snapshot.
        """
        if not self.__snapshot.isNull():
            while os.path.exists(self.__filename):
                self.__autoIncFilename()

            fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
                self, self.tr("Save Snapshot"), self.__filename,
                self.__outputFilter, self.__defaultFilter,
                E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite))
            if not fileName:
                return

            ext = QFileInfo(fileName).suffix()
            if not ext:
                ex = selectedFilter.split("(*")[1].split(")")[0]
                if ex:
                    fileName += ex

            if self.__saveImage(fileName):
                self.__modified = False
                self.__filename = fileName
                self.__autoIncFilename()
                self.__updateCaption()

    def __saveImage(self, fileName):
        """
        Private method to save the snapshot.
        
        @param fileName name of the file to save to (string)
        @return flag indicating success (boolean)
        """
        if QFileInfo(fileName).exists():
            res = E5MessageBox.yesNo(
                self,
                self.tr("Save Snapshot"),
                self.tr("<p>The file <b>{0}</b> already exists."
                        " Overwrite it?</p>").format(fileName),
                icon=E5MessageBox.Warning)
            if not res:
                return False

        file = QFile(fileName)
        if not file.open(QFile.WriteOnly):
            E5MessageBox.warning(
                self, self.tr("Save Snapshot"),
                self.tr("Cannot write file '{0}:\n{1}.").format(
                    fileName, file.errorString()))
            return False

        ok = self.__snapshot.save(file)
        file.close()

        if not ok:
            E5MessageBox.warning(
                self, self.tr("Save Snapshot"),
                self.tr("Cannot write file '{0}:\n{1}.").format(
                    fileName, file.errorString()))

        return ok

    def __autoIncFilename(self):
        """
        Private method to auto-increment the file name.
        """
        # Extract the file name
        name = os.path.basename(self.__filename)

        # If the name contains a number, then increment it.
        numSearch = QRegExp("(^|[^\\d])(\\d+)")
        # We want to match as far left as possible, and when the number is
        # at the start of the name.

        # Does it have a number?
        start = numSearch.lastIndexIn(name)
        if start != -1:
            # It has a number, increment it.
            start = numSearch.pos(2)  # Only the second group is of interest.
            numAsStr = numSearch.capturedTexts()[2]
            number = "{0:0{width}d}".format(int(numAsStr) + 1,
                                            width=len(numAsStr))
            name = name[:start] + number + name[start + len(numAsStr):]
        else:
            # no number
            start = name.rfind('.')
            if start != -1:
                # has a '.' somewhere, e.g. it has an extension
                name = name[:start] + '1' + name[start:]
            else:
                # no extension, just tack it on to the end
                name += '1'

        self.__filename = os.path.join(os.path.dirname(self.__filename), name)
        self.__updateCaption()

    @pyqtSlot()
    def on_takeButton_clicked(self):
        """
        Private slot to take a snapshot.
        """
        self.__mode = self.modeCombo.itemData(self.modeCombo.currentIndex())
        self.__delay = self.delaySpin.value()

        self.__savedPosition = self.pos()
        self.hide()

        if self.__delay:
            self.__grabTimer.start(self.__delay)
        else:
            QTimer.singleShot(200, self.__startUndelayedGrab)

    def __grabTimerTimeout(self):
        """
        Private slot to perform a delayed grab operation.
        """
        if self.__mode == SnapWidget.ModeRectangle:
            self.__grabRectangle()
        elif self.__mode == SnapWidget.ModeEllipse:
            self.__grabEllipse()
        elif self.__mode == SnapWidget.ModeFreehand:
            self.__grabFreehand()
        else:
            self.__performGrab()

    def __startUndelayedGrab(self):
        """
        Private slot to perform an undelayed grab operation.
        """
        if self.__mode == SnapWidget.ModeRectangle:
            self.__grabRectangle()
        elif self.__mode == SnapWidget.ModeEllipse:
            self.__grabEllipse()
        elif self.__mode == SnapWidget.ModeFreehand:
            self.__grabFreehand()
        else:
            if Globals.isMacPlatform():
                self.__performGrab()
            else:
                self.__grabberWidget.show()
                self.__grabberWidget.grabMouse(Qt.CrossCursor)

    def __grabRectangle(self):
        """
        Private method to grab a rectangular screen region.
        """
        from .SnapshotRegionGrabber import SnapshotRegionGrabber
        self.__grabber = SnapshotRegionGrabber(
            mode=SnapshotRegionGrabber.Rectangle)
        self.__grabber.grabbed.connect(self.__captured)

    def __grabEllipse(self):
        """
        Private method to grab an elliptical screen region.
        """
        from .SnapshotRegionGrabber import SnapshotRegionGrabber
        self.__grabber = SnapshotRegionGrabber(
            mode=SnapshotRegionGrabber.Ellipse)
        self.__grabber.grabbed.connect(self.__captured)

    def __grabFreehand(self):
        """
        Private method to grab a non-rectangular screen region.
        """
        from .SnapshotFreehandGrabber import SnapshotFreehandGrabber
        self.__grabber = SnapshotFreehandGrabber()
        self.__grabber.grabbed.connect(self.__captured)

    def __performGrab(self):
        """
        Private method to perform a screen grab other than a selected region.
        """
        self.__grabberWidget.releaseMouse()
        self.__grabberWidget.hide()
        self.__grabTimer.stop()

        if self.__mode == SnapWidget.ModeFullscreen:
            desktop = QApplication.desktop()
            if qVersion() >= "5.0.0":
                self.__snapshot = QApplication.screens()[0].grabWindow(
                    desktop.winId(), desktop.x(), desktop.y(), desktop.width(),
                    desktop.height())
            else:
                self.__snapshot = QPixmap.grabWindow(desktop.winId(),
                                                     desktop.x(), desktop.y(),
                                                     desktop.width(),
                                                     desktop.height())
        elif self.__mode == SnapWidget.ModeScreen:
            desktop = QApplication.desktop()
            screenId = desktop.screenNumber(QCursor.pos())
            geom = desktop.screenGeometry(screenId)
            x = geom.x()
            y = geom.y()
            if qVersion() >= "5.0.0":
                self.__snapshot = QApplication.screens()[0].grabWindow(
                    desktop.winId(), x, y, geom.width(), geom.height())
            else:
                self.__snapshot = QPixmap.grabWindow(desktop.winId(), x, y,
                                                     geom.width(),
                                                     geom.height())
        else:
            self.__snapshot = QPixmap()

        self.__redisplay()
        self.__modified = True
        self.__updateCaption()

    def __redisplay(self):
        """
        Private method to redisplay the window.
        """
        self.__updatePreview()
        QApplication.restoreOverrideCursor()
        if not self.__savedPosition.isNull():
            self.move(self.__savedPosition)
        self.show()
        self.raise_()

        self.saveButton.setEnabled(not self.__snapshot.isNull())
        self.copyButton.setEnabled(not self.__snapshot.isNull())
        self.copyPreviewButton.setEnabled(not self.__snapshot.isNull())

    @pyqtSlot()
    def on_copyButton_clicked(self):
        """
        Private slot to copy the snapshot to the clipboard.
        """
        if not self.__snapshot.isNull():
            QApplication.clipboard().setPixmap(QPixmap(self.__snapshot))

    @pyqtSlot()
    def on_copyPreviewButton_clicked(self):
        """
        Private slot to copy the snapshot preview to the clipboard.
        """
        QApplication.clipboard().setPixmap(self.preview.pixmap())

    def __captured(self, pixmap):
        """
        Private slot to show a preview of the snapshot.
        
        @param pixmap pixmap of the snapshot (QPixmap)
        """
        self.__grabber.close()
        self.__snapshot = QPixmap(pixmap)

        self.__grabber.grabbed.disconnect(self.__captured)
        self.__grabber = None

        self.__redisplay()
        self.__modified = True
        self.__updateCaption()

    def __updatePreview(self):
        """
        Private slot to update the preview picture.
        """
        self.preview.setToolTip(
            self.tr("Preview of the snapshot image ({0} x {1})").format(
                self.__locale.toString(self.__snapshot.width()),
                self.__locale.toString(self.__snapshot.height())))
        self.preview.setPreview(self.__snapshot)
        self.preview.adjustSize()

    def resizeEvent(self, evt):
        """
        Protected method handling a resizing of the window.
        
        @param evt resize event (QResizeEvent)
        """
        self.__updateTimer.start(200)

    def __dragSnapshot(self):
        """
        Private slot handling the dragging of the preview picture.
        """
        drag = QDrag(self)
        mimeData = QMimeData()
        mimeData.setImageData(self.__snapshot)
        drag.setMimeData(mimeData)
        drag.setPixmap(self.preview.pixmap())
        drag.exec_(Qt.CopyAction)

    def eventFilter(self, obj, evt):
        """
        Public method to handle event for other objects.
        
        @param obj reference to the object (QObject)
        @param evt reference to the event (QEvent)
        @return flag indicating that the event should be filtered out (boolean)
        """
        if obj == self.__grabberWidget and \
                evt.type() == QEvent.MouseButtonPress:
            if QWidget.mouseGrabber() != self.__grabberWidget:
                return False
            if evt.button() == Qt.LeftButton:
                self.__performGrab()

        return False

    def closeEvent(self, evt):
        """
        Protected method handling the close event.
        
        @param evt close event (QCloseEvent)
        """
        if self.__modified:
            res = E5MessageBox.question(
                self, self.tr("eric6 Snapshot"),
                self.tr("""The application contains an unsaved snapshot."""),
                E5MessageBox.StandardButtons(E5MessageBox.Abort
                                             | E5MessageBox.Discard
                                             | E5MessageBox.Save))
            if res == E5MessageBox.Abort:
                evt.ignore()
                return
            elif res == E5MessageBox.Save:
                self.on_saveButton_clicked()

        Preferences.Prefs.settings.setValue("Snapshot/Delay",
                                            self.delaySpin.value())
        Preferences.Prefs.settings.setValue(
            "Snapshot/Mode",
            self.modeCombo.itemData(self.modeCombo.currentIndex()))
        Preferences.Prefs.settings.setValue("Snapshot/Filename",
                                            self.__filename)
        Preferences.Prefs.settings.sync()

    def __updateCaption(self):
        """
        Private method to update the window caption.
        """
        self.setWindowTitle("{0}[*] - {1}".format(
            os.path.basename(self.__filename), self.tr("eric6 Snapshot")))
        self.setWindowModified(self.__modified)
        self.pathNameEdit.setText(os.path.dirname(self.__filename))
예제 #36
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        model = self.sourceModel()
        source_data = model.data(source_index, role)
        state_col = model.columns_types.index('state')
        state_index = model.index(source_index.row(), state_col)
        state_data = model.data(state_index, Qt.DisplayRole)
        if role == Qt.DisplayRole:
            if source_index.column() == model.columns_types.index('uid'):
                return source_data
            if source_index.column() == model.columns_types.index('date'):
                return QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(source_data).date(),
                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                )
            if source_index.column() == model.columns_types.index('payment') or \
                    source_index.column() == model.columns_types.index('deposit'):
                return source_data

        if role == Qt.FontRole:
            font = QFont()
            if state_data == TransferState.AWAITING or state_data == TransferState.VALIDATING:
                font.setItalic(True)
            elif state_data == TransferState.REFUSED:
                font.setItalic(True)
            elif state_data == TransferState.TO_SEND:
                font.setBold(True)
            else:
                font.setItalic(False)
            return font

        if role == Qt.ForegroundRole:
            if state_data == TransferState.REFUSED:
                return QColor(Qt.red)
            elif state_data == TransferState.TO_SEND:
                return QColor(Qt.blue)

        if role == Qt.TextAlignmentRole:
            if source_index.column() == self.sourceModel().columns_types.index(
                    'deposit') or source_index.column() == self.sourceModel().columns_types.index('payment'):
                return Qt.AlignRight | Qt.AlignVCenter
            if source_index.column() == self.sourceModel().columns_types.index('date'):
                return Qt.AlignCenter

        if role == Qt.ToolTipRole:
            if source_index.column() == self.sourceModel().columns_types.index('date'):
                return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate)

            if state_data == TransferState.VALIDATING or state_data == TransferState.AWAITING:
                block_col = model.columns_types.index('block_number')
                block_index = model.index(source_index.row(), block_col)
                block_data = model.data(block_index, Qt.DisplayRole)

                current_confirmations = 0
                if state_data == TransferState.VALIDATING:
                    current_blockid_number = self.community.network.current_blockid.number
                    if current_blockid_number:
                        current_confirmations = current_blockid_number - block_data
                elif state_data == TransferState.AWAITING:
                    current_confirmations = 0

                max_confirmations = self.sourceModel().max_confirmations()

                if self.app.preferences['expert_mode']:
                    return self.tr("{0} / {1} confirmations").format(current_confirmations, max_confirmations)
                else:
                    confirmation = current_confirmations / max_confirmations * 100
                    confirmation = 100 if confirmation > 100 else confirmation
                    return self.tr("Confirming... {0} %").format(QLocale().toString(float(confirmation), 'f', 0))

            return None

        return source_data
예제 #37
0
파일: identities.py 프로젝트: mmuman/sakia
    def data(self, index, role):
        source_index = self.mapToSource(index)
        if source_index.isValid():
            source_data = self.sourceModel().data(source_index, role)
            expiration_col = self.sourceModel().columns_ids.index('expiration')
            expiration_index = self.sourceModel().index(
                source_index.row(), expiration_col)

            STATUS_NOT_MEMBER = 0
            STATUS_MEMBER = 1
            STATUS_EXPIRE_SOON = 3
            status = STATUS_NOT_MEMBER
            expiration_data = self.sourceModel().data(expiration_index,
                                                      Qt.DisplayRole)
            current_time = QDateTime().currentDateTime().toMSecsSinceEpoch()
            sig_validity = self.sourceModel().sig_validity()
            warning_expiration_time = int(sig_validity / 3)
            #logging.debug("{0} > {1}".format(current_time, expiration_data))

            if expiration_data is not None:
                status = STATUS_MEMBER
                if current_time > (expiration_data * 1000):
                    status = STATUS_NOT_MEMBER
                elif current_time > ((expiration_data * 1000) -
                                     (warning_expiration_time * 1000)):
                    status = STATUS_EXPIRE_SOON

            if role == Qt.DisplayRole:
                if source_index.column() in (
                        self.sourceModel().columns_ids.index('renewed'),
                        self.sourceModel().columns_ids.index('expiration')):
                    if source_data is not None:
                        return QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(source_data).date(),
                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat))
                    else:
                        return ""
                if source_index.column() == self.sourceModel(
                ).columns_ids.index('publication'):
                    if source_data is not None:
                        return QLocale.toString(
                            QLocale(), QDateTime.fromTime_t(source_data),
                            QLocale.dateTimeFormat(QLocale(),
                                                   QLocale.LongFormat))
                    else:
                        return ""
                if source_index.column() == self.sourceModel(
                ).columns_ids.index('pubkey'):
                    return "pub:{0}".format(source_data[:5])

            if role == Qt.ForegroundRole:
                if status == STATUS_EXPIRE_SOON:
                    return QColor("darkorange").darker(120)
                elif status == STATUS_NOT_MEMBER:
                    return QColor(Qt.red)
                else:
                    return QColor(Qt.blue)
            if role == Qt.DecorationRole and source_index.column(
            ) == self.sourceModel().columns_ids.index('uid'):
                if status == STATUS_NOT_MEMBER:
                    return QIcon(":/icons/not_member")
                elif status == STATUS_MEMBER:
                    return QIcon(":/icons/member")
                elif status == STATUS_EXPIRE_SOON:
                    return QIcon(":/icons/member_warning")

            return source_data
예제 #38
0
    async def refresh_labels(self):
        self.busy.show()
        #  try to request money parameters
        try:
            params = await self.community.parameters()
        except NoPeerAvailable as e:
            logging.debug('community parameters error : ' + str(e))
            return False

        #  try to request money variables from last ud block
        try:
            block_ud = await self.community.get_ud_block()
        except NoPeerAvailable as e:
            logging.debug('community get_ud_block error : ' + str(e))
            return False
        try:
            block_ud_minus_1 = await self.community.get_ud_block(x=1)
        except NoPeerAvailable as e:
            logging.debug('community get_ud_block error : ' + str(e))
            return False

        if block_ud:
            # display float values
            localized_ud = await self.account.current_ref.instance(block_ud['dividend'] * math.pow(10, block_ud['unitbase']),
                                                               self.community,
                                                               self.app) \
                .diff_localized(True, self.app.preferences['international_system_of_units'])

            computed_dividend = await self.community.computed_dividend()
            # display float values
            localized_ud_plus_1 = await self.account.current_ref.instance(computed_dividend,
                                                    self.community, self.app)\
                .diff_localized(True, self.app.preferences['international_system_of_units'])

            localized_mass = await self.account.current_ref.instance(block_ud['monetaryMass'],
                                                    self.community, self.app)\
                .diff_localized(True, self.app.preferences['international_system_of_units'])

            localized_ud_median_time = QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(block_ud['medianTime']),
                        QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                    )

            localized_next_ud_median_time = QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(block_ud['medianTime'] + params['dt']),
                        QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                    )

            if block_ud_minus_1:
                mass_minus_1 = (float(0) if block_ud['membersCount'] == 0 else
                        block_ud_minus_1['monetaryMass'] / block_ud['membersCount'])
                localized_mass_minus_1_per_member = await self.account.current_ref.instance(mass_minus_1,
                                                                  self.community, self.app)\
                    .diff_localized(True, self.app.preferences['international_system_of_units'])
                localized_mass_minus_1 = await self.account.current_ref.instance(block_ud_minus_1['monetaryMass'],
                                                                  self.community, self.app)\
                    .diff_localized(True, self.app.preferences['international_system_of_units'])
                # avoid divide by zero !
                if block_ud['membersCount'] == 0 or block_ud_minus_1['monetaryMass'] == 0:
                    actual_growth = float(0)
                else:
                    actual_growth = (block_ud['dividend'] * math.pow(10, block_ud['unitbase'])) / (block_ud_minus_1['monetaryMass'] / block_ud['membersCount'])

                localized_ud_median_time_minus_1 = QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(block_ud_minus_1['medianTime']),
                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                )
            else:
                localized_mass_minus_1_per_member = QLocale().toString(
                        float(0), 'f', self.app.preferences['digits_after_comma']
                )
                localized_mass_minus_1 = QLocale().toString(
                        float(0), 'f', self.app.preferences['digits_after_comma']
                )
                actual_growth = float(0)
                localized_ud_median_time_minus_1 = "####"

            # set infos in label
            self.label_general.setText(
                    self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:2.2%} / {:} days</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    localized_ud,
                    self.tr('Universal Dividend UD(t) in'),
                    self.account.current_ref.instance(0, self.community, self.app, None).diff_units,
                    localized_mass_minus_1,
                    self.tr('Monetary Mass M(t-1) in'),
                    self.account.current_ref.instance(0, self.community, self.app, None).units,
                    block_ud['membersCount'],
                    self.tr('Members N(t)'),
                    localized_mass_minus_1_per_member,
                    self.tr('Monetary Mass per member M(t-1)/N(t) in'),
                    self.account.current_ref.instance(0, self.community, self.app, None).diff_units,
                    actual_growth,
                    params['dt'] / 86400,
                    self.tr('Actual growth c = UD(t)/[M(t-1)/N(t)]'),
                    localized_ud_median_time_minus_1,
                    self.tr('Penultimate UD date and time (t-1)'),
                    localized_ud_median_time,
                    self.tr('Last UD date and time (t)'),
                    localized_next_ud_median_time,
                    self.tr('Next UD date and time (t+1)')
                )
            )
        else:
            self.label_general.setText(self.tr('No Universal Dividend created yet.'))

        if block_ud:
            # set infos in label
            self.label_rules.setText(
                    self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.tr('{:2.0%} / {:} days').format(params['c'], params['dt'] / 86400),
                    self.tr('Fundamental growth (c) / Delta time (dt)'),
                    self.tr('UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }'),
                    self.tr('Universal Dividend (formula)'),
                    self.tr('{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}').format(
                        localized_ud_plus_1,
                        localized_ud,
                        self.account.current_ref.instance(0, self.community, self.app, None).diff_units,
                        params['c'],
                        localized_mass,
                        self.account.current_ref.instance(0, self.community, self.app, None).diff_units,
                        block_ud['membersCount']
                    ),
                    self.tr('Universal Dividend (computed)')
                )
            )
        else:
            self.label_rules.setText(self.tr('No Universal Dividend created yet.'))

        # set infos in label
        ref_template = """
        <table cellpadding="5">
        <tr><th>{:}</th><td>{:}</td></tr>
        <tr><th>{:}</th><td>{:}</td></tr>
        <tr><th>{:}</th><td>{:}</td></tr>
        <tr><th>{:}</th><td>{:}</td></tr>
        </table>
        """
        templates = []
        for ref_class in Referentials:
            ref = ref_class(0, self.community, self.app, None)
            # print(ref_class.__class__.__name__)
            # if ref_class.__class__.__name__ == 'RelativeToPast':
            #     continue
            templates.append(ref_template.format(self.tr('Name'), ref.translated_name(),
                                        self.tr('Units'), ref.units,
                                        self.tr('Formula'), ref.formula,
                                        self.tr('Description'), ref.description
                                        )
                             )

        self.label_referentials.setText('<hr>'.join(templates))

        # set infos in label
        self.label_money.setText(
                self.tr("""
            <table cellpadding="5">
            <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr>
            </table>
            """).format(
                        params['c'],
                        params['dt'] / 86400,
                        self.tr('Fundamental growth (c)'),
                        params['ud0'],
                        self.tr('Initial Universal Dividend UD(0) in'),
                        self.community.short_currency,
                        params['dt'] / 86400,
                        self.tr('Time period (dt) in days (86400 seconds) between two UD'),
                        params['medianTimeBlocks'],
                        self.tr('Number of blocks used for calculating median time'),
                        params['avgGenTime'],
                        self.tr('The average time in seconds for writing 1 block (wished time)'),
                        params['dtDiffEval'],
                        self.tr('The number of blocks required to evaluate again PoWMin value'),
                        params['blocksRot'],
                        self.tr('The number of previous blocks to check for personalized difficulty'),
                        params['percentRot'],
                        self.tr('The percent of previous issuers to reach for personalized difficulty')
                )
        )

        # set infos in label
        self.label_wot.setText(
                self.tr("""
            <table cellpadding="5">
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            </table>
            """).format(
                        params['sigPeriod'] / 86400,
                        self.tr('Minimum delay between 2 certifications (in days)'),
                        params['sigValidity'] / 86400,
                        self.tr('Maximum age of a valid signature (in days)'),
                        params['sigQty'],
                        self.tr('Minimum quantity of signatures to be part of the WoT'),
                        params['sigStock'],
                        self.tr('Maximum quantity of active certifications made by member.'),
                        params['sigWindow'],
                        self.tr('Maximum delay a certification can wait before being expired for non-writing.'),
                        params['xpercent'],
                        self.tr('Minimum percent of sentries to reach to match the distance rule'),
                        params['msValidity'] / 86400,
                        self.tr('Maximum age of a valid membership (in days)'),
                        params['stepMax'],
                        self.tr('Maximum distance between each WoT member and a newcomer'),
                )
        )
        self.busy.hide()
예제 #39
0
    def refresh(self):
        parameters = self.community.parameters
        last_renewal = ""
        expiration = ""
        try:
            person = Person.lookup(self.account.pubkey, self.community)
            membership = person.membership(self.community)
            renew_block = membership['blockNumber']
            last_renewal = self.community.get_block(renew_block).mediantime
            expiration = last_renewal + parameters['sigValidity']
        except MembershipNotFoundError:
            last_renewal = None
            expiration = None

        certified = person.unique_valid_certified_by(self.community)
        certifiers = person.unique_valid_certifiers_of(self.community)
        if last_renewal and expiration:
            date_renewal = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
            )
            date_expiration = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
            )
            # set infos in label
            self.label_general.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.account.name, self.account.pubkey,
                    self.tr("Membership"),
                    self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
                    self.tr("Your web of trust"),
                    self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
                                                                                             len(certified))
                )
            )
        else:
            # set infos in label
            self.label_general.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.account.name, self.account.pubkey,
                    self.tr("Not a member"),
                    self.tr("Your web of trust"),
                    self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
                                                                                             len(certified))
                )
            )

        amount = self.account.amount(self.community)
        maximum = self.community.monetary_mass
        # if referential type is quantitative...
        if self.account.ref_type() == 'q':
            # display int values
            localized_amount = QLocale().toString(float(self.get_referential_value(amount)), 'f', 0)
            localized_minimum = QLocale().toString(float(self.get_referential_value(0)), 'f', 0)
            localized_maximum = QLocale().toString(float(self.get_referential_value(maximum)), 'f', 0)
        else:
            # display float values
            localized_amount = QLocale().toString(float(self.get_referential_value(amount)), 'f', 6)
            localized_minimum = QLocale().toString(float(self.get_referential_value(0)), 'f', 6)
            localized_maximum = QLocale().toString(float(self.get_referential_value(maximum)), 'f', 6)

        # set infos in label
        self.label_balance.setText(
            self.tr("""
            <table cellpadding="5">
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            </table>
            """).format(
                self.tr("Your money share "),
                self.tr("{:.2f}%").format(amount / maximum * 100) if maximum != 0 else "0%",
                self.tr("Your part "),
                self.tr("{:} {:} in [{:} ; {:}] {:}")
                .format(
                    localized_amount,
                    self.get_referential_name(),
                    localized_minimum,
                    localized_maximum,
                    self.get_referential_name()
                )
            )
        )

        wallets_model = WalletsTableModel(self.account, self.community)
        proxy_model = WalletsFilterProxyModel()
        proxy_model.setSourceModel(wallets_model)
        wallets_model.dataChanged.connect(self.wallet_changed)
        self.table_wallets.setModel(proxy_model)
        self.table_wallets.resizeColumnsToContents()
예제 #40
0
파일: graph_tab.py 프로젝트: mmuman/sakia
    async def refresh_informations_frame(self):
        parameters = self.community.parameters
        try:
            identity = await self.account.identity(self.community)
            membership = identity.membership(self.community)
            renew_block = membership['blockNumber']
            last_renewal = self.community.get_block(renew_block)['medianTime']
            expiration = last_renewal + parameters['sigValidity']
        except MembershipNotFoundError:
            last_renewal = None
            expiration = None

        certified = await identity.unique_valid_certified_by(
            self.app.identities_registry, self.community)
        certifiers = await identity.unique_valid_certifiers_of(
            self.app.identities_registry, self.community)
        if last_renewal and expiration:
            date_renewal = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(last_renewal).date(),
                QLocale.dateFormat(QLocale(), QLocale.LongFormat))
            date_expiration = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(expiration).date(),
                QLocale.dateFormat(QLocale(), QLocale.LongFormat))

            if self.account.pubkey in self.community.members_pubkeys():
                # set infos in label
                self.label_general.setText(
                    self.tr("""
                    <table cellpadding="5">
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    </table>
                    """).format(
                        self.account.name, self.account.pubkey,
                        self.tr("Membership"),
                        self.tr(
                            "Last renewal on {:}, expiration on {:}").format(
                                date_renewal, date_expiration),
                        self.tr("Your web of trust"),
                        self.
                        tr("Certified by {:} members; Certifier of {:} members"
                           ).format(len(certifiers), len(certified))))
            else:
                # set infos in label
                self.label_general.setText(
                    self.tr("""
                    <table cellpadding="5">
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    </table>
                    """).format(
                        self.account.name, self.account.pubkey,
                        self.tr("Not a member"),
                        self.tr(
                            "Last renewal on {:}, expiration on {:}").format(
                                date_renewal, date_expiration),
                        self.tr("Your web of trust"),
                        self.
                        tr("Certified by {:} members; Certifier of {:} members"
                           ).format(len(certifiers), len(certified))))
        else:
            # set infos in label
            self.label_general.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.account.name, self.account.pubkey,
                    self.tr("Not a member"), self.tr("Your web of trust"),
                    self.tr(
                        "Certified by {:} members; Certifier of {:} members").
                    format(len(certifiers), len(certified))))
예제 #41
0
파일: table_model.py 프로젝트: florck/sakia
    def data(self, index, role):
        source_index = self.mapToSource(index)
        if source_index.isValid():
            source_data = self.sourceModel().data(source_index, role)
            expiration_col = IdentitiesTableModel.columns_ids.index('expiration')
            expiration_index = self.sourceModel().index(source_index.row(), expiration_col)

            STATUS_NOT_MEMBER = 0
            STATUS_MEMBER = 1
            STATUS_UNKNOWN = 2
            STATUS_EXPIRE_SOON = 3
            status = STATUS_NOT_MEMBER
            expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole)
            current_time = QDateTime().currentDateTime().toMSecsSinceEpoch()
            sig_validity = self.sourceModel().sig_validity()
            warning_expiration_time = int(sig_validity / 3)
            #logging.debug("{0} > {1}".format(current_time, expiration_data))

            if expiration_data == 0:
                status = STATUS_UNKNOWN
            elif expiration_data is not None:
                status = STATUS_MEMBER
                if current_time > (expiration_data*1000):
                    status = STATUS_NOT_MEMBER
                elif current_time > ((expiration_data*1000) - (warning_expiration_time*1000)):
                    status = STATUS_EXPIRE_SOON

            if role == Qt.DisplayRole:
                if source_index.column() in (IdentitiesTableModel.columns_ids.index('renewed'),
                                             IdentitiesTableModel.columns_ids.index('expiration')):
                    if source_data:
                        ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data)
                        return QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(ts).date(),
                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                        )
                    else:
                        return ""
                if source_index.column() == IdentitiesTableModel.columns_ids.index('publication'):
                    if source_data:
                        ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data)
                        return QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(ts),
                            QLocale.dateTimeFormat(QLocale(), QLocale.LongFormat)
                        )
                    else:
                        return ""
                if source_index.column() == IdentitiesTableModel.columns_ids.index('pubkey'):
                    return source_data
                if source_index.column() == IdentitiesTableModel.columns_ids.index('block'):
                    return str(source_data)[:20]

            if role == Qt.ForegroundRole:
                if status == STATUS_EXPIRE_SOON:
                    return QColor("darkorange").darker(120)
                elif status == STATUS_NOT_MEMBER:
                    return QColor(Qt.red)
                elif status == STATUS_UNKNOWN:
                    return QColor(Qt.black)
                else:
                    return QColor(Qt.blue)

            if role == Qt.FontRole and status == STATUS_UNKNOWN:
                font = QFont()
                font.setItalic(True)
                return font

            if role == Qt.DecorationRole and source_index.column() == IdentitiesTableModel.columns_ids.index('uid'):
                if status == STATUS_NOT_MEMBER:
                    return QIcon(":/icons/not_member")
                elif status == STATUS_MEMBER:
                    return QIcon(":/icons/member")
                elif status == STATUS_EXPIRE_SOON:
                    return QIcon(":/icons/member_warning")

            return source_data
class PipPackageDetailsDialog(QDialog, Ui_PipPackageDetailsDialog):
    """
    Class implementing a dialog to show details about a package.
    """
    def __init__(self, detailsData, parent=None):
        """
        Constructor
        
        @param detailsData package details
        @type dict
        @param parent reference to the parent widget
        @type QWidget
        """
        super(PipPackageDetailsDialog, self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlags(Qt.Window)

        self.__locale = QLocale()
        self.__packageTypeMap = {
            "sdist": self.tr("Source"),
            "bdist_wheel": self.tr("Python Wheel"),
            "bdist_egg": self.tr("Python Egg"),
            "bdist_wininst": self.tr("MS Windows Installer"),
            "bdist_msi": self.tr("MS Windows Installer"),
            "bdist_rpm": self.tr("Unix Installer"),
            "bdist_deb": self.tr("Unix Installer"),
            "bdist_dumb": self.tr("Archive"),
        }

        self.__populateDetails(detailsData["info"])
        self.__populateDownloadUrls(detailsData["urls"])
        self.__populateRequiresProvides(detailsData["info"])

    def __populateDetails(self, detailsData):
        """
        Private method to populate the details tab.
        
        @param detailsData package details
        @type dict
        """
        self.packageNameLabel.setText("<h1>{0} {1}</h1".format(
            self.__sanitize(detailsData["name"]),
            self.__sanitize(detailsData["version"])))
        self.summaryLabel.setText(self.__sanitize(
            detailsData["summary"][:240]))
        self.descriptionEdit.setPlainText(
            self.__sanitize(detailsData["description"]))
        self.authorLabel.setText(self.__sanitize(detailsData["author"]))
        self.authorEmailLabel.setText('<a href="mailto:{0}">{0}</a>'.format(
            self.__sanitize(detailsData["author_email"])))
        self.licenseLabel.setText(self.__sanitize(detailsData["license"]))
        self.platformLabel.setText(self.__sanitize(detailsData["platform"]))
        self.homePageLabel.setText('<a href="{0}">{0}</a>'.format(
            self.__sanitize(detailsData["home_page"], forUrl=True)))
        self.packageUrlLabel.setText('<a href="{0}">{0}</a>'.format(
            self.__sanitize(detailsData["package_url"], forUrl=True)))
        self.releaseUrlLabel.setText('<a href="{0}">{0}</a>'.format(
            self.__sanitize(detailsData["release_url"], forUrl=True)))
        self.docsUrlLabel.setText('<a href="{0}">{0}</a>'.format(
            self.__sanitize(detailsData["docs_url"], forUrl=True)))
        self.downloadsDayLabel.setText(
            self.__locale.toString(detailsData["downloads"]["last_day"]))
        self.downloadsWeekLabel.setText(
            self.__locale.toString(detailsData["downloads"]["last_week"]))
        self.downloadsMonthLabel.setText(
            self.__locale.toString(detailsData["downloads"]["last_month"]))
        self.classifiersList.addItems(detailsData["classifiers"])

        self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
        self.buttonBox.button(QDialogButtonBox.Close).setFocus(
            Qt.OtherFocusReason)

    def __populateDownloadUrls(self, downloadsData):
        """
        Private method to populate the download URLs tab.
        
        @param downloadsData downloads information
        @type dict
        """
        index = self.infoWidget.indexOf(self.urls)
        if downloadsData:
            self.infoWidget.setTabEnabled(index, True)
            for download in downloadsData:
                itm = QTreeWidgetItem(self.downloadUrlsList, [
                    "",
                    self.__packageTypeMap[download["packagetype"]] if
                    download["packagetype"] in self.__packageTypeMap else "",
                    download["python_version"]
                    if download["python_version"] != "source" else "",
                    self.__locale.toString(download["downloads"]),
                    self.__formatUploadDate(download["upload_time"]),
                    self.__formatSize(download["size"]),
                ])
                if download["has_sig"]:
                    pgpLink = ' (<a href="{0}">pgp</a>)'.format(
                        download["url"] + ".asc")
                else:
                    pgpLink = ""
                urlLabel = QLabel('<a href="{0}#md5={2}">{1}</a>{3}'.format(
                    download["url"], download["filename"],
                    download["md5_digest"], pgpLink))
                urlLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
                urlLabel.setOpenExternalLinks(True)
                self.downloadUrlsList.setItemWidget(itm, 0, urlLabel)
            header = self.downloadUrlsList.header()
            header.resizeSections(QHeaderView.ResizeToContents)
        else:
            self.infoWidget.setTabEnabled(index, False)

    def __populateRequiresProvides(self, detailsData):
        """
        Private method to populate the requires/provides tab.
        
        @param detailsData package details
        @type dict
        """
        populatedItems = 0

        if "requires" in detailsData and detailsData["requires"]:
            self.requiredPackagesList.addItems(detailsData["requires"])
            populatedItems += len(detailsData["requires"])
        if "requires_dist" in detailsData and detailsData["requires_dist"]:
            self.requiredDistributionsList.addItems(
                detailsData["requires_dist"])
            populatedItems += len(detailsData["requires_dist"])
        if "provides" in detailsData and detailsData["provides"]:
            self.providedPackagesList.addItems(detailsData["provides"])
            populatedItems += len(detailsData["provides"])
        if "provides_dist" in detailsData and detailsData["provides_dist"]:
            self.providedDistributionsList.addItems(
                detailsData["provides_dist"])
            populatedItems += len(detailsData["provides_dist"])

        index = self.infoWidget.indexOf(self.requires)
        self.infoWidget.setTabEnabled(index, populatedItems > 0)

    def __sanitize(self, text, forUrl=False):
        """
        Private method to clean-up the given text.
        
        @param text raw text
        @type str
        @param forUrl flag indicating to sanitize an URL text
        @type bool
        @return processed text
        @rtype str
        """
        if text == "UNKNOWN":
            text = ""
        elif text == "any":
            text = self.tr("any")
        elif text is None:
            text = ""
        if forUrl:
            if (not isinstance(text, str) or not text.startswith(
                ("http://", "https://", "ftp://"))):
                # ignore if the schema is not one of the listed ones
                text = ""

        return text

    def __formatUploadDate(self, datetime):
        """
        Private method to format the upload date.
        
        @param datetime upload date and time
        @type xmlrpc.DateTime or str
        @return formatted date string
        @rtype str
        """
        if isinstance(datetime, str):
            return datetime.split("T")[0]
        else:
            date = datetime.value.split("T")[0]
            return "{0}-{1}-{2}".format(date[:4], date[4:6], date[6:])

    def __formatSize(self, size):
        """
        Private slot to format the size.
        
        @param size size to be formatted
        @type int
        @return formatted size
        @rtype str
        """
        unit = ""
        if size < 1024:
            unit = self.tr("B")
        elif size < 1024 * 1024:
            size /= 1024
            unit = self.tr("KB")
        elif size < 1024 * 1024 * 1024:
            size /= 1024 * 1024
            unit = self.tr("MB")
        else:
            size /= 1024 * 1024 * 1024
            unit = self.tr("GB")
        return self.tr("{0:.1f} {1}", "value, unit").format(size, unit)
예제 #43
0
    def get_localized_data(self):
        localized_data = {}
        #  try to request money parameters
        try:
            params = self.blockchain_service.parameters()
        except NoPeerAvailable as e:
            logging.debug('community parameters error : ' + str(e))
            return None

        localized_data['currency'] = ROOT_SERVERS[
            self.connection.currency]["display"]
        localized_data['growth'] = params.c
        localized_data['days_per_dividend'] = QLocale().toString(
            params.dt / 86400, 'f', 2)

        last_ud, last_ud_base = self.blockchain_service.last_ud()
        members_count = self.blockchain_service.last_members_count()
        previous_ud, previous_ud_base = self.blockchain_service.previous_ud()
        previous_ud_time = self.blockchain_service.previous_ud_time()
        previous_monetary_mass = self.blockchain_service.previous_monetary_mass(
        )
        previous_members_count = self.blockchain_service.previous_members_count(
        )

        localized_data['units'] = self.app.current_ref.instance(
            0, self.connection.currency, self.app, None).units
        localized_data['diff_units'] = self.app.current_ref.instance(
            0, self.connection.currency, self.app, None).diff_units

        if last_ud:
            # display float values
            localized_data['ud'] = self.app.current_ref.instance(
                last_ud * math.pow(10, last_ud_base), self.connection.currency,
                self.app).diff_localized(False, True)

            localized_data[
                'members_count'] = self.blockchain_service.current_members_count(
                )

            computed_dividend = self.blockchain_service.computed_dividend()
            # display float values
            localized_data['ud_plus_1'] = self.app.current_ref.instance(
                computed_dividend, self.connection.currency,
                self.app).diff_localized(False, True)

            localized_data['mass'] = self.app.current_ref.instance(
                self.blockchain_service.current_mass(),
                self.connection.currency, self.app).localized(False, True)

            ud_median_time = self.blockchain_service.last_ud_time()
            ud_median_time = self.blockchain_processor.adjusted_ts(
                self.app.currency, ud_median_time)

            localized_data['ud_median_time'] = QLocale.toString(
                QLocale(), QDateTime.fromTime_t(ud_median_time),
                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat))

            next_ud_median_time = self.blockchain_service.last_ud_time(
            ) + params.dt
            next_ud_median_time = self.blockchain_processor.adjusted_ts(
                self.app.currency, next_ud_median_time)

            localized_data['next_ud_median_time'] = QLocale.toString(
                QLocale(), QDateTime.fromTime_t(next_ud_median_time),
                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat))

            next_ud_reeval = self.blockchain_service.next_ud_reeval()
            next_ud_reeval = self.blockchain_processor.adjusted_ts(
                self.app.currency, next_ud_reeval)
            localized_data['next_ud_reeval'] = QLocale.toString(
                QLocale(), QDateTime.fromTime_t(next_ud_reeval),
                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat))

            if previous_ud:
                mass_minus_1_per_member = (float(0) if previous_ud == 0
                                           or previous_members_count == 0 else
                                           previous_monetary_mass /
                                           previous_members_count)
                localized_data['mass_minus_1_per_member'] = self.app.current_ref.instance(mass_minus_1_per_member,
                                                  self.connection.currency, self.app) \
                                                  .localized(False, True)
                localized_data['mass_minus_1'] = self.app.current_ref.instance(previous_monetary_mass,
                                                  self.connection.currency, self.app) \
                                                  .localized(False, True)
                # avoid divide by zero !
                if members_count == 0 or previous_members_count == 0:
                    localized_data['actual_growth'] = float(0)
                else:
                    localized_data['actual_growth'] = (last_ud * math.pow(
                        10, last_ud_base)) / (previous_monetary_mass /
                                              members_count)

                previous_ud_time = self.blockchain_processor.adjusted_ts(
                    self.app.currency, previous_ud_time)
                localized_data['ud_median_time_minus_1'] = QLocale.toString(
                    QLocale(), QDateTime.fromTime_t(previous_ud_time),
                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat))
        return localized_data
예제 #44
0
 def start(self, fn):
     """
     Public slot to start the code metrics determination.
     
     @param fn file or list of files or directory to show
             the code metrics for (string or list of strings)
     """
     self.cancelled = False
     self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
     self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True)
     self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
     QApplication.processEvents()
     
     loc = QLocale()
     if isinstance(fn, list):
         files = fn
     elif os.path.isdir(fn):
         files = Utilities.direntries(fn, True, '*.py', False)
     else:
         files = [fn]
     files.sort()
     # check for missing files
     for f in files[:]:
         if not os.path.exists(f):
             files.remove(f)
     
     self.checkProgress.setMaximum(len(files))
     QApplication.processEvents()
     
     total = {}
     CodeMetrics.summarize(total, 'files', len(files))
     
     progress = 0
     
     try:
         # disable updates of the list for speed
         self.resultList.setUpdatesEnabled(False)
         self.resultList.setSortingEnabled(False)
         
         # now go through all the files
         for file in files:
             if self.cancelled:
                 return
             
             stats = CodeMetrics.analyze(file, total)
             
             v = self.__getValues(loc, stats, 'TOTAL ')
             fitm = self.__createResultItem(self.resultList, [file] + v)
             
             identifiers = stats.identifiers
             for identifier in identifiers:
                 v = self.__getValues(loc, stats, identifier)
                 
                 self.__createResultItem(fitm, [identifier] + v)
             self.resultList.expandItem(fitm)
             
             progress += 1
             self.checkProgress.setValue(progress)
             QApplication.processEvents()
     finally:
         # reenable updates of the list
         self.resultList.setSortingEnabled(True)
         self.resultList.setUpdatesEnabled(True)
     self.__resizeResultColumns()
     
     # now do the summary stuff
     self.__createSummaryItem(self.tr("files"),
                              loc.toString(total['files']))
     self.__createSummaryItem(self.tr("lines"),
                              loc.toString(total['lines']))
     self.__createSummaryItem(self.tr("bytes"),
                              loc.toString(total['bytes']))
     self.__createSummaryItem(self.tr("comments"),
                              loc.toString(total['comments']))
     self.__createSummaryItem(self.tr("comment lines"),
                              loc.toString(total['commentlines']))
     self.__createSummaryItem(self.tr("empty lines"),
                              loc.toString(total['empty lines']))
     self.__createSummaryItem(self.tr("non-commentary lines"),
                              loc.toString(total['non-commentary lines']))
     self.__resizeSummaryColumns()
     self.__finish()
예제 #45
0
class SymbolsModel(QAbstractTableModel):
    """
    Class implementing the model for the symbols widget.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent object (QObject)
        """
        super(SymbolsModel, self).__init__(parent)
        
        self.__locale = QLocale()
        
        self.__headerData = [
            self.tr("Code"),
            self.tr("Char"),
            self.tr("Hex"),
            self.tr("HTML"),
            self.tr("Name"),
        ]
        
        self.__tables = [
            # first   last     display name
            (0x0, 0x1f, self.tr("Control Characters")),
            (0x20, 0x7f, self.tr("Basic Latin")),
            (0x80, 0xff, self.tr("Latin-1 Supplement")),
            (0x100, 0x17f, self.tr("Latin Extended-A")),
            (0x180, 0x24f, self.tr("Latin Extended-B")),
            (0x250, 0x2af, self.tr("IPA Extensions")),
            (0x2b0, 0x2ff, self.tr("Spacing Modifier Letters")),
            (0x300, 0x36f, self.tr("Combining Diacritical Marks")),
            (0x370, 0x3ff, self.tr("Greek and Coptic")),
            (0x400, 0x4ff, self.tr("Cyrillic")),
            (0x500, 0x52f, self.tr("Cyrillic Supplement")),
            (0x530, 0x58f, self.tr("Armenian")),
            (0x590, 0x5ff, self.tr("Hebrew")),
            (0x600, 0x6ff, self.tr("Arabic")),
            (0x700, 0x74f, self.tr("Syriac")),
            (0x780, 0x7bf, self.tr("Thaana")),
            (0x7c0, 0x7ff, self.tr("N'Ko")),
            (0x800, 0x83f, self.tr("Samaritan")),
            (0x840, 0x85f, self.tr("Mandaic")),
            (0x8a0, 0x8ff, self.tr("Arabic Extended-A")),
            (0x900, 0x97f, self.tr("Devanagari")),
            (0x980, 0x9ff, self.tr("Bengali")),
            (0xa00, 0xa7f, self.tr("Gurmukhi")),
            (0xa80, 0xaff, self.tr("Gujarati")),
            (0xb00, 0xb7f, self.tr("Oriya")),
            (0xb80, 0xbff, self.tr("Tamil")),
            (0xc00, 0xc7f, self.tr("Telugu")),
            (0xc80, 0xcff, self.tr("Kannada")),
            (0xd00, 0xd7f, self.tr("Malayalam")),
            (0xd80, 0xdff, self.tr("Sinhala")),
            (0xe00, 0xe7f, self.tr("Thai")),
            (0xe80, 0xeff, self.tr("Lao")),
            (0xf00, 0xfff, self.tr("Tibetan")),
            (0x1000, 0x109f, self.tr("Myanmar")),
            (0x10a0, 0x10ff, self.tr("Georgian")),
            (0x1100, 0x11ff, self.tr("Hangul Jamo")),
            (0x1200, 0x137f, self.tr("Ethiopic")),
            (0x1380, 0x139f, self.tr("Ethiopic Supplement")),
            (0x13a0, 0x13ff, self.tr("Cherokee")),
            (0x1400, 0x167f,
             self.tr("Unified Canadian Aboriginal Syllabics")),
            (0x1680, 0x169f, self.tr("Ogham")),
            (0x16a0, 0x16ff, self.tr("Runic")),
            (0x1700, 0x171f, self.tr("Tagalog")),
            (0x1720, 0x173f, self.tr("Hanunoo")),
            (0x1740, 0x175f, self.tr("Buhid")),
            (0x1760, 0x177f, self.tr("Tagbanwa")),
            (0x1780, 0x17ff, self.tr("Khmer")),
            (0x1800, 0x18af, self.tr("Mongolian")),
            (0x18b0, 0x18ff,
             self.tr("Unified Canadian Aboriginal Syllabics Extended")),
            (0x1900, 0x194f, self.tr("Limbu")),
            (0x1950, 0x197f, self.tr("Tai Le")),
            (0x19e0, 0x19ff, self.tr("Khmer Symbols")),
            (0x1a00, 0x1a1f, self.tr("Buginese")),
            (0x1a20, 0x1aaf, self.tr("Tai Tham")),
            (0x1b00, 0x1b7f, self.tr("Balinese")),
            (0x1b80, 0x1bbf, self.tr("Sundanese")),
            (0x1bc0, 0x1bff, self.tr("Batak")),
            (0x1c00, 0x1c4f, self.tr("Lepcha")),
            (0x1c50, 0x1c7f, self.tr("Ol Chiki")),
            (0x1cc0, 0x1ccf, self.tr("Sundanese Supplement")),
            (0x1cd0, 0x1cff, self.tr("Vedic Extensions")),
            (0x1d00, 0x1d7f, self.tr("Phonetic Extensions")),
            (0x1d80, 0x1dbf, self.tr("Phonetic Extensions Supplement")),
            (0x1dc0, 0x1dff,
             self.tr("Combining Diacritical Marks Supplement")),
            (0x1e00, 0x1eff, self.tr("Latin Extended Additional")),
            (0x1f00, 0x1fff, self.tr("Greek Extended")),
            (0x2000, 0x206f, self.tr("General Punctuation")),
            (0x2070, 0x209f, self.tr("Superscripts and Subscripts")),
            (0x20a0, 0x20cf, self.tr("Currency Symbols")),
            (0x20d0, 0x20ff, self.tr("Combining Diacritical Marks")),
            (0x2100, 0x214f, self.tr("Letterlike Symbols")),
            (0x2150, 0x218f, self.tr("Number Forms")),
            (0x2190, 0x21ff, self.tr("Arcolumns")),
            (0x2200, 0x22ff, self.tr("Mathematical Operators")),
            (0x2300, 0x23ff, self.tr("Miscellaneous Technical")),
            (0x2400, 0x243f, self.tr("Control Pictures")),
            (0x2440, 0x245f, self.tr("Optical Character Recognition")),
            (0x2460, 0x24ff, self.tr("Enclosed Alphanumerics")),
            (0x2500, 0x257f, self.tr("Box Drawing")),
            (0x2580, 0x259f, self.tr("Block Elements")),
            (0x25A0, 0x25ff, self.tr("Geometric Shapes")),
            (0x2600, 0x26ff, self.tr("Miscellaneous Symbols")),
            (0x2700, 0x27bf, self.tr("Dingbats")),
            (0x27c0, 0x27ef,
             self.tr("Miscellaneous Mathematical Symbols-A")),
            (0x27f0, 0x27ff, self.tr("Supplement Arcolumns-A")),
            (0x2800, 0x28ff, self.tr("Braille Patterns")),
            (0x2900, 0x297f, self.tr("Supplement Arcolumns-B")),
            (0x2980, 0x29ff,
             self.tr("Miscellaneous Mathematical Symbols-B")),
            (0x2a00, 0x2aff,
             self.tr("Supplemental Mathematical Operators")),
            (0x2b00, 0x2bff,
             self.tr("Miscellaneous Symbols and Arcolumns")),
            (0x2c00, 0x2c5f, self.tr("Glagolitic")),
            (0x2c60, 0x2c7f, self.tr("Latin Extended-C")),
            (0x2c80, 0x2cff, self.tr("Coptic")),
            (0x2d00, 0x2d2f, self.tr("Georgian Supplement")),
            (0x2d30, 0x2d7f, self.tr("Tifinagh")),
            (0x2d80, 0x2ddf, self.tr("Ethiopic Extended")),
            (0x2de0, 0x2dff, self.tr("Cyrillic Extended-A")),
            (0x2e00, 0x2e7f, self.tr("Supplemental Punctuation")),
            (0x2e80, 0x2eff, self.tr("CJK Radicals Supplement")),
            (0x2f00, 0x2fdf, self.tr("KangXi Radicals")),
            (0x2ff0, 0x2fff, self.tr("Ideographic Description Chars")),
            (0x3000, 0x303f, self.tr("CJK Symbols and Punctuation")),
            (0x3040, 0x309f, self.tr("Hiragana")),
            (0x30a0, 0x30ff, self.tr("Katakana")),
            (0x3100, 0x312f, self.tr("Bopomofo")),
            (0x3130, 0x318f, self.tr("Hangul Compatibility Jamo")),
            (0x3190, 0x319f, self.tr("Kanbun")),
            (0x31a0, 0x31bf, self.tr("Bopomofo Extended")),
            (0x31c0, 0x31ef, self.tr("CJK Strokes")),
            (0x31f0, 0x31ff, self.tr("Katakana Phonetic Extensions")),
            (0x3200, 0x32ff, self.tr("Enclosed CJK Letters and Months")),
            (0x3300, 0x33ff, self.tr("CJK Compatibility")),
            (0x3400, 0x4dbf, self.tr("CJK Unified Ideogr. Ext. A")),
            (0x4dc0, 0x4dff, self.tr("Yijing Hexagram Symbols")),
            (0x4e00, 0x9fff, self.tr("CJK Unified Ideographs")),
            (0xa000, 0xa48f, self.tr("Yi Syllables")),
            (0xa490, 0xa4cf, self.tr("Yi Radicals")),
            (0xa4d0, 0xa4ff, self.tr("Lisu")),
            (0xa500, 0xa63f, self.tr("Vai")),
            (0xa640, 0xa69f, self.tr("Cyrillic Extended-B")),
            (0xa6a0, 0xa6ff, self.tr("Bamum")),
            (0xa700, 0xa71f, self.tr("Modifier Tone Letters")),
            (0xa720, 0xa7ff, self.tr("Latin Extended-D")),
            (0xa800, 0xa82f, self.tr("Syloti Nagri")),
            (0xa830, 0xa83f, self.tr("Common Indic Number Forms")),
            (0xa840, 0xa87f, self.tr("Phags-pa")),
            (0xa880, 0xa8df, self.tr("Saurashtra")),
            (0xa8e0, 0xa8ff, self.tr("Devanagari Extended")),
            (0xa900, 0xa92f, self.tr("Kayah Li")),
            (0xa930, 0xa95f, self.tr("Rejang")),
            (0xa960, 0xa97f, self.tr("Hangul Jamo Extended-A")),
            (0xa980, 0xa9df, self.tr("Javanese")),
            (0xaa00, 0xaa5f, self.tr("Cham")),
            (0xaa60, 0xaa7f, self.tr("Myanmar Extended-A")),
            (0xaa80, 0xaadf, self.tr("Tai Viet")),
            (0xaae0, 0xaaff, self.tr("Meetei Mayek Extensions")),
            (0xab00, 0xab2f, self.tr("Ethiopic Extended-A")),
            (0xabc0, 0xabff, self.tr("Meetei Mayek")),
            (0xac00, 0xd7af, self.tr("Hangul Syllables")),
            (0xd7b0, 0xd7ff, self.tr("Hangul Jamo Extended-B")),
            (0xd800, 0xdb7f, self.tr("High Surrogates")),
            (0xdb80, 0xdbff, self.tr("High Private Use Surrogates")),
            (0xdc00, 0xdfff, self.tr("Low Surrogates")),
            (0xe000, 0xf8ff, self.tr("Private Use")),
            (0xf900, 0xfaff, self.tr("CJK Compatibility Ideographs")),
            (0xfb00, 0xfb4f, self.tr("Alphabetic Presentation Forms")),
            (0xfb50, 0xfdff, self.tr("Arabic Presentation Forms-A")),
            (0xfe00, 0xfe0f, self.tr("Variation Selectors")),
            (0xfe10, 0xfe1f, self.tr("Vertical Forms")),
            (0xfe20, 0xfe2f, self.tr("Combining Half Marks")),
            (0xfe30, 0xfe4f, self.tr("CJK Compatibility Forms")),
            (0xfe50, 0xfe6f, self.tr("Small Form Variants")),
            (0xfe70, 0xfeff, self.tr("Arabic Presentation Forms-B")),
            (0xff00, 0xffef, self.tr("Half- and Fullwidth Forms")),
            (0xfff0, 0xffff, self.tr("Specials")),
        ]
        if sys.maxunicode > 0xffff:
            self.__tables.extend([
                (0x10000, 0x1007f, self.tr("Linear B Syllabary")),
                (0x10080, 0x100ff, self.tr("Linear B Ideograms")),
                (0x10100, 0x1013f, self.tr("Aegean Numbers")),
                (0x10140, 0x1018f, self.tr("Ancient Greek Numbers")),
                (0x10190, 0x101cf, self.tr("Ancient Symbols")),
                (0x101d0, 0x101ff, self.tr("Phaistos Disc")),
                (0x10280, 0x1029f, self.tr("Lycian")),
                (0x102a0, 0x102df, self.tr("Carian")),
                (0x10300, 0x1032f, self.tr("Old Italic")),
                (0x10330, 0x1034f, self.tr("Gothic")),
                (0x10380, 0x1039f, self.tr("Ugaritic")),
                (0x103a0, 0x103df, self.tr("Old Persian")),
                (0x10400, 0x1044f, self.tr("Deseret")),
                (0x10450, 0x1047f, self.tr("Shavian")),
                (0x10480, 0x104af, self.tr("Osmanya")),
                (0x10800, 0x1083f, self.tr("Cypriot Syllabary")),
                (0x10840, 0x1085f, self.tr("Imperial Aramaic")),
                (0x10900, 0x1091f, self.tr("Phoenician")),
                (0x10920, 0x1093f, self.tr("Lydian")),
                (0x10980, 0x1099f, self.tr("Meroitic Hieroglyphs")),
                (0x109a0, 0x109ff, self.tr("Meroitic Cursive")),
                (0x10a00, 0x10a5f, self.tr("Kharoshthi")),
                (0x10a60, 0x10a7f, self.tr("Old South Arabian")),
                (0x10b00, 0x10b3f, self.tr("Avestan")),
                (0x10b40, 0x10b5f, self.tr("Inscriptional Parthian")),
                (0x10b60, 0x10b7f, self.tr("Inscriptional Pahlavi")),
                (0x10c00, 0x10c4f, self.tr("Old Turkic")),
                (0x10e60, 0x10e7f, self.tr("Rumi Numeral Symbols")),
                (0x11000, 0x1107f, self.tr("Brahmi")),
                (0x11080, 0x110cf, self.tr("Kaithi")),
                (0x110d0, 0x110ff, self.tr("Sora Sompeng")),
                (0x11100, 0x1114f, self.tr("Chakma")),
                (0x11180, 0x111df, self.tr("Sharada")),
                (0x11680, 0x116cf, self.tr("Takri")),
                (0x12000, 0x123ff, self.tr("Cuneiform")),
                (0x12400, 0x1247f,
                 self.tr("Cuneiform Numbers and Punctuation")),
                (0x13000, 0x1342f, self.tr("Egyptian Hieroglyphs")),
                (0x16800, 0x16a3f, self.tr("Bamum Supplement")),
                (0x16f00, 0x16f9f, self.tr("Miao")),
                (0x1b000, 0x1b0ff, self.tr("Kana Supplement")),
                (0x1d000, 0x1d0ff, self.tr("Byzantine Musical Symbols")),
                (0x1d100, 0x1d1ff, self.tr("Musical Symbols")),
                (0x1d200, 0x1d24f,
                 self.tr("Ancient Greek Musical Notation")),
                (0x1d300, 0x1d35f, self.tr("Tai Xuan Jing Symbols")),
                (0x1d360, 0x1d37f,
                 self.tr("Counting Rod Numerals")),
                (0x1d400, 0x1d7ff,
                 self.tr("Mathematical Alphanumeric Symbols")),
                (0x1ee00, 0x1eeff,
                 self.tr("Arabic Mathematical Alphabetic Symbols")),
                (0x1f000, 0x1f02f, self.tr("Mahjong Tiles")),
                (0x1f030, 0x1f09f, self.tr("Domino Tiles")),
                (0x1f0a0, 0x1f0ff, self.tr("Playing Cards")),
                (0x1f100, 0x1f1ff,
                 self.tr("Enclosed Alphanumeric Supplement")),
                (0x1f200, 0x1f2ff,
                 self.tr("Enclosed Ideographic Supplement")),
                (0x1f300, 0x1f5ff,
                 self.tr("Miscellaneous Symbols And Pictographs")),
                (0x1f600, 0x1f64f, self.tr("Emoticons")),
                (0x1f680, 0x1f6ff, self.tr("Transport And Map Symbols")),
                (0x1f700, 0x1f77f, self.tr("Alchemical Symbols")),
                (0x20000, 0x2a6df, self.tr("CJK Unified Ideogr. Ext. B")),
                (0x2a700, 0x2b73f,
                 self.tr("CJK Unified Ideographs Extension C")),
                (0x2b740, 0x2b81f,
                 self.tr("CJK Unified Ideographs Extension D")),
                (0x2f800, 0x2fa1f,
                 self.tr("CJK Compatapility Ideogr. Suppl.")),
                (0xe0000, 0xe007f, self.tr("Tags")),
                (0xe0100, 0xe01ef,
                 self.tr("Variation Selectors Supplement")),
                (0xf0000, 0xfffff,
                 self.tr("Supplementary Private Use Area-A")),
                (0x100000, 0x10ffff,
                 self.tr("Supplementary Private Use Area-B")),
            ])
        self.__currentTableIndex = 0
    
    def getTableNames(self):
        """
        Public method to get a list of table names.
        
        @return list of table names (list of strings)
        """
        return [table[2] for table in self.__tables]
    
    def getTableBoundaries(self, index):
        """
        Public method to get the first and last character position
        of the given table.
        
        @param index index of the character table (integer)
        @return first and last character position (integer, integer)
        """
        return self.__tables[index][0], self.__tables[index][1]
    
    def getTableIndex(self):
        """
        Public method to get the current table index.
        
        @return current table index (integer)
        """
        return self.__currentTableIndex
    
    def selectTable(self, index):
        """
        Public method to select the shown character table.
        
        @param index index of the character table (integer)
        """
        self.beginResetModel()
        self.__currentTableIndex = index
        self.endResetModel()
    
    def headerData(self, section, orientation, role=Qt.DisplayRole):
        """
        Public method to get header data from the model.
        
        @param section section number (integer)
        @param orientation orientation (Qt.Orientation)
        @param role role of the data to retrieve (integer)
        @return requested data
        """
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.__headerData[section]
        
        return QAbstractTableModel.headerData(self, section, orientation, role)
    
    def data(self, index, role=Qt.DisplayRole):
        """
        Public method to get data from the model.
        
        @param index index to get data for (QModelIndex)
        @param role role of the data to retrieve (integer)
        @return requested data
        """
        id = self.__tables[self.__currentTableIndex][0] + index.row()
        
        if role == Qt.DisplayRole:
            col = index.column()
            if col == 0:
                return self.__locale.toString(id)
            elif col == 1:
                return chr(id)
            elif col == 2:
                return "0x{0:04x}".format(id)
            elif col == 3:
                if id in html_entities.codepoint2name:
                    return "&{0};".format(html_entities.codepoint2name[id])
            elif col == 4:
                return unicodedata.name(chr(id), '').title()
        
        if role == Qt.BackgroundColorRole:
            if index.column() == 0:
                return QColor(Qt.lightGray)
        
        if role == Qt.TextColorRole:
            char = chr(id)
            if self.__isDigit(char):
                return QColor(Qt.darkBlue)
            elif self.__isLetter(char):
                return QColor(Qt.darkGreen)
            elif self.__isMark(char):
                return QColor(Qt.darkRed)
            elif self.__isSymbol(char):
                return QColor(Qt.black)
            elif self.__isPunct(char):
                return QColor(Qt.darkMagenta)
            else:
                return QColor(Qt.darkGray)
        
        if role == Qt.TextAlignmentRole:
            if index.column() in [0, 1, 3]:
                return Qt.AlignHCenter
        
        return None
    
    def columnCount(self, parent):
        """
        Public method to get the number of columns of the model.
        
        @param parent parent index (QModelIndex)
        @return number of columns (integer)
        """
        if parent.column() > 0:
            return 0
        else:
            return len(self.__headerData)
    
    def rowCount(self, parent):
        """
        Public method to get the number of rows of the model.
        
        @param parent parent index (QModelIndex)
        @return number of columns (integer)
        """
        if parent.isValid():
            return 0
        else:
            first, last = self.__tables[self.__currentTableIndex][:2]
            return last - first + 1
    
    def __isDigit(self, char):
        """
        Private method to check, if a character is a digit.
        
        @param char character to test (one character string)
        @return flag indicating a digit (boolean)
        """
        return unicodedata.category(str(char)) == "Nd"
    
    def __isLetter(self, char):
        """
        Private method to check, if a character is a letter.
        
        @param char character to test (one character string)
        @return flag indicating a letter (boolean)
        """
        return unicodedata.category(str(char)) in ["Lu", "Ll", "Lt", "Lm",
                                                   "Lo"]
    
    def __isMark(self, char):
        """
        Private method to check, if a character is a mark character.
        
        @param char character to test (one character string)
        @return flag indicating a mark character (boolean)
        """
        return unicodedata.category(str(char)) in ["Mn", "Mc", "Me"]
    
    def __isSymbol(self, char):
        """
        Private method to check, if a character is a symbol.
        
        @param char character to test (one character string)
        @return flag indicating a symbol (boolean)
        """
        return unicodedata.category(str(char)) in ["Sm", "Sc", "Sk", "So"]
    
    def __isPunct(self, char):
        """
        Private method to check, if a character is a punctuation character.
        
        @param char character to test (one character string)
        @return flag indicating a punctuation character (boolean)
        """
        return unicodedata.category(str(char)) in ["Pc", "Pd", "Ps", "Pe",
                                                   "Pi", "Pf", "Po"]
    
    def getLocale(self):
        """
        Public method to get the used locale.
        
        @return used locale
        @rtype QLocale
        """
        return self.__locale
예제 #46
0
class SnapshotRegionGrabber(QWidget):
    """
    Class implementing a grabber widget for a rectangular snapshot region.
    
    @signal grabbed(QPixmap) emitted after the region was grabbed
    """
    grabbed = pyqtSignal(QPixmap)
    
    StrokeMask = 0
    FillMask = 1
    
    Rectangle = 0
    Ellipse = 1
    
    def __init__(self, mode=Rectangle):
        """
        Constructor
        
        @param mode region grabber mode (SnapshotRegionGrabber.Rectangle or
            SnapshotRegionGrabber.Ellipse)
        """
        super(SnapshotRegionGrabber, self).__init__(
            None,
            Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint |
            Qt.FramelessWindowHint | Qt.Tool)
        
        assert mode in [SnapshotRegionGrabber.Rectangle,
                        SnapshotRegionGrabber.Ellipse]
        self.__mode = mode
        
        self.__selection = QRect()
        self.__mouseDown = False
        self.__newSelection = False
        self.__handleSize = 10
        self.__mouseOverHandle = None
        self.__showHelp = True
        self.__grabbing = False
        self.__dragStartPoint = QPoint()
        self.__selectionBeforeDrag = QRect()
        self.__locale = QLocale()
        
        # naming conventions for handles
        # T top, B bottom, R Right, L left
        # 2 letters: a corner
        # 1 letter: the handle on the middle of the corresponding side
        self.__TLHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__TRHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__BLHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__BRHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__LHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__THandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__RHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__BHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__handles = [self.__TLHandle, self.__TRHandle, self.__BLHandle,
                          self.__BRHandle, self.__LHandle, self.__THandle,
                          self.__RHandle, self.__BHandle]
        self.__helpTextRect = QRect()
        self.__helpText = self.tr(
            "Select a region using the mouse. To take the snapshot, press"
            " the Enter key or double click. Press Esc to quit.")
        
        self.__pixmap = QPixmap()
        
        self.setMouseTracking(True)
        
        QTimer.singleShot(200, self.__initialize)
    
    def __initialize(self):
        """
        Private slot to initialize the rest of the widget.
        """
        self.__desktop = QApplication.desktop()
        x = self.__desktop.x()
        y = self.__desktop.y()
        if qVersion() >= "5.0.0":
            self.__pixmap = QApplication.screens()[0].grabWindow(
                self.__desktop.winId(), x, y,
                self.__desktop.width(), self.__desktop.height())
        else:
            self.__pixmap = QPixmap.grabWindow(
                self.__desktop.winId(), x, y,
                self.__desktop.width(), self.__desktop.height())
        self.resize(self.__pixmap.size())
        self.move(x, y)
        self.setCursor(Qt.CrossCursor)
        self.show()

        self.grabMouse()
        self.grabKeyboard()
        self.activateWindow()
    
    def paintEvent(self, evt):
        """
        Protected method handling paint events.
        
        @param evt paint event (QPaintEvent)
        """
        if self.__grabbing:     # grabWindow() should just get the background
            return
        
        painter = QPainter(self)
        pal = QPalette(QToolTip.palette())
        font = QToolTip.font()
        
        handleColor = pal.color(QPalette.Active, QPalette.Highlight)
        handleColor.setAlpha(160)
        overlayColor = QColor(0, 0, 0, 160)
        textColor = pal.color(QPalette.Active, QPalette.Text)
        textBackgroundColor = pal.color(QPalette.Active, QPalette.Base)
        painter.drawPixmap(0, 0, self.__pixmap)
        painter.setFont(font)
        
        r = QRect(self.__selection)
        if not self.__selection.isNull():
            grey = QRegion(self.rect())
            if self.__mode == SnapshotRegionGrabber.Ellipse:
                reg = QRegion(r, QRegion.Ellipse)
            else:
                reg = QRegion(r)
            grey = grey.subtracted(reg)
            painter.setClipRegion(grey)
            painter.setPen(Qt.NoPen)
            painter.setBrush(overlayColor)
            painter.drawRect(self.rect())
            painter.setClipRect(self.rect())
            drawRect(painter, r, handleColor)
        
        if self.__showHelp:
            painter.setPen(textColor)
            painter.setBrush(textBackgroundColor)
            self.__helpTextRect = painter.boundingRect(
                self.rect().adjusted(2, 2, -2, -2),
                Qt.TextWordWrap, self.__helpText).translated(
                -self.__desktop.x(), -self.__desktop.y())
            self.__helpTextRect.adjust(-2, -2, 4, 2)
            drawRect(painter, self.__helpTextRect, textColor,
                     textBackgroundColor)
            painter.drawText(
                self.__helpTextRect.adjusted(3, 3, -3, -3),
                Qt.TextWordWrap, self.__helpText)
        
        if self.__selection.isNull():
            return
        
        # The grabbed region is everything which is covered by the drawn
        # rectangles (border included). This means that there is no 0px
        # selection, since a 0px wide rectangle will always be drawn as a line.
        txt = "{0}, {1} ({2} x {3})".format(
            self.__locale.toString(self.__selection.x()),
            self.__locale.toString(self.__selection.y()),
            self.__locale.toString(self.__selection.width()),
            self.__locale.toString(self.__selection.height())
        )
        textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
        boundingRect = textRect.adjusted(-4, 0, 0, 0)
        
        if textRect.width() < r.width() - 2 * self.__handleSize and \
           textRect.height() < r.height() - 2 * self.__handleSize and \
           r.width() > 100 and \
           r.height() > 100:
            # center, unsuitable for small selections
            boundingRect.moveCenter(r.center())
            textRect.moveCenter(r.center())
        elif r.y() - 3 > textRect.height() and \
                r.x() + textRect.width() < self.rect().width():
            # on top, left aligned
            boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3))
            textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3))
        elif r.x() - 3 > textRect.width():
            # left, top aligned
            boundingRect.moveTopRight(QPoint(r.x() - 3, r.y()))
            textRect.moveTopRight(QPoint(r.x() - 5, r.y()))
        elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \
                r.right() > textRect.width():
            # at bottom, right aligned
            boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3))
            textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3))
        elif r.right() + textRect.width() + 3 < self.rect().width():
            # right, bottom aligned
            boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom()))
            textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom()))
        
        # If the above didn't catch it, you are running on a very
        # tiny screen...
        drawRect(painter, boundingRect, textColor, textBackgroundColor)
        painter.drawText(textRect, Qt.AlignHCenter, txt)
        
        if (r.height() > self.__handleSize * 2 and
            r.width() > self.__handleSize * 2) or \
           not self.__mouseDown:
            self.__updateHandles()
            painter.setPen(Qt.NoPen)
            painter.setBrush(handleColor)
            painter.setClipRegion(
                self.__handleMask(SnapshotRegionGrabber.StrokeMask))
            painter.drawRect(self.rect())
            handleColor.setAlpha(60)
            painter.setBrush(handleColor)
            painter.setClipRegion(
                self.__handleMask(SnapshotRegionGrabber.FillMask))
            painter.drawRect(self.rect())
    
    def resizeEvent(self, evt):
        """
        Protected method to handle resize events.
        
        @param evt resize event (QResizeEvent)
        """
        if self.__selection.isNull():
            return
        
        r = QRect(self.__selection)
        r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect()))
        r.setBottomRight(self.__limitPointToRect(r.bottomRight(), self.rect()))
        if r.width() <= 1 or r.height() <= 1:
            # This just results in ugly drawing...
            self.__selection = QRect()
        else:
            self.__selection = self.__normalizeSelection(r)
    
    def mousePressEvent(self, evt):
        """
        Protected method to handle mouse button presses.
        
        @param evt mouse press event (QMouseEvent)
        """
        self.__showHelp = not self.__helpTextRect.contains(evt.pos())
        if evt.button() == Qt.LeftButton:
            self.__mouseDown = True
            self.__dragStartPoint = evt.pos()
            self.__selectionBeforeDrag = QRect(self.__selection)
            if not self.__selection.contains(evt.pos()):
                self.__newSelection = True
                self.__selection = QRect()
            else:
                self.setCursor(Qt.ClosedHandCursor)
        elif evt.button() == Qt.RightButton:
            self.__newSelection = False
            self.__selection = QRect()
            self.setCursor(Qt.CrossCursor)
        self.update()
    
    def mouseMoveEvent(self, evt):
        """
        Protected method to handle mouse movements.
        
        @param evt mouse move event (QMouseEvent)
        """
        shouldShowHelp = not self.__helpTextRect.contains(evt.pos())
        if shouldShowHelp != self.__showHelp:
            self.__showHelp = shouldShowHelp
            self.update()
        
        if self.__mouseDown:
            if self.__newSelection:
                p = evt.pos()
                r = self.rect()
                self.__selection = self.__normalizeSelection(
                    QRect(self.__dragStartPoint,
                          self.__limitPointToRect(p, r)))
            elif self.__mouseOverHandle is None:
                # moving the whole selection
                r = self.rect().normalized()
                s = self.__selectionBeforeDrag.normalized()
                p = s.topLeft() + evt.pos() - self.__dragStartPoint
                r.setBottomRight(
                    r.bottomRight() - QPoint(s.width(), s.height()) +
                    QPoint(1, 1))
                if not r.isNull() and r.isValid():
                    self.__selection.moveTo(self.__limitPointToRect(p, r))
            else:
                # dragging a handle
                r = QRect(self.__selectionBeforeDrag)
                offset = evt.pos() - self.__dragStartPoint
                
                if self.__mouseOverHandle in \
                   [self.__TLHandle, self.__THandle, self.__TRHandle]:
                    r.setTop(r.top() + offset.y())
                
                if self.__mouseOverHandle in \
                   [self.__TLHandle, self.__LHandle, self.__BLHandle]:
                    r.setLeft(r.left() + offset.x())
                
                if self.__mouseOverHandle in \
                   [self.__BLHandle, self.__BHandle, self.__BRHandle]:
                    r.setBottom(r.bottom() + offset.y())
                
                if self.__mouseOverHandle in \
                   [self.__TRHandle, self.__RHandle, self.__BRHandle]:
                    r.setRight(r.right() + offset.x())
                
                r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect()))
                r.setBottomRight(
                    self.__limitPointToRect(r.bottomRight(), self.rect()))
                self.__selection = self.__normalizeSelection(r)
            
            self.update()
        else:
            if self.__selection.isNull():
                return
            
            found = False
            for r in self.__handles:
                if r.contains(evt.pos()):
                    self.__mouseOverHandle = r
                    found = True
                    break
            
            if not found:
                self.__mouseOverHandle = None
                if self.__selection.contains(evt.pos()):
                    self.setCursor(Qt.OpenHandCursor)
                else:
                    self.setCursor(Qt.CrossCursor)
            else:
                if self.__mouseOverHandle in [self.__TLHandle,
                                              self.__BRHandle]:
                    self.setCursor(Qt.SizeFDiagCursor)
                elif self.__mouseOverHandle in [self.__TRHandle,
                                                self.__BLHandle]:
                    self.setCursor(Qt.SizeBDiagCursor)
                elif self.__mouseOverHandle in [self.__LHandle,
                                                self.__RHandle]:
                    self.setCursor(Qt.SizeHorCursor)
                elif self.__mouseOverHandle in [self.__THandle,
                                                self.__BHandle]:
                    self.setCursor(Qt.SizeVerCursor)
    
    def mouseReleaseEvent(self, evt):
        """
        Protected method to handle mouse button releases.
        
        @param evt mouse release event (QMouseEvent)
        """
        self.__mouseDown = False
        self.__newSelection = False
        if self.__mouseOverHandle is None and \
           self.__selection.contains(evt.pos()):
            self.setCursor(Qt.OpenHandCursor)
        self.update()
    
    def mouseDoubleClickEvent(self, evt):
        """
        Protected method to handle mouse double clicks.
        
        @param evt mouse double click event (QMouseEvent)
        """
        self.__grabRect()
    
    def keyPressEvent(self, evt):
        """
        Protected method to handle key presses.
        
        @param evt key press event (QKeyEvent)
        """
        if evt.key() == Qt.Key_Escape:
            self.grabbed.emit(QPixmap())
        elif evt.key() in [Qt.Key_Enter, Qt.Key_Return]:
            self.__grabRect()
        else:
            evt.ignore()
    
    def __updateHandles(self):
        """
        Private method to update the handles.
        """
        r = QRect(self.__selection)
        s2 = self.__handleSize // 2
        
        self.__TLHandle.moveTopLeft(r.topLeft())
        self.__TRHandle.moveTopRight(r.topRight())
        self.__BLHandle.moveBottomLeft(r.bottomLeft())
        self.__BRHandle.moveBottomRight(r.bottomRight())
        
        self.__LHandle.moveTopLeft(QPoint(r.x(), r.y() + r.height() // 2 - s2))
        self.__THandle.moveTopLeft(QPoint(r.x() + r.width() // 2 - s2, r.y()))
        self.__RHandle.moveTopRight(
            QPoint(r.right(), r.y() + r.height() // 2 - s2))
        self.__BHandle.moveBottomLeft(
            QPoint(r.x() + r.width() // 2 - s2, r.bottom()))
    
    def __handleMask(self, maskType):
        """
        Private method to calculate the handle mask.
        
        @param maskType type of the mask to be used
            (SnapshotRegionGrabber.FillMask or
            SnapshotRegionGrabber.StrokeMask)
        @return calculated mask (QRegion)
        """
        mask = QRegion()
        for rect in self.__handles:
            if maskType == SnapshotRegionGrabber.StrokeMask:
                r = QRegion(rect)
                mask += r.subtracted(QRegion(rect.adjusted(1, 1, -1, -1)))
            else:
                mask += QRegion(rect.adjusted(1, 1, -1, -1))
        return mask
    
    def __limitPointToRect(self, point, rect):
        """
        Private method to limit the given point to the given rectangle.
        
        @param point point to be limited (QPoint)
        @param rect rectangle the point shall be limited to (QRect)
        @return limited point (QPoint)
        """
        q = QPoint()
        if point.x() < rect.x():
            q.setX(rect.x())
        elif point.x() < rect.right():
            q.setX(point.x())
        else:
            q.setX(rect.right())
        if point.y() < rect.y():
            q.setY(rect.y())
        elif point.y() < rect.bottom():
            q.setY(point.y())
        else:
            q.setY(rect.bottom())
        return q
    
    def __normalizeSelection(self, sel):
        """
        Private method to normalize the given selection.
        
        @param sel selection to be normalized (QRect)
        @return normalized selection (QRect)
        """
        rect = QRect(sel)
        if rect.width() <= 0:
            left = rect.left()
            width = rect.width()
            rect.setLeft(left + width - 1)
            rect.setRight(left)
        if rect.height() <= 0:
            top = rect.top()
            height = rect.height()
            rect.setTop(top + height - 1)
            rect.setBottom(top)
        return rect
    
    def __grabRect(self):
        """
        Private method to grab the selected rectangle (i.e. do the snapshot).
        """
        if self.__mode == SnapshotRegionGrabber.Ellipse:
            ell = QRegion(self.__selection, QRegion.Ellipse)
            if not ell.isEmpty():
                self.__grabbing = True
                
                xOffset = self.__pixmap.rect().x() - ell.boundingRect().x()
                yOffset = self.__pixmap.rect().y() - ell.boundingRect().y()
                translatedEll = ell.translated(xOffset, yOffset)
                
                pixmap2 = QPixmap(ell.boundingRect().size())
                pixmap2.fill(Qt.transparent)
                
                pt = QPainter()
                pt.begin(pixmap2)
                if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff):
                    pt.setRenderHints(
                        QPainter.Antialiasing |
                        QPainter.HighQualityAntialiasing |
                        QPainter.SmoothPixmapTransform,
                        True)
                    pt.setBrush(Qt.black)
                    pt.setPen(QPen(QBrush(Qt.black), 0.5))
                    pt.drawEllipse(translatedEll.boundingRect())
                    pt.setCompositionMode(QPainter.CompositionMode_SourceIn)
                else:
                    pt.setClipRegion(translatedEll)
                    pt.setCompositionMode(QPainter.CompositionMode_Source)
                
                pt.drawPixmap(pixmap2.rect(), self.__pixmap,
                              ell.boundingRect())
                pt.end()
                
                self.grabbed.emit(pixmap2)
        else:
            r = QRect(self.__selection)
            if not r.isNull() and r.isValid():
                self.__grabbing = True
                self.grabbed.emit(self.__pixmap.copy(r))
예제 #47
0
    def refresh(self):
        #  try to request money parameters
        try:
            params = self.community.parameters
        except Exception as e:
            logging.debug('community parameters error : ' + str(e))
            return False

        #  try to request money variables from last ud block
        try:
            block = self.community.get_ud_block()
        except Exception as e:
            logging.debug('community get_ud_block error : ' + str(e))
            return False
        try:
            block_t_minus_1 = self.community.get_ud_block(1)
        except Exception as e:
            logging.debug('community get_ud_block error : ' + str(e))
            return False

        if block:
            ud = self.get_referential_diff_value(block['dividend'])
            # if referential type is quantitative...
            if self.account.ref_type() == 'q':
                # display int values
                # use the float type of 64bits, to avoid display a 32bit signed integer...
                localized_ud = QLocale().toString(float(ud), 'f', 0)
                localized_mass_per_member = QLocale().toString(
                    float(self.get_referential_diff_value(block['monetaryMass'] / block['membersCount'])), 'f', 0
                )
                localized_monetary_mass = QLocale().toString(
                    float(self.get_referential_diff_value(block['monetaryMass'])), 'f', 0
                )
            else:
                # display float values
                localized_ud = QLocale().toString(ud, 'f', 6)
                localized_mass_per_member = QLocale().toString(
                    self.get_referential_diff_value(block['monetaryMass'] / block['membersCount']), 'f', 6
                )
                localized_monetary_mass = QLocale().toString(
                    self.get_referential_diff_value(block['monetaryMass']), 'f', 6
                )

            # set infos in label
            self.label_general.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
                <tr><td align="right"><b>{:2.2%} / {:} days</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    localized_ud,
                    self.tr('Universal Dividend UD(t) in'),
                    self.get_referential_diff_name(),
                    localized_monetary_mass,
                    self.tr('Monetary Mass M(t) in'),
                    self.get_referential_diff_name(),
                    block['membersCount'],
                    self.tr('Members N(t)'),
                    localized_mass_per_member,
                    self.tr('Monetary Mass per member M(t)/N(t) in'),
                    self.get_referential_diff_name(),
                    block['dividend'] / (block_t_minus_1['monetaryMass'] / block_t_minus_1['membersCount']),
                    params['dt'] / 86400,
                    self.tr('Actual growth c = UD(t)/[M(t-1)/N(t-1)]'),
                    QLocale.toString(
                        QLocale(),
                        QDateTime.fromTime_t(block['medianTime'] + params['dt']),
                        QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                    ),
                    self.tr('Next UD date and time (t+1)')
                )
            )
        else:
            self.label_general.setText(self.tr('No Universal Dividend created yet.'))

        if block:
            # if referential type is quantitative...
            if self.account.ref_type() == 'q':
                # display int values
                localized_ud_t1 = QLocale().toString(
                    float(
                        self.get_referential_diff_value(
                            math.ceil(
                                max(block['dividend'], params['c'] * block['monetaryMass'] / block['membersCount'])
                            )
                        )
                    ),
                    'f',
                    0
                )
            else:
                # display float values
                localized_ud_t1 = QLocale().toString(
                    float(
                        self.get_referential_diff_value(
                            math.ceil(
                                max(block['dividend'], params['c'] * block['monetaryMass'] / block['membersCount'])
                            )
                        )
                    ),
                    'f',
                    6
                )

            # set infos in label
            self.label_rules.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.tr('{:2.0%} / {:} days').format(params['c'], params['dt'] / 86400),
                    self.tr('Fundamental growth (c) / Delta time (dt)'),
                    self.tr('UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t) }'),
                    self.tr('Universal Dividend (formula)'),
                    self.tr('{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}').format(
                        localized_ud_t1,
                        localized_ud,
                        self.get_referential_diff_name(),
                        params['c'],
                        localized_monetary_mass,
                        self.get_referential_diff_name(),
                        block['membersCount']
                    ),
                    self.tr('Universal Dividend (computed)')
                )
            )
        else:
            self.label_rules.setText(self.tr('No Universal Dividend created yet.'))

        # set infos in label
        self.label_money.setText(
            self.tr("""
            <table cellpadding="5">
            <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr>
            </table>
            """).format(
                params['c'],
                params['dt'] / 86400,
                self.tr('Fundamental growth (c)'),
                params['ud0'],
                self.tr('Initial Universal Dividend UD(0) in'),
                self.community.short_currency,
                params['dt'] / 86400,
                self.tr('Time period (dt) in days (86400 seconds) between two UD'),
                params['medianTimeBlocks'],
                self.tr('Number of blocks used for calculating median time'),
                params['avgGenTime'],
                self.tr('The average time in seconds for writing 1 block (wished time)'),
                params['dtDiffEval'],
                self.tr('The number of blocks required to evaluate again PoWMin value'),
                params['blocksRot'],
                self.tr('The number of previous blocks to check for personalized difficulty'),
                params['percentRot'],
                self.tr('The percent of previous issuers to reach for personalized difficulty')
            )
        )

        # set infos in label
        self.label_wot.setText(
            self.tr("""
            <table cellpadding="5">
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            </table>
            """).format(
                params['sigDelay'] / 86400,
                self.tr('Minimum delay between 2 identical certifications (in days)'),
                params['sigValidity'] / 86400,
                self.tr('Maximum age of a valid signature (in days)'),
                params['sigQty'],
                self.tr('Minimum quantity of signatures to be part of the WoT'),
                params['sigWoT'],
                self.tr('Minimum quantity of valid made certifications to be part of the WoT for distance rule'),
                params['msValidity'] / 86400,
                self.tr('Maximum age of a valid membership (in days)'),
                params['stepMax'],
                self.tr('Maximum distance between each WoT member and a newcomer'),
            )
        )
예제 #48
0
    def data(self, index, role):
        source_index = self.mapToSource(index)
        model = self.sourceModel()
        source_data = model.data(source_index, role)
        state_col = model.columns_types.index('state')
        state_index = model.index(source_index.row(), state_col)
        state_data = model.data(state_index, Qt.DisplayRole)

        block_col = model.columns_types.index('block_number')
        block_index = model.index(source_index.row(), block_col)
        block_data = model.data(block_index, Qt.DisplayRole)

        if state_data == Transaction.VALIDATED and block_data:
            current_confirmations = self.blockchain_service.current_buid(
            ).number - block_data
        else:
            current_confirmations = 0

        if role == Qt.DisplayRole:
            if source_index.column() == model.columns_types.index('uid'):
                return source_data
            if source_index.column() == model.columns_types.index('date'):
                return QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(source_data).date(),
                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat))
            if source_index.column() == model.columns_types.index('amount'):
                amount = self.app.current_ref.instance(
                    source_data, model.connection.currency, self.app,
                    block_data).diff_localized(False, False)
                return amount

        if role == Qt.FontRole:
            font = QFont()
            if state_data == Transaction.AWAITING or \
                    (state_data == Transaction.VALIDATED and current_confirmations < MAX_CONFIRMATIONS):
                font.setItalic(True)
            elif state_data == Transaction.REFUSED:
                font.setItalic(True)
            elif state_data == Transaction.TO_SEND:
                font.setBold(True)
            else:
                font.setItalic(False)
            return font

        if role == Qt.ForegroundRole:
            if state_data == Transaction.REFUSED:
                return QColor(Qt.darkGray)
            elif state_data == Transaction.TO_SEND:
                return QColor(Qt.blue)
            if source_index.column() == model.columns_types.index('amount'):
                if source_data < 0:
                    return QColor(Qt.darkRed)
                elif state_data == HistoryTableModel.DIVIDEND:
                    return QColor(Qt.darkBlue)

        if role == Qt.TextAlignmentRole:
            if self.sourceModel().columns_types.index('amount'):
                return Qt.AlignRight | Qt.AlignVCenter
            if source_index.column() == model.columns_types.index('date'):
                return Qt.AlignCenter

        if role == Qt.ToolTipRole:
            if source_index.column() == model.columns_types.index('date'):
                return QDateTime.fromTime_t(source_data).toString(
                    Qt.SystemLocaleLongDate)

            if state_data == Transaction.VALIDATED or state_data == Transaction.AWAITING:
                if current_confirmations >= MAX_CONFIRMATIONS:
                    return None
                elif self.app.parameters.expert_mode:
                    return self.tr("{0} / {1} confirmations").format(
                        current_confirmations, MAX_CONFIRMATIONS)
                else:
                    confirmation = current_confirmations / MAX_CONFIRMATIONS * 100
                    confirmation = 100 if confirmation > 100 else confirmation
                    return self.tr("Confirming... {0} %").format(
                        QLocale().toString(float(confirmation), 'f', 0))

            return None
        return source_data
예제 #49
0
파일: wot_tab.py 프로젝트: zero-code/sakia
    def refresh_informations_frame(self):
        parameters = self.community.parameters
        try:
            identity = yield from self.account.identity(self.community)
            membership = identity.membership(self.community)
            renew_block = membership['blockNumber']
            last_renewal = self.community.get_block(renew_block)['medianTime']
            expiration = last_renewal + parameters['sigValidity']
        except MembershipNotFoundError:
            last_renewal = None
            expiration = None

        certified = yield from identity.unique_valid_certified_by(self.app.identities_registry, self.community)
        certifiers = yield from identity.unique_valid_certifiers_of(self.app.identities_registry, self.community)
        if last_renewal and expiration:
            date_renewal = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
            )
            date_expiration = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
            )

            if self.account.pubkey in self.community.members_pubkeys():
                # set infos in label
                self.label_general.setText(
                    self.tr("""
                    <table cellpadding="5">
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    </table>
                    """).format(
                        self.account.name, self.account.pubkey,
                        self.tr("Membership"),
                        self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
                        self.tr("Your web of trust"),
                        self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
                                                                                             len(certified))
                    )
                )
            else:
                # set infos in label
                self.label_general.setText(
                    self.tr("""
                    <table cellpadding="5">
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                    </table>
                    """).format(
                        self.account.name, self.account.pubkey,
                        self.tr("Not a member"),
                        self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
                        self.tr("Your web of trust"),
                        self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
                                                                                             len(certified))
                    )
                )
        else:
            # set infos in label
            self.label_general.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.account.name, self.account.pubkey,
                    self.tr("Not a member"),
                    self.tr("Your web of trust"),
                    self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
                                                                                         len(certified))
                )
            )
예제 #50
0
    def refresh(self):
        parameters = self.community.parameters
        last_renewal = ""
        expiration = ""
        try:
            person = Person.lookup(self.account.pubkey, self.community)
            membership = person.membership(self.community)
            renew_block = membership['blockNumber']
            last_renewal = self.community.get_block(renew_block).mediantime
            expiration = last_renewal + parameters['sigValidity']
        except MembershipNotFoundError:
            last_renewal = None
            expiration = None

        certified = person.unique_valid_certified_by(self.community)
        certifiers = person.unique_valid_certifiers_of(self.community)
        if last_renewal and expiration:
            date_renewal = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(last_renewal).date(),
                QLocale.dateFormat(QLocale(), QLocale.LongFormat))
            date_expiration = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(expiration).date(),
                QLocale.dateFormat(QLocale(), QLocale.LongFormat))
            # set infos in label
            self.label_general.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.account.name, self.account.pubkey,
                    self.tr("Membership"),
                    self.tr("Last renewal on {:}, expiration on {:}").format(
                        date_renewal, date_expiration),
                    self.tr("Your web of trust"),
                    self.tr(
                        "Certified by {:} members; Certifier of {:} members").
                    format(len(certifiers), len(certified))))
        else:
            # set infos in label
            self.label_general.setText(
                self.tr("""
                <table cellpadding="5">
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                <tr><td align="right"><b>{:}</b></td></tr>
                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
                </table>
                """).format(
                    self.account.name, self.account.pubkey,
                    self.tr("Not a member"), self.tr("Your web of trust"),
                    self.tr(
                        "Certified by {:} members; Certifier of {:} members").
                    format(len(certifiers), len(certified))))

        amount = self.account.amount(self.community)
        maximum = self.community.monetary_mass
        # if referential type is quantitative...
        if self.account.ref_type() == 'q':
            # display int values
            localized_amount = QLocale().toString(
                float(self.get_referential_value(amount)), 'f', 0)
            localized_minimum = QLocale().toString(
                float(self.get_referential_value(0)), 'f', 0)
            localized_maximum = QLocale().toString(
                float(self.get_referential_value(maximum)), 'f', 0)
        else:
            # display float values
            localized_amount = QLocale().toString(
                float(self.get_referential_value(amount)), 'f', 6)
            localized_minimum = QLocale().toString(
                float(self.get_referential_value(0)), 'f', 6)
            localized_maximum = QLocale().toString(
                float(self.get_referential_value(maximum)), 'f', 6)

        # set infos in label
        self.label_balance.setText(
            self.tr("""
            <table cellpadding="5">
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
            </table>
            """).format(
                self.tr("Your money share "),
                self.tr("{:.2f}%").format(amount / maximum *
                                          100) if maximum != 0 else "0%",
                self.tr("Your part "),
                self.tr("{:} {:} in [{:} ; {:}] {:}").format(
                    localized_amount, self.get_referential_name(),
                    localized_minimum, localized_maximum,
                    self.get_referential_name())))

        wallets_model = WalletsTableModel(self.account, self.community)
        proxy_model = WalletsFilterProxyModel()
        proxy_model.setSourceModel(wallets_model)
        wallets_model.dataChanged.connect(self.wallet_changed)
        self.table_wallets.setModel(proxy_model)
        self.table_wallets.resizeColumnsToContents()
예제 #51
0
파일: model.py 프로젝트: duniter/sakia
    def get_localized_data(self):
        localized_data = {}
        #  try to request money parameters
        try:
            params = self.blockchain_service.parameters()
        except NoPeerAvailable as e:
            logging.debug('community parameters error : ' + str(e))
            return None

        localized_data['currency'] = ROOT_SERVERS[self.connection.currency]["display"]
        localized_data['growth'] = params.c
        localized_data['days_per_dividend'] = QLocale().toString(params.dt / 86400, 'f', 2)

        last_ud, last_ud_base = self.blockchain_service.last_ud()
        members_count = self.blockchain_service.last_members_count()
        previous_ud, previous_ud_base = self.blockchain_service.previous_ud()
        previous_ud_time = self.blockchain_service.previous_ud_time()
        previous_monetary_mass = self.blockchain_service.previous_monetary_mass()
        previous_members_count = self.blockchain_service.previous_members_count()

        localized_data['units'] = self.app.current_ref.instance(0,
                                                                self.connection.currency,
                                                                self.app, None).units
        localized_data['diff_units'] = self.app.current_ref.instance(0,
                                                                     self.connection.currency,
                                                                     self.app, None).diff_units

        if last_ud:
            # display float values
            localized_data['ud'] = self.app.current_ref.instance(last_ud * math.pow(10, last_ud_base),
                                              self.connection.currency,
                                              self.app).diff_localized(False, True)

            localized_data['members_count'] = self.blockchain_service.current_members_count()

            computed_dividend = self.blockchain_service.computed_dividend()
            # display float values
            localized_data['ud_plus_1'] = self.app.current_ref.instance(computed_dividend,
                                              self.connection.currency, self.app).diff_localized(False, True)

            localized_data['mass'] = self.app.current_ref.instance(self.blockchain_service.current_mass(),
                                              self.connection.currency, self.app).localized(False, True)

            ud_median_time = self.blockchain_service.last_ud_time()
            ud_median_time = self.blockchain_processor.adjusted_ts(self.app.currency, ud_median_time)

            localized_data['ud_median_time'] = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(ud_median_time),
                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
            )

            next_ud_median_time = self.blockchain_service.last_ud_time() + params.dt
            next_ud_median_time = self.blockchain_processor.adjusted_ts(self.app.currency, next_ud_median_time)

            localized_data['next_ud_median_time'] = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(next_ud_median_time),
                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
            )

            next_ud_reeval = self.blockchain_service.next_ud_reeval()
            next_ud_reeval = self.blockchain_processor.adjusted_ts(self.app.currency, next_ud_reeval)
            localized_data['next_ud_reeval'] = QLocale.toString(
                QLocale(),
                QDateTime.fromTime_t(next_ud_reeval),
                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
            )

            if previous_ud:
                mass_minus_1_per_member = (float(0) if previous_ud == 0 or previous_members_count == 0 else
                                           previous_monetary_mass / previous_members_count)
                localized_data['mass_minus_1_per_member'] = self.app.current_ref.instance(mass_minus_1_per_member,
                                                  self.connection.currency, self.app) \
                                                  .localized(False, True)
                localized_data['mass_minus_1'] = self.app.current_ref.instance(previous_monetary_mass,
                                                  self.connection.currency, self.app) \
                                                  .localized(False, True)
                # avoid divide by zero !
                if members_count == 0 or previous_members_count == 0:
                    localized_data['actual_growth'] = float(0)
                else:
                    localized_data['actual_growth'] = (last_ud * math.pow(10, last_ud_base)) / (
                    previous_monetary_mass / members_count)

                previous_ud_time = self.blockchain_processor.adjusted_ts(self.app.currency, previous_ud_time)
                localized_data['ud_median_time_minus_1'] = QLocale.toString(
                    QLocale(),
                    QDateTime.fromTime_t(previous_ud_time),
                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
                )
        return localized_data
예제 #52
0
class SnapshotFreehandGrabber(QWidget):
    """
    Class implementing a grabber widget for a freehand snapshot region.
    
    @signal grabbed(QPixmap) emitted after the region was grabbed
    """
    grabbed = pyqtSignal(QPixmap)
    
    def __init__(self):
        """
        Constructor
        """
        super(SnapshotFreehandGrabber, self).__init__(
            None,
            Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint |
            Qt.FramelessWindowHint | Qt.Tool)
        
        self.__selection = QPolygon()
        self.__mouseDown = False
        self.__newSelection = False
        self.__handleSize = 10
        self.__showHelp = True
        self.__grabbing = False
        self.__dragStartPoint = QPoint()
        self.__selectionBeforeDrag = QPolygon()
        self.__locale = QLocale()
        
        self.__helpTextRect = QRect()
        self.__helpText = self.tr(
            "Select a region using the mouse. To take the snapshot,"
            " press the Enter key or double click. Press Esc to quit.")
        
        self.__pixmap = QPixmap()
        self.__pBefore = QPoint()
        
        self.setMouseTracking(True)
        
        QTimer.singleShot(200, self.__initialize)
    
    def __initialize(self):
        """
        Private slot to initialize the rest of the widget.
        """
        self.__desktop = QApplication.desktop()
        x = self.__desktop.x()
        y = self.__desktop.y()
        if qVersion() >= "5.0.0":
            self.__pixmap = QApplication.screens()[0].grabWindow(
                self.__desktop.winId(), x, y,
                self.__desktop.width(), self.__desktop.height())
        else:
            self.__pixmap = QPixmap.grabWindow(
                self.__desktop.winId(), x, y,
                self.__desktop.width(), self.__desktop.height())
        self.resize(self.__pixmap.size())
        self.move(x, y)
        self.setCursor(Qt.CrossCursor)
        self.show()

        self.grabMouse()
        self.grabKeyboard()
        self.activateWindow()
    
    def paintEvent(self, evt):
        """
        Protected method handling paint events.
        
        @param evt paint event (QPaintEvent)
        """
        if self.__grabbing:     # grabWindow() should just get the background
            return
        
        painter = QPainter(self)
        pal = QPalette(QToolTip.palette())
        font = QToolTip.font()
        
        handleColor = pal.color(QPalette.Active, QPalette.Highlight)
        handleColor.setAlpha(160)
        overlayColor = QColor(0, 0, 0, 160)
        textColor = pal.color(QPalette.Active, QPalette.Text)
        textBackgroundColor = pal.color(QPalette.Active, QPalette.Base)
        painter.drawPixmap(0, 0, self.__pixmap)
        painter.setFont(font)
        
        pol = QPolygon(self.__selection)
        if not self.__selection.boundingRect().isNull():
            # Draw outline around selection.
            # Important: the 1px-wide outline is *also* part of the
            # captured free-region
            pen = QPen(handleColor, 1, Qt.SolidLine, Qt.SquareCap,
                       Qt.BevelJoin)
            painter.setPen(pen)
            painter.drawPolygon(pol)
            
            # Draw the grey area around the selection.
            grey = QRegion(self.rect())
            grey = grey - QRegion(pol)
            painter.setClipRegion(grey)
            painter.setPen(Qt.NoPen)
            painter.setBrush(overlayColor)
            painter.drawRect(self.rect())
            painter.setClipRect(self.rect())
            drawPolygon(painter, pol, handleColor)
        
        if self.__showHelp:
            painter.setPen(textColor)
            painter.setBrush(textBackgroundColor)
            self.__helpTextRect = painter.boundingRect(
                self.rect().adjusted(2, 2, -2, -2),
                Qt.TextWordWrap, self.__helpText).translated(
                -self.__desktop.x(), -self.__desktop.y())
            self.__helpTextRect.adjust(-2, -2, 4, 2)
            drawPolygon(painter, self.__helpTextRect, textColor,
                        textBackgroundColor)
            painter.drawText(
                self.__helpTextRect.adjusted(3, 3, -3, -3),
                Qt.TextWordWrap, self.__helpText)
        
        if self.__selection.isEmpty():
            return
        
        # The grabbed region is everything which is covered by the drawn
        # rectangles (border included). This means that there is no 0px
        # selection, since a 0px wide rectangle will always be drawn as a line.
        boundingRect = self.__selection.boundingRect()
        txt = "{0}, {1} ({2} x {3})".format(
            self.__locale.toString(boundingRect.x()),
            self.__locale.toString(boundingRect.y()),
            self.__locale.toString(boundingRect.width()),
            self.__locale.toString(boundingRect.height())
        )
        textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
        boundingRect = textRect.adjusted(-4, 0, 0, 0)
        
        polBoundingRect = pol.boundingRect()
        if (textRect.width() <
            polBoundingRect.width() - 2 * self.__handleSize) and \
           (textRect.height() <
            polBoundingRect.height() - 2 * self.__handleSize) and \
           polBoundingRect.width() > 100 and \
           polBoundingRect.height() > 100:
            # center, unsuitable for small selections
            boundingRect.moveCenter(polBoundingRect.center())
            textRect.moveCenter(polBoundingRect.center())
        elif polBoundingRect.y() - 3 > textRect.height() and \
                polBoundingRect.x() + textRect.width() < self.rect().width():
            # on top, left aligned
            boundingRect.moveBottomLeft(
                QPoint(polBoundingRect.x(), polBoundingRect.y() - 3))
            textRect.moveBottomLeft(
                QPoint(polBoundingRect.x() + 2, polBoundingRect.y() - 3))
        elif polBoundingRect.x() - 3 > textRect.width():
            # left, top aligned
            boundingRect.moveTopRight(
                QPoint(polBoundingRect.x() - 3, polBoundingRect.y()))
            textRect.moveTopRight(
                QPoint(polBoundingRect.x() - 5, polBoundingRect.y()))
        elif (polBoundingRect.bottom() + 3 + textRect.height() <
              self.rect().bottom()) and \
                polBoundingRect.right() > textRect.width():
            # at bottom, right aligned
            boundingRect.moveTopRight(
                QPoint(polBoundingRect.right(), polBoundingRect.bottom() + 3))
            textRect.moveTopRight(
                QPoint(polBoundingRect.right() - 2,
                       polBoundingRect.bottom() + 3))
        elif polBoundingRect.right() + textRect.width() + 3 < \
                self.rect().width():
            # right, bottom aligned
            boundingRect.moveBottomLeft(
                QPoint(polBoundingRect.right() + 3, polBoundingRect.bottom()))
            textRect.moveBottomLeft(
                QPoint(polBoundingRect.right() + 5, polBoundingRect.bottom()))
        
        # If the above didn't catch it, you are running on a very
        # tiny screen...
        drawPolygon(painter, boundingRect, textColor, textBackgroundColor)
        painter.drawText(textRect, Qt.AlignHCenter, txt)
        
        if (polBoundingRect.height() > self.__handleSize * 2 and
            polBoundingRect.width() > self.__handleSize * 2) or \
           not self.__mouseDown:
            painter.setBrush(Qt.transparent)
            painter.setClipRegion(QRegion(pol))
            painter.drawPolygon(QPolygon(self.rect()))
    
    def mousePressEvent(self, evt):
        """
        Protected method to handle mouse button presses.
        
        @param evt mouse press event (QMouseEvent)
        """
        self.__pBefore = evt.pos()
        
        self.__showHelp = not self.__helpTextRect.contains(evt.pos())
        if evt.button() == Qt.LeftButton:
            self.__mouseDown = True
            self.__dragStartPoint = evt.pos()
            self.__selectionBeforeDrag = QPolygon(self.__selection)
            if not self.__selection.containsPoint(evt.pos(), Qt.WindingFill):
                self.__newSelection = True
                self.__selection = QPolygon()
            else:
                self.setCursor(Qt.ClosedHandCursor)
        elif evt.button() == Qt.RightButton:
            self.__newSelection = False
            self.__selection = QPolygon()
            self.setCursor(Qt.CrossCursor)
        self.update()
    
    def mouseMoveEvent(self, evt):
        """
        Protected method to handle mouse movements.
        
        @param evt mouse move event (QMouseEvent)
        """
        shouldShowHelp = not self.__helpTextRect.contains(evt.pos())
        if shouldShowHelp != self.__showHelp:
            self.__showHelp = shouldShowHelp
            self.update()
        
        if self.__mouseDown:
            if self.__newSelection:
                p = evt.pos()
                self.__selection.append(p)
            else:
                # moving the whole selection
                p = evt.pos() - self.__pBefore  # Offset
                self.__pBefore = evt.pos()  # save position for next iteration
                self.__selection.translate(p)
            
            self.update()
        else:
            if self.__selection.boundingRect().isEmpty():
                return
            
            if self.__selection.containsPoint(evt.pos(), Qt.WindingFill):
                self.setCursor(Qt.OpenHandCursor)
            else:
                self.setCursor(Qt.CrossCursor)
    
    def mouseReleaseEvent(self, evt):
        """
        Protected method to handle mouse button releases.
        
        @param evt mouse release event (QMouseEvent)
        """
        self.__mouseDown = False
        self.__newSelection = False
        if self.__selection.containsPoint(evt.pos(), Qt.WindingFill):
            self.setCursor(Qt.OpenHandCursor)
        self.update()
    
    def mouseDoubleClickEvent(self, evt):
        """
        Protected method to handle mouse double clicks.
        
        @param evt mouse double click event (QMouseEvent)
        """
        self.__grabRegion()
    
    def keyPressEvent(self, evt):
        """
        Protected method to handle key presses.
        
        @param evt key press event (QKeyEvent)
        """
        if evt.key() == Qt.Key_Escape:
            self.grabbed.emit(QPixmap())
        elif evt.key() in [Qt.Key_Enter, Qt.Key_Return]:
            self.__grabRegion()
        else:
            evt.ignore()
    
    def __grabRegion(self):
        """
        Private method to grab the selected region (i.e. do the snapshot).
        """
        pol = QPolygon(self.__selection)
        if not pol.isEmpty():
            self.__grabbing = True
            
            xOffset = self.__pixmap.rect().x() - pol.boundingRect().x()
            yOffset = self.__pixmap.rect().y() - pol.boundingRect().y()
            translatedPol = pol.translated(xOffset, yOffset)
            
            pixmap2 = QPixmap(pol.boundingRect().size())
            pixmap2.fill(Qt.transparent)
            
            pt = QPainter()
            pt.begin(pixmap2)
            if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff):
                pt.setRenderHints(
                    QPainter.Antialiasing |
                    QPainter.HighQualityAntialiasing |
                    QPainter.SmoothPixmapTransform,
                    True)
                pt.setBrush(Qt.black)
                pt.setPen(QPen(QBrush(Qt.black), 0.5))
                pt.drawPolygon(translatedPol)
                pt.setCompositionMode(QPainter.CompositionMode_SourceIn)
            else:
                pt.setClipRegion(QRegion(translatedPol))
                pt.setCompositionMode(QPainter.CompositionMode_Source)
            
            pt.drawPixmap(pixmap2.rect(), self.__pixmap, pol.boundingRect())
            pt.end()
            
            self.grabbed.emit(pixmap2)
예제 #53
0
class SnapWidget(QWidget, Ui_SnapWidget):
    """
    Class implementing the snapshot widget.
    """
    ModeFullscreen = 0
    ModeScreen = 1
    ModeRectangle = 2
    ModeFreehand = 3
    ModeEllipse = 4
    
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(SnapWidget, self).__init__(parent)
        self.setupUi(self)
        
        self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSaveAs.png"))
        self.takeButton.setIcon(UI.PixmapCache.getIcon("cameraPhoto.png"))
        self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
        self.copyPreviewButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
        self.setWindowIcon(UI.PixmapCache.getIcon("ericSnap.png"))
        
        self.modeCombo.addItem(self.tr("Fullscreen"),
                               SnapWidget.ModeFullscreen)
        self.modeCombo.addItem(self.tr("Rectangular Selection"),
                               SnapWidget.ModeRectangle)
        self.modeCombo.addItem(self.tr("Ellipical Selection"),
                               SnapWidget.ModeEllipse)
        self.modeCombo.addItem(self.tr("Freehand Selection"),
                               SnapWidget.ModeFreehand)
        if QApplication.desktop().screenCount() > 1:
            self.modeCombo.addItem(self.tr("Current Screen"),
                                   SnapWidget.ModeScreen)
        self.__mode = int(Preferences.Prefs.settings.value("Snapshot/Mode", 0))
        index = self.modeCombo.findData(self.__mode)
        if index == -1:
            index = 0
        self.modeCombo.setCurrentIndex(index)
        
        self.__delay = int(
            Preferences.Prefs.settings.value("Snapshot/Delay", 0))
        self.delaySpin.setValue(self.__delay)
        
        if PYQT_VERSION_STR >= "5.0.0":
            from PyQt5.QtCore import QStandardPaths
            picturesLocation = QStandardPaths.writableLocation(
                QStandardPaths.PicturesLocation)
        else:
            from PyQt5.QtGui import QDesktopServices
            picturesLocation = QDesktopServices.storageLocation(
                QDesktopServices.PicturesLocation)
        self.__filename = Preferences.Prefs.settings.value(
            "Snapshot/Filename",
            os.path.join(picturesLocation,
                         self.tr("snapshot") + "1.png"))
        
        self.__grabber = None
        self.__snapshot = QPixmap()
        self.__savedPosition = QPoint()
        self.__modified = False
        self.__locale = QLocale()
        
        self.__grabberWidget = QWidget(None, Qt.X11BypassWindowManagerHint)
        self.__grabberWidget.move(-10000, -10000)
        self.__grabberWidget.installEventFilter(self)
        
        self.__initFileFilters()
        
        self.__initShortcuts()
        
        self.preview.startDrag.connect(self.__dragSnapshot)
        
        from .SnapshotTimer import SnapshotTimer
        self.__grabTimer = SnapshotTimer()
        self.__grabTimer.timeout.connect(self.__grabTimerTimeout)
        self.__updateTimer = QTimer()
        self.__updateTimer.setSingleShot(True)
        self.__updateTimer.timeout.connect(self.__updatePreview)
        
        self.__updateCaption()
        self.takeButton.setFocus()
    
    def __initFileFilters(self):
        """
        Private method to define the supported image file filters.
        """
        filters = {
            'bmp': self.tr("Windows Bitmap File (*.bmp)"),
            'gif': self.tr("Graphic Interchange Format File (*.gif)"),
            'ico': self.tr("Windows Icon File (*.ico)"),
            'jpg': self.tr("JPEG File (*.jpg)"),
            'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"),
            'pbm': self.tr("Portable Bitmap File (*.pbm)"),
            'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"),
            'pgm': self.tr("Portable Graymap File (*.pgm)"),
            'png': self.tr("Portable Network Graphics File (*.png)"),
            'ppm': self.tr("Portable Pixmap File (*.ppm)"),
            'sgi': self.tr("Silicon Graphics Image File (*.sgi)"),
            'svg': self.tr("Scalable Vector Graphics File (*.svg)"),
            'tga': self.tr("Targa Graphic File (*.tga)"),
            'tif': self.tr("TIFF File (*.tif)"),
            'xbm': self.tr("X11 Bitmap File (*.xbm)"),
            'xpm': self.tr("X11 Pixmap File (*.xpm)"),
        }
        
        outputFormats = []
        writeFormats = QImageWriter.supportedImageFormats()
        for writeFormat in writeFormats:
            try:
                outputFormats.append(filters[bytes(writeFormat).decode()])
            except KeyError:
                pass
        outputFormats.sort()
        self.__outputFilter = ';;'.join(outputFormats)
        
        self.__defaultFilter = filters['png']
    
    def __initShortcuts(self):
        """
        Private method to initialize the keyboard shortcuts.
        """
        self.__quitShortcut = QShortcut(
            QKeySequence(QKeySequence.Quit), self, self.close)
        
        self.__copyShortcut = QShortcut(
            QKeySequence(QKeySequence.Copy), self,
            self.copyButton.animateClick)
        
        self.__quickSaveShortcut = QShortcut(
            QKeySequence(Qt.Key_Q), self, self.__quickSave)
        
        self.__save1Shortcut = QShortcut(
            QKeySequence(QKeySequence.Save), self,
            self.saveButton.animateClick)
        self.__save2Shortcut = QShortcut(
            QKeySequence(Qt.Key_S), self, self.saveButton.animateClick)
        
        self.__grab1Shortcut = QShortcut(
            QKeySequence(QKeySequence.New), self, self.takeButton.animateClick)
        self.__grab2Shortcut = QShortcut(
            QKeySequence(Qt.Key_N), self, self.takeButton.animateClick)
        self.__grab3Shortcut = QShortcut(
            QKeySequence(Qt.Key_Space), self, self.takeButton.animateClick)
    
    def __quickSave(self):
        """
        Private slot to save the snapshot bypassing the file selection dialog.
        """
        if not self.__snapshot.isNull():
            while os.path.exists(self.__filename):
                self.__autoIncFilename()
            
            if self.__saveImage(self.__filename):
                self.__modified = False
                self.__autoIncFilename()
                self.__updateCaption()
    
    @pyqtSlot()
    def on_saveButton_clicked(self):
        """
        Private slot to save the snapshot.
        """
        if not self.__snapshot.isNull():
            while os.path.exists(self.__filename):
                self.__autoIncFilename()
            
            fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
                self,
                self.tr("Save Snapshot"),
                self.__filename,
                self.__outputFilter,
                self.__defaultFilter,
                E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite))
            if not fileName:
                return
            
            ext = QFileInfo(fileName).suffix()
            if not ext:
                ex = selectedFilter.split("(*")[1].split(")")[0]
                if ex:
                    fileName += ex
            
            if self.__saveImage(fileName):
                self.__modified = False
                self.__filename = fileName
                self.__autoIncFilename()
                self.__updateCaption()
    
    def __saveImage(self, fileName):
        """
        Private method to save the snapshot.
        
        @param fileName name of the file to save to (string)
        @return flag indicating success (boolean)
        """
        if QFileInfo(fileName).exists():
            res = E5MessageBox.yesNo(
                self,
                self.tr("Save Snapshot"),
                self.tr("<p>The file <b>{0}</b> already exists."
                        " Overwrite it?</p>").format(fileName),
                icon=E5MessageBox.Warning)
            if not res:
                return False
        
        file = QFile(fileName)
        if not file.open(QFile.WriteOnly):
            E5MessageBox.warning(
                self, self.tr("Save Snapshot"),
                self.tr("Cannot write file '{0}:\n{1}.")
                .format(fileName, file.errorString()))
            return False
        
        ok = self.__snapshot.save(file)
        file.close()
        
        if not ok:
            E5MessageBox.warning(
                self, self.tr("Save Snapshot"),
                self.tr("Cannot write file '{0}:\n{1}.")
                .format(fileName, file.errorString()))
        
        return ok
    
    def __autoIncFilename(self):
        """
        Private method to auto-increment the file name.
        """
        # Extract the file name
        name = os.path.basename(self.__filename)
        
        # If the name contains a number, then increment it.
        numSearch = QRegExp("(^|[^\\d])(\\d+)")
        # We want to match as far left as possible, and when the number is
        # at the start of the name.
        
        # Does it have a number?
        start = numSearch.lastIndexIn(name)
        if start != -1:
            # It has a number, increment it.
            start = numSearch.pos(2)    # Only the second group is of interest.
            numAsStr = numSearch.capturedTexts()[2]
            number = "{0:0{width}d}".format(
                int(numAsStr) + 1, width=len(numAsStr))
            name = name[:start] + number + name[start + len(numAsStr):]
        else:
            # no number
            start = name.rfind('.')
            if start != -1:
                # has a '.' somewhere, e.g. it has an extension
                name = name[:start] + '1' + name[start:]
            else:
                # no extension, just tack it on to the end
                name += '1'
        
        self.__filename = os.path.join(os.path.dirname(self.__filename), name)
        self.__updateCaption()
    
    @pyqtSlot()
    def on_takeButton_clicked(self):
        """
        Private slot to take a snapshot.
        """
        self.__mode = self.modeCombo.itemData(self.modeCombo.currentIndex())
        self.__delay = self.delaySpin.value()
        
        self.__savedPosition = self.pos()
        self.hide()
        
        if self.__delay:
            self.__grabTimer.start(self.__delay)
        else:
            QTimer.singleShot(200, self.__startUndelayedGrab)
    
    def __grabTimerTimeout(self):
        """
        Private slot to perform a delayed grab operation.
        """
        if self.__mode == SnapWidget.ModeRectangle:
            self.__grabRectangle()
        elif self.__mode == SnapWidget.ModeEllipse:
            self.__grabEllipse()
        elif self.__mode == SnapWidget.ModeFreehand:
            self.__grabFreehand()
        else:
            self.__performGrab()
    
    def __startUndelayedGrab(self):
        """
        Private slot to perform an undelayed grab operation.
        """
        if self.__mode == SnapWidget.ModeRectangle:
            self.__grabRectangle()
        elif self.__mode == SnapWidget.ModeEllipse:
            self.__grabEllipse()
        elif self.__mode == SnapWidget.ModeFreehand:
            self.__grabFreehand()
        else:
            if Globals.isMacPlatform():
                self.__performGrab()
            else:
                self.__grabberWidget.show()
                self.__grabberWidget.grabMouse(Qt.CrossCursor)
    
    def __grabRectangle(self):
        """
        Private method to grab a rectangular screen region.
        """
        from .SnapshotRegionGrabber import SnapshotRegionGrabber
        self.__grabber = SnapshotRegionGrabber(
            mode=SnapshotRegionGrabber.Rectangle)
        self.__grabber.grabbed.connect(self.__captured)
    
    def __grabEllipse(self):
        """
        Private method to grab an elliptical screen region.
        """
        from .SnapshotRegionGrabber import SnapshotRegionGrabber
        self.__grabber = SnapshotRegionGrabber(
            mode=SnapshotRegionGrabber.Ellipse)
        self.__grabber.grabbed.connect(self.__captured)
    
    def __grabFreehand(self):
        """
        Private method to grab a non-rectangular screen region.
        """
        from .SnapshotFreehandGrabber import SnapshotFreehandGrabber
        self.__grabber = SnapshotFreehandGrabber()
        self.__grabber.grabbed.connect(self.__captured)
    
    def __performGrab(self):
        """
        Private method to perform a screen grab other than a selected region.
        """
        self.__grabberWidget.releaseMouse()
        self.__grabberWidget.hide()
        self.__grabTimer.stop()
        
        if self.__mode == SnapWidget.ModeFullscreen:
            desktop = QApplication.desktop()
            if qVersion() >= "5.0.0":
                self.__snapshot = QApplication.screens()[0].grabWindow(
                    desktop.winId(), desktop.x(), desktop.y(),
                    desktop.width(), desktop.height())
            else:
                self.__snapshot = QPixmap.grabWindow(
                    desktop.winId(), desktop.x(), desktop.y(),
                    desktop.width(), desktop.height())
        elif self.__mode == SnapWidget.ModeScreen:
            desktop = QApplication.desktop()
            screenId = desktop.screenNumber(QCursor.pos())
            geom = desktop.screenGeometry(screenId)
            x = geom.x()
            y = geom.y()
            if qVersion() >= "5.0.0":
                self.__snapshot = QApplication.screens()[0].grabWindow(
                    desktop.winId(), x, y, geom.width(), geom.height())
            else:
                self.__snapshot = QPixmap.grabWindow(
                    desktop.winId(), x, y, geom.width(), geom.height())
        else:
            self.__snapshot = QPixmap()
        
        self.__redisplay()
        self.__modified = True
        self.__updateCaption()
    
    def __redisplay(self):
        """
        Private method to redisplay the window.
        """
        self.__updatePreview()
        QApplication.restoreOverrideCursor()
        if not self.__savedPosition.isNull():
            self.move(self.__savedPosition)
        self.show()
        self.raise_()
        
        self.saveButton.setEnabled(not self.__snapshot.isNull())
        self.copyButton.setEnabled(not self.__snapshot.isNull())
        self.copyPreviewButton.setEnabled(not self.__snapshot.isNull())
    
    @pyqtSlot()
    def on_copyButton_clicked(self):
        """
        Private slot to copy the snapshot to the clipboard.
        """
        if not self.__snapshot.isNull():
            QApplication.clipboard().setPixmap(QPixmap(self.__snapshot))
    
    @pyqtSlot()
    def on_copyPreviewButton_clicked(self):
        """
        Private slot to copy the snapshot preview to the clipboard.
        """
        QApplication.clipboard().setPixmap(self.preview.pixmap())
    
    def __captured(self, pixmap):
        """
        Private slot to show a preview of the snapshot.
        
        @param pixmap pixmap of the snapshot (QPixmap)
        """
        self.__grabber.close()
        self.__snapshot = QPixmap(pixmap)
        
        self.__grabber.grabbed.disconnect(self.__captured)
        self.__grabber = None
        
        self.__redisplay()
        self.__modified = True
        self.__updateCaption()
    
    def __updatePreview(self):
        """
        Private slot to update the preview picture.
        """
        self.preview.setToolTip(self.tr(
            "Preview of the snapshot image ({0} x {1})").format(
            self.__locale.toString(self.__snapshot.width()),
            self.__locale.toString(self.__snapshot.height()))
        )
        self.preview.setPreview(self.__snapshot)
        self.preview.adjustSize()
    
    def resizeEvent(self, evt):
        """
        Protected method handling a resizing of the window.
        
        @param evt resize event (QResizeEvent)
        """
        self.__updateTimer.start(200)
    
    def __dragSnapshot(self):
        """
        Private slot handling the dragging of the preview picture.
        """
        drag = QDrag(self)
        mimeData = QMimeData()
        mimeData.setImageData(self.__snapshot)
        drag.setMimeData(mimeData)
        drag.setPixmap(self.preview.pixmap())
        drag.exec_(Qt.CopyAction)
    
    def eventFilter(self, obj, evt):
        """
        Public method to handle event for other objects.
        
        @param obj reference to the object (QObject)
        @param evt reference to the event (QEvent)
        @return flag indicating that the event should be filtered out (boolean)
        """
        if obj == self.__grabberWidget and \
                evt.type() == QEvent.MouseButtonPress:
            if QWidget.mouseGrabber() != self.__grabberWidget:
                return False
            if evt.button() == Qt.LeftButton:
                self.__performGrab()
        
        return False
    
    def closeEvent(self, evt):
        """
        Protected method handling the close event.
        
        @param evt close event (QCloseEvent)
        """
        if self.__modified:
            res = E5MessageBox.question(
                self,
                self.tr("eric6 Snapshot"),
                self.tr(
                    """The application contains an unsaved snapshot."""),
                E5MessageBox.StandardButtons(
                    E5MessageBox.Abort |
                    E5MessageBox.Discard |
                    E5MessageBox.Save))
            if res == E5MessageBox.Abort:
                evt.ignore()
                return
            elif res == E5MessageBox.Save:
                self.on_saveButton_clicked()
        
        Preferences.Prefs.settings.setValue(
            "Snapshot/Delay", self.delaySpin.value())
        Preferences.Prefs.settings.setValue(
            "Snapshot/Mode",
            self.modeCombo.itemData(self.modeCombo.currentIndex()))
        Preferences.Prefs.settings.setValue(
            "Snapshot/Filename", self.__filename)
        Preferences.Prefs.settings.sync()
    
    def __updateCaption(self):
        """
        Private method to update the window caption.
        """
        self.setWindowTitle("{0}[*] - {1}".format(
            os.path.basename(self.__filename),
            self.tr("eric6 Snapshot")))
        self.setWindowModified(self.__modified)
        self.pathNameEdit.setText(os.path.dirname(self.__filename))
예제 #54
0
class SnapshotRegionGrabber(QWidget):
    """
    Class implementing a grabber widget for a rectangular snapshot region.
    
    @signal grabbed(QPixmap) emitted after the region was grabbed
    """
    grabbed = pyqtSignal(QPixmap)

    StrokeMask = 0
    FillMask = 1

    Rectangle = 0
    Ellipse = 1

    def __init__(self, mode=Rectangle):
        """
        Constructor
        
        @param mode region grabber mode (SnapshotRegionGrabber.Rectangle or
            SnapshotRegionGrabber.Ellipse)
        """
        super(SnapshotRegionGrabber, self).__init__(
            None, Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint
            | Qt.FramelessWindowHint | Qt.Tool)

        assert mode in [
            SnapshotRegionGrabber.Rectangle, SnapshotRegionGrabber.Ellipse
        ]
        self.__mode = mode

        self.__selection = QRect()
        self.__mouseDown = False
        self.__newSelection = False
        self.__handleSize = 10
        self.__mouseOverHandle = None
        self.__showHelp = True
        self.__grabbing = False
        self.__dragStartPoint = QPoint()
        self.__selectionBeforeDrag = QRect()
        self.__locale = QLocale()

        # naming conventions for handles
        # T top, B bottom, R Right, L left
        # 2 letters: a corner
        # 1 letter: the handle on the middle of the corresponding side
        self.__TLHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__TRHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__BLHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__BRHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__LHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__THandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__RHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__BHandle = QRect(0, 0, self.__handleSize, self.__handleSize)
        self.__handles = [
            self.__TLHandle, self.__TRHandle, self.__BLHandle, self.__BRHandle,
            self.__LHandle, self.__THandle, self.__RHandle, self.__BHandle
        ]
        self.__helpTextRect = QRect()
        self.__helpText = self.tr(
            "Select a region using the mouse. To take the snapshot, press"
            " the Enter key or double click. Press Esc to quit.")

        self.__pixmap = QPixmap()

        self.setMouseTracking(True)

        QTimer.singleShot(200, self.__initialize)

    def __initialize(self):
        """
        Private slot to initialize the rest of the widget.
        """
        self.__desktop = QApplication.desktop()
        x = self.__desktop.x()
        y = self.__desktop.y()
        if qVersion() >= "5.0.0":
            self.__pixmap = QApplication.screens()[0].grabWindow(
                self.__desktop.winId(), x, y, self.__desktop.width(),
                self.__desktop.height())
        else:
            self.__pixmap = QPixmap.grabWindow(self.__desktop.winId(), x, y,
                                               self.__desktop.width(),
                                               self.__desktop.height())
        self.resize(self.__pixmap.size())
        self.move(x, y)
        self.setCursor(Qt.CrossCursor)
        self.show()

        self.grabMouse()
        self.grabKeyboard()
        self.activateWindow()

    def paintEvent(self, evt):
        """
        Protected method handling paint events.
        
        @param evt paint event (QPaintEvent)
        """
        if self.__grabbing:  # grabWindow() should just get the background
            return

        painter = QPainter(self)
        pal = QPalette(QToolTip.palette())
        font = QToolTip.font()

        handleColor = pal.color(QPalette.Active, QPalette.Highlight)
        handleColor.setAlpha(160)
        overlayColor = QColor(0, 0, 0, 160)
        textColor = pal.color(QPalette.Active, QPalette.Text)
        textBackgroundColor = pal.color(QPalette.Active, QPalette.Base)
        painter.drawPixmap(0, 0, self.__pixmap)
        painter.setFont(font)

        r = QRect(self.__selection)
        if not self.__selection.isNull():
            grey = QRegion(self.rect())
            if self.__mode == SnapshotRegionGrabber.Ellipse:
                reg = QRegion(r, QRegion.Ellipse)
            else:
                reg = QRegion(r)
            grey = grey.subtracted(reg)
            painter.setClipRegion(grey)
            painter.setPen(Qt.NoPen)
            painter.setBrush(overlayColor)
            painter.drawRect(self.rect())
            painter.setClipRect(self.rect())
            drawRect(painter, r, handleColor)

        if self.__showHelp:
            painter.setPen(textColor)
            painter.setBrush(textBackgroundColor)
            self.__helpTextRect = painter.boundingRect(
                self.rect().adjusted(2, 2, -2, -2), Qt.TextWordWrap,
                self.__helpText).translated(-self.__desktop.x(),
                                            -self.__desktop.y())
            self.__helpTextRect.adjust(-2, -2, 4, 2)
            drawRect(painter, self.__helpTextRect, textColor,
                     textBackgroundColor)
            painter.drawText(self.__helpTextRect.adjusted(3, 3, -3, -3),
                             Qt.TextWordWrap, self.__helpText)

        if self.__selection.isNull():
            return

        # The grabbed region is everything which is covered by the drawn
        # rectangles (border included). This means that there is no 0px
        # selection, since a 0px wide rectangle will always be drawn as a line.
        txt = "{0}, {1} ({2} x {3})".format(
            self.__locale.toString(self.__selection.x()),
            self.__locale.toString(self.__selection.y()),
            self.__locale.toString(self.__selection.width()),
            self.__locale.toString(self.__selection.height()))
        textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
        boundingRect = textRect.adjusted(-4, 0, 0, 0)

        if textRect.width() < r.width() - 2 * self.__handleSize and \
           textRect.height() < r.height() - 2 * self.__handleSize and \
           r.width() > 100 and \
           r.height() > 100:
            # center, unsuitable for small selections
            boundingRect.moveCenter(r.center())
            textRect.moveCenter(r.center())
        elif r.y() - 3 > textRect.height() and \
                r.x() + textRect.width() < self.rect().width():
            # on top, left aligned
            boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3))
            textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3))
        elif r.x() - 3 > textRect.width():
            # left, top aligned
            boundingRect.moveTopRight(QPoint(r.x() - 3, r.y()))
            textRect.moveTopRight(QPoint(r.x() - 5, r.y()))
        elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \
                r.right() > textRect.width():
            # at bottom, right aligned
            boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3))
            textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3))
        elif r.right() + textRect.width() + 3 < self.rect().width():
            # right, bottom aligned
            boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom()))
            textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom()))

        # If the above didn't catch it, you are running on a very
        # tiny screen...
        drawRect(painter, boundingRect, textColor, textBackgroundColor)
        painter.drawText(textRect, Qt.AlignHCenter, txt)

        if (r.height() > self.__handleSize * 2 and
            r.width() > self.__handleSize * 2) or \
           not self.__mouseDown:
            self.__updateHandles()
            painter.setPen(Qt.NoPen)
            painter.setBrush(handleColor)
            painter.setClipRegion(
                self.__handleMask(SnapshotRegionGrabber.StrokeMask))
            painter.drawRect(self.rect())
            handleColor.setAlpha(60)
            painter.setBrush(handleColor)
            painter.setClipRegion(
                self.__handleMask(SnapshotRegionGrabber.FillMask))
            painter.drawRect(self.rect())

    def resizeEvent(self, evt):
        """
        Protected method to handle resize events.
        
        @param evt resize event (QResizeEvent)
        """
        if self.__selection.isNull():
            return

        r = QRect(self.__selection)
        r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect()))
        r.setBottomRight(self.__limitPointToRect(r.bottomRight(), self.rect()))
        if r.width() <= 1 or r.height() <= 1:
            # This just results in ugly drawing...
            self.__selection = QRect()
        else:
            self.__selection = self.__normalizeSelection(r)

    def mousePressEvent(self, evt):
        """
        Protected method to handle mouse button presses.
        
        @param evt mouse press event (QMouseEvent)
        """
        self.__showHelp = not self.__helpTextRect.contains(evt.pos())
        if evt.button() == Qt.LeftButton:
            self.__mouseDown = True
            self.__dragStartPoint = evt.pos()
            self.__selectionBeforeDrag = QRect(self.__selection)
            if not self.__selection.contains(evt.pos()):
                self.__newSelection = True
                self.__selection = QRect()
            else:
                self.setCursor(Qt.ClosedHandCursor)
        elif evt.button() == Qt.RightButton:
            self.__newSelection = False
            self.__selection = QRect()
            self.setCursor(Qt.CrossCursor)
        self.update()

    def mouseMoveEvent(self, evt):
        """
        Protected method to handle mouse movements.
        
        @param evt mouse move event (QMouseEvent)
        """
        shouldShowHelp = not self.__helpTextRect.contains(evt.pos())
        if shouldShowHelp != self.__showHelp:
            self.__showHelp = shouldShowHelp
            self.update()

        if self.__mouseDown:
            if self.__newSelection:
                p = evt.pos()
                r = self.rect()
                self.__selection = self.__normalizeSelection(
                    QRect(self.__dragStartPoint, self.__limitPointToRect(p,
                                                                         r)))
            elif self.__mouseOverHandle is None:
                # moving the whole selection
                r = self.rect().normalized()
                s = self.__selectionBeforeDrag.normalized()
                p = s.topLeft() + evt.pos() - self.__dragStartPoint
                r.setBottomRight(r.bottomRight() -
                                 QPoint(s.width(), s.height()) + QPoint(1, 1))
                if not r.isNull() and r.isValid():
                    self.__selection.moveTo(self.__limitPointToRect(p, r))
            else:
                # dragging a handle
                r = QRect(self.__selectionBeforeDrag)
                offset = evt.pos() - self.__dragStartPoint

                if self.__mouseOverHandle in \
                   [self.__TLHandle, self.__THandle, self.__TRHandle]:
                    r.setTop(r.top() + offset.y())

                if self.__mouseOverHandle in \
                   [self.__TLHandle, self.__LHandle, self.__BLHandle]:
                    r.setLeft(r.left() + offset.x())

                if self.__mouseOverHandle in \
                   [self.__BLHandle, self.__BHandle, self.__BRHandle]:
                    r.setBottom(r.bottom() + offset.y())

                if self.__mouseOverHandle in \
                   [self.__TRHandle, self.__RHandle, self.__BRHandle]:
                    r.setRight(r.right() + offset.x())

                r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect()))
                r.setBottomRight(
                    self.__limitPointToRect(r.bottomRight(), self.rect()))
                self.__selection = self.__normalizeSelection(r)

            self.update()
        else:
            if self.__selection.isNull():
                return

            found = False
            for r in self.__handles:
                if r.contains(evt.pos()):
                    self.__mouseOverHandle = r
                    found = True
                    break

            if not found:
                self.__mouseOverHandle = None
                if self.__selection.contains(evt.pos()):
                    self.setCursor(Qt.OpenHandCursor)
                else:
                    self.setCursor(Qt.CrossCursor)
            else:
                if self.__mouseOverHandle in [
                        self.__TLHandle, self.__BRHandle
                ]:
                    self.setCursor(Qt.SizeFDiagCursor)
                elif self.__mouseOverHandle in [
                        self.__TRHandle, self.__BLHandle
                ]:
                    self.setCursor(Qt.SizeBDiagCursor)
                elif self.__mouseOverHandle in [
                        self.__LHandle, self.__RHandle
                ]:
                    self.setCursor(Qt.SizeHorCursor)
                elif self.__mouseOverHandle in [
                        self.__THandle, self.__BHandle
                ]:
                    self.setCursor(Qt.SizeVerCursor)

    def mouseReleaseEvent(self, evt):
        """
        Protected method to handle mouse button releases.
        
        @param evt mouse release event (QMouseEvent)
        """
        self.__mouseDown = False
        self.__newSelection = False
        if self.__mouseOverHandle is None and \
           self.__selection.contains(evt.pos()):
            self.setCursor(Qt.OpenHandCursor)
        self.update()

    def mouseDoubleClickEvent(self, evt):
        """
        Protected method to handle mouse double clicks.
        
        @param evt mouse double click event (QMouseEvent)
        """
        self.__grabRect()

    def keyPressEvent(self, evt):
        """
        Protected method to handle key presses.
        
        @param evt key press event (QKeyEvent)
        """
        if evt.key() == Qt.Key_Escape:
            self.grabbed.emit(QPixmap())
        elif evt.key() in [Qt.Key_Enter, Qt.Key_Return]:
            self.__grabRect()
        else:
            evt.ignore()

    def __updateHandles(self):
        """
        Private method to update the handles.
        """
        r = QRect(self.__selection)
        s2 = self.__handleSize // 2

        self.__TLHandle.moveTopLeft(r.topLeft())
        self.__TRHandle.moveTopRight(r.topRight())
        self.__BLHandle.moveBottomLeft(r.bottomLeft())
        self.__BRHandle.moveBottomRight(r.bottomRight())

        self.__LHandle.moveTopLeft(QPoint(r.x(), r.y() + r.height() // 2 - s2))
        self.__THandle.moveTopLeft(QPoint(r.x() + r.width() // 2 - s2, r.y()))
        self.__RHandle.moveTopRight(
            QPoint(r.right(),
                   r.y() + r.height() // 2 - s2))
        self.__BHandle.moveBottomLeft(
            QPoint(r.x() + r.width() // 2 - s2, r.bottom()))

    def __handleMask(self, maskType):
        """
        Private method to calculate the handle mask.
        
        @param maskType type of the mask to be used
            (SnapshotRegionGrabber.FillMask or
            SnapshotRegionGrabber.StrokeMask)
        @return calculated mask (QRegion)
        """
        mask = QRegion()
        for rect in self.__handles:
            if maskType == SnapshotRegionGrabber.StrokeMask:
                r = QRegion(rect)
                mask += r.subtracted(QRegion(rect.adjusted(1, 1, -1, -1)))
            else:
                mask += QRegion(rect.adjusted(1, 1, -1, -1))
        return mask

    def __limitPointToRect(self, point, rect):
        """
        Private method to limit the given point to the given rectangle.
        
        @param point point to be limited (QPoint)
        @param rect rectangle the point shall be limited to (QRect)
        @return limited point (QPoint)
        """
        q = QPoint()
        if point.x() < rect.x():
            q.setX(rect.x())
        elif point.x() < rect.right():
            q.setX(point.x())
        else:
            q.setX(rect.right())
        if point.y() < rect.y():
            q.setY(rect.y())
        elif point.y() < rect.bottom():
            q.setY(point.y())
        else:
            q.setY(rect.bottom())
        return q

    def __normalizeSelection(self, sel):
        """
        Private method to normalize the given selection.
        
        @param sel selection to be normalized (QRect)
        @return normalized selection (QRect)
        """
        rect = QRect(sel)
        if rect.width() <= 0:
            left = rect.left()
            width = rect.width()
            rect.setLeft(left + width - 1)
            rect.setRight(left)
        if rect.height() <= 0:
            top = rect.top()
            height = rect.height()
            rect.setTop(top + height - 1)
            rect.setBottom(top)
        return rect

    def __grabRect(self):
        """
        Private method to grab the selected rectangle (i.e. do the snapshot).
        """
        if self.__mode == SnapshotRegionGrabber.Ellipse:
            ell = QRegion(self.__selection, QRegion.Ellipse)
            if not ell.isEmpty():
                self.__grabbing = True

                xOffset = self.__pixmap.rect().x() - ell.boundingRect().x()
                yOffset = self.__pixmap.rect().y() - ell.boundingRect().y()
                translatedEll = ell.translated(xOffset, yOffset)

                pixmap2 = QPixmap(ell.boundingRect().size())
                pixmap2.fill(Qt.transparent)

                pt = QPainter()
                pt.begin(pixmap2)
                if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff):
                    pt.setRenderHints(
                        QPainter.Antialiasing
                        | QPainter.HighQualityAntialiasing
                        | QPainter.SmoothPixmapTransform, True)
                    pt.setBrush(Qt.black)
                    pt.setPen(QPen(QBrush(Qt.black), 0.5))
                    pt.drawEllipse(translatedEll.boundingRect())
                    pt.setCompositionMode(QPainter.CompositionMode_SourceIn)
                else:
                    pt.setClipRegion(translatedEll)
                    pt.setCompositionMode(QPainter.CompositionMode_Source)

                pt.drawPixmap(pixmap2.rect(), self.__pixmap,
                              ell.boundingRect())
                pt.end()

                self.grabbed.emit(pixmap2)
        else:
            r = QRect(self.__selection)
            if not r.isNull() and r.isValid():
                self.__grabbing = True
                self.grabbed.emit(self.__pixmap.copy(r))
예제 #55
0
파일: graph.py 프로젝트: zero-code/sakia
    def add_certifier_list(self, certifier_list, identity, identity_account):
        """
        Add list of certifiers to graph
        :param list certifier_list: List of certifiers from api
        :param identity identity:   identity instance which is certified
        :param identity identity_account:   Account identity instance
        :return:
        """
        if self.community:
            try:
                yield from self.refresh_signature_validity()
                #  add certifiers of uid
                for certifier in tuple(certifier_list):
                    # add only valid certification...
                    if (time.time() - certifier['cert_time']) > self.signature_validity:
                        continue
                    # new node
                    if certifier['identity'].pubkey not in self._graph.keys():
                        node_status = 0
                        is_member = yield from certifier['identity'].is_member(self.community)
                        if certifier['identity'].pubkey == identity_account.pubkey:
                            node_status += NODE_STATUS_HIGHLIGHTED
                        if is_member is False:
                            node_status += NODE_STATUS_OUT
                        self._graph[certifier['identity'].pubkey] = {
                            'id': certifier['identity'].pubkey,
                            'arcs': list(),
                            'text': certifier['identity'].uid,
                            'tooltip': certifier['identity'].pubkey,
                            'status': node_status,
                            'connected': [identity.pubkey]
                        }

                    # keep only the latest certification
                    if self._graph[certifier['identity'].pubkey]['arcs']:
                        if certifier['cert_time'] < self._graph[certifier['identity'].pubkey]['arcs'][0]['cert_time']:
                            continue
                    # display validity status
                    if (time.time() - certifier['cert_time']) > self.ARC_STATUS_STRONG_time:
                        arc_status = ARC_STATUS_WEAK
                    else:
                        arc_status = ARC_STATUS_STRONG

                    arc = {
                        'id': identity.pubkey,
                        'status': arc_status,
                        'tooltip': QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(certifier['cert_time'] + self.signature_validity).date(),
                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                        ),
                        'cert_time': certifier['cert_time']
                    }

                    current_block_number = self.community.network.current_blockid.number
                    if current_block_number and certifier['block_number']:
                        current_confirmations = current_block_number - certifier['block_number'] + 1
                    else:
                        current_confirmations = 0
                    members_pubkeys = yield from self.community.members_pubkeys()
                    max_confirmation = self.community.network.fork_window(members_pubkeys) + 1

                    # Current confirmation can be negative if self.community.network.current_blockid.number
                    # is not refreshed yet
                    if max_confirmation > current_confirmations >= 0:
                        if self.app.preferences['expert_mode']:
                            arc['confirmation_text'] = "{0}/{1}".format(current_confirmations,
                                                                      max_confirmation)
                        else:
                            confirmation = current_confirmations / max_confirmation * 100
                            arc['confirmation_text'] = "{0} %".format(QLocale().toString(float(confirmation), 'f', 0))
                    else:
                        arc['confirmation_text'] = None

                    #  add arc to certifier
                    self._graph[certifier['identity'].pubkey]['arcs'].append(arc)
                    # if certifier node not in identity nodes
                    if certifier['identity'].pubkey not in tuple(self._graph[identity.pubkey]['connected']):
                        # add certifier node to identity node
                        self._graph[identity.pubkey]['connected'].append(certifier['identity'].pubkey)
            except NoPeerAvailable as e:
                logging.debug(str(e))
예제 #56
0
class SymbolsModel(QAbstractTableModel):
    """
    Class implementing the model for the symbols widget.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent object (QObject)
        """
        super(SymbolsModel, self).__init__(parent)

        self.__locale = QLocale()

        self.__headerData = [
            self.tr("Code"),
            self.tr("Char"),
            self.tr("Hex"),
            self.tr("HTML"),
            self.tr("Name"),
        ]

        self.__tables = [
            # first   last     display name
            (0x0, 0x1f, self.tr("Control Characters")),
            (0x20, 0x7f, self.tr("Basic Latin")),
            (0x80, 0xff, self.tr("Latin-1 Supplement")),
            (0x100, 0x17f, self.tr("Latin Extended-A")),
            (0x180, 0x24f, self.tr("Latin Extended-B")),
            (0x250, 0x2af, self.tr("IPA Extensions")),
            (0x2b0, 0x2ff, self.tr("Spacing Modifier Letters")),
            (0x300, 0x36f, self.tr("Combining Diacritical Marks")),
            (0x370, 0x3ff, self.tr("Greek and Coptic")),
            (0x400, 0x4ff, self.tr("Cyrillic")),
            (0x500, 0x52f, self.tr("Cyrillic Supplement")),
            (0x530, 0x58f, self.tr("Armenian")),
            (0x590, 0x5ff, self.tr("Hebrew")),
            (0x600, 0x6ff, self.tr("Arabic")),
            (0x700, 0x74f, self.tr("Syriac")),
            (0x780, 0x7bf, self.tr("Thaana")),
            (0x7c0, 0x7ff, self.tr("N'Ko")),
            (0x800, 0x83f, self.tr("Samaritan")),
            (0x840, 0x85f, self.tr("Mandaic")),
            (0x8a0, 0x8ff, self.tr("Arabic Extended-A")),
            (0x900, 0x97f, self.tr("Devanagari")),
            (0x980, 0x9ff, self.tr("Bengali")),
            (0xa00, 0xa7f, self.tr("Gurmukhi")),
            (0xa80, 0xaff, self.tr("Gujarati")),
            (0xb00, 0xb7f, self.tr("Oriya")),
            (0xb80, 0xbff, self.tr("Tamil")),
            (0xc00, 0xc7f, self.tr("Telugu")),
            (0xc80, 0xcff, self.tr("Kannada")),
            (0xd00, 0xd7f, self.tr("Malayalam")),
            (0xd80, 0xdff, self.tr("Sinhala")),
            (0xe00, 0xe7f, self.tr("Thai")),
            (0xe80, 0xeff, self.tr("Lao")),
            (0xf00, 0xfff, self.tr("Tibetan")),
            (0x1000, 0x109f, self.tr("Myanmar")),
            (0x10a0, 0x10ff, self.tr("Georgian")),
            (0x1100, 0x11ff, self.tr("Hangul Jamo")),
            (0x1200, 0x137f, self.tr("Ethiopic")),
            (0x1380, 0x139f, self.tr("Ethiopic Supplement")),
            (0x13a0, 0x13ff, self.tr("Cherokee")),
            (0x1400, 0x167f, self.tr("Unified Canadian Aboriginal Syllabics")),
            (0x1680, 0x169f, self.tr("Ogham")),
            (0x16a0, 0x16ff, self.tr("Runic")),
            (0x1700, 0x171f, self.tr("Tagalog")),
            (0x1720, 0x173f, self.tr("Hanunoo")),
            (0x1740, 0x175f, self.tr("Buhid")),
            (0x1760, 0x177f, self.tr("Tagbanwa")),
            (0x1780, 0x17ff, self.tr("Khmer")),
            (0x1800, 0x18af, self.tr("Mongolian")),
            (0x18b0, 0x18ff,
             self.tr("Unified Canadian Aboriginal Syllabics Extended")),
            (0x1900, 0x194f, self.tr("Limbu")),
            (0x1950, 0x197f, self.tr("Tai Le")),
            (0x19e0, 0x19ff, self.tr("Khmer Symbols")),
            (0x1a00, 0x1a1f, self.tr("Buginese")),
            (0x1a20, 0x1aaf, self.tr("Tai Tham")),
            (0x1b00, 0x1b7f, self.tr("Balinese")),
            (0x1b80, 0x1bbf, self.tr("Sundanese")),
            (0x1bc0, 0x1bff, self.tr("Batak")),
            (0x1c00, 0x1c4f, self.tr("Lepcha")),
            (0x1c50, 0x1c7f, self.tr("Ol Chiki")),
            (0x1cc0, 0x1ccf, self.tr("Sundanese Supplement")),
            (0x1cd0, 0x1cff, self.tr("Vedic Extensions")),
            (0x1d00, 0x1d7f, self.tr("Phonetic Extensions")),
            (0x1d80, 0x1dbf, self.tr("Phonetic Extensions Supplement")),
            (0x1dc0, 0x1dff,
             self.tr("Combining Diacritical Marks Supplement")),
            (0x1e00, 0x1eff, self.tr("Latin Extended Additional")),
            (0x1f00, 0x1fff, self.tr("Greek Extended")),
            (0x2000, 0x206f, self.tr("General Punctuation")),
            (0x2070, 0x209f, self.tr("Superscripts and Subscripts")),
            (0x20a0, 0x20cf, self.tr("Currency Symbols")),
            (0x20d0, 0x20ff, self.tr("Combining Diacritical Marks")),
            (0x2100, 0x214f, self.tr("Letterlike Symbols")),
            (0x2150, 0x218f, self.tr("Number Forms")),
            (0x2190, 0x21ff, self.tr("Arcolumns")),
            (0x2200, 0x22ff, self.tr("Mathematical Operators")),
            (0x2300, 0x23ff, self.tr("Miscellaneous Technical")),
            (0x2400, 0x243f, self.tr("Control Pictures")),
            (0x2440, 0x245f, self.tr("Optical Character Recognition")),
            (0x2460, 0x24ff, self.tr("Enclosed Alphanumerics")),
            (0x2500, 0x257f, self.tr("Box Drawing")),
            (0x2580, 0x259f, self.tr("Block Elements")),
            (0x25A0, 0x25ff, self.tr("Geometric Shapes")),
            (0x2600, 0x26ff, self.tr("Miscellaneous Symbols")),
            (0x2700, 0x27bf, self.tr("Dingbats")),
            (0x27c0, 0x27ef, self.tr("Miscellaneous Mathematical Symbols-A")),
            (0x27f0, 0x27ff, self.tr("Supplement Arcolumns-A")),
            (0x2800, 0x28ff, self.tr("Braille Patterns")),
            (0x2900, 0x297f, self.tr("Supplement Arcolumns-B")),
            (0x2980, 0x29ff, self.tr("Miscellaneous Mathematical Symbols-B")),
            (0x2a00, 0x2aff, self.tr("Supplemental Mathematical Operators")),
            (0x2b00, 0x2bff, self.tr("Miscellaneous Symbols and Arcolumns")),
            (0x2c00, 0x2c5f, self.tr("Glagolitic")),
            (0x2c60, 0x2c7f, self.tr("Latin Extended-C")),
            (0x2c80, 0x2cff, self.tr("Coptic")),
            (0x2d00, 0x2d2f, self.tr("Georgian Supplement")),
            (0x2d30, 0x2d7f, self.tr("Tifinagh")),
            (0x2d80, 0x2ddf, self.tr("Ethiopic Extended")),
            (0x2de0, 0x2dff, self.tr("Cyrillic Extended-A")),
            (0x2e00, 0x2e7f, self.tr("Supplemental Punctuation")),
            (0x2e80, 0x2eff, self.tr("CJK Radicals Supplement")),
            (0x2f00, 0x2fdf, self.tr("KangXi Radicals")),
            (0x2ff0, 0x2fff, self.tr("Ideographic Description Chars")),
            (0x3000, 0x303f, self.tr("CJK Symbols and Punctuation")),
            (0x3040, 0x309f, self.tr("Hiragana")),
            (0x30a0, 0x30ff, self.tr("Katakana")),
            (0x3100, 0x312f, self.tr("Bopomofo")),
            (0x3130, 0x318f, self.tr("Hangul Compatibility Jamo")),
            (0x3190, 0x319f, self.tr("Kanbun")),
            (0x31a0, 0x31bf, self.tr("Bopomofo Extended")),
            (0x31c0, 0x31ef, self.tr("CJK Strokes")),
            (0x31f0, 0x31ff, self.tr("Katakana Phonetic Extensions")),
            (0x3200, 0x32ff, self.tr("Enclosed CJK Letters and Months")),
            (0x3300, 0x33ff, self.tr("CJK Compatibility")),
            (0x3400, 0x4dbf, self.tr("CJK Unified Ideogr. Ext. A")),
            (0x4dc0, 0x4dff, self.tr("Yijing Hexagram Symbols")),
            (0x4e00, 0x9fff, self.tr("CJK Unified Ideographs")),
            (0xa000, 0xa48f, self.tr("Yi Syllables")),
            (0xa490, 0xa4cf, self.tr("Yi Radicals")),
            (0xa4d0, 0xa4ff, self.tr("Lisu")),
            (0xa500, 0xa63f, self.tr("Vai")),
            (0xa640, 0xa69f, self.tr("Cyrillic Extended-B")),
            (0xa6a0, 0xa6ff, self.tr("Bamum")),
            (0xa700, 0xa71f, self.tr("Modifier Tone Letters")),
            (0xa720, 0xa7ff, self.tr("Latin Extended-D")),
            (0xa800, 0xa82f, self.tr("Syloti Nagri")),
            (0xa830, 0xa83f, self.tr("Common Indic Number Forms")),
            (0xa840, 0xa87f, self.tr("Phags-pa")),
            (0xa880, 0xa8df, self.tr("Saurashtra")),
            (0xa8e0, 0xa8ff, self.tr("Devanagari Extended")),
            (0xa900, 0xa92f, self.tr("Kayah Li")),
            (0xa930, 0xa95f, self.tr("Rejang")),
            (0xa960, 0xa97f, self.tr("Hangul Jamo Extended-A")),
            (0xa980, 0xa9df, self.tr("Javanese")),
            (0xaa00, 0xaa5f, self.tr("Cham")),
            (0xaa60, 0xaa7f, self.tr("Myanmar Extended-A")),
            (0xaa80, 0xaadf, self.tr("Tai Viet")),
            (0xaae0, 0xaaff, self.tr("Meetei Mayek Extensions")),
            (0xab00, 0xab2f, self.tr("Ethiopic Extended-A")),
            (0xabc0, 0xabff, self.tr("Meetei Mayek")),
            (0xac00, 0xd7af, self.tr("Hangul Syllables")),
            (0xd7b0, 0xd7ff, self.tr("Hangul Jamo Extended-B")),
            (0xd800, 0xdb7f, self.tr("High Surrogates")),
            (0xdb80, 0xdbff, self.tr("High Private Use Surrogates")),
            (0xdc00, 0xdfff, self.tr("Low Surrogates")),
            (0xe000, 0xf8ff, self.tr("Private Use")),
            (0xf900, 0xfaff, self.tr("CJK Compatibility Ideographs")),
            (0xfb00, 0xfb4f, self.tr("Alphabetic Presentation Forms")),
            (0xfb50, 0xfdff, self.tr("Arabic Presentation Forms-A")),
            (0xfe00, 0xfe0f, self.tr("Variation Selectors")),
            (0xfe10, 0xfe1f, self.tr("Vertical Forms")),
            (0xfe20, 0xfe2f, self.tr("Combining Half Marks")),
            (0xfe30, 0xfe4f, self.tr("CJK Compatibility Forms")),
            (0xfe50, 0xfe6f, self.tr("Small Form Variants")),
            (0xfe70, 0xfeff, self.tr("Arabic Presentation Forms-B")),
            (0xff00, 0xffef, self.tr("Half- and Fullwidth Forms")),
            (0xfff0, 0xffff, self.tr("Specials")),
        ]
        if sys.maxunicode > 0xffff:
            self.__tables.extend([
                (0x10000, 0x1007f, self.tr("Linear B Syllabary")),
                (0x10080, 0x100ff, self.tr("Linear B Ideograms")),
                (0x10100, 0x1013f, self.tr("Aegean Numbers")),
                (0x10140, 0x1018f, self.tr("Ancient Greek Numbers")),
                (0x10190, 0x101cf, self.tr("Ancient Symbols")),
                (0x101d0, 0x101ff, self.tr("Phaistos Disc")),
                (0x10280, 0x1029f, self.tr("Lycian")),
                (0x102a0, 0x102df, self.tr("Carian")),
                (0x10300, 0x1032f, self.tr("Old Italic")),
                (0x10330, 0x1034f, self.tr("Gothic")),
                (0x10380, 0x1039f, self.tr("Ugaritic")),
                (0x103a0, 0x103df, self.tr("Old Persian")),
                (0x10400, 0x1044f, self.tr("Deseret")),
                (0x10450, 0x1047f, self.tr("Shavian")),
                (0x10480, 0x104af, self.tr("Osmanya")),
                (0x10800, 0x1083f, self.tr("Cypriot Syllabary")),
                (0x10840, 0x1085f, self.tr("Imperial Aramaic")),
                (0x10900, 0x1091f, self.tr("Phoenician")),
                (0x10920, 0x1093f, self.tr("Lydian")),
                (0x10980, 0x1099f, self.tr("Meroitic Hieroglyphs")),
                (0x109a0, 0x109ff, self.tr("Meroitic Cursive")),
                (0x10a00, 0x10a5f, self.tr("Kharoshthi")),
                (0x10a60, 0x10a7f, self.tr("Old South Arabian")),
                (0x10b00, 0x10b3f, self.tr("Avestan")),
                (0x10b40, 0x10b5f, self.tr("Inscriptional Parthian")),
                (0x10b60, 0x10b7f, self.tr("Inscriptional Pahlavi")),
                (0x10c00, 0x10c4f, self.tr("Old Turkic")),
                (0x10e60, 0x10e7f, self.tr("Rumi Numeral Symbols")),
                (0x11000, 0x1107f, self.tr("Brahmi")),
                (0x11080, 0x110cf, self.tr("Kaithi")),
                (0x110d0, 0x110ff, self.tr("Sora Sompeng")),
                (0x11100, 0x1114f, self.tr("Chakma")),
                (0x11180, 0x111df, self.tr("Sharada")),
                (0x11680, 0x116cf, self.tr("Takri")),
                (0x12000, 0x123ff, self.tr("Cuneiform")),
                (0x12400, 0x1247f,
                 self.tr("Cuneiform Numbers and Punctuation")),
                (0x13000, 0x1342f, self.tr("Egyptian Hieroglyphs")),
                (0x16800, 0x16a3f, self.tr("Bamum Supplement")),
                (0x16f00, 0x16f9f, self.tr("Miao")),
                (0x1b000, 0x1b0ff, self.tr("Kana Supplement")),
                (0x1d000, 0x1d0ff, self.tr("Byzantine Musical Symbols")),
                (0x1d100, 0x1d1ff, self.tr("Musical Symbols")),
                (0x1d200, 0x1d24f, self.tr("Ancient Greek Musical Notation")),
                (0x1d300, 0x1d35f, self.tr("Tai Xuan Jing Symbols")),
                (0x1d360, 0x1d37f, self.tr("Counting Rod Numerals")),
                (0x1d400, 0x1d7ff,
                 self.tr("Mathematical Alphanumeric Symbols")),
                (0x1ee00, 0x1eeff,
                 self.tr("Arabic Mathematical Alphabetic Symbols")),
                (0x1f000, 0x1f02f, self.tr("Mahjong Tiles")),
                (0x1f030, 0x1f09f, self.tr("Domino Tiles")),
                (0x1f0a0, 0x1f0ff, self.tr("Playing Cards")),
                (0x1f100, 0x1f1ff,
                 self.tr("Enclosed Alphanumeric Supplement")),
                (0x1f200, 0x1f2ff, self.tr("Enclosed Ideographic Supplement")),
                (0x1f300, 0x1f5ff,
                 self.tr("Miscellaneous Symbols And Pictographs")),
                (0x1f600, 0x1f64f, self.tr("Emoticons")),
                (0x1f680, 0x1f6ff, self.tr("Transport And Map Symbols")),
                (0x1f700, 0x1f77f, self.tr("Alchemical Symbols")),
                (0x20000, 0x2a6df, self.tr("CJK Unified Ideogr. Ext. B")),
                (0x2a700, 0x2b73f,
                 self.tr("CJK Unified Ideographs Extension C")),
                (0x2b740, 0x2b81f,
                 self.tr("CJK Unified Ideographs Extension D")),
                (0x2f800, 0x2fa1f,
                 self.tr("CJK Compatapility Ideogr. Suppl.")),
                (0xe0000, 0xe007f, self.tr("Tags")),
                (0xe0100, 0xe01ef, self.tr("Variation Selectors Supplement")),
                (0xf0000, 0xfffff,
                 self.tr("Supplementary Private Use Area-A")),
                (0x100000, 0x10ffff,
                 self.tr("Supplementary Private Use Area-B")),
            ])
        self.__currentTableIndex = 0

    def getTableNames(self):
        """
        Public method to get a list of table names.
        
        @return list of table names (list of strings)
        """
        return [table[2] for table in self.__tables]

    def getTableBoundaries(self, index):
        """
        Public method to get the first and last character position
        of the given table.
        
        @param index index of the character table (integer)
        @return first and last character position (integer, integer)
        """
        return self.__tables[index][0], self.__tables[index][1]

    def getTableIndex(self):
        """
        Public method to get the current table index.
        
        @return current table index (integer)
        """
        return self.__currentTableIndex

    def selectTable(self, index):
        """
        Public method to select the shown character table.
        
        @param index index of the character table (integer)
        """
        self.beginResetModel()
        self.__currentTableIndex = index
        self.endResetModel()

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        """
        Public method to get header data from the model.
        
        @param section section number (integer)
        @param orientation orientation (Qt.Orientation)
        @param role role of the data to retrieve (integer)
        @return requested data
        """
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.__headerData[section]

        return QAbstractTableModel.headerData(self, section, orientation, role)

    def data(self, index, role=Qt.DisplayRole):
        """
        Public method to get data from the model.
        
        @param index index to get data for (QModelIndex)
        @param role role of the data to retrieve (integer)
        @return requested data
        """
        symbolId = self.__tables[self.__currentTableIndex][0] + index.row()

        if role == Qt.DisplayRole:
            col = index.column()
            if col == 0:
                return self.__locale.toString(symbolId)
            elif col == 1:
                return chr(symbolId)
            elif col == 2:
                return "0x{0:04x}".format(symbolId)
            elif col == 3:
                if symbolId in html.entities.codepoint2name:
                    return "&{0};".format(
                        html.entities.codepoint2name[symbolId])
            elif col == 4:
                return unicodedata.name(chr(symbolId), '').title()

        if role == Qt.BackgroundColorRole:
            if index.column() == 0:
                return QColor(Qt.lightGray)

        if role == Qt.TextColorRole:
            char = chr(symbolId)
            if self.__isDigit(char):
                return QColor(Qt.darkBlue)
            elif self.__isLetter(char):
                return QColor(Qt.darkGreen)
            elif self.__isMark(char):
                return QColor(Qt.darkRed)
            elif self.__isSymbol(char):
                return QColor(Qt.black)
            elif self.__isPunct(char):
                return QColor(Qt.darkMagenta)
            else:
                return QColor(Qt.darkGray)

        if role == Qt.TextAlignmentRole:
            if index.column() in [0, 1, 3]:
                return Qt.AlignHCenter

        return None

    def columnCount(self, parent):
        """
        Public method to get the number of columns of the model.
        
        @param parent parent index (QModelIndex)
        @return number of columns (integer)
        """
        if parent.column() > 0:
            return 0
        else:
            return len(self.__headerData)

    def rowCount(self, parent):
        """
        Public method to get the number of rows of the model.
        
        @param parent parent index (QModelIndex)
        @return number of columns (integer)
        """
        if parent.isValid():
            return 0
        else:
            first, last = self.__tables[self.__currentTableIndex][:2]
            return last - first + 1

    def __isDigit(self, char):
        """
        Private method to check, if a character is a digit.
        
        @param char character to test (one character string)
        @return flag indicating a digit (boolean)
        """
        return unicodedata.category(str(char)) == "Nd"

    def __isLetter(self, char):
        """
        Private method to check, if a character is a letter.
        
        @param char character to test (one character string)
        @return flag indicating a letter (boolean)
        """
        return unicodedata.category(
            str(char)) in ["Lu", "Ll", "Lt", "Lm", "Lo"]

    def __isMark(self, char):
        """
        Private method to check, if a character is a mark character.
        
        @param char character to test (one character string)
        @return flag indicating a mark character (boolean)
        """
        return unicodedata.category(str(char)) in ["Mn", "Mc", "Me"]

    def __isSymbol(self, char):
        """
        Private method to check, if a character is a symbol.
        
        @param char character to test (one character string)
        @return flag indicating a symbol (boolean)
        """
        return unicodedata.category(str(char)) in ["Sm", "Sc", "Sk", "So"]

    def __isPunct(self, char):
        """
        Private method to check, if a character is a punctuation character.
        
        @param char character to test (one character string)
        @return flag indicating a punctuation character (boolean)
        """
        return unicodedata.category(
            str(char)) in ["Pc", "Pd", "Ps", "Pe", "Pi", "Pf", "Po"]

    def getLocale(self):
        """
        Public method to get the used locale.
        
        @return used locale
        @rtype QLocale
        """
        return self.__locale
예제 #57
0
파일: graph.py 프로젝트: zero-code/sakia
    def add_certified_list(self, certified_list, identity, identity_account):
        """
        Add list of certified from api to graph
        :param list certified_list: List of certified from api
        :param identity identity:   identity instance which is certifier
        :param identity identity_account:   Account identity instance
        :return:
        """

        if self.community:
            try:
                yield from self.refresh_signature_validity()
                # add certified by uid
                for certified in tuple(certified_list):
                    # add only valid certification...
                    if (time.time() - certified['cert_time']) > self.signature_validity:
                        continue
                    if certified['identity'].pubkey not in self._graph.keys():
                        node_status = 0
                        is_member = yield from certified['identity'].is_member(self.community)
                        if certified['identity'].pubkey == identity_account.pubkey:
                            node_status += NODE_STATUS_HIGHLIGHTED
                        if is_member is False:
                            node_status += NODE_STATUS_OUT
                        self._graph[certified['identity'].pubkey] = {
                            'id': certified['identity'].pubkey,
                            'arcs': list(),
                            'text': certified['identity'].uid,
                            'tooltip': certified['identity'].pubkey,
                            'status': node_status,
                            'connected': [identity.pubkey]
                        }
                    # display validity status
                    if (time.time() - certified['cert_time']) > self.ARC_STATUS_STRONG_time:
                        arc_status = ARC_STATUS_WEAK
                    else:
                        arc_status = ARC_STATUS_STRONG
                    arc = {
                        'id': certified['identity'].pubkey,
                        'status': arc_status,
                        'tooltip': QLocale.toString(
                            QLocale(),
                            QDateTime.fromTime_t(certified['cert_time'] + self.signature_validity).date(),
                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
                        ),
                        'cert_time': certified['cert_time']
                    }

                    current_block_number = self.community.network.current_blockid.number
                    if current_block_number and certified['block_number']:
                        current_confirmations = current_block_number - certified['block_number'] + 1
                    else:
                        current_confirmations = 0
                    members_pubkeys = yield from self.community.members_pubkeys()
                    max_confirmations = self.community.network.fork_window(members_pubkeys) + 1

                    if max_confirmations > current_confirmations >= 0:
                        if self.app.preferences['expert_mode']:
                            arc['confirmation_text'] = "{0}/{1}".format(current_confirmations,
                                                                      max_confirmations)
                        else:
                            confirmation = current_confirmations / max_confirmations * 100
                            confirmation = 100 if confirmation > 100 else confirmation
                            arc['confirmation_text'] = "{0} %".format(QLocale().toString(float(confirmation), 'f', 0))
                    else:
                        arc['confirmation_text'] = None

                    # replace old arc if this one is more recent
                    new_arc = True
                    index = 0
                    for a in self._graph[identity.pubkey]['arcs']:
                        # if same arc already exists...
                        if a['id'] == arc['id']:
                            # if arc more recent, dont keep old one...
                            if arc['cert_time'] >= a['cert_time']:
                                self._graph[identity.pubkey]['arcs'][index] = arc
                            new_arc = False
                        index += 1

                    #  if arc not in graph...
                    if new_arc:
                        # add arc in graph
                        self._graph[identity.pubkey]['arcs'].append(arc)
                    # if certified node not in identity nodes
                    if certified['identity'].pubkey not in tuple(self._graph[identity.pubkey]['connected']):
                        # add certified node to identity node
                        self._graph[identity.pubkey]['connected'].append(certified['identity'].pubkey)
            except NoPeerAvailable as e:
                logging.debug(str(e))