Skip to content
Snippets Groups Projects
Commit 752b21b8 authored by inso's avatar inso
Browse files

Add busy indicators during loading in views

parent 5d6cf050
No related branches found
No related tags found
No related merge requests found
from PyQt5.QtWidgets import QWidget
from PyQt5.QtGui import QPalette, QPainter, QColor, QBrush, QPen
from PyQt5.QtCore import Qt
import math
class Busy(QWidget):
def __init__(self, parent = None):
QWidget.__init__(self, parent)
palette = QPalette(self.palette())
palette.setColor(palette.Background, Qt.transparent)
self.setPalette(palette)
self.timer = None
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.fillRect(event.rect(), QBrush(QColor(255, 255, 255, 127)))
painter.setPen(QPen(Qt.NoPen))
for i in range(12):
if self.counter % 12 == i:
painter.setBrush(QBrush(QColor(165, 165, 165, (self.counter % 12)*22)))
else:
painter.setBrush(QBrush(QColor(165, 165, 165)))
painter.drawEllipse(
self.width()/2 + 50 * math.cos(2 * math.pi * i / 12.0) - 5,
self.height()/2 + 50 * math.sin(2 * math.pi * i / 12.0) - 5,
12, 12)
painter.end()
def showEvent(self, event):
self.timer = self.startTimer(150)
self.counter = 0
super().showEvent(event)
def hideEvent(self, event):
if self.timer:
self.killTimer(self.timer)
self.timer = None
super().hideEvent(event)
def timerEvent(self, event):
self.counter += 1
self.update()
super().timerEvent(event)
......@@ -14,6 +14,7 @@ from ..gen_resources.identities_tab_uic import Ui_IdentitiesTab
from .contact import ConfigureContactDialog
from .member import MemberDialog
from .transfer import TransferMoneyDialog
from .busy import Busy
from .certification import CertificationDialog
import asyncio
from ..core.net.api import bma as qtbma
......@@ -62,11 +63,15 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
self.button_search.addAction(direct_connections)
self.button_search.clicked.connect(self._async_execute_search_text)
self.busy = Busy(self.table_identities)
self.busy.hide()
def cancel_once_tasks(self):
cancel_once_task(self, self.identity_context_menu)
cancel_once_task(self, self._async_execute_search_text)
cancel_once_task(self, self._async_search_members)
cancel_once_task(self, self._async_search_direct_connections)
cancel_once_task(self, self.refresh_identities)
def change_account(self, account, password_asker):
self.cancel_once_tasks()
......@@ -173,6 +178,7 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
@asyncify
@asyncio.coroutine
def _async_execute_search_text(self, checked):
self.busy.show()
text = self.edit_textsearch.text()
if len(text) < 2:
return
......@@ -184,6 +190,7 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
self.edit_textsearch.clear()
self.refresh_identities(identities)
self.busy.hide()
@once_at_a_time
@asyncify
......@@ -193,6 +200,7 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
Search members of community and display found members
"""
if self.community:
self.busy.show()
pubkeys = yield from self.community.members_pubkeys()
identities = []
for p in pubkeys:
......@@ -201,6 +209,7 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
self.edit_textsearch.clear()
self.refresh_identities(identities)
self.busy.hide()
@once_at_a_time
@asyncify
......@@ -210,6 +219,7 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
Search members of community and display found members
"""
if self.account and self.community:
self.busy.show()
self_identity = yield from self.account.identity(self.community)
account_connections = []
certs_of = yield from self_identity.unique_valid_certifiers_of(self.app.identities_registry, self.community)
......@@ -223,14 +233,24 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
if p.pubkey not in [i.pubkey for i in certifiers_of]]
identities = certifiers_of + certified_by
self.refresh_identities(identities)
self.busy.hide()
@once_at_a_time
@asyncify
@asyncio.coroutine
def refresh_identities(self, identities):
"""
Refresh the table with specified identities.
If no identities is passed, use the account connections.
"""
self.table_identities.model().sourceModel().refresh_identities(identities)
self.busy.show()
yield from self.table_identities.model().sourceModel().refresh_identities(identities)
self.table_identities.resizeColumnsToContents()
self.busy.hide()
def resizeEvent(self, event):
self.busy.resize(event.size())
super().resizeEvent(event)
def changeEvent(self, event):
"""
......
......@@ -17,6 +17,7 @@ from .contact import ConfigureContactDialog
from ..gen_resources.wot_tab_uic import Ui_WotTabWidget
from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_SELECTED, NODE_STATUS_OUT, ARC_STATUS_STRONG, \
ARC_STATUS_WEAK
from .busy import Busy
class WotTabWidget(QWidget, Ui_WotTabWidget):
......@@ -40,6 +41,9 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
# the edited text is not added in the item list
self.comboBoxSearch.setInsertPolicy(QComboBox.NoInsert)
self.busy = Busy(self.graphicsView)
self.busy.hide()
# add scene events
self.graphicsView.scene().node_clicked.connect(self.handle_node_click)
self.graphicsView.scene().node_signed.connect(self.sign_node)
......@@ -177,6 +181,7 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
:param cutecoin.core.registry.Identity identity: Graph node identity
"""
logging.debug("Draw graph - " + identity.uid)
self.busy.show()
if self.community:
identity_account = yield from self.account.identity(self.community)
......@@ -217,6 +222,7 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
path = yield from graph.get_shortest_path_between_members(identity, identity_account)
if path:
self.graphicsView.scene().update_path(path)
self.busy.hide()
@once_at_a_time
@asyncify
......@@ -322,6 +328,10 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
if result == QDialog.Accepted:
self.window().refresh_contacts()
def resizeEvent(self, event):
self.busy.resize(event.size())
super().resizeEvent(event)
def changeEvent(self, event):
"""
Intercepte LanguageChange event to translate UI
......
......@@ -40,37 +40,38 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel):
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.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:
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)
)
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)
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:
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 ""
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
return QColor(Qt.blue)
return source_data
class IdentitiesTableModel(QAbstractTableModel):
......@@ -95,7 +96,6 @@ class IdentitiesTableModel(QAbstractTableModel):
self._sig_validity = 0
def change_community(self, community):
cancel_once_task(self, self.refresh_identities)
self.community = community
def sig_validity(self):
......@@ -119,8 +119,6 @@ class IdentitiesTableModel(QAbstractTableModel):
return (identity.uid, identity.pubkey, join_date, expiration_date)
@once_at_a_time
@asyncify
@asyncio.coroutine
def refresh_identities(self, identities):
"""
......@@ -153,7 +151,8 @@ class IdentitiesTableModel(QAbstractTableModel):
if role == Qt.DisplayRole:
row = index.row()
col = index.column()
return self.identities_data[row][col]
identity_data = self.identities_data[row]
return identity_data[col]
def identity_index(self, pubkey):
try:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment