X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Futil%2Fqui_utils.py;h=9e33f88fc71d4a99b60280073c13de86e5558dae;hb=842f868e4e0f7d4912699c568d32b1c0f9ef97e1;hp=41ed1bdcc569b23dc756c35acafe1f6ef8f362f2;hpb=dd3eb8b866e2570d0481af86191aae97c38ea863;p=gc-dialer diff --git a/src/util/qui_utils.py b/src/util/qui_utils.py index 41ed1bd..9e33f88 100644 --- a/src/util/qui_utils.py +++ b/src/util/qui_utils.py @@ -1,5 +1,6 @@ import sys import contextlib +import datetime import logging from PyQt4 import QtCore @@ -19,15 +20,25 @@ def notify_error(log): log.push_exception() +@contextlib.contextmanager +def notify_busy(log, message): + log.push_busy(message) + try: + yield + finally: + log.pop(message) + + class ErrorMessage(object): - LEVEL_BUSY = "busy" - LEVEL_INFO = "info" - LEVEL_ERROR = "error" + LEVEL_ERROR = 0 + LEVEL_BUSY = 1 + LEVEL_INFO = 2 def __init__(self, message, level): self._message = message self._level = level + self._time = datetime.datetime.now() @property def level(self): @@ -37,6 +48,9 @@ class ErrorMessage(object): def message(self): return self._message + def __repr__(self): + return "%s.%s(%r, %r)" % (__name__, self.__class__.__name__, self._message, self._level) + class QErrorLog(QtCore.QObject): @@ -48,6 +62,7 @@ class QErrorLog(QtCore.QObject): self._messages = [] def push_busy(self, message): + _moduleLogger.info("Entering state: %s" % message) self._push_message(message, ErrorMessage.LEVEL_BUSY) def push_message(self, message): @@ -65,6 +80,7 @@ class QErrorLog(QtCore.QObject): if message is None: del self._messages[0] else: + _moduleLogger.info("Exiting state: %s" % message) messageIndex = [ i for (i, error) in enumerate(self._messages) @@ -80,6 +96,8 @@ class QErrorLog(QtCore.QObject): def _push_message(self, message, level): self._messages.append(ErrorMessage(message, level)) + # Sort is defined as stable, so this should be fine + self._messages.sort(key=lambda x: x.level) self.messagePushed.emit() def __len__(self): @@ -98,8 +116,8 @@ class ErrorDisplay(object): self._icons = { ErrorMessage.LEVEL_BUSY: get_theme_icon( - #("process-working", "gtk-refresh") - ("gtk-refresh", ) + #("process-working", "view-refresh", "general_refresh", "gtk-refresh") + ("view-refresh", "general_refresh", "gtk-refresh", ) ).pixmap(32, 32), ErrorMessage.LEVEL_INFO: get_theme_icon( @@ -116,6 +134,7 @@ class ErrorDisplay(object): self._message = QtGui.QLabel() self._message.setText("Boo") self._message.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + self._message.setWordWrap(True) closeIcon = get_theme_icon(("window-close", "general_close", "gtk-close"), self._SENTINEL_ICON) if closeIcon is not self._SENTINEL_ICON: @@ -129,16 +148,20 @@ class ErrorDisplay(object): self._controlLayout.addWidget(self._message, 1000) self._controlLayout.addWidget(self._closeLabel, 1, QtCore.Qt.AlignCenter) - self._topLevelLayout = QtGui.QHBoxLayout() - self._topLevelLayout.addLayout(self._controlLayout) self._widget = QtGui.QWidget() - self._widget.setLayout(self._topLevelLayout) + self._widget.setLayout(self._controlLayout) self._widget.hide() @property def toplevel(self): return self._widget + def _show_error(self): + error = self._errorLog.peek_message() + self._message.setText(error.message) + self._severityLabel.setPixmap(self._icons[error.level]) + self._widget.show() + @QtCore.pyqtSlot() @QtCore.pyqtSlot(bool) @misc.log_exception(_moduleLogger) @@ -148,11 +171,7 @@ class ErrorDisplay(object): @QtCore.pyqtSlot() @misc.log_exception(_moduleLogger) def _on_message_pushed(self): - if 1 <= len(self._errorLog) and self._widget.isHidden(): - error = self._errorLog.peek_message() - self._message.setText(error.message) - self._severityLabel.setPixmap(self._icons[error.level]) - self._widget.show() + self._show_error() @QtCore.pyqtSlot() @misc.log_exception(_moduleLogger) @@ -161,14 +180,16 @@ class ErrorDisplay(object): self._message.setText("") self._widget.hide() else: - error = self._errorLog.peek_message() - self._message.setText(error.message) - self._severityLabel.setPixmap(self._icons[error.level]) + self._show_error() class QHtmlDelegate(QtGui.QStyledItemDelegate): - # @bug Not showing all of a message + UNDEFINED_SIZE = -1 + + def __init__(self, *args, **kwd): + QtGui.QStyledItemDelegate.__init__(*((self, ) + args), **kwd) + self._width = self.UNDEFINED_SIZE def paint(self, painter, option, index): newOption = QtGui.QStyleOptionViewItemV4(option) @@ -210,17 +231,55 @@ class QHtmlDelegate(QtGui.QStyledItemDelegate): doc.documentLayout().draw(painter, ctx) painter.restore() + def setWidth(self, width, model): + if self._width == width: + return + self._width = width + for c in xrange(model.rowCount()): + cItem = model.item(c, 0) + for r in xrange(model.rowCount()): + rItem = cItem.child(r, 0) + rIndex = model.indexFromItem(rItem) + self.sizeHintChanged.emit(rIndex) + return + def sizeHint(self, option, index): newOption = QtGui.QStyleOptionViewItemV4(option) self.initStyleOption(newOption, index) doc = QtGui.QTextDocument() doc.setHtml(newOption.text) - doc.setTextWidth(newOption.rect.width()) + if self._width != self.UNDEFINED_SIZE: + width = self._width + else: + width = newOption.rect.width() + doc.setTextWidth(width) size = QtCore.QSize(doc.idealWidth(), doc.size().height()) return size +class QSignalingMainWindow(QtGui.QMainWindow): + + closed = QtCore.pyqtSignal() + hidden = QtCore.pyqtSignal() + shown = QtCore.pyqtSignal() + + def __init__(self, *args, **kwd): + QtGui.QMainWindow.__init__(*((self, )+args), **kwd) + + def closeEvent(self, event): + QtGui.QMainWindow.closeEvent(self, event) + self.closed.emit() + + def hideEvent(self, event): + QtGui.QMainWindow.hideEvent(self, event) + self.hidden.emit() + + def showEvent(self, event): + QtGui.QMainWindow.showEvent(self, event) + self.shown.emit() + + def _null_set_stackable(window, isStackable): pass @@ -241,7 +300,7 @@ def _null_set_autorient(window, isStackable): def _maemo_set_autorient(window, isStackable): - window.setAttribute(QtCore.Qt.WA_Maemo5StackedWindow, isStackable) + window.setAttribute(QtCore.Qt.WA_Maemo5AutoOrientation, isStackable) try: @@ -251,34 +310,35 @@ except AttributeError: set_autorient = _null_set_autorient -def _null_set_landscape(window, isStackable): - pass - - -def _maemo_set_landscape(window, isStackable): - window.setAttribute(QtCore.Qt.WA_Maemo5StackedWindow, isStackable) - - -try: - QtCore.Qt.WA_Maemo5LandscapeOrientation - set_landscape = _maemo_set_landscape -except AttributeError: - set_landscape = _null_set_landscape +def screen_orientation(): + geom = QtGui.QApplication.desktop().screenGeometry() + if geom.width() <= geom.height(): + return QtCore.Qt.Vertical + else: + return QtCore.Qt.Horizontal -def _null_set_portrait(window, isStackable): +def _null_set_window_orientation(window, orientation): pass -def _maemo_set_portrait(window, isStackable): - window.setAttribute(QtCore.Qt.WA_Maemo5StackedWindow, isStackable) +def _maemo_set_window_orientation(window, orientation): + if orientation == QtCore.Qt.Vertical: + oldHint = QtCore.Qt.WA_Maemo5LandscapeOrientation + newHint = QtCore.Qt.WA_Maemo5PortraitOrientation + elif orientation == QtCore.Qt.Horizontal: + oldHint = QtCore.Qt.WA_Maemo5PortraitOrientation + newHint = QtCore.Qt.WA_Maemo5LandscapeOrientation + window.setAttribute(oldHint, False) + window.setAttribute(newHint, True) try: + QtCore.Qt.WA_Maemo5LandscapeOrientation QtCore.Qt.WA_Maemo5PortraitOrientation - set_portrait = _maemo_set_portrait + set_window_orientation = _maemo_set_window_orientation except AttributeError: - set_portrait = _null_set_portrait + set_window_orientation = _null_set_window_orientation def _null_show_progress_indicator(window, isStackable): @@ -286,7 +346,7 @@ def _null_show_progress_indicator(window, isStackable): def _maemo_show_progress_indicator(window, isStackable): - window.setAttribute(QtCore.Qt.WA_Maemo5StackedWindow, isStackable) + window.setAttribute(QtCore.Qt.WA_Maemo5ShowProgressIndicator, isStackable) try: @@ -311,14 +371,6 @@ except AttributeError: mark_numbers_preferred = _null_mark_numbers_preferred -def screen_orientation(): - geom = QtGui.QApplication.desktop().screenGeometry() - if geom.width() <= geom.height(): - return QtCore.Qt.Vertical - else: - return QtCore.Qt.Horizontal - - def _null_get_theme_icon(iconNames, fallback = None): icon = fallback if fallback is not None else QtGui.QIcon() return icon