X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Futil%2Fqui_utils.py;fp=src%2Futil%2Fqui_utils.py;h=0000000000000000000000000000000000000000;hb=18df79328b4665753f6d41d549ab991e060bb39d;hp=11b34536fafa82529e986165ec731d66fc58c8ac;hpb=f68aa1f2965ce6bfe8f76325b44436c826cb68fd;p=gonvert diff --git a/src/util/qui_utils.py b/src/util/qui_utils.py deleted file mode 100644 index 11b3453..0000000 --- a/src/util/qui_utils.py +++ /dev/null @@ -1,419 +0,0 @@ -import sys -import contextlib -import datetime -import logging - -import qt_compat -QtCore = qt_compat.QtCore -QtGui = qt_compat.import_module("QtGui") - -import misc - - -_moduleLogger = logging.getLogger(__name__) - - -@contextlib.contextmanager -def notify_error(log): - try: - yield - except: - log.push_exception() - - -@contextlib.contextmanager -def notify_busy(log, message): - log.push_busy(message) - try: - yield - finally: - log.pop(message) - - -class ErrorMessage(object): - - 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): - return self._level - - @property - 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): - - messagePushed = qt_compat.Signal() - messagePopped = qt_compat.Signal() - - def __init__(self): - QtCore.QObject.__init__(self) - 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): - 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_error(userMessage) - - def pop(self, message = None): - if message is None: - del self._messages[0] - else: - _moduleLogger.info("Exiting state: %s" % message) - 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)) - # Sort is defined as stable, so this should be fine - self._messages.sort(key=lambda x: x.level) - self.messagePushed.emit() - - def __len__(self): - return len(self._messages) - - -class ErrorDisplay(object): - - _SENTINEL_ICON = QtGui.QIcon() - - def __init__(self, errorLog): - self._errorLog = errorLog - self._errorLog.messagePushed.connect(self._on_message_pushed) - self._errorLog.messagePopped.connect(self._on_message_popped) - - self._icons = None - self._severityLabel = QtGui.QLabel() - 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) - self._message.setWordWrap(True) - - self._closeLabel = None - - self._controlLayout = QtGui.QHBoxLayout() - self._controlLayout.addWidget(self._severityLabel, 1, QtCore.Qt.AlignCenter) - self._controlLayout.addWidget(self._message, 1000) - - self._widget = QtGui.QWidget() - self._widget.setLayout(self._controlLayout) - self._widget.hide() - - @property - def toplevel(self): - return self._widget - - def _show_error(self): - if self._icons is None: - self._icons = { - ErrorMessage.LEVEL_BUSY: - get_theme_icon( - #("process-working", "view-refresh", "general_refresh", "gtk-refresh") - ("view-refresh", "general_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), - } - if self._closeLabel is None: - closeIcon = get_theme_icon(("window-close", "general_close", "gtk-close"), self._SENTINEL_ICON) - if closeIcon is not self._SENTINEL_ICON: - self._closeLabel = QtGui.QPushButton(closeIcon, "") - else: - self._closeLabel = QtGui.QPushButton("X") - self._closeLabel.clicked.connect(self._on_close) - self._controlLayout.addWidget(self._closeLabel, 1, QtCore.Qt.AlignCenter) - error = self._errorLog.peek_message() - self._message.setText(error.message) - self._severityLabel.setPixmap(self._icons[error.level]) - self._widget.show() - - @qt_compat.Slot() - @qt_compat.Slot(bool) - @misc.log_exception(_moduleLogger) - def _on_close(self, checked = False): - self._errorLog.pop() - - @qt_compat.Slot() - @misc.log_exception(_moduleLogger) - def _on_message_pushed(self): - self._show_error() - - @qt_compat.Slot() - @misc.log_exception(_moduleLogger) - def _on_message_popped(self): - if len(self._errorLog) == 0: - self._message.setText("") - self._widget.hide() - else: - self._show_error() - - -class QHtmlDelegate(QtGui.QStyledItemDelegate): - - 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) - self.initStyleOption(newOption, index) - if newOption.widget is not None: - style = newOption.widget.style() - else: - style = QtGui.QApplication.style() - - doc = QtGui.QTextDocument() - doc.setHtml(newOption.text) - doc.setTextWidth(newOption.rect.width()) - - newOption.text = "" - style.drawControl(QtGui.QStyle.CE_ItemViewItem, newOption, painter) - - ctx = QtGui.QAbstractTextDocumentLayout.PaintContext() - if newOption.state & QtGui.QStyle.State_Selected: - ctx.palette.setColor( - QtGui.QPalette.Text, - newOption.palette.color( - QtGui.QPalette.Active, - QtGui.QPalette.HighlightedText - ) - ) - else: - ctx.palette.setColor( - QtGui.QPalette.Text, - newOption.palette.color( - QtGui.QPalette.Active, - QtGui.QPalette.Text - ) - ) - - textRect = style.subElementRect(QtGui.QStyle.SE_ItemViewItemText, newOption) - painter.save() - painter.translate(textRect.topLeft()) - painter.setClipRect(textRect.translated(-textRect.topLeft())) - 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) - 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 = qt_compat.Signal() - hidden = qt_compat.Signal() - shown = qt_compat.Signal() - resized = qt_compat.Signal() - - def __init__(self, *args, **kwd): - QtGui.QMainWindow.__init__(*((self, )+args), **kwd) - - def closeEvent(self, event): - val = QtGui.QMainWindow.closeEvent(self, event) - self.closed.emit() - return val - - def hideEvent(self, event): - val = QtGui.QMainWindow.hideEvent(self, event) - self.hidden.emit() - return val - - def showEvent(self, event): - val = QtGui.QMainWindow.showEvent(self, event) - self.shown.emit() - return val - - def resizeEvent(self, event): - val = QtGui.QMainWindow.resizeEvent(self, event) - self.resized.emit() - return val - -def set_current_index(selector, itemText, default = 0): - for i in xrange(selector.count()): - if selector.itemText(i) == itemText: - selector.setCurrentIndex(i) - break - else: - itemText.setCurrentIndex(default) - - -def _null_set_stackable(window, isStackable): - pass - - -def _maemo_set_stackable(window, isStackable): - window.setAttribute(QtCore.Qt.WA_Maemo5StackedWindow, isStackable) - - -try: - QtCore.Qt.WA_Maemo5StackedWindow - set_stackable = _maemo_set_stackable -except AttributeError: - set_stackable = _null_set_stackable - - -def _null_set_autorient(window, doAutoOrient): - pass - - -def _maemo_set_autorient(window, doAutoOrient): - window.setAttribute(QtCore.Qt.WA_Maemo5AutoOrientation, doAutoOrient) - - -try: - QtCore.Qt.WA_Maemo5AutoOrientation - set_autorient = _maemo_set_autorient -except AttributeError: - set_autorient = _null_set_autorient - - -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_window_orientation(window, orientation): - pass - - -def _maemo_set_window_orientation(window, orientation): - if orientation == QtCore.Qt.Vertical: - window.setAttribute(QtCore.Qt.WA_Maemo5LandscapeOrientation, False) - window.setAttribute(QtCore.Qt.WA_Maemo5PortraitOrientation, True) - elif orientation == QtCore.Qt.Horizontal: - window.setAttribute(QtCore.Qt.WA_Maemo5LandscapeOrientation, True) - window.setAttribute(QtCore.Qt.WA_Maemo5PortraitOrientation, False) - elif orientation is None: - window.setAttribute(QtCore.Qt.WA_Maemo5LandscapeOrientation, False) - window.setAttribute(QtCore.Qt.WA_Maemo5PortraitOrientation, False) - else: - raise RuntimeError("Unknown orientation: %r" % orientation) - - -try: - QtCore.Qt.WA_Maemo5LandscapeOrientation - QtCore.Qt.WA_Maemo5PortraitOrientation - set_window_orientation = _maemo_set_window_orientation -except AttributeError: - set_window_orientation = _null_set_window_orientation - - -def _null_show_progress_indicator(window, isStackable): - pass - - -def _maemo_show_progress_indicator(window, isStackable): - window.setAttribute(QtCore.Qt.WA_Maemo5ShowProgressIndicator, isStackable) - - -try: - QtCore.Qt.WA_Maemo5ShowProgressIndicator - show_progress_indicator = _maemo_show_progress_indicator -except AttributeError: - show_progress_indicator = _null_show_progress_indicator - - -def _null_mark_numbers_preferred(widget): - pass - - -def _newqt_mark_numbers_preferred(widget): - widget.setInputMethodHints(QtCore.Qt.ImhPreferNumbers) - - -try: - QtCore.Qt.ImhPreferNumbers - mark_numbers_preferred = _newqt_mark_numbers_preferred -except AttributeError: - mark_numbers_preferred = _null_mark_numbers_preferred - - -def _null_get_theme_icon(iconNames, fallback = None): - icon = fallback if fallback is not None else QtGui.QIcon() - return icon - - -def _newqt_get_theme_icon(iconNames, fallback = None): - for iconName in iconNames: - if QtGui.QIcon.hasThemeIcon(iconName): - icon = QtGui.QIcon.fromTheme(iconName) - break - else: - icon = fallback if fallback is not None else QtGui.QIcon() - return icon - - -try: - QtGui.QIcon.fromTheme - get_theme_icon = _newqt_get_theme_icon -except AttributeError: - get_theme_icon = _null_get_theme_icon -