def __init__(self, parent, app):
self._app = app
- self._session = session.Session(constants._data_path_)
+
+ self._errorLog = qui_utils.QErrorLog()
+ self._errorDisplay = qui_utils.ErrorDisplay(self._errorLog)
+
+ self._session = session.Session(self._errorLog, constants._data_path_)
self._session.error.connect(self._on_session_error)
self._session.loggedIn.connect(self._on_login)
self._session.loggedOut.connect(self._on_logout)
self._accountDialog = None
self._aboutDialog = None
- self._errorLog = qui_utils.QErrorLog()
- self._errorDisplay = qui_utils.ErrorDisplay(self._errorLog)
-
self._tabsContents = [
DelayedWidget(self._app, self._TAB_SETTINGS_NAMES[i])
for i in xrange(self.MAX_TABS)
@QtCore.pyqtSlot(str)
@misc_utils.log_exception(_moduleLogger)
def _on_session_error(self, message):
- self._errorLog.push_message(message)
+ with qui_utils.notify_error(self._errorLog):
+ self._errorLog.push_error(message)
@QtCore.pyqtSlot()
@misc_utils.log_exception(_moduleLogger)
def _on_login(self):
- if self._defaultCredentials != self._curentCredentials:
- self._show_account_dialog()
- self._defaultCredentials = self._curentCredentials
- for tab in self._tabsContents:
- tab.enable()
+ with qui_utils.notify_error(self._errorLog):
+ if self._defaultCredentials != self._curentCredentials:
+ self._show_account_dialog()
+ self._defaultCredentials = self._curentCredentials
+ for tab in self._tabsContents:
+ tab.enable()
@QtCore.pyqtSlot()
@misc_utils.log_exception(_moduleLogger)
def _on_logout(self):
- for tab in self._tabsContents:
- tab.disable()
+ with qui_utils.notify_error(self._errorLog):
+ for tab in self._tabsContents:
+ tab.disable()
@QtCore.pyqtSlot()
@misc_utils.log_exception(_moduleLogger)
def _on_recipients_changed(self):
- if self._session.draft.get_num_contacts() == 0:
- return
+ with qui_utils.notify_error(self._errorLog):
+ if self._session.draft.get_num_contacts() == 0:
+ return
- if self._smsEntryDialog is None:
- import dialogs
- self._smsEntryDialog = dialogs.SMSEntryWindow(self.window, self._app, self._session, self._errorLog)
- pass
+ if self._smsEntryDialog is None:
+ import dialogs
+ self._smsEntryDialog = dialogs.SMSEntryWindow(self.window, self._app, self._session, self._errorLog)
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(bool)
@misc_utils.log_exception(_moduleLogger)
def _on_login_requested(self, checked = True):
- self._prompt_for_login()
+ with qui_utils.notify_error(self._errorLog):
+ self._prompt_for_login()
@QtCore.pyqtSlot(int)
@misc_utils.log_exception(_moduleLogger)
def _on_tab_changed(self, index):
- self._currentTab = index
- self._initialize_tab(index)
+ with qui_utils.notify_error(self._errorLog):
+ self._currentTab = index
+ self._initialize_tab(index)
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(bool)
@misc_utils.log_exception(_moduleLogger)
def _on_refresh(self, checked = True):
- self._tabsContents[self._currentTab].refresh(force=True)
+ with qui_utils.notify_error(self._errorLog):
+ self._tabsContents[self._currentTab].refresh(force=True)
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(bool)
@misc_utils.log_exception(_moduleLogger)
def _on_import(self, checked = True):
- csvName = QtGui.QFileDialog.getOpenFileName(self._window, caption="Import", filter="CSV Files (*.csv)")
- if not csvName:
- return
- import shutil
- shutil.copy2(csvName, self._app.fsContactsPath)
- self._tabsContents[self.CONTACTS_TAB].update_addressbooks()
+ with qui_utils.notify_error(self._errorLog):
+ csvName = QtGui.QFileDialog.getOpenFileName(self._window, caption="Import", filter="CSV Files (*.csv)")
+ if not csvName:
+ return
+ import shutil
+ shutil.copy2(csvName, self._app.fsContactsPath)
+ self._tabsContents[self.CONTACTS_TAB].update_addressbooks()
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(bool)
@misc_utils.log_exception(_moduleLogger)
def _on_account(self, checked = True):
- self._show_account_dialog()
+ with qui_utils.notify_error(self._errorLog):
+ self._show_account_dialog()
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(bool)
def _on_about(self, checked = True):
- if self._aboutDialog is None:
- import dialogs
- self._aboutDialog = dialogs.AboutDialog(self._app)
- response = self._aboutDialog.run()
+ with qui_utils.notify_error(self._errorLog):
+ if self._aboutDialog is None:
+ import dialogs
+ self._aboutDialog = dialogs.AboutDialog(self._app)
+ response = self._aboutDialog.run()
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(bool)
self._update_recipients()
def close(self):
- self._dialog.reject()
+ self._window.destroy()
+ self._window = None
def _update_letter_count(self):
count = self._smsEntry.toPlainText().size()
self._smsButton.setVisible(True)
self._dialButton.setVisible(True)
- self._errorLog.push_message(message)
+ self._errorLog.push_error(message)
@QtCore.pyqtSlot()
@misc_utils.log_exception(_moduleLogger)
@misc_utils.log_exception(_moduleLogger)
def _on_keypress(self, key):
- self._entry.insert(key)
+ with qui_utils.notify_error(self._errorLog):
+ self._entry.insert(key)
@misc_utils.log_exception(_moduleLogger)
def _on_backspace(self, toggled = False):
- self._entry.backspace()
+ with qui_utils.notify_error(self._errorLog):
+ self._entry.backspace()
@misc_utils.log_exception(_moduleLogger)
def _on_clear_text(self, toggled = False):
- self._entry.clear()
+ with qui_utils.notify_error(self._errorLog):
+ self._entry.clear()
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(bool)
@misc_utils.log_exception(_moduleLogger)
def _on_sms_clicked(self, checked = False):
- number = misc_utils.make_ugly(str(self._entry.text()))
- self._entry.clear()
+ with qui_utils.notify_error(self._errorLog):
+ number = misc_utils.make_ugly(str(self._entry.text()))
+ self._entry.clear()
- contactId = number
- title = misc_utils.make_pretty(number)
- description = misc_utils.make_pretty(number)
- numbersWithDescriptions = [(number, "")]
- self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
+ contactId = number
+ title = misc_utils.make_pretty(number)
+ description = misc_utils.make_pretty(number)
+ numbersWithDescriptions = [(number, "")]
+ self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(bool)
@misc_utils.log_exception(_moduleLogger)
def _on_call_clicked(self, checked = False):
- number = misc_utils.make_ugly(str(self._entry.text()))
- self._entry.clear()
+ with qui_utils.notify_error(self._errorLog):
+ number = misc_utils.make_ugly(str(self._entry.text()))
+ self._entry.clear()
- contactId = number
- title = misc_utils.make_pretty(number)
- description = misc_utils.make_pretty(number)
- numbersWithDescriptions = [(number, "")]
- self._session.draft.clear()
- self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
- self._session.draft.call()
+ contactId = number
+ title = misc_utils.make_pretty(number)
+ description = misc_utils.make_pretty(number)
+ numbersWithDescriptions = [(number, "")]
+ self._session.draft.clear()
+ self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
+ self._session.draft.call()
class TimeCategories(object):
@QtCore.pyqtSlot(str)
@misc_utils.log_exception(_moduleLogger)
def _on_filter_changed(self, newItem):
- self._selectedFilter = str(newItem)
- self._populate_items()
+ with qui_utils.notify_error(self._errorLog):
+ self._selectedFilter = str(newItem)
+ self._populate_items()
@QtCore.pyqtSlot()
@misc_utils.log_exception(_moduleLogger)
def _on_history_updated(self):
- self._populate_items()
+ with qui_utils.notify_error(self._errorLog):
+ self._populate_items()
@QtCore.pyqtSlot(QtCore.QModelIndex)
@misc_utils.log_exception(_moduleLogger)
def _on_row_activated(self, index):
- timeIndex = index.parent()
- assert timeIndex.isValid()
- timeRow = timeIndex.row()
- row = index.row()
- detailsItem = self._categoryManager.get_item(timeRow, row, self.DETAILS_IDX)
- fromItem = self._categoryManager.get_item(timeRow, row, self.FROM_IDX)
- contactDetails = detailsItem.data().toPyObject()
-
- title = str(fromItem.text())
- number = str(contactDetails[QtCore.QString("number")])
- contactId = number # ids don't seem too unique so using numbers
-
- descriptionRows = []
- for t in xrange(self._itemStore.rowCount()):
- randomTimeItem = self._itemStore.item(t, 0)
- for i in xrange(randomTimeItem.rowCount()):
- iItem = randomTimeItem.child(i, 0)
- iContactDetails = iItem.data().toPyObject()
- iNumber = str(iContactDetails[QtCore.QString("number")])
- if number != iNumber:
- continue
- relTime = misc_utils.abbrev_relative_date(iContactDetails[QtCore.QString("relTime")])
- action = str(iContactDetails[QtCore.QString("action")])
- number = str(iContactDetails[QtCore.QString("number")])
- prettyNumber = misc_utils.make_pretty(number)
- rowItems = relTime, action, prettyNumber
- descriptionRows.append("<tr><td>%s</td></tr>" % "</td><td>".join(rowItems))
- description = "<table>%s</table>" % "".join(descriptionRows)
- numbersWithDescriptions = [(str(contactDetails[QtCore.QString("number")]), "")]
- self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
+ with qui_utils.notify_error(self._errorLog):
+ timeIndex = index.parent()
+ assert timeIndex.isValid()
+ timeRow = timeIndex.row()
+ row = index.row()
+ detailsItem = self._categoryManager.get_item(timeRow, row, self.DETAILS_IDX)
+ fromItem = self._categoryManager.get_item(timeRow, row, self.FROM_IDX)
+ contactDetails = detailsItem.data().toPyObject()
+
+ title = str(fromItem.text())
+ number = str(contactDetails[QtCore.QString("number")])
+ contactId = number # ids don't seem too unique so using numbers
+
+ descriptionRows = []
+ for t in xrange(self._itemStore.rowCount()):
+ randomTimeItem = self._itemStore.item(t, 0)
+ for i in xrange(randomTimeItem.rowCount()):
+ iItem = randomTimeItem.child(i, 0)
+ iContactDetails = iItem.data().toPyObject()
+ iNumber = str(iContactDetails[QtCore.QString("number")])
+ if number != iNumber:
+ continue
+ relTime = misc_utils.abbrev_relative_date(iContactDetails[QtCore.QString("relTime")])
+ action = str(iContactDetails[QtCore.QString("action")])
+ number = str(iContactDetails[QtCore.QString("number")])
+ prettyNumber = misc_utils.make_pretty(number)
+ rowItems = relTime, action, prettyNumber
+ descriptionRows.append("<tr><td>%s</td></tr>" % "</td><td>".join(rowItems))
+ description = "<table>%s</table>" % "".join(descriptionRows)
+ numbersWithDescriptions = [(str(contactDetails[QtCore.QString("number")]), "")]
+ self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
class Messages(object):
@QtCore.pyqtSlot(str)
@misc_utils.log_exception(_moduleLogger)
def _on_type_filter_changed(self, newItem):
- self._selectedTypeFilter = str(newItem)
- self._populate_items()
+ with qui_utils.notify_error(self._errorLog):
+ self._selectedTypeFilter = str(newItem)
+ self._populate_items()
@QtCore.pyqtSlot(str)
@misc_utils.log_exception(_moduleLogger)
def _on_status_filter_changed(self, newItem):
- self._selectedStatusFilter = str(newItem)
- self._populate_items()
+ with qui_utils.notify_error(self._errorLog):
+ self._selectedStatusFilter = str(newItem)
+ self._populate_items()
@QtCore.pyqtSlot()
@misc_utils.log_exception(_moduleLogger)
def _on_messages_updated(self):
- self._populate_items()
+ with qui_utils.notify_error(self._errorLog):
+ self._populate_items()
@QtCore.pyqtSlot(QtCore.QModelIndex)
@misc_utils.log_exception(_moduleLogger)
def _on_row_activated(self, index):
- timeIndex = index.parent()
- assert timeIndex.isValid()
- timeRow = timeIndex.row()
- row = index.row()
- item = self._categoryManager.get_item(timeRow, row, 0)
- contactDetails = item.data().toPyObject()
-
- name = str(contactDetails[QtCore.QString("name")])
- number = str(contactDetails[QtCore.QString("number")])
- if not name or name == number:
- name = str(contactDetails[QtCore.QString("location")])
- if not name:
- name = "Unknown"
-
- contactId = str(contactDetails[QtCore.QString("id")])
- title = name
- description = str(contactDetails[QtCore.QString("expandedMessages")])
- numbersWithDescriptions = [(number, "")]
- self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
+ with qui_utils.notify_error(self._errorLog):
+ timeIndex = index.parent()
+ assert timeIndex.isValid()
+ timeRow = timeIndex.row()
+ row = index.row()
+ item = self._categoryManager.get_item(timeRow, row, 0)
+ contactDetails = item.data().toPyObject()
+
+ name = str(contactDetails[QtCore.QString("name")])
+ number = str(contactDetails[QtCore.QString("number")])
+ if not name or name == number:
+ name = str(contactDetails[QtCore.QString("location")])
+ if not name:
+ name = "Unknown"
+
+ contactId = str(contactDetails[QtCore.QString("id")])
+ title = name
+ description = str(contactDetails[QtCore.QString("expandedMessages")])
+ numbersWithDescriptions = [(number, "")]
+ self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
class Contacts(object):
@QtCore.pyqtSlot(str)
@misc_utils.log_exception(_moduleLogger)
def _on_filter_changed(self, newItem):
- self._activeList = str(newItem)
- self.refresh(force=False)
- self._populate_items()
+ with qui_utils.notify_error(self._errorLog):
+ self._activeList = str(newItem)
+ self.refresh(force=False)
+ self._populate_items()
@QtCore.pyqtSlot()
@misc_utils.log_exception(_moduleLogger)
def _on_contacts_updated(self):
- self._populate_items()
+ with qui_utils.notify_error(self._errorLog):
+ self._populate_items()
@QtCore.pyqtSlot(QtCore.QModelIndex)
@misc_utils.log_exception(_moduleLogger)
def _on_row_activated(self, index):
- letterIndex = index.parent()
- assert letterIndex.isValid()
- letterRow = letterIndex.row()
- letter = list(self._prefixes())[letterRow]
- letterItem = self._alphaItem[letter]
- rowIndex = index.row()
- item = letterItem.child(rowIndex, 0)
- contactDetails = item.data().toPyObject()
-
- name = str(contactDetails[QtCore.QString("name")])
- if not name:
- name = str(contactDetails[QtCore.QString("location")])
- if not name:
- name = "Unknown"
-
- contactId = str(contactDetails[QtCore.QString("contactId")])
- numbers = contactDetails[QtCore.QString("numbers")]
- numbers = [
- dict(
- (str(k), str(v))
- for (k, v) in number.iteritems()
- )
- for number in numbers
- ]
- numbersWithDescriptions = [
- (
- number["phoneNumber"],
- self._choose_phonetype(number),
- )
- for number in numbers
- ]
- title = name
- description = name
- self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
+ with qui_utils.notify_error(self._errorLog):
+ letterIndex = index.parent()
+ assert letterIndex.isValid()
+ letterRow = letterIndex.row()
+ letter = list(self._prefixes())[letterRow]
+ letterItem = self._alphaItem[letter]
+ rowIndex = index.row()
+ item = letterItem.child(rowIndex, 0)
+ contactDetails = item.data().toPyObject()
+
+ name = str(contactDetails[QtCore.QString("name")])
+ if not name:
+ name = str(contactDetails[QtCore.QString("location")])
+ if not name:
+ name = "Unknown"
+
+ contactId = str(contactDetails[QtCore.QString("contactId")])
+ numbers = contactDetails[QtCore.QString("numbers")]
+ numbers = [
+ dict(
+ (str(k), str(v))
+ for (k, v) in number.iteritems()
+ )
+ for number in numbers
+ ]
+ numbersWithDescriptions = [
+ (
+ number["phoneNumber"],
+ self._choose_phonetype(number),
+ )
+ for number in numbers
+ ]
+ title = name
+ description = name
+ self._session.draft.add_contact(contactId, title, description, numbersWithDescriptions)
@staticmethod
def _choose_phonetype(numberDetails):
import os
import time
import datetime
+import contextlib
import logging
try:
_moduleLogger = logging.getLogger(__name__)
+@contextlib.contextmanager
+def notify_busy(log, message):
+ log.push_busy(message)
+ try:
+ yield
+ finally:
+ log.pop(message)
+
+
class _DraftContact(object):
def __init__(self, title, description, numbersWithDescriptions):
recipientsChanged = QtCore.pyqtSignal()
- def __init__(self, pool, backend):
+ def __init__(self, pool, backend, errorLog):
QtCore.QObject.__init__(self)
+ self._errorLog = errorLog
self._contacts = {}
self._pool = pool
self._backend = backend
def _send(self, numbers, text):
self.sendingMessage.emit()
try:
- yield (
- self._backend[0].send_sms,
- (numbers, text),
- {},
- )
+ with notify_busy(self._errorLog, "Sending Text"):
+ yield (
+ self._backend[0].send_sms,
+ (numbers, text),
+ {},
+ )
self.sentMessage.emit()
self.clear()
except Exception, e:
def _call(self, number):
self.calling.emit()
try:
- yield (
- self._backend[0].call,
- (number, ),
- {},
- )
+ with notify_busy(self._errorLog, "Calling"):
+ yield (
+ self._backend[0].call,
+ (number, ),
+ {},
+ )
self.called.emit()
self.clear()
except Exception, e:
def _cancel(self):
self.cancelling.emit()
try:
- yield (
- self._backend[0].cancel,
- (),
- {},
- )
+ with notify_busy(self._errorLog, "Cancelling"):
+ yield (
+ self._backend[0].cancel,
+ (),
+ {},
+ )
self.cancelled.emit()
except Exception, e:
self.error.emit(str(e))
_LOGGEDOUT_TIME = -1
_LOGGINGIN_TIME = 0
- def __init__(self, cachePath = None):
+ def __init__(self, errorLog, cachePath = None):
QtCore.QObject.__init__(self)
+ self._errorLog = errorLog
self._pool = qore_utils.AsyncPool()
self._backend = []
self._loggedInTime = self._LOGGEDOUT_TIME
self._loginOps = []
self._cachePath = cachePath
self._username = None
- self._draft = Draft(self._pool, self._backend)
+ self._draft = Draft(self._pool, self._backend, self._errorLog)
self._contacts = {}
self._contactUpdateTime = datetime.datetime(1971, 1, 1)
assert self.state == self.LOGGEDIN_STATE
oldDnd = self._dnd
try:
- yield (
- self._backend[0].set_dnd,
- (dnd, ),
- {},
- )
+ with notify_busy(self._errorLog, "Setting DND Status"):
+ yield (
+ self._backend[0].set_dnd,
+ (dnd, ),
+ {},
+ )
except Exception, e:
self.error.emit(str(e))
return
assert self.state == self.LOGGEDIN_STATE
oldCallback = self._callback
try:
- yield (
- self._backend[0].set_callback_number,
- (callback, ),
- {},
- )
+ with notify_busy(self._errorLog, "Setting Callback"):
+ yield (
+ self._backend[0].set_callback_number,
+ (callback, ),
+ {},
+ )
except Exception, e:
self.error.emit(str(e))
return
self.callbackNumberChanged.emit(self._callback)
def _login(self, username, password):
- self._loggedInTime = self._LOGGINGIN_TIME
- self.stateChange.emit(self.LOGGINGIN_STATE)
- finalState = self.LOGGEDOUT_STATE
- try:
- isLoggedIn = False
-
- if not isLoggedIn and self._backend[0].is_quick_login_possible():
- isLoggedIn = yield (
- self._backend[0].is_authed,
- (),
- {},
- )
- if isLoggedIn:
- _moduleLogger.info("Logged in through cookies")
- else:
- # Force a clearing of the cookies
- yield (
- self._backend[0].logout,
+ with notify_busy(self._errorLog, "Logging In"):
+ self._loggedInTime = self._LOGGINGIN_TIME
+ self.stateChange.emit(self.LOGGINGIN_STATE)
+ finalState = self.LOGGEDOUT_STATE
+ try:
+ isLoggedIn = False
+
+ if not isLoggedIn and self._backend[0].is_quick_login_possible():
+ isLoggedIn = yield (
+ self._backend[0].is_authed,
(),
{},
)
+ if isLoggedIn:
+ _moduleLogger.info("Logged in through cookies")
+ else:
+ # Force a clearing of the cookies
+ yield (
+ self._backend[0].logout,
+ (),
+ {},
+ )
+
+ if not isLoggedIn:
+ isLoggedIn = yield (
+ self._backend[0].login,
+ (username, password),
+ {},
+ )
+ if isLoggedIn:
+ _moduleLogger.info("Logged in through credentials")
- if not isLoggedIn:
- isLoggedIn = yield (
- self._backend[0].login,
- (username, password),
- {},
- )
if isLoggedIn:
- _moduleLogger.info("Logged in through credentials")
-
- if isLoggedIn:
- self._loggedInTime = int(time.time())
- oldUsername = self._username
- self._username = username
- finalState = self.LOGGEDIN_STATE
- self.loggedIn.emit()
- if oldUsername != self._username:
- needOps = not self._load()
- else:
- needOps = True
- if needOps:
- loginOps = self._loginOps[:]
- else:
- loginOps = []
- del self._loginOps[:]
- for asyncOp in loginOps:
- asyncOp.start()
- except Exception, e:
- self.error.emit(str(e))
- finally:
- self.stateChange.emit(finalState)
+ self._loggedInTime = int(time.time())
+ oldUsername = self._username
+ self._username = username
+ finalState = self.LOGGEDIN_STATE
+ self.loggedIn.emit()
+ if oldUsername != self._username:
+ needOps = not self._load()
+ else:
+ needOps = True
+ if needOps:
+ loginOps = self._loginOps[:]
+ else:
+ loginOps = []
+ del self._loginOps[:]
+ for asyncOp in loginOps:
+ asyncOp.start()
+ except Exception, e:
+ self.error.emit(str(e))
+ finally:
+ self.stateChange.emit(finalState)
def _load(self):
updateContacts = len(self._contacts) != 0
def _update_contacts(self):
try:
- self._contacts = yield (
- self._backend[0].get_contacts,
- (),
- {},
- )
+ with notify_busy(self._errorLog, "Updating Contacts"):
+ self._contacts = yield (
+ self._backend[0].get_contacts,
+ (),
+ {},
+ )
except Exception, e:
self.error.emit(str(e))
return
def _update_messages(self):
try:
- self._messages = yield (
- self._backend[0].get_messages,
- (),
- {},
- )
+ with notify_busy(self._errorLog, "Updating Messages"):
+ self._messages = yield (
+ self._backend[0].get_messages,
+ (),
+ {},
+ )
except Exception, e:
self.error.emit(str(e))
return
def _update_history(self):
try:
- self._history = yield (
- self._backend[0].get_recent,
- (),
- {},
- )
+ with notify_busy(self._errorLog, "Updating History"):
+ self._history = yield (
+ self._backend[0].get_recent,
+ (),
+ {},
+ )
except Exception, e:
self.error.emit(str(e))
return
import sys
+import contextlib
import logging
from PyQt4 import QtCore
_moduleLogger = logging.getLogger(__name__)
+@contextlib.contextmanager
+def notify_error(log):
+ try:
+ yield
+ except:
+ log.push_exception()
+
+
+class ErrorMessage(object):
+
+ LEVEL_BUSY = "busy"
+ LEVEL_INFO = "info"
+ LEVEL_ERROR = "error"
+
+ def __init__(self, message, level):
+ self._message = message
+ self._level = level
+
+ @property
+ def level(self):
+ return self._level
+
+ @property
+ def message(self):
+ return self._message
+
+
class QErrorLog(QtCore.QObject):
messagePushed = QtCore.pyqtSignal()
QtCore.QObject.__init__(self)
self._messages = []
+ def push_busy(self, message):
+ self._push_message(message, ErrorMessage.LEVEL_BUSY)
+
def push_message(self, message):
- self._messages.append(message)
- self.messagePushed.emit()
+ self._push_message(message, ErrorMessage.LEVEL_INFO)
+
+ def push_error(self, message):
+ self._push_message(message, ErrorMessage.LEVEL_ERROR)
def push_exception(self):
userMessage = str(sys.exc_info()[1])
_moduleLogger.exception(userMessage)
- self.push_message(userMessage)
+ self.push_error(userMessage)
- def pop_message(self):
- del self._messages[0]
+ def pop(self, message = None):
+ if message is None:
+ del self._messages[0]
+ else:
+ messageIndex = [
+ i
+ for (i, error) in enumerate(self._messages)
+ if error.message == message
+ ]
+ # Might be removed out of order
+ if messageIndex:
+ del self._messages[messageIndex[0]]
self.messagePopped.emit()
def peek_message(self):
return self._messages[0]
+ def _push_message(self, message, level):
+ self._messages.append(ErrorMessage(message, level))
+ self.messagePushed.emit()
+
def __len__(self):
return len(self._messages)
self._errorLog.messagePushed.connect(self._on_message_pushed)
self._errorLog.messagePopped.connect(self._on_message_popped)
- errorIcon = get_theme_icon(("dialog-error", "app_install_error", "gtk-dialog-error"))
- self._severityIcon = errorIcon.pixmap(32, 32)
+ self._icons = {
+ ErrorMessage.LEVEL_BUSY:
+ get_theme_icon(
+ #("process-working", "gtk-refresh")
+ ("gtk-refresh", )
+ ).pixmap(32, 32),
+ ErrorMessage.LEVEL_INFO:
+ get_theme_icon(
+ ("dialog-information", "general_notes", "gtk-info")
+ ).pixmap(32, 32),
+ ErrorMessage.LEVEL_ERROR:
+ get_theme_icon(
+ ("dialog-error", "app_install_error", "gtk-dialog-error")
+ ).pixmap(32, 32),
+ }
self._severityLabel = QtGui.QLabel()
- self._severityLabel.setPixmap(self._severityIcon)
+ self._severityLabel.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self._message = QtGui.QLabel()
self._message.setText("Boo")
+ self._message.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
closeIcon = get_theme_icon(("window-close", "general_close", "gtk-close"))
self._closeLabel = QtGui.QPushButton(closeIcon, "")
self._closeLabel.clicked.connect(self._on_close)
self._controlLayout = QtGui.QHBoxLayout()
- self._controlLayout.addWidget(self._severityLabel)
- self._controlLayout.addWidget(self._message)
- self._controlLayout.addWidget(self._closeLabel)
+ self._controlLayout.addWidget(self._severityLabel, 1, QtCore.Qt.AlignCenter)
+ self._controlLayout.addWidget(self._message, 1000)
+ self._controlLayout.addWidget(self._closeLabel, 1, QtCore.Qt.AlignCenter)
self._topLevelLayout = QtGui.QHBoxLayout()
self._topLevelLayout.addLayout(self._controlLayout)
@QtCore.pyqtSlot(bool)
@misc.log_exception(_moduleLogger)
def _on_close(self, checked = False):
- self._errorLog.pop_message()
+ self._errorLog.pop()
@QtCore.pyqtSlot()
@misc.log_exception(_moduleLogger)
def _on_message_pushed(self):
if 1 <= len(self._errorLog) and self._widget.isHidden():
- self._message.setText(self._errorLog.peek_message())
+ error = self._errorLog.peek_message()
+ self._message.setText(error.message)
+ self._severityLabel.setPixmap(self._icons[error.level])
self._widget.show()
@QtCore.pyqtSlot()
self._message.setText("")
self._widget.hide()
else:
- self._message.setText(self._errorLog.peek_message())
+ error = self._errorLog.peek_message()
+ self._message.setText(error.message)
+ self._severityLabel.setPixmap(self._icons[error.level])
class QHtmlDelegate(QtGui.QStyledItemDelegate):