def process_duplicates(self, db, duplicates): ta = _('%(title)s by %(author)s') bf = QFont(self.dup_list.font()) bf.setBold(True) itf = QFont(self.dup_list.font()) itf.setItalic(True) for mi, cover, formats in duplicates: item = QTreeWidgetItem([ta%dict( title=mi.title, author=mi.format_field('authors')[1])] , 0) item.setCheckState(0, Qt.Checked) item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable) item.setData(0, Qt.FontRole, bf) item.setData(0, Qt.UserRole, (mi, cover, formats)) matching_books = db.books_with_same_title(mi) def add_child(text): c = QTreeWidgetItem([text], 1) c.setFlags(Qt.ItemIsEnabled) item.addChild(c) return c add_child(_('Already in calibre:')).setData(0, Qt.FontRole, itf) for book_id in matching_books: aut = [a.replace('|', ',') for a in (db.authors(book_id, index_is_id=True) or '').split(',')] add_child(ta%dict( title=db.title(book_id, index_is_id=True), author=authors_to_string(aut))) add_child('') yield item
def paint_line_numbers(self, ev): painter = QPainter(self.line_number_area) painter.fillRect(ev.rect(), self.line_number_palette.color(QPalette.Base)) block = self.firstVisibleBlock() num = block.blockNumber() top = int(self.blockBoundingGeometry(block).translated(self.contentOffset()).top()) bottom = top + int(self.blockBoundingRect(block).height()) current = self.textCursor().block().blockNumber() painter.setPen(self.line_number_palette.color(QPalette.Text)) while block.isValid() and top <= ev.rect().bottom(): if block.isVisible() and bottom >= ev.rect().top(): if current == num: painter.save() painter.setPen(self.line_number_palette.color(QPalette.BrightText)) f = QFont(self.font()) f.setBold(True) painter.setFont(f) self.last_current_lnum = (top, bottom - top) painter.drawText(0, top, self.line_number_area.width() - 5, self.fontMetrics().height(), Qt.AlignRight, str(num + 1)) if current == num: painter.restore() block = block.next() top = bottom bottom = top + int(self.blockBoundingRect(block).height()) num += 1
def paint_line_numbers(self, ev): painter = QPainter(self.line_number_area) painter.fillRect(ev.rect(), self.line_number_palette.color(QPalette.Base)) block = self.firstVisibleBlock() num = block.blockNumber() top = int( self.blockBoundingGeometry(block).translated( self.contentOffset()).top()) bottom = top + int(self.blockBoundingRect(block).height()) current = self.textCursor().block().blockNumber() painter.setPen(self.line_number_palette.color(QPalette.Text)) while block.isValid() and top <= ev.rect().bottom(): if block.isVisible() and bottom >= ev.rect().top(): if current == num: painter.save() painter.setPen( self.line_number_palette.color(QPalette.BrightText)) f = QFont(self.font()) f.setBold(True) painter.setFont(f) self.last_current_lnum = (top, bottom - top) painter.drawText(0, top, self.line_number_area.width() - 5, self.fontMetrics().height(), Qt.AlignRight, str(num + 1)) if current == num: painter.restore() block = block.next() top = bottom bottom = top + int(self.blockBoundingRect(block).height()) num += 1
def capture_clicked(self, which=1): self.capture = which button = getattr(self, 'button%d' % which) button.setText(_('Press a key...')) button.setFocus(Qt.OtherFocusReason) font = QFont() font.setBold(True) button.setFont(font)
def _initFonts(): """Initializes fonts on fitrst call""" if SkyModelTreeWidgetItem._fonts is None: stdfont = QApplication.font() boldfont = QFont(stdfont) boldfont.setBold(True) SkyModelTreeWidgetItem._fonts = [stdfont, boldfont] SkyModelTreeWidgetItem._fontmetrics = QFontMetrics(boldfont)
def getLabelFont(self, isBold=False): """ Returns the font for the labels in the grid """ # Font for labels. labelFont = QFont(self.font()) labelFont.setBold(False) return labelFont
def getLabelFont(self, isBold = False): """ Returns the font for the labels in the grid """ # Font for labels. labelFont = QFont(self.font()) labelFont.setBold(False) return labelFont
def _getFontForTextNearCursor(self, fontSize = 10, isBold = False): """ Returns the font for text near the cursor. @see: self.renderTextNearCursor """ font = QFont("Arial", fontSize) font.setBold(isBold) return font
class HeaderView(QHeaderView): # {{{ def __init__(self, *args): QHeaderView.__init__(self, *args) self.hover = -1 self.current_font = QFont(self.font()) self.current_font.setBold(True) self.current_font.setItalic(True) def event(self, e): if e.type() in (e.HoverMove, e.HoverEnter): self.hover = self.logicalIndexAt(e.pos()) elif e.type() in (e.Leave, e.HoverLeave): self.hover = -1 return QHeaderView.event(self, e) def paintSection(self, painter, rect, logical_index): opt = QStyleOptionHeader() self.initStyleOption(opt) opt.rect = rect opt.section = logical_index opt.orientation = self.orientation() opt.textAlignment = Qt.AlignHCenter | Qt.AlignVCenter model = self.parent().model() opt.text = model.headerData(logical_index, opt.orientation, Qt.DisplayRole).toString() if self.isSortIndicatorShown() and self.sortIndicatorSection( ) == logical_index: opt.sortIndicator = QStyleOptionHeader.SortDown if self.sortIndicatorOrder( ) == Qt.AscendingOrder else QStyleOptionHeader.SortUp opt.text = opt.fontMetrics.elidedText(opt.text, Qt.ElideRight, rect.width() - 4) if self.isEnabled(): opt.state |= QStyle.State_Enabled if self.window().isActiveWindow(): opt.state |= QStyle.State_Active if self.hover == logical_index: opt.state |= QStyle.State_MouseOver sm = self.selectionModel() if opt.orientation == Qt.Vertical: try: opt.icon = model.headerData(logical_index, opt.orientation, Qt.DecorationRole) opt.iconAlignment = Qt.AlignVCenter except (IndexError, ValueError, TypeError): pass if sm.isRowSelected(logical_index, QModelIndex()): opt.state |= QStyle.State_Sunken painter.save() if ((opt.orientation == Qt.Horizontal and sm.currentIndex().column() == logical_index) or (opt.orientation == Qt.Vertical and sm.currentIndex().row() == logical_index)): painter.setFont(self.current_font) self.style().drawControl(QStyle.CE_Header, opt, painter, self) painter.restore()
def paintEvent(self, ev): # We do it like this so that the popup uses a normal font if self.emphasize: ofont = self.font() f = QFont(ofont) f.setBold(True), f.setItalic(True) self.setFont(f) QComboBox.paintEvent(self, ev) if self.emphasize: self.setFont(ofont)
def set_preferred_country(self): item = self.dictionaries.currentItem() bf = QFont(self.dictionaries.font()) bf.setBold(True) for x in (item.parent().child(i) for i in xrange(item.parent().childCount())): x.setData(0, Qt.FontRole, bf if x is item else None) lc = unicode(item.parent().data(0, Qt.UserRole).toPyObject()) pl = dprefs['preferred_locales'] pl[lc] = '%s-%s' % (lc, unicode(item.data(0, Qt.UserRole).toPyObject())) dprefs['preferred_locales'] = pl
def set_window_title(self): db = self.current_db restrictions = [x for x in (db.data.get_base_restriction_name(), db.data.get_search_restriction_name()) if x] restrictions = " :: ".join(restrictions) font = QFont() if restrictions: restrictions = " :: " + restrictions font.setBold(True) font.setItalic(True) self.virtual_library.setFont(font) title = u"{0} - || {1}{2} ||".format(__appname__, self.iactions["Choose Library"].library_name(), restrictions) self.setWindowTitle(title)
def _getHeaderFont(self): """ Returns the font used for the header. @return: the header font @rtype: QFont """ font = QFont() font.setFamily(PM_HEADER_FONT) font.setPointSize(PM_HEADER_FONT_POINT_SIZE) font.setBold(PM_HEADER_FONT_BOLD) return font
def getButtonFont(self): """ Returns the font for the tool buttons in the grid. @return: Button font. @rtype: U{B{QFont}<http://doc.trolltech.com/4/qfont.html>} """ # Font for tool buttons. buttonFont = QFont(self.font()) buttonFont.setFamily(BUTTON_FONT) buttonFont.setPointSize(BUTTON_FONT_POINT_SIZE) buttonFont.setBold(BUTTON_FONT_BOLD) return buttonFont
class StatusBar(QStatusBar): # {{{ def __init__(self, parent=None): QStatusBar.__init__(self, parent) self.default_message = __appname__ + ' ' + _('version') + ' ' + \ __version__ + ' ' + _('created by Kovid Goyal') self.device_string = '' self._font = QFont() self._font.setBold(True) self.setFont(self._font) self.w = QLabel(self.default_message) self.w.setFont(self._font) self.addWidget(self.w)
class HeaderView(QHeaderView): # {{{ def __init__(self, *args): QHeaderView.__init__(self, *args) self.hover = -1 self.current_font = QFont(self.font()) self.current_font.setBold(True) self.current_font.setItalic(True) def event(self, e): if e.type() in (e.HoverMove, e.HoverEnter): self.hover = self.logicalIndexAt(e.pos()) elif e.type() in (e.Leave, e.HoverLeave): self.hover = -1 return QHeaderView.event(self, e) def paintSection(self, painter, rect, logical_index): opt = QStyleOptionHeader() self.initStyleOption(opt) opt.rect = rect opt.section = logical_index opt.orientation = self.orientation() opt.textAlignment = Qt.AlignHCenter | Qt.AlignVCenter model = self.parent().model() opt.text = model.headerData(logical_index, opt.orientation, Qt.DisplayRole).toString() if self.isSortIndicatorShown() and self.sortIndicatorSection() == logical_index: opt.sortIndicator = QStyleOptionHeader.SortDown if self.sortIndicatorOrder() == Qt.AscendingOrder else QStyleOptionHeader.SortUp opt.text = opt.fontMetrics.elidedText(opt.text, Qt.ElideRight, rect.width() - 4) if self.isEnabled(): opt.state |= QStyle.State_Enabled if self.window().isActiveWindow(): opt.state |= QStyle.State_Active if self.hover == logical_index: opt.state |= QStyle.State_MouseOver sm = self.selectionModel() if opt.orientation == Qt.Vertical: try: opt.icon = model.headerData(logical_index, opt.orientation, Qt.DecorationRole) opt.iconAlignment = Qt.AlignVCenter except TypeError: pass if sm.isRowSelected(logical_index, QModelIndex()): opt.state |= QStyle.State_Sunken painter.save() if ( (opt.orientation == Qt.Horizontal and sm.currentIndex().column() == logical_index) or (opt.orientation == Qt.Vertical and sm.currentIndex().row() == logical_index)): painter.setFont(self.current_font) self.style().drawControl(QStyle.CE_Header, opt, painter, self) painter.restore()
def set_window_title(self): db = self.current_db restrictions = [x for x in (db.data.get_base_restriction_name(), db.data.get_search_restriction_name()) if x] restrictions = ' :: '.join(restrictions) font = QFont() if restrictions: restrictions = ' :: ' + restrictions font.setBold(True) font.setItalic(True) self.virtual_library.setFont(font) title = u'{0} - || {1}{2} ||'.format( __appname__, self.iactions['Choose Library'].library_name(), restrictions) self.setWindowTitle(title)
def data(self, index, role): try: widget = self.widgets[index.row()] except: return NONE if role == Qt.DisplayRole: return QVariant(widget.config_title()) if role == Qt.DecorationRole: return QVariant(widget.config_icon()) if role == Qt.FontRole: f = QFont() f.setBold(True) return QVariant(f) return NONE
def setBold(self, isBold=True): """ Sets or unsets font of all labels in this widget to bold @param isBold: If true, sets the font of all labels in the widget to bold. @type isBold: bool @see: B{MovePropertyManager.updateRotationDeltaLabels} for an example on how this function is used. """ for label in self.labels: font = QFont(label.font()) font.setBold(isBold) label.setFont(font)
def setBold(self, isBold = True): """ Sets or unsets font of all labels in this widget to bold @param isBold: If true, sets the font of all labels in the widget to bold. @type isBold: bool @see: B{MovePropertyManager.updateRotationDeltaLabels} for an example on how this function is used. """ for label in self.labels: font = QFont(label.font()) font.setBold(isBold) label.setFont(font)
class StatusBar(QStatusBar): # {{{ def __init__(self, parent=None): QStatusBar.__init__(self, parent) self.default_message = __appname__ + ' ' + _('version') + ' ' + \ self.get_version() + ' ' + _('created by Kovid Goyal') self.device_string = '' self.update_label = UpdateLabel('') self.addPermanentWidget(self.update_label) self.update_label.setVisible(False) self._font = QFont() self._font.setBold(True) self.setFont(self._font) self.defmsg = QLabel(self.default_message) self.defmsg.setFont(self._font) self.addWidget(self.defmsg) def initialize(self, systray=None): self.systray = systray self.notifier = get_notifier(systray) def device_connected(self, devname): self.device_string = _('Connected ') + devname self.defmsg.setText(self.default_message + ' ..::.. ' + self.device_string) self.clearMessage() def device_disconnected(self): self.device_string = '' self.defmsg.setText(self.default_message) self.clearMessage() def get_version(self): return get_version() def show_message(self, msg, timeout=0): self.showMessage(msg, timeout) if self.notifier is not None and not config['disable_tray_notification']: if isosx and isinstance(msg, unicode): try: msg = msg.encode(preferred_encoding) except UnicodeEncodeError: msg = msg.encode('utf-8') self.notifier(msg) def clear_message(self): self.clearMessage()
def process_duplicates(self, db, duplicates): ta = _('%(title)s by %(author)s [%(formats)s]') bf = QFont(self.dup_list.font()) bf.setBold(True) itf = QFont(self.dup_list.font()) itf.setItalic(True) for mi, cover, formats in duplicates: # formats is a list of file paths # Grab just the extension and display to the user # Based only off the file name, no file type tests are done. incoming_formats = ', '.join( os.path.splitext(path)[-1].replace('.', '').upper() for path in formats) item = QTreeWidgetItem([ ta % dict(title=mi.title, author=mi.format_field('authors')[1], formats=incoming_formats) ], 0) item.setCheckState(0, Qt.Checked) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) item.setData(0, Qt.FontRole, bf) item.setData(0, Qt.UserRole, (mi, cover, formats)) matching_books = db.books_with_same_title(mi) def add_child(text): c = QTreeWidgetItem([text], 1) c.setFlags(Qt.ItemIsEnabled) item.addChild(c) return c add_child(_('Already in calibre:')).setData(0, Qt.FontRole, itf) for book_id in matching_books: aut = [ a.replace('|', ',') for a in ( db.authors(book_id, index_is_id=True) or '').split(',') ] add_child( ta % dict(title=db.title(book_id, index_is_id=True), author=authors_to_string(aut), formats=db.formats( book_id, index_is_id=True, verify_formats=False))) add_child('') yield item
class StatusBar(QStatusBar): # {{{ def __init__(self, parent=None): QStatusBar.__init__(self, parent) self.default_message = __appname__ + ' ' + _('version') + ' ' + \ self.get_version() + ' ' + _('created by Kovid Goyal') self.device_string = '' self.update_label = UpdateLabel('') self.addPermanentWidget(self.update_label) self.update_label.setVisible(False) self._font = QFont() self._font.setBold(True) self.setFont(self._font) self.defmsg = QLabel(self.default_message) self.defmsg.setFont(self._font) self.addWidget(self.defmsg) def initialize(self, systray=None): self.systray = systray self.notifier = get_notifier(systray) def device_connected(self, devname): self.device_string = _('Connected ') + devname self.defmsg.setText(self.default_message + ' ..::.. ' + self.device_string) self.clearMessage() def device_disconnected(self): self.device_string = '' self.defmsg.setText(self.default_message) self.clearMessage() def get_version(self): return get_version() def show_message(self, msg, timeout=0): self.showMessage(msg, timeout) if self.notifier is not None and not config[ 'disable_tray_notification']: if isosx and isinstance(msg, unicode): try: msg = msg.encode(preferred_encoding) except UnicodeEncodeError: msg = msg.encode('utf-8') self.notifier(msg) def clear_message(self): self.clearMessage()
def paint_line_numbers(self, ev): painter = QPainter(self.line_number_area) painter.fillRect(ev.rect(), self.line_number_palette.color(QPalette.Base)) block = self.firstVisibleBlock() num = block.blockNumber() top = int( self.blockBoundingGeometry(block).translated( self.contentOffset()).top()) bottom = top + int(self.blockBoundingRect(block).height()) painter.setPen(self.line_number_palette.color(QPalette.Text)) change_starts = {x[0] for x in self.changes} while block.isValid() and top <= ev.rect().bottom(): r = ev.rect() if block.isVisible() and bottom >= r.top(): text = unicode(self.line_number_map.get(num, '')) is_start = text != '-' and num in change_starts if is_start: painter.save() f = QFont(self.font()) f.setBold(True) painter.setFont(f) painter.setPen( self.line_number_palette.color(QPalette.BrightText)) if text == '-': painter.drawLine(r.left() + 2, (top + bottom) // 2, r.right() - 2, (top + bottom) // 2) else: if self.right: painter.drawText(r.left() + 3, top, r.right(), self.fontMetrics().height(), Qt.AlignLeft, text) else: painter.drawText(r.left() + 2, top, r.right() - 5, self.fontMetrics().height(), Qt.AlignRight, text) if is_start: painter.restore() block = block.next() top = bottom bottom = top + int(self.blockBoundingRect(block).height()) num += 1
class Category(QWidget): # {{{ plugin_activated = pyqtSignal(object) def __init__(self, name, plugins, gui_name, parent=None): QWidget.__init__(self, parent) self._layout = QVBoxLayout() self.setLayout(self._layout) self.label = QLabel(gui_name) self.sep = QFrame(self) self.bf = QFont() self.bf.setBold(True) self.label.setFont(self.bf) self.sep.setFrameShape(QFrame.HLine) self._layout.addWidget(self.label) self._layout.addWidget(self.sep) self.plugins = plugins self.bar = QToolBar(self) self.bar.setStyleSheet( 'QToolBar { border: none; background: none }') self.bar.setIconSize(QSize(32, 32)) self.bar.setMovable(False) self.bar.setFloatable(False) self.bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self._layout.addWidget(self.bar) self.actions = [] for p in plugins: target = partial(self.triggered, p) ac = self.bar.addAction(QIcon(p.icon), p.gui_name, target) ac.setToolTip(textwrap.fill(p.description)) ac.setWhatsThis(textwrap.fill(p.description)) ac.setStatusTip(p.description) self.actions.append(ac) w = self.bar.widgetForAction(ac) w.setCursor(Qt.PointingHandCursor) w.setAutoRaise(True) w.setMinimumWidth(100) def triggered(self, plugin, *args): self.plugin_activated.emit(plugin)
def process_duplicates(self, db, duplicates): ta = _('%(title)s by %(author)s [%(formats)s]') bf = QFont(self.dup_list.font()) bf.setBold(True) itf = QFont(self.dup_list.font()) itf.setItalic(True) for mi, cover, formats in duplicates: # formats is a list of file paths # Grab just the extension and display to the user # Based only off the file name, no file type tests are done. incoming_formats = ', '.join(os.path.splitext(path)[-1].replace('.', '').upper() for path in formats) item = QTreeWidgetItem([ta%dict( title=mi.title, author=mi.format_field('authors')[1], formats=incoming_formats)] , 0) item.setCheckState(0, Qt.Checked) item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable) item.setData(0, Qt.FontRole, bf) item.setData(0, Qt.UserRole, (mi, cover, formats)) matching_books = db.books_with_same_title(mi) def add_child(text): c = QTreeWidgetItem([text], 1) c.setFlags(Qt.ItemIsEnabled) item.addChild(c) return c add_child(_('Already in calibre:')).setData(0, Qt.FontRole, itf) for book_id in matching_books: aut = [a.replace('|', ',') for a in (db.authors(book_id, index_is_id=True) or '').split(',')] add_child(ta%dict( title=db.title(book_id, index_is_id=True), author=authors_to_string(aut), formats=db.formats(book_id, index_is_id=True, verify_formats=False))) add_child('') yield item
def data(self, index, role): row = index.row() try: tweak = self.tweaks[row] except: return NONE if role == Qt.DisplayRole: return textwrap.fill(tweak.name, 40) if role == Qt.FontRole and tweak.is_customized: ans = QFont() ans.setBold(True) return ans if role == Qt.ToolTipRole: tt = _('This tweak has it default value') if tweak.is_customized: tt = '<p>'+_('This tweak has been customized') tt += '<pre>' for varn, val in tweak.custom_values.iteritems(): tt += '%s = %r\n\n'%(varn, val) return textwrap.fill(tt) if role == Qt.UserRole: return tweak return NONE
def data(self, index, role): row = index.row() try: tweak = self.tweaks[row] except: return NONE if role == Qt.DisplayRole: return textwrap.fill(tweak.name, 40) if role == Qt.FontRole and tweak.is_customized: ans = QFont() ans.setBold(True) return ans if role == Qt.ToolTipRole: tt = _('This tweak has it default value') if tweak.is_customized: tt = '<p>'+_('This tweak has been customized') tt += '<pre>' for varn, val in tweak.custom_values.iteritems(): tt += '%s = %r\n\n'%(varn, val) return tt if role == Qt.UserRole: return tweak return NONE
def paint_line_numbers(self, ev): painter = QPainter(self.line_number_area) painter.fillRect(ev.rect(), self.line_number_palette.color(QPalette.Base)) block = self.firstVisibleBlock() num = block.blockNumber() top = int(self.blockBoundingGeometry(block).translated(self.contentOffset()).top()) bottom = top + int(self.blockBoundingRect(block).height()) painter.setPen(self.line_number_palette.color(QPalette.Text)) change_starts = {x[0] for x in self.changes} while block.isValid() and top <= ev.rect().bottom(): r = ev.rect() if block.isVisible() and bottom >= r.top(): text = unicode(self.line_number_map.get(num, '')) is_start = text != '-' and num in change_starts if is_start: painter.save() f = QFont(self.font()) f.setBold(True) painter.setFont(f) painter.setPen(self.line_number_palette.color(QPalette.BrightText)) if text == '-': painter.drawLine(r.left() + 2, (top + bottom)//2, r.right() - 2, (top + bottom)//2) else: if self.right: painter.drawText(r.left() + 3, top, r.right(), self.fontMetrics().height(), Qt.AlignLeft, text) else: painter.drawText(r.left() + 2, top, r.right() - 5, self.fontMetrics().height(), Qt.AlignRight, text) if is_start: painter.restore() block = block.next() top = bottom bottom = top + int(self.blockBoundingRect(block).height()) num += 1
def build_dictionaries(self, reread=False): all_dictionaries = builtin_dictionaries() | custom_dictionaries(reread=reread) languages = defaultdict(lambda : defaultdict(set)) for d in all_dictionaries: for locale in d.locales | {d.primary_locale}: languages[locale.langcode][locale.countrycode].add(d) bf = QFont(self.dictionaries.font()) bf.setBold(True) itf = QFont(self.dictionaries.font()) itf.setItalic(True) self.dictionaries.clear() for lc in sorted(languages, key=lambda x:sort_key(calibre_langcode_to_name(x))): i = QTreeWidgetItem(self.dictionaries, LANG) i.setText(0, calibre_langcode_to_name(lc)) i.setData(0, Qt.UserRole, lc) best_country = getattr(best_locale_for_language(lc), 'countrycode', None) for countrycode in sorted(languages[lc], key=lambda x: country_map()['names'].get(x, x)): j = QTreeWidgetItem(i, COUNTRY) j.setText(0, country_map()['names'].get(countrycode, countrycode)) j.setData(0, Qt.UserRole, countrycode) if countrycode == best_country: j.setData(0, Qt.FontRole, bf) pd = get_dictionary(DictionaryLocale(lc, countrycode)) for dictionary in sorted(languages[lc][countrycode], key=lambda d:d.name): k = QTreeWidgetItem(j, DICTIONARY) pl = calibre_langcode_to_name(dictionary.primary_locale.langcode) if dictionary.primary_locale.countrycode: pl += '-' + dictionary.primary_locale.countrycode.upper() k.setText(0, dictionary.name or (_('<Builtin dictionary for {0}>').format(pl))) k.setData(0, Qt.UserRole, dictionary) if dictionary.name: k.setFlags(k.flags() | Qt.ItemIsEditable) if pd == dictionary: k.setData(0, Qt.FontRole, itf) self.dictionaries.expandAll()
class VoivoiShow(Slide): ''' VoiVoi Slideshow class for displaying images from voivoi database ''' imgList = list() eventID = 0 mostRecent = datetime.fromtimestamp(0) host = "127.0.0.1" user = "******" passwd = "secret" db = "voivoi" def __init__(self, parent = None): ''' Constructor ''' super(VoivoiShow, self).__init__(parent) #self.setStyleSheet("background: #000;") self.splashscreen = QImage("res/splashscreen.jpg") #print(self.splashscreen.isNull()) if not self.splashscreen.isNull(): self.imgList.append(self.splashscreen) self.imageLabel = QLabel() self.imageLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imageLabel.setParent(self) self.httpPool = urllib3.PoolManager() self.slideIterator = 0 self.timer.timeout.connect(self.nextImage) self.updateTimer = QTimer() self.updateTimer.timeout.connect(self.updateImages) self.mostRecent = datetime.fromtimestamp(0) self.layout = QHBoxLayout() self.layout.setMargin(0) self.layout.addWidget(self.imageLabel) self.layout.setAlignment(self.imageLabel, Qt.AlignHCenter) self.setLayout(self.layout) self.voivoifont = QFont("Helvetica", 48) self.voivoifont.setBold(True) def setup(self, host, user, passwd, event_id, database="voivoi", slideInterval=10, updateInterval=60): ''' setup the slide for it's display routine ''' self.host = host print(self.host) self.user = user self.passwd = passwd self.interval = slideInterval self.updateInterval = updateInterval self.db=database self.eventID = event_id self.updateImages() def updateImages(self, buffer_limit=20): try: db_connection = pymysql.connect(self.host, self.user, self.passwd, self.db) except: print("Database connection not available") return sqlquery = "SELECT `categoryOrder`, `userID`, `dayID`, `comment`, `timestamp`, `eventID` FROM `pictures` WHERE `eventID`>=" + str(self.eventID) + " AND `timestamp`>'" + str(self.mostRecent) + "' ORDER BY `timestamp` ASC" #print(sqlquery) try: with db_connection.cursor() as cursor: cursor.execute(sqlquery) result = cursor.fetchall() for entry in result: print(entry[4]) #print(self.mostRecent) if entry[4] > self.mostRecent: if entry[0] == 0: print("BREAKING") continue self.mostRecent = entry[4] image_url = "http://voivoi.eventfive.de/events/" + str(entry[5]) + "/uploads/" + str(entry[0]) + "_" + str(entry[1]) + "_" + str(entry[2]) + ".jpg" req = self.httpPool.request('GET',image_url) if req.status == 200: data = req.data print("Newer file downloaded") might_be_image = QImage() if might_be_image.loadFromData(data) : #print("URL is valid") self.drawOverlay(might_be_image, entry) if len(self.imgList) > buffer_limit-1: #TODO: change behaviour to iteration over fixed list, to prevent jumps self.imgList.pop(1) self.imgList.append(might_be_image) finally: print("Update done, closing connection") db_connection.close() def drawOverlay(self, image, entry): #establish painter painter = QPainter() #set adjustment factor corner_fac = 0.037 category_fac = 0.27 text_fac = 0.03 #load images category = QImage("res/" + str(entry[0]) + ".png") upperLeft = QImage("res/upperLeft.png") upperRight = QImage("res/upperRight.png") lowerLeft = QImage("res/lowerLeft.png") lowerRight = QImage("res/lowerRight.png") #adjust overlays to image size category = category.scaledToHeight(category_fac*image.height(), Qt.SmoothTransformation) upperLeft = upperLeft.scaledToHeight(corner_fac*image.height(), Qt.SmoothTransformation) upperRight = upperRight.scaledToHeight(corner_fac*image.height(), Qt.SmoothTransformation) lowerLeft = lowerLeft.scaledToHeight(corner_fac*image.height(), Qt.SmoothTransformation) lowerRight = lowerRight.scaledToHeight(corner_fac*image.height(), Qt.SmoothTransformation) self.voivoifont.setPixelSize(text_fac*image.height()) # create size calculator for font size_calculator = QFontMetrics(self.voivoifont) text_width = size_calculator.boundingRect(entry[3]).width() text_height = size_calculator.height() #define text-boundary margin_hor = 0.01*image.width() max_text_bound = QRect(margin_hor,image.height()-image.height()/3, image.width()-image.width()/3, image.height()/3) #format text for display #text_elided = size_calculator.elidedText(entry[3].upper(), Qt.ElideRight, max_text_bound.width(), Qt.TextWordWrap) text_upper = entry[3].upper() text_bounds = size_calculator.boundingRect(max_text_bound, Qt.TextWordWrap, text_upper) text_width = text_bounds.width() text_height = text_bounds.height() #calculate positions margin_ver = 0.018*image.height() #margin_hor = 0.01*image.width() lower_bound = image.height()-margin_ver upper_bound = lower_bound-lowerRight.height()-text_height-upperLeft.height() #begin painting on image painter.begin(image) #first paint category painter.drawImage(image.width()-category.width()-margin_hor, margin_ver, category) # now background rectangle and corners + comment if len(text_upper) > 0: painter.fillRect(margin_hor, upper_bound , lowerLeft.width()+text_width+lowerRight.width(), lowerLeft.height()+text_height+upperLeft.height(), QColor(qRgb(255,255,255))) painter.drawImage(margin_hor, lower_bound-lowerLeft.height(), lowerLeft) painter.drawImage(margin_hor, upper_bound, upperLeft) painter.drawImage(margin_hor+lowerLeft.width()+text_width, upper_bound, upperRight) painter.drawImage(margin_hor+lowerLeft.width()+text_width,lower_bound-lowerRight.height(), lowerRight) # write text to prepared rectangle painter.setPen(QColor(qRgb(17,195,159))) painter.setFont(self.voivoifont) #print(text_upper) painter.drawText(margin_hor+lowerLeft.width(),image.height()-lowerRight.height()-margin_ver-text_height, text_width, text_height, Qt.TextWordWrap, text_upper) painter.end() def run(self): ''' run the widgets display routine ''' self.timer.start(self.interval*1000) self.updateTimer.start(self.updateInterval*1000) self.nextImage() def nextImage(self): ''' take image from list and scale it to height of parent widget (which should be QMainWindow). Then generate a pixmap from the scaled image and display it on a QLabel''' if len(self.imgList) > 0: image = self.imgList[self.slideIterator%len(self.imgList)] else: return #print("IMAGE SIZE AFTER: " + str(image.size())) currImage = QPixmap.fromImage(image.scaledToHeight(self.parentWidget().height(), Qt.SmoothTransformation)) self.imageLabel.setPixmap(currImage) self.slideIterator += 1 def stop(self): Slide.stop(self) self.timer.stop() def shutdown(self): qWarning("Shutting down Slideshow-Module, this will purge all loaded images! \nTo pause, use stop() instead") Slide.shutdown(self) self.timer.stop() self.imgList.clear()
def __init__(self, parent=None, desc=None, name=None, modal=0, fl=0, env=None, type="QDialog"): if env is None: import foundation.env as env # this is a little weird... probably it'll be ok, and logically it seems correct. self.desc = desc self.typ = type if type == "QDialog": QDialog.__init__(self, parent, name, modal, fl) elif type == "QTextEdit": QTextEdit.__init__(self, parent, name) elif type == "QFrame": QFrame.__init__(self, parent, name) else: print "don't know about type == %r" % (type, ) self.image1 = QPixmap() self.image1.loadFromData(image1_data, "PNG") # should be: title_icon #### self.image3 = QPixmap() self.image3.loadFromData(image3_data, "PNG") self.image4 = QPixmap() self.image4.loadFromData(image4_data, "PNG") self.image5 = QPixmap() self.image5.loadFromData(image5_data, "PNG") self.image6 = QPixmap() self.image6.loadFromData(image6_data, "PNG") self.image7 = QPixmap() self.image7.loadFromData(image7_data, "PNG") self.image0 = QPixmap(image0_data) # should be: border_icon #### self.image2 = QPixmap(image2_data) # should be: sponsor_pixmap #### try: ####@@@@ title_icon_name = self.desc.options.get('title_icon') border_icon_name = self.desc.options.get('border_icon') if title_icon_name: self.image1 = imagename_to_pixmap( title_icon_name) ###@@@ pass icon_path ###@@@ import imagename_to_pixmap or use env function # or let that func itself be an arg, or have an env arg for it ###e rename it icon_name_to_pixmap, or find_icon? (the latter only if it's ok if it returns an iconset) ###e use iconset instead? if border_icon_name: self.image0 = imagename_to_pixmap(border_icon_name) except: print_compact_traceback( "bug in icon-setting code, using fallback icons: ") pass if not name: self.setName("parameter_dialog_or_frame") ### ###k guess this will need: if type == 'QDialog' self.setIcon(self.image0) # should be: border_icon #### nanotube_dialogLayout = QVBoxLayout(self, 0, 0, "nanotube_dialogLayout") self.heading_frame = QFrame(self, "heading_frame") self.heading_frame.setPaletteBackgroundColor(QColor(122, 122, 122)) self.heading_frame.setFrameShape(QFrame.NoFrame) self.heading_frame.setFrameShadow(QFrame.Plain) heading_frameLayout = QHBoxLayout(self.heading_frame, 0, 3, "heading_frameLayout") self.heading_pixmap = QLabel(self.heading_frame, "heading_pixmap") self.heading_pixmap.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed, 0, 0, self.heading_pixmap.sizePolicy().hasHeightForWidth())) self.heading_pixmap.setPixmap( self.image1) # should be: title_icon #### self.heading_pixmap.setScaledContents(1) heading_frameLayout.addWidget(self.heading_pixmap) self.heading_label = QLabel(self.heading_frame, "heading_label") self.heading_label.setPaletteForegroundColor(QColor(255, 255, 255)) heading_label_font = QFont(self.heading_label.font()) heading_label_font.setPointSize(12) heading_label_font.setBold(1) self.heading_label.setFont(heading_label_font) heading_frameLayout.addWidget(self.heading_label) nanotube_dialogLayout.addWidget(self.heading_frame) self.body_frame = QFrame(self, "body_frame") self.body_frame.setFrameShape(QFrame.StyledPanel) self.body_frame.setFrameShadow(QFrame.Raised) body_frameLayout = QVBoxLayout(self.body_frame, 3, 3, "body_frameLayout") self.sponsor_frame = QFrame(self.body_frame, "sponsor_frame") self.sponsor_frame.setPaletteBackgroundColor(QColor(255, 255, 255)) self.sponsor_frame.setFrameShape(QFrame.StyledPanel) self.sponsor_frame.setFrameShadow(QFrame.Raised) sponsor_frameLayout = QHBoxLayout(self.sponsor_frame, 0, 0, "sponsor_frameLayout") self.sponsor_btn = QPushButton(self.sponsor_frame, "sponsor_btn") self.sponsor_btn.setAutoDefault(0) #bruce 060703 bugfix self.sponsor_btn.setSizePolicy( QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred, 0, 0, self.sponsor_btn.sizePolicy().hasHeightForWidth())) self.sponsor_btn.setPaletteBackgroundColor(QColor(255, 255, 255)) self.sponsor_btn.setPixmap( self.image2 ) # should be: sponsor_pixmap #### [also we'll need to support >1 sponsor] self.sponsor_btn.setFlat(1) sponsor_frameLayout.addWidget(self.sponsor_btn) body_frameLayout.addWidget(self.sponsor_frame) layout59 = QHBoxLayout(None, 0, 6, "layout59") left_spacer = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout59.addItem(left_spacer) self.done_btn = QToolButton(self.body_frame, "done_btn") self.done_btn.setIcon(QIcon(self.image3)) layout59.addWidget(self.done_btn) self.abort_btn = QToolButton(self.body_frame, "abort_btn") self.abort_btn.setIcon(QIcon(self.image4)) layout59.addWidget(self.abort_btn) self.preview_btn = QToolButton(self.body_frame, "preview_btn") self.preview_btn.setIcon(QIcon(self.image5)) layout59.addWidget(self.preview_btn) self.whatsthis_btn = QToolButton(self.body_frame, "whatsthis_btn") self.whatsthis_btn.setIcon(QIcon(self.image6)) layout59.addWidget(self.whatsthis_btn) right_spacer = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout59.addItem(right_spacer) body_frameLayout.addLayout(layout59) self.groups = [] self.param_getters = { } # map from param name to get-function (which gets current value out of its widget or controller) for group_desc in self.desc.kids('group'): # == start parameters_grpbox ### this will differ for Windows style header_refs = [ ] # keep python refcounted refs to all objects we make (at least the ones pyuic stored in self attrs) self.parameters_grpbox = QGroupBox(self.body_frame, "parameters_grpbox") self.parameters_grpbox.setFrameShape(QGroupBox.StyledPanel) self.parameters_grpbox.setFrameShadow(QGroupBox.Sunken) self.parameters_grpbox.setMargin(0) self.parameters_grpbox.setColumnLayout(0, Qt.Vertical) self.parameters_grpbox.layout().setSpacing(1) self.parameters_grpbox.layout().setMargin(4) parameters_grpboxLayout = QVBoxLayout( self.parameters_grpbox.layout()) parameters_grpboxLayout.setAlignment(Qt.AlignTop) layout20 = QHBoxLayout(None, 0, 6, "layout20") self.nt_parameters_grpbtn = QPushButton(self.parameters_grpbox, "nt_parameters_grpbtn") self.nt_parameters_grpbtn.setSizePolicy( QSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed, 0, 0, self.nt_parameters_grpbtn.sizePolicy().hasHeightForWidth()) ) self.nt_parameters_grpbtn.setMaximumSize(QSize(16, 16)) self.nt_parameters_grpbtn.setAutoDefault(0) self.nt_parameters_grpbtn.setIcon(QIcon( self.image7)) ### not always right, but doesn't matter self.nt_parameters_grpbtn.setFlat(1) layout20.addWidget(self.nt_parameters_grpbtn) self.parameters_grpbox_label = QLabel(self.parameters_grpbox, "parameters_grpbox_label") self.parameters_grpbox_label.setSizePolicy( QSizePolicy( QSizePolicy.Preferred, QSizePolicy.Minimum, 0, 0, self.parameters_grpbox_label.sizePolicy(). hasHeightForWidth())) self.parameters_grpbox_label.setAlignment(QLabel.AlignVCenter) layout20.addWidget(self.parameters_grpbox_label) gbx_spacer1 = QSpacerItem(67, 16, QSizePolicy.Expanding, QSizePolicy.Minimum) layout20.addItem(gbx_spacer1) parameters_grpboxLayout.addLayout(layout20) nt_parameters_body_layout = QGridLayout( None, 1, 1, 0, 6, "nt_parameters_body_layout" ) ### what is 6 -- is it related to number of items??? # is it 6 in all the ones we got, but that could be a designer error so i better look it up sometime. # == start its kids # will use from above: self.parameters_grpbox, nt_parameters_body_layout nextrow = 0 # which row of the QGridLayout to start filling next (loop variable) hidethese = [ ] # set of objects to hide or show, when this group is closed or opened for param in group_desc.kids('parameter'): # param (a group subobj desc) is always a parameter, but we already plan to extend this beyond that, # so we redundantly test for this here. getter = None paramname = None # set these for use by uniform code at the end (e.g. for tooltips) editfield = None label = None if param.isa('parameter'): label = QLabel(self.parameters_grpbox, "members_label") label.setAlignment(QLabel.AlignVCenter | QLabel.AlignRight) nt_parameters_body_layout.addWidget(label, nextrow, 0) hidethese.append(label) thisrow = nextrow nextrow += 1 #e following should be known in a place that knows the input language, not here paramname = param.options.get('name') or ( param.args and param.args[0]) or "?" paramlabel = param.options.get( 'label' ) or paramname ##e wrong, label "" or none ought to be possible # QtGui.QApplication.translate(self.__class__.__name__, "xyz") label.setText( QtGui.QApplication.translate(self.__class__.__name__, paramlabel)) if param.isa('parameter', widget='combobox', type=('str', None)): self.members_combox = QComboBox( 0, self.parameters_grpbox, "members_combox") ###k what's 0? editfield = self.members_combox #### it probably needs a handler class, and then that could do this setup self.members_combox.clear() default = param.options.get( 'default', None) # None is not equal to any string thewidgetkid = param.kids( 'widget' )[-1] # kluge; need to think what the desc method for this should be for item in thewidgetkid.kids('item'): itemval = item.args[0] itemtext = itemval self.members_combox.insertItem( QtGui.QApplication.translate( self.__class__.__name__, itemtext)) #k __tr ok?? if itemval == default: #k or itemtext? pass ##k i find no setItem in our py code, so not sure yet what to do for this. nt_parameters_body_layout.addWidget( self.members_combox, thisrow, 1) hidethese.append(self.members_combox) getter = (lambda combobox=self.members_combox: str( combobox.currentText())) ##e due to __tr or non-str values, it might be better to use currentIndex and look it up in a table # (though whether __tr is good here might depend on what it's used for) elif param.isa('parameter', widget=('lineedit', None), type=('str', None)): # this covers explicit str|lineedit, and 3 default cases str, lineedit, neither. # (i.e. if you say parameter and nothing else, it's str lineedit by default.) self.length_linedit = QLineEdit(self.parameters_grpbox, "length_linedit") editfield = self.length_linedit nt_parameters_body_layout.addWidget( self.length_linedit, thisrow, 1) hidethese.append(self.length_linedit) default = str(param.options.get('default', "")) self.length_linedit.setText( QtGui.QApplication.translate(self.__class__.__name__, default)) # __tr ok? getter = (lambda lineedit=self.length_linedit: str( lineedit.text())) elif param.isa('parameter', widget=('lineedit', None), type='float'): self.length_linedit = QLineEdit(self.parameters_grpbox, "length_linedit") editfield = self.length_linedit nt_parameters_body_layout.addWidget( self.length_linedit, thisrow, 1) hidethese.append(self.length_linedit) controller = FloatLineeditController_Qt( self, param, self.length_linedit) header_refs.append(controller) getter = controller.get_value elif param.isa('parameter', widget = ('spinbox', None), type = 'int') or \ param.isa('parameter', widget = ('spinbox'), type = None): self.chirality_N_spinbox = QSpinBox( self.parameters_grpbox, "chirality_N_spinbox" ) # was chirality_m_spinbox, now chirality_N_spinbox editfield = self.chirality_N_spinbox ### seems like Qt defaults for min and max are 0,100 -- way too small a range! if param.options.has_key('min') or 1: self.chirality_N_spinbox.setMinimum( param.options.get('min', -999999999)) # was 0 if param.options.has_key('max') or 1: self.chirality_N_spinbox.setMaximum( param.options.get( 'max', +999999999)) # wasn't in egcode, but needed self.chirality_N_spinbox.setValue( param.options.get('default', 0)) # was 5 ##e note: i suspect this default 0 should come from something that knows this desc grammar. suffix = param.options.get('suffix', '') if suffix: self.chirality_N_spinbox.setSuffix( QtGui.QApplication.translate( self.__class__.__name__, suffix)) else: self.chirality_N_spinbox.setSuffix( QString.null) # probably not needed nt_parameters_body_layout.addWidget( self.chirality_N_spinbox, thisrow, 1) hidethese.append(self.chirality_N_spinbox) getter = self.chirality_N_spinbox.value # note: it also has .text, which includes suffix else: print "didn't match:", param ###e improve this # things done the same way for all kinds of param-editing widgets if 1: #bruce 060703 moved this down here, as bugfix # set tooltip (same one for editfield and label) tooltip = param.options.get('tooltip', '') ###e do it for more kinds of params; share the code somehow; do it in controller, or setup-aid? ###k QToolTip appropriateness; tooltip option might be entirely untested if tooltip and label: QToolTip.add( label, QtGui.QApplication.translate( self.__class__.__name__, tooltip)) if tooltip and editfield: QToolTip.add( editfield, QtGui.QApplication.translate( self.__class__.__name__, tooltip) ) ##k ok?? review once not all params have same-row labels. if getter and paramname and paramname != '?': self.param_getters[paramname] = getter ### also bind these params to actions... continue # next param header_refs.extend([ self.parameters_grpbox, self.nt_parameters_grpbtn, self.parameters_grpbox_label ]) # now create the logic/control object for the group group = CollapsibleGroupController_Qt(self, group_desc, header_refs, hidethese, self.nt_parameters_grpbtn) ### maybe ask env for the class to use for this? self.groups.append( group ) ### needed?? only for scanning the params, AFAIK -- oh, and to maintain a python refcount. # from languageChange: if 1: # i don't know if these are needed: self.parameters_grpbox.setTitle(QString.null) self.nt_parameters_grpbtn.setText(QString.null) self.parameters_grpbox_label.setText( QtGui.QApplication.translate( self.__class__.__name__, group_desc.args[0])) # was "Nanotube Parameters" ##e note that it's questionable in the syntax design for this property of a group (overall group label) # to be in that position (desc arg 0). # == end its kids parameters_grpboxLayout.addLayout(nt_parameters_body_layout) body_frameLayout.addWidget(self.parameters_grpbox) # == end parameters groupbox continue # next group nanotube_dialogLayout.addWidget(self.body_frame) spacer14 = QSpacerItem(20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) nanotube_dialogLayout.addItem(spacer14) layout42 = QHBoxLayout(None, 4, 6, "layout42") btm_spacer = QSpacerItem(59, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout42.addItem(btm_spacer) self.cancel_btn = QPushButton(self, "cancel_btn") self.cancel_btn.setAutoDefault(0) #bruce 060703 bugfix layout42.addWidget(self.cancel_btn) self.ok_btn = QPushButton(self, "ok_btn") self.ok_btn.setAutoDefault(0) #bruce 060703 bugfix layout42.addWidget(self.ok_btn) nanotube_dialogLayout.addLayout(layout42) self.languageChange() self.resize( QSize(246, 618).expandedTo(self.minimumSizeHint()) ) ### this size will need to be adjusted (guess -- it's only place overall size is set) qt4todo('self.clearWState(Qt.WState_Polished)') ## self.connect(self.nt_parameters_grpbtn,SIGNAL("clicked()"),self.toggle_nt_parameters_grpbtn) #### # new: for button, methodname in ( (self.sponsor_btn, 'do_sponsor_btn'), #e generalize to more than one sponsor button (self.done_btn, 'do_done_btn'), (self.abort_btn, 'do_abort_btn'), (self.preview_btn, 'do_preview_btn'), (self.whatsthis_btn, 'do_whatsthis_btn'), (self.cancel_btn, 'do_cancel_btn'), (self.ok_btn, 'do_ok_btn')): if hasattr(self, methodname): self.connect(button, SIGNAL("clicked()"), getattr(self, methodname)) return
class StatusBar(QStatusBar): # {{{ def __init__(self, parent=None): QStatusBar.__init__(self, parent) self.version = get_version() self.base_msg = "%s %s" % (__appname__, self.version) if tweaks.get("use_new_db", False): self.base_msg += " [newdb]" self.device_string = "" self.update_label = UpdateLabel("") self.total = self.current = self.selected = self.library_total = 0 self.addPermanentWidget(self.update_label) self.update_label.setVisible(False) self._font = QFont() self._font.setBold(True) self.setFont(self._font) self.defmsg = QLabel("") self.defmsg.setFont(self._font) self.addWidget(self.defmsg) self.set_label() def initialize(self, systray=None): self.systray = systray self.notifier = get_notifier(systray) def device_connected(self, devname): self.device_string = _("Connected ") + devname self.set_label() def update_state(self, library_total, total, current, selected): self.library_total = library_total self.total, self.current, self.selected = total, current, selected self.set_label() def set_label(self): try: self._set_label() except: import traceback traceback.print_exc() def _set_label(self): msg = self.base_msg if self.device_string: msg += " ..::.. " + self.device_string else: msg += _(" %(created)s %(name)s") % dict(created=_("created by"), name="Kovid Goyal") if self.total != self.current: base = _("%(num)d of %(total)d books") % dict(num=self.current, total=self.total) else: base = _("%d books") % self.total if self.selected > 0: base = _("%(num)s, %(sel)d selected") % dict(num=base, sel=self.selected) if self.library_total != self.total: base = _("{0}, {1} total").format(base, self.library_total) self.defmsg.setText(u"%s\xa0\xa0\xa0\xa0[%s]" % (msg, base)) self.clearMessage() def device_disconnected(self): self.device_string = "" self.set_label() def show_message(self, msg, timeout=0): self.showMessage(msg, timeout) if self.notifier is not None and not config["disable_tray_notification"]: if isosx and isinstance(msg, unicode): try: msg = msg.encode(preferred_encoding) except UnicodeEncodeError: msg = msg.encode("utf-8") self.notifier(msg) def clear_message(self): self.clearMessage()
def ui_MMKit_GroupBox(self, MMKitDialog): #Start MMKit groupbox (includes atom, clipboard and library tabs) self.MMKit_groupBox = QtGui.QGroupBox(MMKitDialog) self.MMKit_groupBox.setObjectName("MMKit_groupBox") self.MMKit_groupBox.setAutoFillBackground(True) palette = MMKitDialog.getGroupBoxPalette() self.MMKit_groupBox.setPalette(palette) styleSheet = MMKitDialog.getGroupBoxStyleSheet() self.MMKit_groupBox.setStyleSheet(styleSheet) self.MMKitGrpBox_VBoxLayout = QtGui.QVBoxLayout(self.MMKit_groupBox) self.MMKitGrpBox_VBoxLayout.setMargin(pmGrpBoxVboxLayoutMargin) self.MMKitGrpBox_VBoxLayout.setSpacing(pmGrpBoxVboxLayoutSpacing) self.MMKitGrpBox_VBoxLayout.setObjectName("MMKitGrpBox_VBoxLayout") self.MMKitGrpBox_TitleButton = MMKitDialog.getGroupBoxTitleButton("MMKit", self.MMKit_groupBox) self.MMKitGrpBox_VBoxLayout.addWidget(self.MMKitGrpBox_TitleButton) self.mmkit_tab = QtGui.QTabWidget(self.MMKit_groupBox) self.mmkit_tab.setEnabled(True) # Height is fixed. Mark 2007-05-29. self.mmkit_tab.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.Preferred), QSizePolicy.Policy(QSizePolicy.Fixed))) self.mmkit_tab.setObjectName("mmkit_tab") self.atomsPage = QtGui.QWidget() self.atomsPage.setObjectName("atomsPage") self.mmkit_tab.addTab(self.atomsPage, "") self.atomsPageFrame = QtGui.QFrame(self.atomsPage) # atomsPageFrame needs to be reviewed carefully. Mark 2007-06-20 sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(3),QtGui.QSizePolicy.Policy(1)) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.atomsPageFrame.sizePolicy().hasHeightForWidth()) self.atomsPageFrame.setSizePolicy(sizePolicy) self.atomsPageFrame.setFrameShape(QtGui.QFrame.NoFrame) self.atomsPageFrame.setFrameShadow(QtGui.QFrame.Plain) self.atomsPageFrame.setMinimumSize(QtCore.QSize(100,100)) self.atomsPageFrame.setObjectName("atomsPageFrame") self.atomsPage_VBoxLayout = QtGui.QVBoxLayout(self.atomsPageFrame) self.atomsPage_VBoxLayout.setMargin(pmMMKitPageMargin) # Was 4. Mark 2007-05-30 self.atomsPage_VBoxLayout.setSpacing(2) # Element Button GroupBox begins here. ##################### self.elementButtonGroup = QtGui.QGroupBox(self.atomsPageFrame) sizePolicy = QtGui.QSizePolicy( QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) self.elementButtonGroup.setSizePolicy(sizePolicy) self.elementButtonGroup.setMinimumSize( QtCore.QSize(pmMMKitButtonWidth * 4, pmMMKitButtonHeight * 4 + 4)) self.elementButtonGroup.setObjectName("elementButtonGroup") self.MMKit_GridLayout = QtGui.QGridLayout(self.elementButtonGroup) self.MMKit_GridLayout.setMargin(1) # Was 0. Mark 2007-05-30 self.MMKit_GridLayout.setSpacing(0) self.MMKit_GridLayout.setObjectName("MMKit_GridLayout") # Font for toolbuttons. font = QFont(self.atomsPageFrame.font()) font.setFamily(pmMMKitButtonFont) font.setPointSize(pmMMKitButtonFontPointSize) font.setBold(pmMMKitButtonFontBold) #font.setWeight(75) #font.setItalic(False) #font.setUnderline(False) #font.setStrikeOut(False) # All this would be much nicer using a dictionary in a loop. # Later, when time permits. Mark 2007-05-30. self.toolButton1 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton1.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton1.setCheckable(True) self.toolButton1.setFont(font) self.toolButton1.setObjectName("toolButton1") self.MMKit_GridLayout.addWidget(self.toolButton1,0,4,1,1) self.toolButton2 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton2.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton2.setCheckable(True) self.toolButton2.setFont(font) self.toolButton2.setObjectName("toolButton2") self.MMKit_GridLayout.addWidget(self.toolButton2,0,5,1,1) self.toolButton6 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton6.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton6.setCheckable(True) self.toolButton6.setFont(font) self.toolButton6.setObjectName("toolButton6") self.MMKit_GridLayout.addWidget(self.toolButton6,1,1,1,1) self.toolButton7 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton7.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton7.setCheckable(True) self.toolButton7.setFont(font) self.toolButton7.setObjectName("toolButton7") self.MMKit_GridLayout.addWidget(self.toolButton7,1,2,1,1) self.toolButton8 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton8.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton8.setCheckable(True) self.toolButton8.setFont(font) self.toolButton8.setObjectName("toolButton8") self.MMKit_GridLayout.addWidget(self.toolButton8,1,3,1,1) self.toolButton10 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton10.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton10.setCheckable(True) self.toolButton10.setFont(font) self.toolButton10.setObjectName("toolButton10") self.MMKit_GridLayout.addWidget(self.toolButton10,1,5,1,1) self.toolButton9 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton9.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton9.setCheckable(True) self.toolButton9.setFont(font) self.toolButton9.setObjectName("toolButton9") self.MMKit_GridLayout.addWidget(self.toolButton9,1,4,1,1) self.toolButton13 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton13.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton13.setCheckable(True) self.toolButton13.setFont(font) self.toolButton13.setObjectName("toolButton13") self.MMKit_GridLayout.addWidget(self.toolButton13,2,0,1,1) self.toolButton17 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton17.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton17.setCheckable(True) self.toolButton17.setFont(font) self.toolButton17.setObjectName("toolButton17") self.MMKit_GridLayout.addWidget(self.toolButton17,2,4,1,1) self.toolButton5 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton5.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton5.setCheckable(True) self.toolButton5.setFont(font) self.toolButton5.setObjectName("toolButton5") self.MMKit_GridLayout.addWidget(self.toolButton5,1,0,1,1) self.toolButton10_2 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton10_2.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton10_2.setCheckable(True) self.toolButton10_2.setFont(font) self.toolButton10_2.setObjectName("toolButton10_2") self.MMKit_GridLayout.addWidget(self.toolButton10_2,2,5,1,1) self.toolButton15 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton15.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton15.setCheckable(True) self.toolButton15.setFont(font) self.toolButton15.setObjectName("toolButton15") self.MMKit_GridLayout.addWidget(self.toolButton15,2,2,1,1) self.toolButton16 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton16.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton16.setCheckable(True) self.toolButton16.setFont(font) self.toolButton16.setObjectName("toolButton16") self.MMKit_GridLayout.addWidget(self.toolButton16,2,3,1,1) self.toolButton14 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton14.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton14.setCheckable(True) self.toolButton14.setFont(font) self.toolButton14.setObjectName("toolButton14") self.MMKit_GridLayout.addWidget(self.toolButton14,2,1,1,1) self.toolButton33 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton33.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton33.setCheckable(True) self.toolButton33.setFont(font) self.toolButton33.setObjectName("toolButton33") self.MMKit_GridLayout.addWidget(self.toolButton33,3,2,1,1) self.toolButton34 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton34.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton34.setCheckable(True) self.toolButton34.setFont(font) self.toolButton34.setObjectName("toolButton34") self.MMKit_GridLayout.addWidget(self.toolButton34,3,3,1,1) self.toolButton35 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton35.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton35.setCheckable(True) self.toolButton35.setFont(font) self.toolButton35.setObjectName("toolButton35") self.MMKit_GridLayout.addWidget(self.toolButton35,3,4,1,1) self.toolButton32 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton32.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton32.setCheckable(True) self.toolButton32.setFont(font) self.toolButton32.setObjectName("toolButton32") self.MMKit_GridLayout.addWidget(self.toolButton32,3,1,1,1) self.toolButton36 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton36.setFixedSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.toolButton36.setCheckable(True) self.toolButton36.setFont(font) self.toolButton36.setObjectName("toolButton36") self.MMKit_GridLayout.addWidget(self.toolButton36,3,5,1,1) self.atomsPage_VBoxLayout.addWidget(self.elementButtonGroup) # Height is fixed (i.e. locked). Mark 2007-05-29. self.elementButtonGroup.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.Preferred), QSizePolicy.Policy(QSizePolicy.Fixed))) # Atomic Hybrid label self.atomic_hybrids_label = QtGui.QLabel(self.atomsPageFrame) self.atomic_hybrids_label.setText("Atomic Hybrids :") self.atomsPage_VBoxLayout.addWidget(self.atomic_hybrids_label) # Elements Button GroupBox ends here. ####################### # This special HBoxLayout contains both the hybrid button group and a # vert spacer (width = 0) to keep the Qt layout working properly # in certain situations like that described in bug 2407. # Mark 2007-06-20. self.special_HBoxLayout = QtGui.QHBoxLayout() self.special_HBoxLayout.setMargin(0) self.special_HBoxLayout.setSpacing(6) self.special_HBoxLayout.setObjectName("special_HBoxLayout") self.atomsPage_VBoxLayout.addLayout(self.special_HBoxLayout) # Hybrid GroupBox begins here ############################### self.hybrid_btngrp = QtGui.QGroupBox(self.atomsPageFrame) self.hybrid_btngrp.setObjectName("hybrid_btngrp") self.special_HBoxLayout.addWidget(self.hybrid_btngrp) self.hybridBtns_HBoxLayout = QtGui.QHBoxLayout(self.hybrid_btngrp) self.hybridBtns_HBoxLayout.setMargin(2) self.hybridBtns_HBoxLayout.setSpacing(0) self.hybridBtns_HBoxLayout.setObjectName("hybridBtns_HBoxLayout") self.sp3_btn = QtGui.QToolButton(self.hybrid_btngrp) self.sp3_btn.setMinimumSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.sp3_btn.setMaximumSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.sp3_btn.setCheckable(True) self.sp3_btn.setObjectName("sp3_btn") self.hybridBtns_HBoxLayout.addWidget(self.sp3_btn) self.sp2_btn = QtGui.QToolButton(self.hybrid_btngrp) self.sp2_btn.setMinimumSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.sp2_btn.setMaximumSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.sp2_btn.setCheckable(True) self.sp2_btn.setObjectName("sp2_btn") self.hybridBtns_HBoxLayout.addWidget(self.sp2_btn) self.sp_btn = QtGui.QToolButton(self.hybrid_btngrp) self.sp_btn.setMinimumSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.sp_btn.setMaximumSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.sp_btn.setCheckable(True) self.sp_btn.setObjectName("sp_btn") self.hybridBtns_HBoxLayout.addWidget(self.sp_btn) self.graphitic_btn = QtGui.QToolButton(self.hybrid_btngrp) self.graphitic_btn.setMinimumSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.graphitic_btn.setMaximumSize(QtCore.QSize(pmMMKitButtonWidth,pmMMKitButtonHeight)) self.graphitic_btn.setCheckable(True) self.graphitic_btn.setObjectName("graphitic_btn") self.hybridBtns_HBoxLayout.addWidget(self.graphitic_btn) # This VSpacer is needed to help (but not completely) fix bug 2407. It # maintains the height of the layout(s) containing the hybrid button # group when it is hidden using hide(). Without this spacer the layout # gets screwed up in special situations like that described in bug 2407. # The + 10 below is needed to account for the margin (4 pixels) and # the additional 6 just help (I have a theory that the height of the # frame containing the label above the hybrid group box shrinks when # the label is hidden by inserting a space character). I'm # not going to worry about this now. +10 works well enough. # Mark 2007-06-20. VSpacer = QtGui.QSpacerItem(0, pmMMKitButtonHeight + 10, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) #self.hybridBtns_HBoxLayout.addItem(VSpacer) self.special_HBoxLayout.addItem(VSpacer) self.hybridBtns_HBoxLayout.addStretch(0) # Height is fixed. Mark 2007-05-29. self.hybrid_btngrp.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.MinimumExpanding), QSizePolicy.Policy(QSizePolicy.Fixed))) # This spacer keeps the MMKit button grid compressed when # the hybrid button group is hidden. self.atomsPageBottomVSpacer = \ QtGui.QSpacerItem(5, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.MinimumExpanding) self.atomsPage_VBoxLayout.addItem(self.atomsPageBottomVSpacer) # Clipboard page begins here ############################################ self.clipboardPage = QtGui.QWidget() self.clipboardPage.setObjectName("clipboardPage") self.gridlayout3 = QtGui.QGridLayout(self.clipboardPage) self.gridlayout3.setMargin(pmMMKitPageMargin) # Was 4. Mark 2007-05-30 self.gridlayout3.setSpacing(2) self.gridlayout3.setObjectName("gridlayout3") self.chunkListBox = QtGui.QListWidget(self.clipboardPage) self.chunkListBox.setMinimumSize(QtCore.QSize(100,100)) # Height is fixed. Mark 2007-05-29. self.chunkListBox.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.MinimumExpanding), QSizePolicy.Policy(QSizePolicy.Fixed))) self.chunkListBox.setObjectName("chunkListBox") self.gridlayout3.addWidget(self.chunkListBox,0,0,1,1) self.mmkit_tab.addTab(self.clipboardPage, "") self.libraryPage = QtGui.QWidget() #self.libraryPage = QtGui.QScrollArea() #self.libraryPageWidget = QtGui.QWidget() #self.libraryPage.setWidget(self.libraryPageWidget) self.libraryPage.setObjectName("libraryPage") self.mmkit_tab.addTab(self.libraryPage, "") self.MMKitGrpBox_VBoxLayout.addWidget(self.mmkit_tab) self.transmuteAtomsAction = QtGui.QWidgetAction(self.w) self.transmuteAtomsAction.setText("Transmute Atoms") self.transmuteAtomsAction.setIcon(geticon( 'ui/actions/Toolbars/Smart/Transmute_Atoms')) self.transmuteAtomsAction.setCheckable(False) transmuteBtn_HBoxLayout = QtGui.QHBoxLayout() self.transmuteBtn = QtGui.QToolButton(self.MMKit_groupBox) self.transmuteBtn.setDefaultAction(self.transmuteAtomsAction) self.transmuteBtn.setFixedSize(QtCore.QSize(36, 36)) self.transmuteBtn.setIconSize(QtCore.QSize(22,22)) transmuteBtn_HBoxLayout.addWidget(self.transmuteBtn) self.browseButton = QtGui.QPushButton(MMKitDialog) transmuteBtn_HBoxLayout.addWidget(self.browseButton) self.defaultPartLibButton = QtGui.QPushButton(MMKitDialog) transmuteBtn_HBoxLayout.addWidget(self.defaultPartLibButton) self.atomsPageSpacer = QtGui.QSpacerItem(0, 5, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) transmuteBtn_HBoxLayout.addItem(self.atomsPageSpacer) self.MMKitGrpBox_VBoxLayout.addLayout(transmuteBtn_HBoxLayout) self.transmuteCB = QtGui.QCheckBox(" Force to Keep Bonds", self.MMKit_groupBox) self.MMKitGrpBox_VBoxLayout.addWidget(self.transmuteCB) #End MMKit groupbox self.pmVBoxLayout.addWidget(self.MMKit_groupBox) # This line is important. Without it, the MMKit groupbox is # too wide by default and causes a horizontal scrollbar # to be displayed at the bottom of the PropMgr. Mark 2007-05-30 self.MMKit_groupBox.setMinimumWidth(200) # Height is fixed. Mark 2007-05-29. self.MMKit_groupBox.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.MinimumExpanding), QSizePolicy.Policy(QSizePolicy.Fixed)))
class MainView(QMainWindow): # Signals startPressed = pyqtSignal(bool) resetPressed = pyqtSignal() broadcastPressed = pyqtSignal(bool) def __init__(self): super(MainView, self).__init__() self.initUI() # Private variables self._running = False # ADE7753 instance self.meter = ade.ADE7753() # Connect signals and slots self.startPressed.connect(self.meter.startStopSlot) self.resetPressed.connect(self.meter.resetSlot) self.broadcastPressed.connect(self.meter.broadcastSlot) self.meter.varData.connect(self.updateData) self.meter.varPower.connect(self.updatePower) self.meter.varEnergy.connect(self.updateEnergy) # Slots # Update Vrms, Irms and Frequency @pyqtSlot(float, float, float, float) def updateData(self, vrms, irms, frequency, period): vrms = '{:.2f}'.format(vrms) irms = '{:.3f}'.format(irms) frequency = '{:.2f}'.format(frequency) self.voltageLabel.setText(vrms) self.currentLabel.setText(irms) self.frequencyLabel.setText(frequency) # Update energy @pyqtSlot(float, float, float) def updateEnergy(self, activeEnergy, apparentEnergy, reactiveEnergy): activeEnergy = '{:.3f}'.format(activeEnergy) apparentEnergy = '{:.3f}'.format(apparentEnergy) reactiveEnergy = '{:.3f}'.format(reactiveEnergy) self.activeEnergyLabel.setText(activeEnergy) self.apparentEnergyLabel.setText(apparentEnergy) self.reactiveEnergyLabel.setText(reactiveEnergy) # Update power @pyqtSlot(float, float, float) def updatePower(self, activePower, apparentPower, reactivePower): activePower = '{:.3f}'.format(activePower) apparentPower = '{:.3f}'.format(apparentPower) reactivePower = '{:.3f}'.format(reactivePower) self.activePowerLabel.setText(activePower) self.apparentPowerLabel.setText(apparentPower) self.reactivePowerLabel.setText(reactivePower) def initUI(self): # Set central widget centralWidget = QWidget() self.setCentralWidget(centralWidget) # Load LCD fonts lcdNumbersFontID = QFontDatabase().addApplicationFont("lcdmn.ttf") #fontNames = QFontDatabase().applicationFontFamilies(lcdNumbersFontID) # Change font size and use italic for strings #self.lcdNumbersFont = QFont(fontNames[0]) self.lcdNumbersFont = QFont() self.lcdNumbersFont.setPointSize(40) #self.lcdStringFont = QFont(fontNames[0]) self.lcdStringFont = QFont() self.lcdStringFont.setPointSize(35) self.lcdStringFont.setItalic(True) # self.lcdBoldFont = QFont(fontNames[0]) self.lcdBoldFont = QFont() self.lcdBoldFont.setPointSize(50) self.lcdBoldFont.setBold(True) # Labels dataLabel = QLabel("DATA") dataLabel.setStyleSheet(""" QLabel {color:red} """) energyLabel = QLabel("ENERGY") energyLabel.setStyleSheet(""" QLabel {color:red} """) powerLabel = QLabel("POWER") powerLabel.setStyleSheet(""" QLabel {color:red} """) dataLabel.setFont(self.lcdBoldFont) powerLabel.setFont(self.lcdBoldFont) energyLabel.setFont(self.lcdBoldFont) self.voltageLabel = QLabel("0.00") self.voltageLabel.setFont(self.lcdNumbersFont) self.voltageString = QLabel("V") self.voltageString.setFont(self.lcdStringFont) self.currentLabel = QLabel("0.00") self.currentLabel.setFont(self.lcdNumbersFont) self.currentString = QLabel("A") self.currentString.setFont(self.lcdStringFont) self.frequencyLabel = QLabel("0.00") self.frequencyLabel.setFont(self.lcdNumbersFont) self.frequencyString = QLabel("Hz") self.frequencyString.setFont(self.lcdStringFont) self.activeEnergyLabel = QLabel("0.00") self.activeEnergyLabel.setFont(self.lcdNumbersFont) self.activeEnergyString = QLabel("Wh") self.activeEnergyString.setFont(self.lcdStringFont) self.apparentEnergyLabel = QLabel("0.00") self.apparentEnergyLabel.setFont(self.lcdNumbersFont) self.apparentEnergyString = QLabel("VAh") self.apparentEnergyString.setFont(self.lcdStringFont) self.reactiveEnergyLabel = QLabel("0.00") self.reactiveEnergyLabel.setFont(self.lcdNumbersFont) self.reactiveEnergyString = QLabel("VARh") self.reactiveEnergyString.setFont(self.lcdStringFont) self.activePowerLabel = QLabel("0.00") self.activePowerLabel.setFont(self.lcdNumbersFont) self.activePowerString = QLabel("W") self.activePowerString.setFont(self.lcdStringFont) self.apparentPowerLabel = QLabel("0.00") self.apparentPowerLabel.setFont(self.lcdNumbersFont) self.apparentPowerString = QLabel("VA") self.apparentPowerString.setFont(self.lcdStringFont) self.reactivePowerLabel = QLabel("0.00") self.reactivePowerLabel.setFont(self.lcdNumbersFont) self.reactivePowerString = QLabel("VAR") self.reactivePowerString.setFont(self.lcdStringFont) # Horizontal lines hline1 = self.HLine() hline2 = self.HLine() hline3 = self.HLine() hline4 = self.HLine() # Vertical lines vline1 = self.VLine() vline2 = self.VLine() vline3 = self.VLine() # Central grid layout for central widget self.centralGridLayout = QGridLayout(self.centralWidget()) self.centralGridLayout.setHorizontalSpacing(20) self.centralGridLayout.setVerticalSpacing(5) # Add labels self.centralGridLayout.addWidget(dataLabel,0,0,1,2, QtCore.Qt.AlignCenter) self.centralGridLayout.addWidget(energyLabel,0,3,1,2, QtCore.Qt.AlignCenter) self.centralGridLayout.addWidget(powerLabel,0,6,1,2, QtCore.Qt.AlignCenter) self.centralGridLayout.addWidget(hline1, 1, 0, 1, -1) self.centralGridLayout.addWidget(self.voltageLabel, 2, 0, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.voltageString, 2, 1, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(hline2, 3, 0, 1, -1) self.centralGridLayout.addWidget(self.currentLabel, 4, 0, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.currentString, 4, 1, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(hline3, 5, 0, 1, -1) self.centralGridLayout.addWidget(self.frequencyLabel, 6, 0, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.frequencyString, 6, 1, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(hline4, 7, 0, 1, -1) self.centralGridLayout.addWidget(vline1, 0, 2, -1, 1) self.centralGridLayout.addWidget(self.activeEnergyLabel, 2, 3, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.activeEnergyString, 2, 4, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.apparentEnergyLabel, 4, 3, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.apparentEnergyString, 4, 4, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.reactiveEnergyLabel, 6, 3, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.reactiveEnergyString, 6, 4, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(vline2, 0, 5, -1, 1) self.centralGridLayout.addWidget(self.activePowerLabel, 2, 6, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.activePowerString, 2, 7, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.apparentPowerLabel, 4, 6, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.apparentPowerString, 4, 7, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.reactivePowerLabel, 6, 6, 1, 1, QtCore.Qt.AlignLeft) self.centralGridLayout.addWidget(self.reactivePowerString, 6, 7, 1, 1, QtCore.Qt.AlignLeft) # self.centralGridLayout.addWidget(vline3, 0, 8, -1, 1) # Buttons self.startStopButton = QPushButton("START") self.startStopButton.setFont(self.lcdStringFont) buttonPolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.startStopButton.setSizePolicy(buttonPolicy) self.startStopButton.clicked.connect(self.startStopClicked) self.resetButton = QPushButton("RESET") self.resetButton.setFont(self.lcdStringFont) self.resetButton.setSizePolicy(buttonPolicy) self.resetButton.clicked.connect(self.resetButtonClicked) self.broadcastButton = QPushButton("BROADCAST") self.broadcastButton.setFont(self.lcdStringFont) self.broadcastButton.setSizePolicy(buttonPolicy) self.broadcastButton.setCheckable(True) self.broadcastButton.toggled.connect(self.broadcastButtonClicked) self.centralGridLayout.addWidget(self.startStopButton, 8, 0, 1, 2) self.centralGridLayout.addWidget(self.resetButton, 8, 3, 1, 2) self.centralGridLayout.addWidget(self.broadcastButton, 8, 6, 1, 2) # Status bar and show window self.statusBar().showMessage('Ready') self.setWindowTitle("ADE7753 Power Meter") self.show() # Button slots def startStopClicked(self): if(self._running): self._running = False self.startStopButton.setText("START") self.startPressed.emit(False) else: self._running = True self.startStopButton.setText("STOP") self.startPressed.emit(True) def resetButtonClicked(self): self.resetPressed.emit() def broadcastButtonClicked(self, s): self.broadcastPressed.emit(s) # Helper functions def HLine(self): line = QFrame() line.setFrameStyle(QFrame.HLine) line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) return line def VLine(self): line = QFrame() line.setFrameStyle(QFrame.VLine) line.setFrameShape(QFrame.VLine) line.setFrameShadow(QFrame.Sunken) return line
class TOCItem(QStandardItem): def __init__(self, spine, toc, depth, all_items, parent=None): text = toc.text if text: text = re.sub(r'\s', ' ', text) self.title = text self.parent = parent QStandardItem.__init__(self, text if text else '') self.abspath = toc.abspath if toc.href else None self.fragment = toc.fragment all_items.append(self) self.bold_font = QFont(self.font()) self.bold_font.setBold(True) self.normal_font = self.font() for t in toc: self.appendRow(TOCItem(spine, t, depth+1, all_items, parent=self)) self.setFlags(Qt.ItemIsEnabled) spos = 0 for i, si in enumerate(spine): if si == self.abspath: spos = i break am = {} if self.abspath is not None: try: am = getattr(spine[i], 'anchor_map', {}) except UnboundLocalError: # Spine was empty? pass frag = self.fragment if (self.fragment and self.fragment in am) else None self.starts_at = spos self.start_anchor = frag self.start_src_offset = am.get(frag, 0) self.depth = depth self.is_being_viewed = False @property def ancestors(self): parent = self.parent while parent is not None: yield parent parent = parent.parent @classmethod def type(cls): return QStandardItem.UserType+10 def update_indexing_state(self, spine_index, viewport_rect, anchor_map, in_paged_mode): if in_paged_mode: self.update_indexing_state_paged(spine_index, viewport_rect, anchor_map) else: self.update_indexing_state_unpaged(spine_index, viewport_rect, anchor_map) def update_indexing_state_unpaged(self, spine_index, viewport_rect, anchor_map): is_being_viewed = False top, bottom = viewport_rect[1], viewport_rect[3] # We use bottom-25 in the checks below to account for the case where # the next entry has some invisible margin that just overlaps with the # bottom of the screen. In this case it will appear to the user that # the entry is not visible on the screen. Of course, the margin could # be larger than 25, but that's a decent compromise. Also we dont want # to count a partial line as being visible. # We only care about y position anchor_map = {k:v[1] for k, v in anchor_map.iteritems()} if spine_index >= self.starts_at and spine_index <= self.ends_at: # The position at which this anchor is present in the document start_pos = anchor_map.get(self.start_anchor, 0) psp = [] if self.ends_at == spine_index: # Anchors that could possibly indicate the start of the next # section and therefore the end of this section. # self.possible_end_anchors is a set of anchors belonging to # toc entries with depth <= self.depth that are also not # ancestors of this entry. psp = [anchor_map.get(x, 0) for x in self.possible_end_anchors] psp = [x for x in psp if x >= start_pos] # The end position. The first anchor whose pos is >= start_pos # or if the end is not in this spine item, we set it to the bottom # of the window +1 end_pos = min(psp) if psp else (bottom+1 if self.ends_at >= spine_index else 0) if spine_index > self.starts_at and spine_index < self.ends_at: # The entire spine item is contained in this entry is_being_viewed = True elif (spine_index == self.starts_at and bottom-25 >= start_pos and # This spine item contains the start # The start position is before the end of the viewport (spine_index != self.ends_at or top < end_pos)): # The end position is after the start of the viewport is_being_viewed = True elif (spine_index == self.ends_at and top < end_pos and # This spine item contains the end # The end position is after the start of the viewport (spine_index != self.starts_at or bottom-25 >= start_pos)): # The start position is before the end of the viewport is_being_viewed = True changed = is_being_viewed != self.is_being_viewed self.is_being_viewed = is_being_viewed if changed: self.setFont(self.bold_font if is_being_viewed else self.normal_font) def update_indexing_state_paged(self, spine_index, viewport_rect, anchor_map): is_being_viewed = False left, right = viewport_rect[0], viewport_rect[2] left, right = (left, 0), (right, -1) if spine_index >= self.starts_at and spine_index <= self.ends_at: # The position at which this anchor is present in the document start_pos = anchor_map.get(self.start_anchor, (0, 0)) psp = [] if self.ends_at == spine_index: # Anchors that could possibly indicate the start of the next # section and therefore the end of this section. # self.possible_end_anchors is a set of anchors belonging to # toc entries with depth <= self.depth that are also not # ancestors of this entry. psp = [anchor_map.get(x, (0, 0)) for x in self.possible_end_anchors] psp = [x for x in psp if x >= start_pos] # The end position. The first anchor whose pos is >= start_pos # or if the end is not in this spine item, we set it to the column # after the right edge of the viewport end_pos = min(psp) if psp else (right if self.ends_at >= spine_index else (0, 0)) if spine_index > self.starts_at and spine_index < self.ends_at: # The entire spine item is contained in this entry is_being_viewed = True elif (spine_index == self.starts_at and right > start_pos and # This spine item contains the start # The start position is before the end of the viewport (spine_index != self.ends_at or left < end_pos)): # The end position is after the start of the viewport is_being_viewed = True elif (spine_index == self.ends_at and left < end_pos and # This spine item contains the end # The end position is after the start of the viewport (spine_index != self.starts_at or right > start_pos)): # The start position is before the end of the viewport is_being_viewed = True changed = is_being_viewed != self.is_being_viewed self.is_being_viewed = is_being_viewed if changed: self.setFont(self.bold_font if is_being_viewed else self.normal_font) def __repr__(self): return 'TOC Item: %s %s#%s'%(self.title, self.abspath, self.fragment) def __str__(self): return repr(self)
def ui_MMKit_GroupBox(self, MMKitDialog): #Start MMKit groupbox (includes atom, clipboard and library tabs) self.MMKit_groupBox = QtGui.QGroupBox(MMKitDialog) self.MMKit_groupBox.setObjectName("MMKit_groupBox") self.MMKit_groupBox.setAutoFillBackground(True) palette = MMKitDialog.getGroupBoxPalette() self.MMKit_groupBox.setPalette(palette) styleSheet = MMKitDialog.getGroupBoxStyleSheet() self.MMKit_groupBox.setStyleSheet(styleSheet) self.MMKitGrpBox_VBoxLayout = QtGui.QVBoxLayout(self.MMKit_groupBox) self.MMKitGrpBox_VBoxLayout.setMargin(pmGrpBoxVboxLayoutMargin) self.MMKitGrpBox_VBoxLayout.setSpacing(pmGrpBoxVboxLayoutSpacing) self.MMKitGrpBox_VBoxLayout.setObjectName("MMKitGrpBox_VBoxLayout") self.MMKitGrpBox_TitleButton = MMKitDialog.getGroupBoxTitleButton( "MMKit", self.MMKit_groupBox) self.MMKitGrpBox_VBoxLayout.addWidget(self.MMKitGrpBox_TitleButton) self.mmkit_tab = QtGui.QTabWidget(self.MMKit_groupBox) self.mmkit_tab.setEnabled(True) # Height is fixed. Mark 2007-05-29. self.mmkit_tab.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.Preferred), QSizePolicy.Policy(QSizePolicy.Fixed))) self.mmkit_tab.setObjectName("mmkit_tab") self.atomsPage = QtGui.QWidget() self.atomsPage.setObjectName("atomsPage") self.mmkit_tab.addTab(self.atomsPage, "") self.atomsPageFrame = QtGui.QFrame(self.atomsPage) # atomsPageFrame needs to be reviewed carefully. Mark 2007-06-20 sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(3), QtGui.QSizePolicy.Policy(1)) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.atomsPageFrame.sizePolicy().hasHeightForWidth()) self.atomsPageFrame.setSizePolicy(sizePolicy) self.atomsPageFrame.setFrameShape(QtGui.QFrame.NoFrame) self.atomsPageFrame.setFrameShadow(QtGui.QFrame.Plain) self.atomsPageFrame.setMinimumSize(QtCore.QSize(100, 100)) self.atomsPageFrame.setObjectName("atomsPageFrame") self.atomsPage_VBoxLayout = QtGui.QVBoxLayout(self.atomsPageFrame) self.atomsPage_VBoxLayout.setMargin( pmMMKitPageMargin) # Was 4. Mark 2007-05-30 self.atomsPage_VBoxLayout.setSpacing(2) # Element Button GroupBox begins here. ##################### self.elementButtonGroup = QtGui.QGroupBox(self.atomsPageFrame) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) self.elementButtonGroup.setSizePolicy(sizePolicy) self.elementButtonGroup.setMinimumSize( QtCore.QSize(pmMMKitButtonWidth * 4, pmMMKitButtonHeight * 4 + 4)) self.elementButtonGroup.setObjectName("elementButtonGroup") self.MMKit_GridLayout = QtGui.QGridLayout(self.elementButtonGroup) self.MMKit_GridLayout.setMargin(1) # Was 0. Mark 2007-05-30 self.MMKit_GridLayout.setSpacing(0) self.MMKit_GridLayout.setObjectName("MMKit_GridLayout") # Font for toolbuttons. font = QFont(self.atomsPageFrame.font()) font.setFamily(pmMMKitButtonFont) font.setPointSize(pmMMKitButtonFontPointSize) font.setBold(pmMMKitButtonFontBold) #font.setWeight(75) #font.setItalic(False) #font.setUnderline(False) #font.setStrikeOut(False) # All this would be much nicer using a dictionary in a loop. # Later, when time permits. Mark 2007-05-30. self.toolButton1 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton1.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton1.setCheckable(True) self.toolButton1.setFont(font) self.toolButton1.setObjectName("toolButton1") self.MMKit_GridLayout.addWidget(self.toolButton1, 0, 4, 1, 1) self.toolButton2 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton2.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton2.setCheckable(True) self.toolButton2.setFont(font) self.toolButton2.setObjectName("toolButton2") self.MMKit_GridLayout.addWidget(self.toolButton2, 0, 5, 1, 1) self.toolButton6 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton6.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton6.setCheckable(True) self.toolButton6.setFont(font) self.toolButton6.setObjectName("toolButton6") self.MMKit_GridLayout.addWidget(self.toolButton6, 1, 1, 1, 1) self.toolButton7 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton7.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton7.setCheckable(True) self.toolButton7.setFont(font) self.toolButton7.setObjectName("toolButton7") self.MMKit_GridLayout.addWidget(self.toolButton7, 1, 2, 1, 1) self.toolButton8 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton8.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton8.setCheckable(True) self.toolButton8.setFont(font) self.toolButton8.setObjectName("toolButton8") self.MMKit_GridLayout.addWidget(self.toolButton8, 1, 3, 1, 1) self.toolButton10 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton10.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton10.setCheckable(True) self.toolButton10.setFont(font) self.toolButton10.setObjectName("toolButton10") self.MMKit_GridLayout.addWidget(self.toolButton10, 1, 5, 1, 1) self.toolButton9 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton9.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton9.setCheckable(True) self.toolButton9.setFont(font) self.toolButton9.setObjectName("toolButton9") self.MMKit_GridLayout.addWidget(self.toolButton9, 1, 4, 1, 1) self.toolButton13 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton13.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton13.setCheckable(True) self.toolButton13.setFont(font) self.toolButton13.setObjectName("toolButton13") self.MMKit_GridLayout.addWidget(self.toolButton13, 2, 0, 1, 1) self.toolButton17 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton17.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton17.setCheckable(True) self.toolButton17.setFont(font) self.toolButton17.setObjectName("toolButton17") self.MMKit_GridLayout.addWidget(self.toolButton17, 2, 4, 1, 1) self.toolButton5 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton5.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton5.setCheckable(True) self.toolButton5.setFont(font) self.toolButton5.setObjectName("toolButton5") self.MMKit_GridLayout.addWidget(self.toolButton5, 1, 0, 1, 1) self.toolButton10_2 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton10_2.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton10_2.setCheckable(True) self.toolButton10_2.setFont(font) self.toolButton10_2.setObjectName("toolButton10_2") self.MMKit_GridLayout.addWidget(self.toolButton10_2, 2, 5, 1, 1) self.toolButton15 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton15.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton15.setCheckable(True) self.toolButton15.setFont(font) self.toolButton15.setObjectName("toolButton15") self.MMKit_GridLayout.addWidget(self.toolButton15, 2, 2, 1, 1) self.toolButton16 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton16.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton16.setCheckable(True) self.toolButton16.setFont(font) self.toolButton16.setObjectName("toolButton16") self.MMKit_GridLayout.addWidget(self.toolButton16, 2, 3, 1, 1) self.toolButton14 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton14.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton14.setCheckable(True) self.toolButton14.setFont(font) self.toolButton14.setObjectName("toolButton14") self.MMKit_GridLayout.addWidget(self.toolButton14, 2, 1, 1, 1) self.toolButton33 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton33.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton33.setCheckable(True) self.toolButton33.setFont(font) self.toolButton33.setObjectName("toolButton33") self.MMKit_GridLayout.addWidget(self.toolButton33, 3, 2, 1, 1) self.toolButton34 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton34.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton34.setCheckable(True) self.toolButton34.setFont(font) self.toolButton34.setObjectName("toolButton34") self.MMKit_GridLayout.addWidget(self.toolButton34, 3, 3, 1, 1) self.toolButton35 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton35.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton35.setCheckable(True) self.toolButton35.setFont(font) self.toolButton35.setObjectName("toolButton35") self.MMKit_GridLayout.addWidget(self.toolButton35, 3, 4, 1, 1) self.toolButton32 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton32.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton32.setCheckable(True) self.toolButton32.setFont(font) self.toolButton32.setObjectName("toolButton32") self.MMKit_GridLayout.addWidget(self.toolButton32, 3, 1, 1, 1) self.toolButton36 = QtGui.QToolButton(self.elementButtonGroup) self.toolButton36.setFixedSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.toolButton36.setCheckable(True) self.toolButton36.setFont(font) self.toolButton36.setObjectName("toolButton36") self.MMKit_GridLayout.addWidget(self.toolButton36, 3, 5, 1, 1) self.atomsPage_VBoxLayout.addWidget(self.elementButtonGroup) # Height is fixed (i.e. locked). Mark 2007-05-29. self.elementButtonGroup.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.Preferred), QSizePolicy.Policy(QSizePolicy.Fixed))) # Atomic Hybrid label self.atomic_hybrids_label = QtGui.QLabel(self.atomsPageFrame) self.atomic_hybrids_label.setText("Atomic Hybrids :") self.atomsPage_VBoxLayout.addWidget(self.atomic_hybrids_label) # Elements Button GroupBox ends here. ####################### # This special HBoxLayout contains both the hybrid button group and a # vert spacer (width = 0) to keep the Qt layout working properly # in certain situations like that described in bug 2407. # Mark 2007-06-20. self.special_HBoxLayout = QtGui.QHBoxLayout() self.special_HBoxLayout.setMargin(0) self.special_HBoxLayout.setSpacing(6) self.special_HBoxLayout.setObjectName("special_HBoxLayout") self.atomsPage_VBoxLayout.addLayout(self.special_HBoxLayout) # Hybrid GroupBox begins here ############################### self.hybrid_btngrp = QtGui.QGroupBox(self.atomsPageFrame) self.hybrid_btngrp.setObjectName("hybrid_btngrp") self.special_HBoxLayout.addWidget(self.hybrid_btngrp) self.hybridBtns_HBoxLayout = QtGui.QHBoxLayout(self.hybrid_btngrp) self.hybridBtns_HBoxLayout.setMargin(2) self.hybridBtns_HBoxLayout.setSpacing(0) self.hybridBtns_HBoxLayout.setObjectName("hybridBtns_HBoxLayout") self.sp3_btn = QtGui.QToolButton(self.hybrid_btngrp) self.sp3_btn.setMinimumSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.sp3_btn.setMaximumSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.sp3_btn.setCheckable(True) self.sp3_btn.setObjectName("sp3_btn") self.hybridBtns_HBoxLayout.addWidget(self.sp3_btn) self.sp2_btn = QtGui.QToolButton(self.hybrid_btngrp) self.sp2_btn.setMinimumSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.sp2_btn.setMaximumSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.sp2_btn.setCheckable(True) self.sp2_btn.setObjectName("sp2_btn") self.hybridBtns_HBoxLayout.addWidget(self.sp2_btn) self.sp_btn = QtGui.QToolButton(self.hybrid_btngrp) self.sp_btn.setMinimumSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.sp_btn.setMaximumSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.sp_btn.setCheckable(True) self.sp_btn.setObjectName("sp_btn") self.hybridBtns_HBoxLayout.addWidget(self.sp_btn) self.graphitic_btn = QtGui.QToolButton(self.hybrid_btngrp) self.graphitic_btn.setMinimumSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.graphitic_btn.setMaximumSize( QtCore.QSize(pmMMKitButtonWidth, pmMMKitButtonHeight)) self.graphitic_btn.setCheckable(True) self.graphitic_btn.setObjectName("graphitic_btn") self.hybridBtns_HBoxLayout.addWidget(self.graphitic_btn) # This VSpacer is needed to help (but not completely) fix bug 2407. It # maintains the height of the layout(s) containing the hybrid button # group when it is hidden using hide(). Without this spacer the layout # gets screwed up in special situations like that described in bug 2407. # The + 10 below is needed to account for the margin (4 pixels) and # the additional 6 just help (I have a theory that the height of the # frame containing the label above the hybrid group box shrinks when # the label is hidden by inserting a space character). I'm # not going to worry about this now. +10 works well enough. # Mark 2007-06-20. VSpacer = QtGui.QSpacerItem(0, pmMMKitButtonHeight + 10, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) #self.hybridBtns_HBoxLayout.addItem(VSpacer) self.special_HBoxLayout.addItem(VSpacer) self.hybridBtns_HBoxLayout.addStretch(0) # Height is fixed. Mark 2007-05-29. self.hybrid_btngrp.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.MinimumExpanding), QSizePolicy.Policy(QSizePolicy.Fixed))) # This spacer keeps the MMKit button grid compressed when # the hybrid button group is hidden. self.atomsPageBottomVSpacer = \ QtGui.QSpacerItem(5, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.MinimumExpanding) self.atomsPage_VBoxLayout.addItem(self.atomsPageBottomVSpacer) # Clipboard page begins here ############################################ self.clipboardPage = QtGui.QWidget() self.clipboardPage.setObjectName("clipboardPage") self.gridlayout3 = QtGui.QGridLayout(self.clipboardPage) self.gridlayout3.setMargin(pmMMKitPageMargin) # Was 4. Mark 2007-05-30 self.gridlayout3.setSpacing(2) self.gridlayout3.setObjectName("gridlayout3") self.chunkListBox = QtGui.QListWidget(self.clipboardPage) self.chunkListBox.setMinimumSize(QtCore.QSize(100, 100)) # Height is fixed. Mark 2007-05-29. self.chunkListBox.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.MinimumExpanding), QSizePolicy.Policy(QSizePolicy.Fixed))) self.chunkListBox.setObjectName("chunkListBox") self.gridlayout3.addWidget(self.chunkListBox, 0, 0, 1, 1) self.mmkit_tab.addTab(self.clipboardPage, "") self.libraryPage = QtGui.QWidget() #self.libraryPage = QtGui.QScrollArea() #self.libraryPageWidget = QtGui.QWidget() #self.libraryPage.setWidget(self.libraryPageWidget) self.libraryPage.setObjectName("libraryPage") self.mmkit_tab.addTab(self.libraryPage, "") self.MMKitGrpBox_VBoxLayout.addWidget(self.mmkit_tab) self.transmuteAtomsAction = QtGui.QWidgetAction(self.w) self.transmuteAtomsAction.setText("Transmute Atoms") self.transmuteAtomsAction.setIcon( geticon('ui/actions/Toolbars/Smart/Transmute_Atoms')) self.transmuteAtomsAction.setCheckable(False) transmuteBtn_HBoxLayout = QtGui.QHBoxLayout() self.transmuteBtn = QtGui.QToolButton(self.MMKit_groupBox) self.transmuteBtn.setDefaultAction(self.transmuteAtomsAction) self.transmuteBtn.setFixedSize(QtCore.QSize(36, 36)) self.transmuteBtn.setIconSize(QtCore.QSize(22, 22)) transmuteBtn_HBoxLayout.addWidget(self.transmuteBtn) self.browseButton = QtGui.QPushButton(MMKitDialog) transmuteBtn_HBoxLayout.addWidget(self.browseButton) self.defaultPartLibButton = QtGui.QPushButton(MMKitDialog) transmuteBtn_HBoxLayout.addWidget(self.defaultPartLibButton) self.atomsPageSpacer = QtGui.QSpacerItem(0, 5, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) transmuteBtn_HBoxLayout.addItem(self.atomsPageSpacer) self.MMKitGrpBox_VBoxLayout.addLayout(transmuteBtn_HBoxLayout) self.transmuteCB = QtGui.QCheckBox(" Force to Keep Bonds", self.MMKit_groupBox) self.MMKitGrpBox_VBoxLayout.addWidget(self.transmuteCB) #End MMKit groupbox self.pmVBoxLayout.addWidget(self.MMKit_groupBox) # This line is important. Without it, the MMKit groupbox is # too wide by default and causes a horizontal scrollbar # to be displayed at the bottom of the PropMgr. Mark 2007-05-30 self.MMKit_groupBox.setMinimumWidth(200) # Height is fixed. Mark 2007-05-29. self.MMKit_groupBox.setSizePolicy( QSizePolicy(QSizePolicy.Policy(QSizePolicy.MinimumExpanding), QSizePolicy.Policy(QSizePolicy.Fixed)))
def __init__(self, parent = None, desc = None, name = None, modal = 0, fl = 0, env = None, type = "QDialog"): if env is None: import foundation.env as env # this is a little weird... probably it'll be ok, and logically it seems correct. self.desc = desc self.typ = type if type == "QDialog": QDialog.__init__(self,parent,name,modal,fl) elif type == "QTextEdit": QTextEdit.__init__(self, parent, name) elif type == "QFrame": QFrame.__init__(self,parent,name) else: print "don't know about type == %r" % (type,) self.image1 = QPixmap() self.image1.loadFromData(image1_data,"PNG") # should be: title_icon #### self.image3 = QPixmap() self.image3.loadFromData(image3_data,"PNG") self.image4 = QPixmap() self.image4.loadFromData(image4_data,"PNG") self.image5 = QPixmap() self.image5.loadFromData(image5_data,"PNG") self.image6 = QPixmap() self.image6.loadFromData(image6_data,"PNG") self.image7 = QPixmap() self.image7.loadFromData(image7_data,"PNG") self.image0 = QPixmap(image0_data) # should be: border_icon #### self.image2 = QPixmap(image2_data) # should be: sponsor_pixmap #### try: ####@@@@ title_icon_name = self.desc.options.get('title_icon') border_icon_name = self.desc.options.get('border_icon') if title_icon_name: self.image1 = imagename_to_pixmap(title_icon_name) ###@@@ pass icon_path ###@@@ import imagename_to_pixmap or use env function # or let that func itself be an arg, or have an env arg for it ###e rename it icon_name_to_pixmap, or find_icon? (the latter only if it's ok if it returns an iconset) ###e use iconset instead? if border_icon_name: self.image0 = imagename_to_pixmap(border_icon_name) except: print_compact_traceback("bug in icon-setting code, using fallback icons: ") pass if not name: self.setName("parameter_dialog_or_frame") ### ###k guess this will need: if type == 'QDialog' self.setIcon(self.image0) # should be: border_icon #### nanotube_dialogLayout = QVBoxLayout(self,0,0,"nanotube_dialogLayout") self.heading_frame = QFrame(self,"heading_frame") self.heading_frame.setPaletteBackgroundColor(QColor(122,122,122)) self.heading_frame.setFrameShape(QFrame.NoFrame) self.heading_frame.setFrameShadow(QFrame.Plain) heading_frameLayout = QHBoxLayout(self.heading_frame,0,3,"heading_frameLayout") self.heading_pixmap = QLabel(self.heading_frame,"heading_pixmap") self.heading_pixmap.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.heading_pixmap.sizePolicy().hasHeightForWidth())) self.heading_pixmap.setPixmap(self.image1) # should be: title_icon #### self.heading_pixmap.setScaledContents(1) heading_frameLayout.addWidget(self.heading_pixmap) self.heading_label = QLabel(self.heading_frame,"heading_label") self.heading_label.setPaletteForegroundColor(QColor(255,255,255)) heading_label_font = QFont(self.heading_label.font()) heading_label_font.setPointSize(12) heading_label_font.setBold(1) self.heading_label.setFont(heading_label_font) heading_frameLayout.addWidget(self.heading_label) nanotube_dialogLayout.addWidget(self.heading_frame) self.body_frame = QFrame(self,"body_frame") self.body_frame.setFrameShape(QFrame.StyledPanel) self.body_frame.setFrameShadow(QFrame.Raised) body_frameLayout = QVBoxLayout(self.body_frame,3,3,"body_frameLayout") self.sponsor_frame = QFrame(self.body_frame,"sponsor_frame") self.sponsor_frame.setPaletteBackgroundColor(QColor(255,255,255)) self.sponsor_frame.setFrameShape(QFrame.StyledPanel) self.sponsor_frame.setFrameShadow(QFrame.Raised) sponsor_frameLayout = QHBoxLayout(self.sponsor_frame,0,0,"sponsor_frameLayout") self.sponsor_btn = QPushButton(self.sponsor_frame,"sponsor_btn") self.sponsor_btn.setAutoDefault(0) #bruce 060703 bugfix self.sponsor_btn.setSizePolicy(QSizePolicy(QSizePolicy.Preferred,QSizePolicy.Preferred,0,0,self.sponsor_btn.sizePolicy().hasHeightForWidth())) self.sponsor_btn.setPaletteBackgroundColor(QColor(255,255,255)) self.sponsor_btn.setPixmap(self.image2) # should be: sponsor_pixmap #### [also we'll need to support >1 sponsor] self.sponsor_btn.setFlat(1) sponsor_frameLayout.addWidget(self.sponsor_btn) body_frameLayout.addWidget(self.sponsor_frame) layout59 = QHBoxLayout(None,0,6,"layout59") left_spacer = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum) layout59.addItem(left_spacer) self.done_btn = QToolButton(self.body_frame,"done_btn") self.done_btn.setIcon(QIcon(self.image3)) layout59.addWidget(self.done_btn) self.abort_btn = QToolButton(self.body_frame,"abort_btn") self.abort_btn.setIcon(QIcon(self.image4)) layout59.addWidget(self.abort_btn) self.preview_btn = QToolButton(self.body_frame,"preview_btn") self.preview_btn.setIcon(QIcon(self.image5)) layout59.addWidget(self.preview_btn) self.whatsthis_btn = QToolButton(self.body_frame,"whatsthis_btn") self.whatsthis_btn.setIcon(QIcon(self.image6)) layout59.addWidget(self.whatsthis_btn) right_spacer = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum) layout59.addItem(right_spacer) body_frameLayout.addLayout(layout59) self.groups = [] self.param_getters = {} # map from param name to get-function (which gets current value out of its widget or controller) for group_desc in self.desc.kids('group'): # == start parameters_grpbox ### this will differ for Windows style header_refs = [] # keep python refcounted refs to all objects we make (at least the ones pyuic stored in self attrs) self.parameters_grpbox = QGroupBox(self.body_frame,"parameters_grpbox") self.parameters_grpbox.setFrameShape(QGroupBox.StyledPanel) self.parameters_grpbox.setFrameShadow(QGroupBox.Sunken) self.parameters_grpbox.setMargin(0) self.parameters_grpbox.setColumnLayout(0,Qt.Vertical) self.parameters_grpbox.layout().setSpacing(1) self.parameters_grpbox.layout().setMargin(4) parameters_grpboxLayout = QVBoxLayout(self.parameters_grpbox.layout()) parameters_grpboxLayout.setAlignment(Qt.AlignTop) layout20 = QHBoxLayout(None,0,6,"layout20") self.nt_parameters_grpbtn = QPushButton(self.parameters_grpbox,"nt_parameters_grpbtn") self.nt_parameters_grpbtn.setSizePolicy(QSizePolicy(QSizePolicy.Minimum,QSizePolicy.Fixed,0,0,self.nt_parameters_grpbtn.sizePolicy().hasHeightForWidth())) self.nt_parameters_grpbtn.setMaximumSize(QSize(16,16)) self.nt_parameters_grpbtn.setAutoDefault(0) self.nt_parameters_grpbtn.setIcon(QIcon(self.image7)) ### not always right, but doesn't matter self.nt_parameters_grpbtn.setFlat(1) layout20.addWidget(self.nt_parameters_grpbtn) self.parameters_grpbox_label = QLabel(self.parameters_grpbox,"parameters_grpbox_label") self.parameters_grpbox_label.setSizePolicy(QSizePolicy(QSizePolicy.Preferred,QSizePolicy.Minimum,0,0,self.parameters_grpbox_label.sizePolicy().hasHeightForWidth())) self.parameters_grpbox_label.setAlignment(QLabel.AlignVCenter) layout20.addWidget(self.parameters_grpbox_label) gbx_spacer1 = QSpacerItem(67,16,QSizePolicy.Expanding,QSizePolicy.Minimum) layout20.addItem(gbx_spacer1) parameters_grpboxLayout.addLayout(layout20) nt_parameters_body_layout = QGridLayout(None,1,1,0,6,"nt_parameters_body_layout") ### what is 6 -- is it related to number of items??? # is it 6 in all the ones we got, but that could be a designer error so i better look it up sometime. # == start its kids # will use from above: self.parameters_grpbox, nt_parameters_body_layout nextrow = 0 # which row of the QGridLayout to start filling next (loop variable) hidethese = [] # set of objects to hide or show, when this group is closed or opened for param in group_desc.kids('parameter'): # param (a group subobj desc) is always a parameter, but we already plan to extend this beyond that, # so we redundantly test for this here. getter = None paramname = None # set these for use by uniform code at the end (e.g. for tooltips) editfield = None label = None if param.isa('parameter'): label = QLabel(self.parameters_grpbox,"members_label") label.setAlignment(QLabel.AlignVCenter | QLabel.AlignRight) nt_parameters_body_layout.addWidget(label,nextrow,0) hidethese.append(label) thisrow = nextrow nextrow += 1 #e following should be known in a place that knows the input language, not here paramname = param.options.get('name') or (param.args and param.args[0]) or "?" paramlabel = param.options.get('label') or paramname ##e wrong, label "" or none ought to be possible # QtGui.QApplication.translate(self.__class__.__name__, "xyz") label.setText(QtGui.QApplication.translate(self.__class__.__name__, paramlabel)) if param.isa('parameter', widget = 'combobox', type = ('str',None)): self.members_combox = QComboBox(0,self.parameters_grpbox,"members_combox") ###k what's 0? editfield = self.members_combox #### it probably needs a handler class, and then that could do this setup self.members_combox.clear() default = param.options.get('default', None) # None is not equal to any string thewidgetkid = param.kids('widget')[-1] # kluge; need to think what the desc method for this should be for item in thewidgetkid.kids('item'): itemval = item.args[0] itemtext = itemval self.members_combox.insertItem(QtGui.QApplication.translate(self.__class__.__name__, itemtext)) #k __tr ok?? if itemval == default: #k or itemtext? pass ##k i find no setItem in our py code, so not sure yet what to do for this. nt_parameters_body_layout.addWidget(self.members_combox,thisrow,1) hidethese.append(self.members_combox) getter = (lambda combobox = self.members_combox: str(combobox.currentText())) ##e due to __tr or non-str values, it might be better to use currentIndex and look it up in a table # (though whether __tr is good here might depend on what it's used for) elif param.isa('parameter', widget = ('lineedit', None), type = ('str',None)): # this covers explicit str|lineedit, and 3 default cases str, lineedit, neither. # (i.e. if you say parameter and nothing else, it's str lineedit by default.) self.length_linedit = QLineEdit(self.parameters_grpbox,"length_linedit") editfield = self.length_linedit nt_parameters_body_layout.addWidget(self.length_linedit,thisrow,1) hidethese.append(self.length_linedit) default = str(param.options.get('default', "")) self.length_linedit.setText(QtGui.QApplication.translate(self.__class__.__name__, default)) # __tr ok? getter = (lambda lineedit = self.length_linedit: str(lineedit.text())) elif param.isa('parameter', widget = ('lineedit', None), type = 'float'): self.length_linedit = QLineEdit(self.parameters_grpbox,"length_linedit") editfield = self.length_linedit nt_parameters_body_layout.addWidget(self.length_linedit,thisrow,1) hidethese.append(self.length_linedit) controller = FloatLineeditController_Qt(self, param, self.length_linedit) header_refs.append(controller) getter = controller.get_value elif param.isa('parameter', widget = ('spinbox', None), type = 'int') or \ param.isa('parameter', widget = ('spinbox'), type = None): self.chirality_N_spinbox = QSpinBox(self.parameters_grpbox,"chirality_N_spinbox") # was chirality_m_spinbox, now chirality_N_spinbox editfield = self.chirality_N_spinbox ### seems like Qt defaults for min and max are 0,100 -- way too small a range! if param.options.has_key('min') or 1: self.chirality_N_spinbox.setMinimum(param.options.get('min', -999999999)) # was 0 if param.options.has_key('max') or 1: self.chirality_N_spinbox.setMaximum(param.options.get('max', +999999999)) # wasn't in egcode, but needed self.chirality_N_spinbox.setValue(param.options.get('default', 0)) # was 5 ##e note: i suspect this default 0 should come from something that knows this desc grammar. suffix = param.options.get('suffix', '') if suffix: self.chirality_N_spinbox.setSuffix(QtGui.QApplication.translate(self.__class__.__name__, suffix)) else: self.chirality_N_spinbox.setSuffix(QString.null) # probably not needed nt_parameters_body_layout.addWidget(self.chirality_N_spinbox,thisrow,1) hidethese.append(self.chirality_N_spinbox) getter = self.chirality_N_spinbox.value # note: it also has .text, which includes suffix else: print "didn't match:",param ###e improve this # things done the same way for all kinds of param-editing widgets if 1: #bruce 060703 moved this down here, as bugfix # set tooltip (same one for editfield and label) tooltip = param.options.get('tooltip', '') ###e do it for more kinds of params; share the code somehow; do it in controller, or setup-aid? ###k QToolTip appropriateness; tooltip option might be entirely untested if tooltip and label: QToolTip.add(label, QtGui.QApplication.translate(self.__class__.__name__, tooltip)) if tooltip and editfield: QToolTip.add(editfield, QtGui.QApplication.translate(self.__class__.__name__, tooltip)) ##k ok?? review once not all params have same-row labels. if getter and paramname and paramname != '?': self.param_getters[paramname] = getter ### also bind these params to actions... continue # next param header_refs.extend( [self.parameters_grpbox, self.nt_parameters_grpbtn, self.parameters_grpbox_label] ) # now create the logic/control object for the group group = CollapsibleGroupController_Qt(self, group_desc, header_refs, hidethese, self.nt_parameters_grpbtn) ### maybe ask env for the class to use for this? self.groups.append(group) ### needed?? only for scanning the params, AFAIK -- oh, and to maintain a python refcount. # from languageChange: if 1: # i don't know if these are needed: self.parameters_grpbox.setTitle(QString.null) self.nt_parameters_grpbtn.setText(QString.null) self.parameters_grpbox_label.setText(QtGui.QApplication.translate(self.__class__.__name__, group_desc.args[0])) # was "Nanotube Parameters" ##e note that it's questionable in the syntax design for this property of a group (overall group label) # to be in that position (desc arg 0). # == end its kids parameters_grpboxLayout.addLayout(nt_parameters_body_layout) body_frameLayout.addWidget(self.parameters_grpbox) # == end parameters groupbox continue # next group nanotube_dialogLayout.addWidget(self.body_frame) spacer14 = QSpacerItem(20,20,QSizePolicy.Minimum,QSizePolicy.Expanding) nanotube_dialogLayout.addItem(spacer14) layout42 = QHBoxLayout(None,4,6,"layout42") btm_spacer = QSpacerItem(59,20,QSizePolicy.Expanding,QSizePolicy.Minimum) layout42.addItem(btm_spacer) self.cancel_btn = QPushButton(self,"cancel_btn") self.cancel_btn.setAutoDefault(0) #bruce 060703 bugfix layout42.addWidget(self.cancel_btn) self.ok_btn = QPushButton(self,"ok_btn") self.ok_btn.setAutoDefault(0) #bruce 060703 bugfix layout42.addWidget(self.ok_btn) nanotube_dialogLayout.addLayout(layout42) self.languageChange() self.resize(QSize(246,618).expandedTo(self.minimumSizeHint())) ### this size will need to be adjusted (guess -- it's only place overall size is set) qt4todo('self.clearWState(Qt.WState_Polished)') ## self.connect(self.nt_parameters_grpbtn,SIGNAL("clicked()"),self.toggle_nt_parameters_grpbtn) #### # new: for button, methodname in ((self.sponsor_btn, 'do_sponsor_btn'), #e generalize to more than one sponsor button (self.done_btn, 'do_done_btn'), (self.abort_btn, 'do_abort_btn'), (self.preview_btn, 'do_preview_btn'), (self.whatsthis_btn, 'do_whatsthis_btn'), (self.cancel_btn, 'do_cancel_btn'), (self.ok_btn, 'do_ok_btn')): if hasattr(self, methodname): self.connect(button, SIGNAL("clicked()"), getattr(self, methodname)) return
class StatusBar(QStatusBar): # {{{ def __init__(self, parent=None): QStatusBar.__init__(self, parent) self.version = get_version() self.base_msg = '%s %s' % (__appname__, self.version) self.device_string = '' self.update_label = UpdateLabel('') self.total = self.current = self.selected = self.library_total = 0 self.addPermanentWidget(self.update_label) self.update_label.setVisible(False) self._font = QFont() self._font.setBold(True) self.setFont(self._font) self.defmsg = QLabel('') self.defmsg.setFont(self._font) self.addWidget(self.defmsg) self.set_label() def initialize(self, systray=None): self.systray = systray self.notifier = get_notifier(systray) def device_connected(self, devname): self.device_string = _('Connected ') + devname self.set_label() def update_state(self, library_total, total, current, selected): self.library_total = library_total self.total, self.current, self.selected = total, current, selected self.set_label() def set_label(self): try: self._set_label() except: import traceback traceback.print_exc() def _set_label(self): msg = self.base_msg if self.device_string: msg += ' ..::.. ' + self.device_string else: msg += _(' %(created)s %(name)s') % dict(created=_('created by'), name='Kovid Goyal') if self.total != self.current: base = _('%(num)d of %(total)d books') % dict(num=self.current, total=self.total) else: base = _('%d books') % self.total if self.selected > 0: base = _('%(num)s, %(sel)d selected') % dict(num=base, sel=self.selected) if self.library_total != self.total: base = _('{0}, {1} total').format(base, self.library_total) self.defmsg.setText(u'%s\xa0\xa0\xa0\xa0[%s]' % (msg, base)) self.clearMessage() def device_disconnected(self): self.device_string = '' self.set_label() def show_message(self, msg, timeout=0): self.showMessage(msg, timeout) if self.notifier is not None and not config[ 'disable_tray_notification']: if isosx and isinstance(msg, unicode): try: msg = msg.encode(preferred_encoding) except UnicodeEncodeError: msg = msg.encode('utf-8') self.notifier(msg) def clear_message(self): self.clearMessage()
class CompareSingle(QWidget): def __init__(self, field_metadata, parent=None, revert_tooltip=None, datetime_fmt='MMMM yyyy', blank_as_equal=True, fields=('title', 'authors', 'series', 'tags', 'rating', 'publisher', 'pubdate', 'identifiers', 'languages', 'comments', 'cover')): QWidget.__init__(self, parent) self.l = l = QGridLayout() l.setContentsMargins(0, 0, 0, 0) self.setLayout(l) revert_tooltip = revert_tooltip or _('Revert %s') self.current_mi = None self.changed_font = QFont(QApplication.font()) self.changed_font.setBold(True) self.changed_font.setItalic(True) self.blank_as_equal = blank_as_equal self.widgets = OrderedDict() row = 0 for field in fields: m = field_metadata[field] dt = m['datatype'] extra = None if 'series' in {field, dt}: cls = SeriesEdit elif field == 'identifiers': cls = IdentifiersEdit elif field == 'languages': cls = LanguagesEdit elif 'comments' in {field, dt}: cls = CommentsEdit elif 'rating' in {field, dt}: cls = RatingsEdit elif dt == 'datetime': extra = datetime_fmt cls = DateEdit elif field == 'cover': cls = CoverView elif dt in {'text', 'enum'}: cls = LineEdit else: continue neww = cls(field, True, self, m, extra) neww.changed.connect(partial(self.changed, field)) oldw = cls(field, False, self, m, extra) newl = QLabel('&%s:' % m['name']) newl.setBuddy(neww) button = QToolButton(self) button.setIcon(QIcon(I('back.png'))) button.clicked.connect(partial(self.revert, field)) button.setToolTip(revert_tooltip % m['name']) self.widgets[field] = Widgets(neww, oldw, newl, button) for i, w in enumerate((newl, neww, button, oldw)): c = i if i < 2 else i + 1 if w is oldw: c += 1 l.addWidget(w, row, c) row += 1 self.sep = f = QFrame(self) f.setFrameShape(f.VLine) l.addWidget(f, 0, 2, row, 1) self.sep2 = f = QFrame(self) f.setFrameShape(f.VLine) l.addWidget(f, 0, 4, row, 1) def changed(self, field): w = self.widgets[field] if not w.new.same_as(w.old) and (not self.blank_as_equal or not w.new.is_blank): w.label.setFont(self.changed_font) else: w.label.setFont(QApplication.font()) def revert(self, field): widgets = self.widgets[field] neww, oldw = widgets[:2] neww.current_val = oldw.current_val def __call__(self, oldmi, newmi): self.current_mi = newmi self.initial_vals = {} for field, widgets in self.widgets.iteritems(): widgets.old.from_mi(oldmi) widgets.new.from_mi(newmi) self.initial_vals[field] = widgets.new.current_val def apply_changes(self): changed = False for field, widgets in self.widgets.iteritems(): val = widgets.new.current_val if val != self.initial_vals[field]: widgets.new.to_mi(self.current_mi) changed = True return changed
class CompareSingle(QWidget): def __init__( self, field_metadata, parent=None, revert_tooltip=None, datetime_fmt='MMMM yyyy', blank_as_equal=True, fields=('title', 'authors', 'series', 'tags', 'rating', 'publisher', 'pubdate', 'identifiers', 'languages', 'comments', 'cover')): QWidget.__init__(self, parent) self.l = l = QGridLayout() l.setContentsMargins(0, 0, 0, 0) self.setLayout(l) revert_tooltip = revert_tooltip or _('Revert %s') self.current_mi = None self.changed_font = QFont(QApplication.font()) self.changed_font.setBold(True) self.changed_font.setItalic(True) self.blank_as_equal = blank_as_equal self.widgets = OrderedDict() row = 0 for field in fields: m = field_metadata[field] dt = m['datatype'] extra = None if 'series' in {field, dt}: cls = SeriesEdit elif field == 'identifiers': cls = IdentifiersEdit elif field == 'languages': cls = LanguagesEdit elif 'comments' in {field, dt}: cls = CommentsEdit elif 'rating' in {field, dt}: cls = RatingsEdit elif dt == 'datetime': extra = datetime_fmt cls = DateEdit elif field == 'cover': cls = CoverView elif dt in {'text', 'enum'}: cls = LineEdit else: continue neww = cls(field, True, self, m, extra) neww.changed.connect(partial(self.changed, field)) oldw = cls(field, False, self, m, extra) newl = QLabel('&%s:' % m['name']) newl.setBuddy(neww) button = QToolButton(self) button.setIcon(QIcon(I('back.png'))) button.clicked.connect(partial(self.revert, field)) button.setToolTip(revert_tooltip % m['name']) self.widgets[field] = Widgets(neww, oldw, newl, button) for i, w in enumerate((newl, neww, button, oldw)): c = i if i < 2 else i + 1 if w is oldw: c += 1 l.addWidget(w, row, c) row += 1 self.sep = f = QFrame(self) f.setFrameShape(f.VLine) l.addWidget(f, 0, 2, row, 1) self.sep2 = f = QFrame(self) f.setFrameShape(f.VLine) l.addWidget(f, 0, 4, row, 1) if 'comments' in self.widgets and not gprefs.get('diff_widget_show_comments_controls', True): self.widgets['comments'].new.hide_toolbars() def save_comments_controls_state(self): if 'comments' in self.widgets: vis = self.widgets['comments'].new.toolbars_visible if vis != gprefs.get('diff_widget_show_comments_controls', True): gprefs.set('diff_widget_show_comments_controls', vis) def changed(self, field): w = self.widgets[field] if not w.new.same_as(w.old) and (not self.blank_as_equal or not w.new.is_blank): w.label.setFont(self.changed_font) else: w.label.setFont(QApplication.font()) def revert(self, field): widgets = self.widgets[field] neww, oldw = widgets[:2] neww.current_val = oldw.current_val def __call__(self, oldmi, newmi): self.current_mi = newmi self.initial_vals = {} for field, widgets in self.widgets.iteritems(): widgets.old.from_mi(oldmi) widgets.new.from_mi(newmi) self.initial_vals[field] = widgets.new.current_val def apply_changes(self): changed = False for field, widgets in self.widgets.iteritems(): val = widgets.new.current_val if val != self.initial_vals[field]: widgets.new.to_mi(self.current_mi) changed = True return changed
def mark_item_as_current(self, item): font = QFont(self.font()) font.setItalic(True) font.setBold(True) item.setData(0, Qt.FontRole, font)
class GLTextBox(Action, GLFrame): def __init__(self, parent, text, x=0, y=0, width=100, height=30, action=None, params=None): Action.__init__(self, action, params) GLFrame.__init__(self, parent, x, y, width, height) self.margin = 20 self.textColor = QColor(0, 0, 0) self.focus = False self.enabled = True self.font = QFont() self.font.setBold(True) self.setText(text) self.__initialized__ = False def setText(self, text): if len(text) == 0: return lines = text.split('\n') qf = QFontMetrics(self.font) fmw = max(qf.maxWidth(), 10) nlines = [] w = self.width - 2 * self.margin for line in lines: if qf.width(line) > w: while qf.width(line) > w: for i in xrange(w / fmw, len(line)): if qf.width(line, i) > w: if line[i].isalnum() and line[i - 1].isalnum(): nlines.append(line[0:i - 1] + ( '-' if line[i - 2].isalnum() else '')) line = line[i - 1:] else: nlines.append(line[0:i]) line = line[i:] break nlines.append(QString(line)) else: nlines.append(QString(line)) self.__text = nlines self.__computeTextPosition() def __computeTextPosition(self): if not self.__text is None: qf = QFontMetrics(self.font) self.__textx = self.x + self.margin self.__texty = self.y + self.margin + qf.ascent() + ( self.height - 2 * self.margin - len(self.__text) * qf.height()) / 2 self.__texth = qf.height() def init(self): if not self.__initialized__: self.__initialized__ = True self.__defaultenabled = self.enabled self.__defaultvisible = self.visible else: self.enabled = self.__defaultenabled self.visible = self.__defaultvisible def draw(self): if self.visible: glDisable(GL_LIGHTING) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.parent.startScreenCoordinatesSystem() glLineWidth(2) glDisable(GL_LIGHTING) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glColor4f(0, 0, 0, 1.0) self.drawBox() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glColor4f(1.0, 1.0, 1.0, 0.8) self.drawBox() self.parent.stopScreenCoordinatesSystem() glLineWidth(1) self.mcheckError('1') if not self.__text is None: glColor4f(self.textColor.redF(), self.textColor.greenF(), self.textColor.blueF(), self.textColor.alphaF()) self.mcheckError('2') for i, line in enumerate(self.__text): if len(line) > 0: self.parent.renderText(self.__textx, self.__texty + i * self.__texth, line, self.font) self.mcheckError('n' + str(i) + "'" + line + "'") def mcheckError(self, txt=None): err = glGetError() if err != GL_NO_ERROR: if txt: print txt, ':', print gluErrorString(err) def mousePressEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): return True return False def mouseMoveEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): self.parent.setFocusWidget(self) return True return False def mouseReleaseEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): self.parent.selectedButton = None self.applyAction() return True return False
class StatusBar(QStatusBar): # {{{ def __init__(self, parent=None): QStatusBar.__init__(self, parent) self.base_msg = '%s %s' % (__appname__, get_version()) self.version = get_version() self.device_string = '' self.update_label = UpdateLabel('') self.total = self.current = self.selected = self.library_total = 0 self.addPermanentWidget(self.update_label) self.update_label.setVisible(False) self._font = QFont() self._font.setBold(True) self.setFont(self._font) self.defmsg = QLabel('') self.defmsg.setFont(self._font) self.addWidget(self.defmsg) self.set_label() def initialize(self, systray=None): self.systray = systray self.notifier = get_notifier(systray) def device_connected(self, devname): self.device_string = _('Connected ') + devname self.set_label() def update_state(self, library_total, total, current, selected): self.library_total = library_total self.total, self.current, self.selected = total, current, selected self.set_label() def set_label(self): try: self._set_label() except: import traceback traceback.print_exc() def _set_label(self): msg = self.base_msg if self.device_string: msg += ' ..::.. ' + self.device_string else: msg += _(' %(created)s %(name)s') % dict(created=_('created by'), name='Kovid Goyal') if self.total != self.current: base = _('%(num)d of %(total)d books') % dict(num=self.current, total=self.total) else: base = _('%d books') % self.total if self.selected > 0: base = _('%(num)s, %(sel)d selected') % dict(num=base, sel=self.selected) if self.library_total != self.total: base = _('{0}, {1} total').format(base, self.library_total) self.defmsg.setText('%s [%s]' % (msg, base)) self.clearMessage() def device_disconnected(self): self.device_string = '' self.set_label() def show_message(self, msg, timeout=0): self.showMessage(msg, timeout) if self.notifier is not None and not config['disable_tray_notification']: if isosx and isinstance(msg, unicode): try: msg = msg.encode(preferred_encoding) except UnicodeEncodeError: msg = msg.encode('utf-8') self.notifier(msg) def clear_message(self): self.clearMessage()
class TOCItem(QStandardItem): def __init__(self, spine, toc, depth, all_items, parent=None): text = toc.text if text: text = re.sub(r'\s', ' ', text) self.title = text self.parent = parent QStandardItem.__init__(self, text if text else '') self.abspath = toc.abspath self.fragment = toc.fragment all_items.append(self) self.bold_font = QFont(self.font()) self.bold_font.setBold(True) self.normal_font = self.font() for t in toc: self.appendRow(TOCItem(spine, t, depth+1, all_items, parent=self)) self.setFlags(Qt.ItemIsEnabled) spos = 0 for i, si in enumerate(spine): if si == self.abspath: spos = i break try: am = getattr(spine[i], 'anchor_map', {}) except UnboundLocalError: # Spine was empty? am = {} frag = self.fragment if (self.fragment and self.fragment in am) else None self.starts_at = spos self.start_anchor = frag self.start_src_offset = am.get(frag, 0) self.depth = depth self.is_being_viewed = False @property def ancestors(self): parent = self.parent while parent is not None: yield parent parent = parent.parent @classmethod def type(cls): return QStandardItem.UserType+10 def update_indexing_state(self, spine_index, viewport_rect, anchor_map, in_paged_mode): if in_paged_mode: self.update_indexing_state_paged(spine_index, viewport_rect, anchor_map) else: self.update_indexing_state_unpaged(spine_index, viewport_rect, anchor_map) def update_indexing_state_unpaged(self, spine_index, viewport_rect, anchor_map): is_being_viewed = False top, bottom = viewport_rect[1], viewport_rect[3] # We use bottom-25 in the checks below to account for the case where # the next entry has some invisible margin that just overlaps with the # bottom of the screen. In this case it will appear to the user that # the entry is not visible on the screen. Of course, the margin could # be larger than 25, but that's a decent compromise. Also we dont want # to count a partial line as being visible. # We only care about y position anchor_map = {k:v[1] for k, v in anchor_map.iteritems()} if spine_index >= self.starts_at and spine_index <= self.ends_at: # The position at which this anchor is present in the document start_pos = anchor_map.get(self.start_anchor, 0) psp = [] if self.ends_at == spine_index: # Anchors that could possibly indicate the start of the next # section and therefore the end of this section. # self.possible_end_anchors is a set of anchors belonging to # toc entries with depth <= self.depth that are also not # ancestors of this entry. psp = [anchor_map.get(x, 0) for x in self.possible_end_anchors] psp = [x for x in psp if x >= start_pos] # The end position. The first anchor whose pos is >= start_pos # or if the end is not in this spine item, we set it to the bottom # of the window +1 end_pos = min(psp) if psp else (bottom+1 if self.ends_at >= spine_index else 0) if spine_index > self.starts_at and spine_index < self.ends_at: # The entire spine item is contained in this entry is_being_viewed = True elif (spine_index == self.starts_at and bottom-25 >= start_pos and # This spine item contains the start # The start position is before the end of the viewport (spine_index != self.ends_at or top < end_pos)): # The end position is after the start of the viewport is_being_viewed = True elif (spine_index == self.ends_at and top < end_pos and # This spine item contains the end # The end position is after the start of the viewport (spine_index != self.starts_at or bottom-25 >= start_pos)): # The start position is before the end of the viewport is_being_viewed = True changed = is_being_viewed != self.is_being_viewed self.is_being_viewed = is_being_viewed if changed: self.setFont(self.bold_font if is_being_viewed else self.normal_font) def update_indexing_state_paged(self, spine_index, viewport_rect, anchor_map): is_being_viewed = False left, right = viewport_rect[0], viewport_rect[2] left, right = (left, 0), (right, -1) if spine_index >= self.starts_at and spine_index <= self.ends_at: # The position at which this anchor is present in the document start_pos = anchor_map.get(self.start_anchor, (0, 0)) psp = [] if self.ends_at == spine_index: # Anchors that could possibly indicate the start of the next # section and therefore the end of this section. # self.possible_end_anchors is a set of anchors belonging to # toc entries with depth <= self.depth that are also not # ancestors of this entry. psp = [anchor_map.get(x, (0, 0)) for x in self.possible_end_anchors] psp = [x for x in psp if x >= start_pos] # The end position. The first anchor whose pos is >= start_pos # or if the end is not in this spine item, we set it to the column # after the right edge of the viewport end_pos = min(psp) if psp else (right if self.ends_at >= spine_index else (0, 0)) if spine_index > self.starts_at and spine_index < self.ends_at: # The entire spine item is contained in this entry is_being_viewed = True elif (spine_index == self.starts_at and right > start_pos and # This spine item contains the start # The start position is before the end of the viewport (spine_index != self.ends_at or left < end_pos)): # The end position is after the start of the viewport is_being_viewed = True elif (spine_index == self.ends_at and left < end_pos and # This spine item contains the end # The end position is after the start of the viewport (spine_index != self.starts_at or right > start_pos)): # The start position is before the end of the viewport is_being_viewed = True changed = is_being_viewed != self.is_being_viewed self.is_being_viewed = is_being_viewed if changed: self.setFont(self.bold_font if is_being_viewed else self.normal_font) def __repr__(self): return 'TOC Item: %s %s#%s'%(self.title, self.abspath, self.fragment) def __str__(self): return repr(self)
class CompareSingle(QWidget): def __init__( self, field_metadata, parent=None, revert_tooltip=None, datetime_fmt="MMMM yyyy", blank_as_equal=True, fields=( "title", "authors", "series", "tags", "rating", "publisher", "pubdate", "identifiers", "languages", "comments", "cover", ), ): QWidget.__init__(self, parent) self.l = l = QGridLayout() l.setContentsMargins(0, 0, 0, 0) self.setLayout(l) revert_tooltip = revert_tooltip or _("Revert %s") self.current_mi = None self.changed_font = QFont(QApplication.font()) self.changed_font.setBold(True) self.changed_font.setItalic(True) self.blank_as_equal = blank_as_equal self.widgets = OrderedDict() row = 0 for field in fields: m = field_metadata[field] dt = m["datatype"] extra = None if "series" in {field, dt}: cls = SeriesEdit elif field == "identifiers": cls = IdentifiersEdit elif field == "languages": cls = LanguagesEdit elif "comments" in {field, dt}: cls = CommentsEdit elif "rating" in {field, dt}: cls = RatingsEdit elif dt == "datetime": extra = datetime_fmt cls = DateEdit elif field == "cover": cls = CoverView elif dt in {"text", "enum"}: cls = LineEdit else: continue neww = cls(field, True, self, m, extra) neww.changed.connect(partial(self.changed, field)) oldw = cls(field, False, self, m, extra) newl = QLabel("&%s:" % m["name"]) newl.setBuddy(neww) button = QToolButton(self) button.setIcon(QIcon(I("back.png"))) button.clicked.connect(partial(self.revert, field)) button.setToolTip(revert_tooltip % m["name"]) self.widgets[field] = Widgets(neww, oldw, newl, button) for i, w in enumerate((newl, neww, button, oldw)): c = i if i < 2 else i + 1 if w is oldw: c += 1 l.addWidget(w, row, c) row += 1 self.sep = f = QFrame(self) f.setFrameShape(f.VLine) l.addWidget(f, 0, 2, row, 1) self.sep2 = f = QFrame(self) f.setFrameShape(f.VLine) l.addWidget(f, 0, 4, row, 1) def changed(self, field): w = self.widgets[field] if not w.new.same_as(w.old) and (not self.blank_as_equal or not w.new.is_blank): w.label.setFont(self.changed_font) else: w.label.setFont(QApplication.font()) def revert(self, field): widgets = self.widgets[field] neww, oldw = widgets[:2] neww.current_val = oldw.current_val def __call__(self, oldmi, newmi): self.current_mi = newmi self.initial_vals = {} for field, widgets in self.widgets.iteritems(): widgets.old.from_mi(oldmi) widgets.new.from_mi(newmi) self.initial_vals[field] = widgets.new.current_val def apply_changes(self): changed = False for field, widgets in self.widgets.iteritems(): val = widgets.new.current_val if val != self.initial_vals[field]: widgets.new.to_mi(self.current_mi) changed = True return changed