class ClosableDialog(QDialog): def __init__(self, title, widget, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(title) self.setModal(True) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowCancelButtonHint) layout = QVBoxLayout() layout.setSizeConstraint(QLayout.SetFixedSize) # not resizable!!! layout.addWidget(widget) self.__button_layout = QHBoxLayout() self.close_button = QPushButton("Close") self.close_button.setObjectName("CLOSE") self.close_button.clicked.connect(self.accept) self.__button_layout.addStretch() self.__button_layout.addWidget(self.close_button) layout.addStretch() layout.addLayout(self.__button_layout) self.setLayout(layout) def disableCloseButton(self): self.close_button.setEnabled(False) def enableCloseButton(self): self.close_button.setEnabled(True) def keyPressEvent(self, q_key_event): if not self.close_button.isEnabled() and q_key_event.key() == Qt.Key_Escape: pass else: QDialog.keyPressEvent(self, q_key_event) def addButton(self, caption, listner): button = QPushButton(caption) button.setObjectName(str(caption).capitalize()) self.__button_layout.insertWidget(1,button) button.clicked.connect(listner) def toggleButton(self, caption, enabled): button = self.findChild(QPushButton,str(caption).capitalize()) if button is not None: button.setEnabled(enabled)
def __init__(self, client, key, value, parent=None): QFrame.__init__(self, parent) self.setFrameShape(QFrame.StyledPanel) self.setFrameShadow(QFrame.Raised) self.setContentsMargins(2, 2, 2, 2) self.parent_widget = parent filterbox = QHBoxLayout(self) filterbox.setContentsMargins(1, 1, 1, 1) self.client = client try: self.arg_data = arg_types[key].data(key, value, GenericFetcher(self.client), parent.compatibility) self.arg_filter = arg_types[key].filter(self.client, key, value, parent.compatibility) except KeyError: raise FilterWidgetError() if isinstance(self.arg_data.label, QObject): raise FilterWidgetError() self.arglabel = QLabel('<b>%s</b>' % arg_types[key].label) self.argvalue = QLabel('%s' % self.arg_data.label) self.argunit = QLabel(arg_types[key].unit) filterbox.insertWidget(self.KEY_POS, self.arglabel) filterbox.insertWidget(self.VALUE_POS, self.argvalue) filterbox.insertWidget(self.UNIT_POS, self.argunit) self.argedit = createLink(':/icons-20/edit.png', self.editFilter) self.argedit.setStyleSheet('') self.argremove = createLink(':/icons-20/wrong.png', self.removeFilter) self.argremove.setStyleSheet('') if isinstance(self.arg_filter, QLineEdit): self.connect(self.arg_filter, SIGNAL('returnPressed()'), self.editFilter) elif isinstance(self.arg_filter, QSpinBox): self.connect(self.arg_filter, SIGNAL('editingFinished()'), self.editFilter) filterbox.insertWidget(self.EDIT_POS, self.argedit) filterbox.insertWidget(self.REMOVE_POS, self.argremove) self.edditing = False
def initUI(self, battlepokemon): #Create a layout in which we will place a scrollable view # In this scrollable pane, the trainer and its pokemon are placed. # For smaller windows, all pokemon can be editted by scrolling from left to right. mainlayout = QVBoxLayout(self) scrollArea = QScrollArea() innerwidget = QWidget() #Create a layout for the innerwidget layout = QHBoxLayout() innerwidget.setLayout(layout) layout.setSpacing(0) layout.setMargin(0) layout.setContentsMargins(0, 0, 0, 0) trainerinfo = Trainer(self, self.trainersinfo, self.trainer, self.trainerclasses, self.itemslist) self.trainerinfo = trainerinfo for battlepoke in battlepokemon: pokewidget = TrainerPokemon(self, battlepoke, self.pokemondata, self.movelist, self.itemslist, parent=self) self.pokemonwidgets.append(pokewidget) layout.addWidget(pokewidget, 0) layout.insertWidget(0, trainerinfo, 0) padlabel = QLabel(self) layout.addWidget(padlabel) scrollArea.setWidget(innerwidget) savebutton = QPushButton("Save", self) savebutton.clicked.connect(self.save) mainlayout.addWidget(scrollArea) mainlayout.addWidget(savebutton)
class Block(QGroupBox): def __init__(self, parent, name = '', size = 0, root = None): QGroupBox.__init__(self, name, parent) self.layout = QHBoxLayout(self) self.parent = parent self.root = root self._name = name self._size = size self._partitions = [] def setName(self, name): self._name = name self.setTitle(self._name) def setSize(self, size): self._size = size def addPartition(self, partition = None, index = None): if not partition: partition = Partition(self, root = self.root) if index == None: index = len(self._partitions) self._partitions.insert(index, partition) self.layout.insertWidget(index, partition) self._updateSize() return partition def _updateSize(self): for i in range(len(self._partitions)): self.layout.setStretch(i, self._partitions[i]._size)
def initUI(self, battlepokemon): #Create a layout in which we will place a scrollable view # In this scrollable pane, the trainer and its pokemon are placed. # For smaller windows, all pokemon can be editted by scrolling from left to right. mainlayout = QVBoxLayout(self) scrollArea = QScrollArea() innerwidget = QWidget() #Create a layout for the innerwidget layout = QHBoxLayout() innerwidget.setLayout(layout) layout.setSpacing(0) layout.setMargin(0) layout.setContentsMargins(0,0,0,0) trainerinfo = Trainer(self, self.trainersinfo, self.trainer, self.trainerclasses, self.itemslist) self.trainerinfo = trainerinfo for battlepoke in battlepokemon: pokewidget = TrainerPokemon(self, battlepoke, self.pokemondata, self.movelist, self.itemslist, parent=self) self.pokemonwidgets.append(pokewidget) layout.addWidget(pokewidget, 0) layout.insertWidget(0, trainerinfo, 0) padlabel = QLabel(self) layout.addWidget(padlabel) scrollArea.setWidget(innerwidget) savebutton = QPushButton("Save", self) savebutton.clicked.connect(self.save) mainlayout.addWidget(scrollArea) mainlayout.addWidget(savebutton)
class AboutWidget(QWidgetWithDpi): """ Common About Dialog for the Freeseer Project. This should be used for the about dialog when including one in GUIs. Layout: Logo | About Infos | Buttons """ def __init__(self, parent=None): super(AboutWidget, self).__init__(parent) self.current_language = "en_US" self.uiTranslator = QTranslator() self.uiTranslator.load(":/languages/tr_en_US.qm") self.fontSize = self.font().pixelSize() self.fontUnit = "px" if self.fontSize == -1: # Font is set as points, not pixels. self.fontUnit = "pt" self.fontSize = self.font().pointSize() icon = QIcon() self.logoPixmap = QPixmap(_fromUtf8(":/freeseer/logo.png")) icon.addPixmap(self.logoPixmap, QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.mainLayout = QGridLayout() self.setLayout(self.mainLayout) # Logo self.logo = QLabel("Logo") # To offset the logo so that it's to the right of the title self.logo.setStyleSheet("QLabel {{ margin-left: {} {} }}" .format(self.set_width_with_dpi(90) + (self.fontSize * 2.5), self.fontUnit)) self.logo.setPixmap(self.logoPixmap.scaledToHeight(self.set_height_with_dpi(80))) self.mainLayout.addWidget(self.logo, 0, 0, Qt.AlignTop) # Info self.aboutInfo = QLabel("About Info", openExternalLinks=True) self.aboutInfo.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.aboutInfo.setWordWrap(True) self.mainLayout.addWidget(self.aboutInfo, 0, 0) # Buttons self.buttonsLayout = QHBoxLayout() self.issueButton = QPushButton("Report an issue") self.docsButton = QPushButton("Freeseer documentation") self.contactButton = QPushButton("Contact us") self.buttonsLayout.insertWidget(0, self.docsButton) self.buttonsLayout.insertWidget(1, self.issueButton) self.buttonsLayout.insertWidget(2, self.contactButton) self.mainLayout.addLayout(self.buttonsLayout, 2, 0) self.connect(self.docsButton, SIGNAL('clicked()'), self.openDocsUrl) self.connect(self.issueButton, SIGNAL('clicked()'), self.openNewIssueUrl) self.connect(self.contactButton, SIGNAL('clicked()'), self.openContactUrl) self.retranslate() def retranslate(self, language=None): if language is not None: self.current_language = language self.uiTranslator.load(":/languages/tr_%s.qm" % self.current_language) # # Main Text # self.descriptionString = self.uiTranslator.translate("AboutDialog", "Freeseer is a video capture utility capable of capturing presentations. It captures " "video sources such as usb, firewire, or local desktop along with audio and mixes them " "together to produce a video.") self.copyrightString = self.uiTranslator.translate("AboutDialog", 'Copyright (C) 2014 The Free and ' 'Open Source Software Learning Centre') self.licenseTextString = self.uiTranslator.translate("AboutDialog", "Freeseer is licensed under the GPL " "version 3. This software is provided 'as-is',without any express or implied warranty. In " "no event will the authors be held liable for any damages arising from the use of this software.") self.aboutInfoString = u'<h1>' + NAME.capitalize() + u'</h1>' + \ u'<br><b>' + self.uiTranslator.translate("AboutDialog", "Version") + \ ": " + __version__ + u'</b>' + \ u'<p>' + self.descriptionString + u'</p>' + \ u'<p>' + self.copyrightString + u'</p>' + \ u'<p><a href="' + URL + u'">' + URL + u'</a></p>' \ u'<p>' + self.licenseTextString + u'</p>' \ u'<p>' + self.uiTranslator.translate("AboutDialog", "Record button graphics by") + \ u': <a href="' + RECORD_BUTTON_LINK + u'">' + RECORD_BUTTON_ARTIST + u'</a></p>' \ u'<p>' + self.uiTranslator.translate("AboutDialog", "Headphones graphics by") + \ u': <a href="' + HEADPHONES_LINK + u'">' + HEADPHONES_ARTIST + u'</a></p><br>' self.aboutInfo.setText(self.aboutInfoString) # --- End Main Text def openDocsUrl(self): """Opens a link to the Freeseer online documentation""" url = QUrl("http://freeseer.readthedocs.org") QDesktopServices.openUrl(url) def openNewIssueUrl(self): """Opens a link to the Freeseer new issue page""" url = QUrl("https://github.com/Freeseer/freeseer/issues/new") QDesktopServices.openUrl(url) def openContactUrl(self): """Opens a link to Freeseer's contact information""" url = QUrl("http://freeseer.readthedocs.org/en/latest/contact.html") QDesktopServices.openUrl(url)
class HelpedWidget(QWidget): """ HelpedWidget is a class that enables embedded help messages in widgets. """ STRONG_ERROR_COLOR = QColor(255, 215, 215) ERROR_COLOR = QColor(255, 235, 235) INVALID_COLOR = QColor(235, 235, 255) WARNING = "warning" EXCLAMATION = "ide/small/exclamation" validationChanged = pyqtSignal(bool) def __init__(self, widget_label="", help_link=""): QWidget.__init__(self) if not widget_label == "": self.label = widget_label + ":" else: self.label = "" self.help_link = help_link self.validation_message = None self.validation_type = None self.widget_layout = QHBoxLayout() self.widget_layout.setMargin(0) self.setLayout(self.widget_layout) self.setMinimumHeight(20) self.__error_popup = ErrorPopup() self.destroyed.connect(self.cleanup) def getLabel(self): """Returns the label of this widget if set or empty string.""" return self.label def addLayout(self, layout): """Add a layout to the layout of this widget.""" self.widget_layout.addLayout(layout) def addWidget(self, widget): """Add a widget to the layout of this widget.""" self.widget_layout.addWidget(widget) def addStretch(self, stretch=1): """Add stretch between widgets. """ self.widget_layout.addStretch(stretch) def setValidationMessage(self, message, validation_type=WARNING): """Add a warning or information icon to the widget with a tooltip""" message = message.strip() if message == "": self.validation_type = None self.validation_message = None self.__error_popup.hide() self.validationChanged.emit(True) else: self.validation_type = validation_type self.validation_message = message if self.hasFocus() or self.underMouse(): self.__error_popup.presentError(self, self.validation_message) self.validationChanged.emit(False) # HelpCenter.getHelpCenter("ERT").setHelpMessageLink() # MessageCenter().setWarning(self, self.validation_message) def isValid(self): return self.validation_message is None def includeLabel(self): label_widget = QLabel(self.label) self.widget_layout.insertWidget(0, label_widget) def enterEvent(self, event): QWidget.enterEvent(self, event) try: HelpCenter.getHelpCenter("ERT").setHelpMessageLink(self.help_link) except AttributeError: pass # if HelpedWidget.__error_popup is None: # HelpedWidget.__error_popup = ErrorPopup() if self.validation_message is not None: self.__error_popup.presentError(self, self.validation_message) def leaveEvent(self, event): QWidget.leaveEvent(self, event) if self.__error_popup is not None: self.__error_popup.hide() def cleanup(self): """ Remove any model attachment or similar. Called when QT object is destroyed.""" pass def hideEvent(self, hide_event): self.__error_popup.hide() super(HelpedWidget, self).hideEvent(hide_event) @staticmethod def addHelpToWidget(widget, link): original_enter_event = widget.enterEvent def enterEvent(event): original_enter_event(event) try: HelpCenter.getHelpCenter("ERT").setHelpMessageLink(link) except AttributeError: pass widget.enterEvent = enterEvent
class LineEdit(QLineEdit): inactiveText = QtDynamicProperty('inactiveText', unicode) widgetSpacing = QtDynamicProperty('widgetSpacing', int) def __init__(self, parent=None, contents=u""): QLineEdit.__init__(self, contents, parent) box_direction = QBoxLayout.RightToLeft if self.isRightToLeft() else QBoxLayout.LeftToRight self.inactiveText = u"" self.left_widget = SideWidget(self) self.left_widget.resize(0, 0) self.left_layout = QHBoxLayout(self.left_widget) self.left_layout.setContentsMargins(0, 0, 0, 0) self.left_layout.setDirection(box_direction) self.left_layout.setSizeConstraint(QLayout.SetFixedSize) self.right_widget = SideWidget(self) self.right_widget.resize(0, 0) self.right_layout = QHBoxLayout(self.right_widget) self.right_layout.setContentsMargins(0, 0, 0, 0) self.right_layout.setDirection(box_direction) self.right_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)) self.widgetSpacing = 2 self.left_widget.sizeHintChanged.connect(self._update_text_margins) self.right_widget.sizeHintChanged.connect(self._update_text_margins) @property def left_margin(self): return self.left_widget.sizeHint().width() + 2*self.right_layout.spacing() @property def right_margin(self): return self.right_widget.sizeHint().width() + 2*self.right_layout.spacing() def _update_text_margins(self): self.setTextMargins(self.left_margin, 0, self.right_margin, 0) self._update_side_widget_locations() def _update_side_widget_locations(self): option = QStyleOptionFrameV2() self.initStyleOption(option) spacing = self.right_layout.spacing() text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, option, self) text_rect.adjust(spacing, 0, -spacing, 0) mid_height = text_rect.center().y() + 1 - (text_rect.height() % 2) # need -1 correction for odd heights -Dan if self.left_layout.count() > 0: left_height = mid_height - self.left_widget.height()/2 left_width = self.left_widget.width() if left_width == 0: left_height = mid_height - self.left_widget.sizeHint().height()/2 self.left_widget.move(text_rect.x(), left_height) text_rect.setX(self.left_margin) text_rect.setY(mid_height - self.right_widget.sizeHint().height()/2.0) text_rect.setHeight(self.right_widget.sizeHint().height()) self.right_widget.setGeometry(text_rect) def event(self, event): event_type = event.type() if event_type == QEvent.LayoutDirectionChange: box_direction = QBoxLayout.RightToLeft if self.isRightToLeft() else QBoxLayout.LeftToRight self.left_layout.setDirection(box_direction) self.right_layout.setDirection(box_direction) elif event_type == QEvent.DynamicPropertyChange: property_name = event.propertyName() if property_name == 'widgetSpacing': self.left_layout.setSpacing(self.widgetSpacing) self.right_layout.setSpacing(self.widgetSpacing) self._update_text_margins() elif property_name == 'inactiveText': self.update() return QLineEdit.event(self, event) def resizeEvent(self, event): self._update_side_widget_locations() QLineEdit.resizeEvent(self, event) def paintEvent(self, event): QLineEdit.paintEvent(self, event) if not self.hasFocus() and not self.text() and self.inactiveText: options = QStyleOptionFrameV2() self.initStyleOption(options) text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, options, self) text_rect.adjust(self.left_margin+2, 0, -self.right_margin, 0) painter = QPainter(self) painter.setPen(self.palette().brush(QPalette.Disabled, QPalette.Text).color()) painter.drawText(text_rect, Qt.AlignLeft | Qt.AlignVCenter, self.inactiveText) def addHeadWidget(self, widget): if self.isRightToLeft(): self.right_layout.insertWidget(1, widget) else: self.left_layout.addWidget(widget) def addTailWidget(self, widget): if self.isRightToLeft(): self.left_layout.addWidget(widget) else: self.right_layout.insertWidget(1, widget) def removeWidget(self, widget): self.left_layout.removeWidget(widget) self.right_layout.removeWidget(widget) widget.hide()
class AboutWidget(QWidget): """ Common About Dialog for the Freeseer Project. This should be used for the about dialog when including one in GUIs. Layout: Logo | About Infos | Buttons """ def __init__(self, parent=None): QWidget.__init__(self, parent) self.setMinimumSize(100, 400) self.current_language = "en_US" self.uiTranslator = QTranslator() self.uiTranslator.load(":/languages/tr_en_US.qm") icon = QIcon() icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.mainlayout = QGridLayout() self.setLayout(self.mainlayout) # Left top side of grid, Logo self.logo = QLabel("Logo") self.logo.setPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png"))) self.mainlayout.addWidget(self.logo, 0, 0) # Right top side of grid, Infos self.aboutInfo = QLabel("About Info", openExternalLinks=True) self.aboutInfo.setWordWrap(True) self.mainlayout.addWidget(self.aboutInfo, 0, 1) # Right bottom side of grid, Buttons self.buttonsLayout = QHBoxLayout() self.issueButton = QPushButton("Report an issue") self.docsButton = QPushButton("Freeseer documentation") self.contactButton = QPushButton("Contact us") self.buttonsLayout.insertWidget(0, self.docsButton) self.buttonsLayout.insertWidget(1, self.issueButton) self.buttonsLayout.insertWidget(2, self.contactButton) self.mainlayout.addLayout(self.buttonsLayout, 2, 1) self.connect(self.docsButton, SIGNAL('clicked()'), self.openDocsUrl) self.connect(self.issueButton, SIGNAL('clicked()'), self.openNewIssueUrl) self.connect(self.contactButton, SIGNAL('clicked()'), self.openContactUrl) self.retranslate() def retranslate(self, language=None): if language is not None: self.current_language = language self.uiTranslator.load(":/languages/tr_%s.qm" % self.current_language) # # Main Text # self.descriptionString = self.uiTranslator.translate("AboutDialog", "Freeseer is a video capture utility capable of capturing presentations. It captures " "video sources such as usb, firewire, or local desktop along with audio and mixes them " "together to produce a video.") self.copyrightString = self.uiTranslator.translate("AboutDialog", 'Copyright (C) 2014 The Free and ' 'Open Source Software Learning Centre') self.licenseTextString = self.uiTranslator.translate("AboutDialog", "Freeseer is licensed under the GPL " "version 3. This software is provided 'as-is',without any express or implied warranty. In " "no event will the authors be held liable for any damages arising from the use of this software.") self.aboutInfoString = u'<h1>' + NAME + u'</h1>' + \ u'<br><b>' + self.uiTranslator.translate("AboutDialog", "Version") + ": " + __version__ + u'</b>' + \ u'<p>' + self.descriptionString + u'</p>' + \ u'<p>' + self.copyrightString + u'</p>' + \ u'<p><a href="' + URL + u'">' + URL + u'</a></p>' \ u'<p>' + self.licenseTextString + u'</p>' \ u'<p>' + self.uiTranslator.translate("AboutDialog", "Record button graphics by") + \ u': <a href="' + RECORD_BUTTON_LINK + u'">' + RECORD_BUTTON_ARTIST + u'</a></p>' \ u'<p>' + self.uiTranslator.translate("AboutDialog", "Headphones graphics by") + \ u': <a href="' + HEADPHONES_LINK + u'">' + HEADPHONES_ARTIST + u'</a></p><br>' self.aboutInfo.setText(self.aboutInfoString) # --- End Main Text def openDocsUrl(self): """Opens a link to the Freeseer online documentation""" url = QUrl("http://freeseer.readthedocs.org") QDesktopServices.openUrl(url) def openNewIssueUrl(self): """Opens a link to the Freeseer new issue page""" url = QUrl("https://github.com/Freeseer/freeseer/issues/new") QDesktopServices.openUrl(url) def openContactUrl(self): """Opens a link to Freeseer's contact information""" url = QUrl("http://freeseer.readthedocs.org/en/latest/contact.html") QDesktopServices.openUrl(url)
class ComboBoxPanel(QWidget): def __init__(self, parent, editable=False, spacerItemMove=False): QWidget.__init__(self, parent) while not isinstance(parent, QDialog): parent = parent.parent() self.setObjectName("ComboBoxPanel" + str(len(parent.findChildren(ComboBoxPanel)))) self.hLayoutBoxPanel = QHBoxLayout(self) self.hLayoutBoxPanel.setSpacing(0) self.hLayoutBoxPanel.setContentsMargins(0, 0, 0, 0) self.hLayoutBoxPanel.setObjectName(("hLayoutBoxPanel")) self.frameBoxPanel = QFrame(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.frameBoxPanel.sizePolicy().hasHeightForWidth()) self.frameBoxPanel.setSizePolicy(sizePolicy) self.frameBoxPanel.setFrameShape(QFrame.NoFrame) self.frameBoxPanel.setFrameShadow(QFrame.Raised) self.frameBoxPanel.setObjectName(("frameBoxPanel")) self.hLayoutframeBoxPanel = QHBoxLayout(self.frameBoxPanel) self.hLayoutframeBoxPanel.setSpacing(0) self.hLayoutframeBoxPanel.setMargin(0) self.hLayoutframeBoxPanel.setObjectName(("hLayoutframeBoxPanel")) self.captionLabel = QLabel(self.frameBoxPanel) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.captionLabel.sizePolicy().hasHeightForWidth()) self.captionLabel.setSizePolicy(sizePolicy) self.captionLabel.setMinimumSize(QSize(200, 0)) self.captionLabel.setMaximumSize(QSize(200, 16777215)) font = QFont() font.setBold(False) font.setWeight(50) self.captionLabel.setFont(font) self.captionLabel.setObjectName(("captionLabel")) self.hLayoutframeBoxPanel.addWidget(self.captionLabel) self.comboBox = QComboBox(self.frameBoxPanel) self.comboBox.setEnabled(True) font = QFont() font.setBold(False) font.setWeight(50) self.comboBox.setFont(font) self.comboBox.setObjectName(self.objectName() + "_comboBox") self.comboBox.setMinimumWidth(70) # self.comboBox.setMaximumWidth(70) # self.hLayoutframeBoxPanel.addWidget(self.lineEdit) self.hLayoutframeBoxPanel.addWidget(self.comboBox) self.imageButton = QToolButton(self.frameBoxPanel) self.imageButton.setText(("")) icon = QIcon() icon.addPixmap(QPixmap(("Resource/convex_hull.png")), QIcon.Normal, QIcon.Off) self.imageButton.setIcon(icon) self.imageButton.setObjectName(("imageButton")) self.imageButton.setVisible(False) self.hLayoutframeBoxPanel.addWidget(self.imageButton) self.hLayoutBoxPanel.addWidget(self.frameBoxPanel) if not spacerItemMove: spacerItem = QSpacerItem(10, 10, QSizePolicy.Expanding, QSizePolicy.Minimum) self.hLayoutBoxPanel.addItem(spacerItem) self.comboBox.currentIndexChanged.connect(self.comboBoxChanged) # self.comboBox.editTextChanged.connect(self.comboBoxEditTextChanged) self.imageButton.clicked.connect(self.imageButtonClicked) self.captionUnits = "" self.hasObject = False self.objectList = [] if editable == True: self.lineEdit = QLineEdit(self.frameBoxPanel) self.lineEdit.setObjectName("lineEdit") self.hLayoutframeBoxPanel.insertWidget(1, self.lineEdit) self.comboBox.setLineEdit(self.lineEdit) self.lineEdit.returnPressed.connect(self.comboBoxEditTextChanged) def FindString(self, string): return self.comboBox.findText(string) def comboBoxEditTextChanged(self): self.comboBox.showPopup() def get_Count(self): return self.comboBox.count() Count = property(get_Count, None, None, None) def method_0(self): return self.comboBox.currentIndex( ) >= 0 and self.SelectedItem != None and self.SelectedItem != "" def method_3(self, string_0): return self.comboBox.findText(string_0) def method_11(self, string_0): if (self.IsEmpty): return "%s%s\t" % (string_0, self.Caption) return "%s%s\t%s %s" % (string_0, self.Caption, self.Value, self.CaptionUnits) def comboBoxChanged(self): self.emit(SIGNAL("Event_0"), self) def IndexOf(self, item): if isinstance(item, str) or isinstance(item, QString): return self.comboBox.findText(item) else: return self.comboBox.findText(item.ToString()) def Contains(self, item): compStr = None if isinstance(item, str): compStr = item elif isinstance(item, float) or isinstance(item, int): compStr = str(item) else: compStr = item.ToString() for i in range(self.comboBox.count()): comboItemstr = self.comboBox.itemText(i) if compStr == comboItemstr: return True return False def Clear(self): self.comboBox.clear() self.objectList = [] self.hasObject = False def Add(self, item): if not isinstance(item, str) and not isinstance(item, QString): self.comboBox.addItem(item.ToString()) self.objectList.append(item) self.hasObject = True return self.comboBox.addItem(item) self.hasObject = False def Insert(self, index, item): if not isinstance(item, str) and not isinstance(item, QString): self.comboBox.insertItem(index, item.ToString()) self.objectList.insert(index, item) self.hasObject = True return self.comboBox.insertItem(index, item) self.hasObject = False def imageButtonClicked(self): self.emit(SIGNAL("Event_3"), self) def get_Caption(self): caption = self.captionLabel.text() findIndex = caption.indexOf("(") if findIndex > 0: val = caption.left(findIndex) return val return caption def set_Caption(self, captionStr): if captionStr == "": self.captionLabel.setText("") self.LabelWidth = 0 return if self.CaptionUnits != "" and self.CaptionUnits != None: self.captionLabel.setText(captionStr + "(" + QString(self.CaptionUnits) + ")" + ":") else: self.captionLabel.setText(captionStr + ":") Caption = property(get_Caption, set_Caption, None, None) def get_CaptionUnits(self): return self.captionUnits def set_CaptionUnits(self, captionUnits): self.captionUnits = captionUnits CaptionUnits = property(get_CaptionUnits, set_CaptionUnits, None, None) def set_ButtonVisible(self, bool): self.imageButton.setVisible(bool) ButtonVisible = property(None, set_ButtonVisible, None, None) # def get_Value(self): # return self.comboBox.currentIndex() # def set_Value(self, value): # try: # self.comboBox.setCurrentIndex(value) # except: # self.textBox.setText("") # Value = property(get_Value, set_Value, None, None) def get_IsEmpty(self): return self.comboBox.currentText() == "" or self.comboBox.currentIndex( ) == -1 IsEmpty = property(get_IsEmpty, None, None, None) def get_ReadOnly(self): return self.textBox.isReadOnly() # def set_ReadOnly(self, bool): # self.comboBox.setR.setReadOnly(bool) # ReadOnly = property(get_ReadOnly, set_ReadOnly, None, None) def set_LabelWidth(self, width): self.captionLabel.setMinimumSize(QSize(width, 0)) self.captionLabel.setMaximumSize(QSize(width, 16777215)) LabelWidth = property(None, set_LabelWidth, None, None) def set_Width(self, width): self.comboBox.setMinimumSize(QSize(width, 0)) self.comboBox.setMaximumSize(QSize(width, 16777215)) Width = property(None, set_Width, None, None) def set_Button(self, imageName): if imageName == None or imageName == "": self.imageButton.setVisible(False) return icon = QIcon() icon.addPixmap(QPixmap(("Resource/" + imageName)), QIcon.Normal, QIcon.Off) self.imageButton.setIcon(icon) self.imageButton.setVisible(True) Button = property(None, set_Button, None, None) def get_SelectedIndex(self): return self.comboBox.currentIndex() def set_SelectedIndex(self, index): if self.comboBox.count() == 0: return if index > self.comboBox.count() - 1: self.comboBox.setCurrentIndex(0) else: self.comboBox.setCurrentIndex(index) SelectedIndex = property(get_SelectedIndex, set_SelectedIndex, None, None) def get_Value(self): return self.comboBox.currentIndex() def set_Value(self, valueStr): if self.comboBox.count() == 0: return if valueStr == None: self.SelectedIndex = -1 return self.comboBox.setCurrentIndex(self.comboBox.findText(str(valueStr))) Value = property(get_Value, set_Value, None, None) def get_Items(self): # if self.hasObject: # return self.objectList itemList = [] if self.comboBox.count() > 0: for i in range(self.comboBox.count()): itemList.append(self.comboBox.itemText(i)) return itemList def set_AddItems(self, strList): self.Clear() if len(strList) != 0 and (not isinstance(strList[0], str) and not isinstance(strList[0], QString)): for obj in strList: self.comboBox.addItem(obj.ToString()) self.objectList.append(obj) self.hasObject = True return self.comboBox.addItems(strList) Items = property(get_Items, set_AddItems, None, None) def get_Enabled(self): return self.comboBox.isEnabled() def set_Enabled(self, bool): self.comboBox.setEnabled(bool) Enabled = property(get_Enabled, set_Enabled, None, None) def get_Visible(self): return self.isVisible() def set_Visible(self, bool): self.setVisible(bool) Visible = property(get_Visible, set_Visible, None, None) def get_Editable(self): return self.comboBox.isEditable() def set_Editable(self, bool): self.comboBox.setEditable(bool) Editable = property(get_Editable, set_Editable, None, None) def get_SelectedItem(self): if self.comboBox.count() == 0: return None if self.hasObject: return self.objectList[self.SelectedIndex] return self.comboBox.currentText() def set_SelectedItem(self, val): index = self.comboBox.findText(val) self.comboBox.setCurrentIndex(index) SelectedItem = property(get_SelectedItem, set_SelectedItem, None, None)
class LineEdit(QLineEdit): inactiveText = QtDynamicProperty('inactiveText', unicode) widgetSpacing = QtDynamicProperty('widgetSpacing', int) def __init__(self, parent=None, contents=u""): QLineEdit.__init__(self, contents, parent) box_direction = QBoxLayout.RightToLeft if self.isRightToLeft( ) else QBoxLayout.LeftToRight self.inactiveText = u"" self.left_widget = SideWidget(self) self.left_widget.resize(0, 0) self.left_layout = QHBoxLayout(self.left_widget) self.left_layout.setContentsMargins(0, 0, 0, 0) self.left_layout.setDirection(box_direction) self.left_layout.setSizeConstraint(QLayout.SetFixedSize) self.right_widget = SideWidget(self) self.right_widget.resize(0, 0) self.right_layout = QHBoxLayout(self.right_widget) self.right_layout.setContentsMargins(0, 0, 0, 0) self.right_layout.setDirection(box_direction) self.right_layout.addItem( QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)) self.widgetSpacing = 2 self.left_widget.sizeHintChanged.connect(self._update_text_margins) self.right_widget.sizeHintChanged.connect(self._update_text_margins) @property def left_margin(self): return self.left_widget.sizeHint().width( ) + 2 * self.right_layout.spacing() @property def right_margin(self): return self.right_widget.sizeHint().width( ) + 2 * self.right_layout.spacing() def _update_text_margins(self): self.setTextMargins(self.left_margin, 0, self.right_margin, 0) self._update_side_widget_locations() def _update_side_widget_locations(self): option = QStyleOptionFrameV2() self.initStyleOption(option) spacing = self.right_layout.spacing() text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, option, self) text_rect.adjust(spacing, 0, -spacing, 0) mid_height = text_rect.center().y() + 1 - ( text_rect.height() % 2) # need -1 correction for odd heights -Dan if self.left_layout.count() > 0: left_height = mid_height - self.left_widget.height() / 2 left_width = self.left_widget.width() if left_width == 0: left_height = mid_height - self.left_widget.sizeHint().height( ) / 2 self.left_widget.move(text_rect.x(), left_height) text_rect.setX(self.left_margin) text_rect.setY(mid_height - self.right_widget.sizeHint().height() / 2.0) text_rect.setHeight(self.right_widget.sizeHint().height()) self.right_widget.setGeometry(text_rect) def event(self, event): event_type = event.type() if event_type == QEvent.LayoutDirectionChange: box_direction = QBoxLayout.RightToLeft if self.isRightToLeft( ) else QBoxLayout.LeftToRight self.left_layout.setDirection(box_direction) self.right_layout.setDirection(box_direction) elif event_type == QEvent.DynamicPropertyChange: property_name = event.propertyName() if property_name == 'widgetSpacing': self.left_layout.setSpacing(self.widgetSpacing) self.right_layout.setSpacing(self.widgetSpacing) self._update_text_margins() elif property_name == 'inactiveText': self.update() return QLineEdit.event(self, event) def resizeEvent(self, event): self._update_side_widget_locations() QLineEdit.resizeEvent(self, event) def paintEvent(self, event): QLineEdit.paintEvent(self, event) if not self.hasFocus() and not self.text() and self.inactiveText: options = QStyleOptionFrameV2() self.initStyleOption(options) text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, options, self) text_rect.adjust(self.left_margin + 2, 0, -self.right_margin, 0) painter = QPainter(self) painter.setPen(self.palette().brush(QPalette.Disabled, QPalette.Text).color()) painter.drawText(text_rect, Qt.AlignLeft | Qt.AlignVCenter, self.inactiveText) def addHeadWidget(self, widget): if self.isRightToLeft(): self.right_layout.insertWidget(1, widget) else: self.left_layout.addWidget(widget) def addTailWidget(self, widget): if self.isRightToLeft(): self.left_layout.addWidget(widget) else: self.right_layout.insertWidget(1, widget) def removeWidget(self, widget): self.left_layout.removeWidget(widget) self.right_layout.removeWidget(widget) widget.hide()
class MatplotlibFigure(PluginWidget): """ Matplotlib Figure Dockwidget """ ID = 'figure' features = QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable location = Qt.LeftDockWidgetArea def __init__(self, parent, canvas, num): self.canvas = canvas self.num = num PluginWidget.__init__(self, parent) # Close button self.close_button = create_toolbutton(self, triggered=self.close, icon=get_icon("fileclose.png"), tip=self.tr("Close figure %1").arg(num)) # Top horizontal layout self.h_layout = QHBoxLayout() self.statusbar = self.set_statusbar() self.h_layout.addWidget(self.statusbar) self.h_layout.addWidget(self.close_button) # Main vertical layout self.v_layout = QVBoxLayout() self.v_layout.addLayout(self.h_layout) self.v_layout.addWidget(self.canvas) self.setLayout(self.v_layout) def get_widget_title(self): """Return widget title""" return self.tr("Figure %d" % self.num) def get_focus_widget(self): """ Return the widget to give focus to when this plugin's dockwidget is raised on top-level """ return self.canvas def set_statusbar(self): """Set status bar""" statusbar = QLabel('') statusbar.setFont(get_font(self.ID, 'statusbar')) return statusbar def statusBar(self): """Fake Qt method --> for matplotlib""" return self def showMessage(self, message): """Fake Qt method --> for matplotlib""" self.statusbar.setText(" " + message) def addToolBar(self, toolbar): """Fake Qt method --> for matplotlib""" self.h_layout.insertWidget(0, toolbar) def refresh(self): """Refresh widget""" pass def set_actions(self): """Setup actions""" return (None, None) def closing(self, cancelable=False): """Perform actions before parent main window is closed""" return True def closeEvent(self, event): """closeEvent reimplementation""" if self in self.main.widgetlist: # if self is not in self.main.widgetlist, it only means that a # QMainWindow has been created instead of a QDockWidget self.main.widgetlist.pop(self.main.widgetlist.index(self)) self.dockwidget.close() event.accept()
class AboutWidget(QWidget): """ Common About Dialog for the Freeseer Project. This should be used for the about dialog when including one in GUIs. Layout: Logo | About Infos | Buttons """ def __init__(self, parent=None): QWidget.__init__(self, parent) self.current_language = "en_US" self.uiTranslator = QTranslator() self.uiTranslator.load(":/languages/tr_en_US.qm") self.fontSize = self.font().pixelSize() self.fontUnit = "px" if self.fontSize == -1: # Font is set as points, not pixels. self.fontUnit = "pt" self.fontSize = self.font().pointSize() icon = QIcon() self.logoPixmap = QPixmap(_fromUtf8(":/freeseer/logo.png")) icon.addPixmap(self.logoPixmap, QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.mainLayout = QGridLayout() self.setLayout(self.mainLayout) # Logo self.logo = QLabel("Logo") # To offset the logo so that it's to the right of the title self.logo.setStyleSheet("QLabel {{ margin-left: {} {} }}".format( 90 + (self.fontSize * 2.5), self.fontUnit)) self.logo.setPixmap(self.logoPixmap.scaledToHeight(80)) self.mainLayout.addWidget(self.logo, 0, 0, Qt.AlignTop) # Info self.aboutInfo = QLabel("About Info", openExternalLinks=True) self.aboutInfo.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.aboutInfo.setWordWrap(True) self.mainLayout.addWidget(self.aboutInfo, 0, 0) # Buttons self.buttonsLayout = QHBoxLayout() self.issueButton = QPushButton("Report an issue") self.docsButton = QPushButton("Freeseer documentation") self.contactButton = QPushButton("Contact us") self.buttonsLayout.insertWidget(0, self.docsButton) self.buttonsLayout.insertWidget(1, self.issueButton) self.buttonsLayout.insertWidget(2, self.contactButton) self.mainLayout.addLayout(self.buttonsLayout, 2, 0) self.connect(self.docsButton, SIGNAL('clicked()'), self.openDocsUrl) self.connect(self.issueButton, SIGNAL('clicked()'), self.openNewIssueUrl) self.connect(self.contactButton, SIGNAL('clicked()'), self.openContactUrl) self.retranslate() def retranslate(self, language=None): if language is not None: self.current_language = language self.uiTranslator.load(":/languages/tr_%s.qm" % self.current_language) # # Main Text # self.descriptionString = self.uiTranslator.translate( "AboutDialog", "Freeseer is a video capture utility capable of capturing presentations. It captures " "video sources such as usb, firewire, or local desktop along with audio and mixes them " "together to produce a video.") self.copyrightString = self.uiTranslator.translate( "AboutDialog", 'Copyright (C) 2014 The Free and ' 'Open Source Software Learning Centre') self.licenseTextString = self.uiTranslator.translate( "AboutDialog", "Freeseer is licensed under the GPL " "version 3. This software is provided 'as-is',without any express or implied warranty. In " "no event will the authors be held liable for any damages arising from the use of this software." ) self.aboutInfoString = u'<h1>' + NAME.capitalize() + u'</h1>' + \ u'<br><b>' + self.uiTranslator.translate("AboutDialog", "Version") + \ ": " + __version__ + u'</b>' + \ u'<p>' + self.descriptionString + u'</p>' + \ u'<p>' + self.copyrightString + u'</p>' + \ u'<p><a href="' + URL + u'">' + URL + u'</a></p>' \ u'<p>' + self.licenseTextString + u'</p>' \ u'<p>' + self.uiTranslator.translate("AboutDialog", "Record button graphics by") + \ u': <a href="' + RECORD_BUTTON_LINK + u'">' + RECORD_BUTTON_ARTIST + u'</a></p>' \ u'<p>' + self.uiTranslator.translate("AboutDialog", "Headphones graphics by") + \ u': <a href="' + HEADPHONES_LINK + u'">' + HEADPHONES_ARTIST + u'</a></p><br>' self.aboutInfo.setText(self.aboutInfoString) # --- End Main Text def openDocsUrl(self): """Opens a link to the Freeseer online documentation""" url = QUrl("http://freeseer.readthedocs.org") QDesktopServices.openUrl(url) def openNewIssueUrl(self): """Opens a link to the Freeseer new issue page""" url = QUrl("https://github.com/Freeseer/freeseer/issues/new") QDesktopServices.openUrl(url) def openContactUrl(self): """Opens a link to Freeseer's contact information""" url = QUrl("http://freeseer.readthedocs.org/en/latest/contact.html") QDesktopServices.openUrl(url)
class FiltersListWidget(QWidget): def __init__(self, client, parent=None): QWidget.__init__(self, parent) self.client = client self.filtersWidgetsList = [] self.args = {} self.filters = [] self.filtersWidget = QHBoxLayout(self) self.filtersWidget.setContentsMargins(5, 1, 1, 1) label = u'<h3>%s</h3>' % tr("Filters:") self.filtersWidget.addWidget(QLabel(label)) self.add_link = createLink(':/icons-20/add.png', self.addFilter) self.filtersWidget.addWidget(self.add_link) self.filtersWidget.addStretch() self.compatibility = None def addFilter(self): dialog = EditFilterDialog(self.client, self.args, self.filters, parent=self) value = dialog.run() if value: self.filterChanged(value.filter_arg, value.getValue()) def update(self, args, filters): for filterWidget in self.filtersWidgetsList: self.filtersWidget.removeWidget(filterWidget) filterWidget.setParent(None) filterWidget.hide() self.args = args self.filters = filters self.filtersWidgetsList = [] for key, value in args.items(): try: filterWidget = FilterWidget(self.client, key, value, self) except FilterWidgetError: continue self.connect(filterWidget, SIGNAL('changeFilter'), self.filterChanged) self.connect(filterWidget, SIGNAL('removeFilter'), self.removeFilter) self.filtersWidget.insertWidget(1, filterWidget) self.filtersWidgetsList += [filterWidget] available_filters = set(self.filters).difference(set(self.args.iterkeys())) if len(available_filters) > 0: self.add_link.show() else: self.add_link.hide() if not filters and not self.filtersWidgetsList: self.hide() else: self.show() def filterChanged(self, key, value): QTimer.singleShot(0, lambda: self.emit(SIGNAL('changeFilter'), key, value)) def removeFilter(self, key): QTimer.singleShot(0, lambda: self.emit(SIGNAL('removeFilter'), key)) def setCompatibility(self, compatibility): self.compatibility = compatibility
class FragmentFrame(QFrame): # Signals: SIG_REMOVE_FRAGMENT = 'removeFragment()' # Fragment edition switch FRAGMENT_EDITION = False view = None fetcher = None def __init__(self, fragment, args, client, animation_manager=None, parent=None, has_menu_pos=True): """ @fragment [Fragment] user_settings.Fragment object to describe fragment @client [RpcdClient] client @parent [QWidget] parent widget """ #assert isinstance(client, RpcdClient) assert frag_types.has_key(fragment.type) QFrame.__init__(self, parent) self.animation_manager = animation_manager self.has_menu_pos = has_menu_pos self.fragment = fragment self.fetcher = frag_types[fragment.type].fetcher(fragment, args, client) self.connect(self.fetcher, SIGNAL(self.fetcher.ERROR_SIGNAL), self.errorHandler) self.window = parent self.cumulative_mode = False self.interval = Interval('daily') self.setFragmentColor() self.setFrameShadow(QFrame.Sunken) self.setFrameShape(QFrame.StyledPanel) self.setContextMenuPolicy(Qt.ActionsContextMenu) self.toolspace = None self.vbox = QVBoxLayout() # self.vbox.setContentsMargins(9,0,9,9) self.vbox.setContentsMargins(9,0,9,0) self.setLayout(self.vbox) self.stacked = QStackedWidget(self) updating_label = QLabel("<img src=\":/icons/refresh.png\" /><br />%s" % self.tr("Updating...")) updating_label.setAlignment(Qt.AlignHCenter|Qt.AlignVCenter) self.stacked.addWidget(updating_label) # Create all actions for the rightclick context menu self.action_list = [] self.switch_actions = {} self.viewlayout = QHBoxLayout() self.viewlayout.setContentsMargins(0,0,0,0) self.viewlayout.setSpacing(2) self.viewlayout.addStretch() widget = QWidget() widget.setLayout(self.viewlayout) self.vbox.addWidget(widget) self.line = QFrame(self) self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.line.setObjectName("line") # Menu to choose position of fragment if self.has_menu_pos: self.pos_menu = QMenu(tr('Position'), self) # self.pos_action = QAction(tr('Position'), self.pos_menu) def make_lambda(l): """ usefull to create the lambda function with a copied parameter. or it'll bug """ return lambda: QTimer.singleShot(0, lambda: self.setView(l)) self.buttons = [] button = QToolButton() button.visible = True button.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored) button.setMinimumSize(0,16) button.setIcon(QIcon(":/icons/refresh.png")) button.setFixedHeight(16) button.setToolTip(tr("Refresh")) self.connect(button, SIGNAL("clicked()"), self.updateData) self.viewlayout.addWidget(button) self.buttons.append(button) # All of the views available for this kind of fragment. if len(frag_types[fragment.type].views) > 1: for label in frag_types[fragment.type].views: try: item_name = views_list_label[label] except KeyError: continue # item_name returns a unicode string, but PyQT (Qt 4.2.1) won't convert it to a char* # unless we convert it to a non-unicode string .... action = QAction(QIcon(':/icons/%s' % label), tr("Switch to %s") % self.tr(unicode(item_name)), self) self.connect(action, SIGNAL("triggered()"), make_lambda(label)) self.action_list += [action] self.switch_actions[label] = action button = QToolButton() button.visible = True button.setBackgroundRole(QPalette.Button) button.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum) button.setMinimumSize(0,16) button.setFixedHeight(16) button.setIcon(QIcon(":/icons/%s" % label)) button.setToolTip(tr("Switch to %s") % self.tr(unicode(item_name))) self.connect(button, SIGNAL("clicked()"), make_lambda(label)) self.viewlayout.addWidget(button) self.buttons.append(button) # Separator action = QAction(self) action.setSeparator(True) self.action_list += [action] # Refresh action = QAction(QIcon(':/icons/refresh.png'), tr('Refresh'), self) self.connect(action, SIGNAL('triggered()'), self.updateData) self.action_list += [action] if self.FRAGMENT_EDITION: # Edit action = QAction(QIcon(':/icons/edit.png'), tr('Edit this fragment...'), self) self.connect(action, SIGNAL('triggered()'), self.editFragment) self.action_list += [action] # Delete action = QAction(QIcon(':/icons/moins.png'), tr('Delete this fragment'), self) self.connect(action, SIGNAL('triggered()'), self.removeFragment) self.action_list += [action] self.setView(fragment.view, update=False) self.setAcceptDrops(True) self.pos = -1 def mouseMoveEvent(self, event): if event.buttons() != Qt.LeftButton: return mimeData = QMimeData() if self.pos == -1: return mimeData.setData("splitter/fragment", QByteArray.number(self.pos)) drag = QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(event.pos() - self.rect().topLeft()) dropAction = drag.start(Qt.MoveAction) if dropAction == Qt.MoveAction: self.close() def dragEnterEvent(self, event): event.accept() def dropEvent(self, event): data = event.mimeData().data("splitter/fragment").toInt() if not data[1]: return frame_pos = data[0] if frame_pos == self.pos: return event.setDropAction(Qt.MoveAction) event.accept() self.window.changedPositionFragment(self.pos, frame_pos) # def __del__(self): # self.destructor() def destructor(self): if self.view: self.freeView() if self.fetcher: self.disconnect(self.fetcher, SIGNAL(self.fetcher.ERROR_SIGNAL), self.errorHandler) self.fetcher.destructor() self.fetcher = None def getView(self): return self.view def getFragment(self): return self.fragment def setCumulative(self, cumulative): self.cumulative_mode = cumulative if self.view: self.view.setCumulative(cumulative) def setInterval(self, interval): self.interval = interval if self.view: self.view.setInterval(interval) def setFragmentColor(self): # XXX: We have to put classes which we colorize, because some objects bug # when we try to put a background on them. For example, do NOT colorize # QScrollBar, it'll not work anyway: # http://doc.trolltech.com/4.4/stylesheet-examples.html#customizing-qscrollbar # "The QScrollBar can be styled using its subcontrols like handle, # add-line, sub-line, and so on. Note that if one property or # sub-control is customized, all the other properties or sub-controls # must be customized as well." self.setStyleSheet(""" QFrame, QPushButton, QTableCornerButton, QAbstractSpinBox, QLineEdit { background-color: #%06X; } """ % self.fragment.background_color) def editFragment(self): if AddFragDialog(self.window, self.fragment, self).run(): self.setFragmentColor() self.setView(self.fragment.view, update=True) def removeFragment(self): reply = QMessageBox.question(self, self.tr("Delete a fragment"), unicode(self.tr('Are you sure to delete the fragment "%s" from the view?')) % self.fragment.title, QMessageBox.Yes|QMessageBox.No) if reply == QMessageBox.Yes: QTimer.singleShot(0, self._removeFragment_emit) def _removeFragment_emit(self): self.emit(SIGNAL(self.SIG_REMOVE_FRAGMENT)) # def resizeEvent(self, event): # QFrame.resizeEvent(self, event) # self.view.resize(event.size()) def freeView(self): if self.view: self.view.destructor() self.disconnect(self.view, SIGNAL('open_page'), self._open_page) self.disconnect(self.view, SIGNAL('add_filter'), self._add_filter) self.disconnect(self.view, SIGNAL('updating'), self._show_animation) self.disconnect(self.view, SIGNAL('updated'), self._show_view) self.disconnect(self.view, SIGNAL('EAS_Message'), self.EAS_SendMessage) self.stacked.removeWidget(self.view) self.vbox.removeWidget(self.stacked) self.vbox.removeWidget(self.line) self.view.setParent(None) self.view.hide() self.view.deleteLater() if self.toolspace: self.viewlayout.removeWidget(self.toolspace) self.toolspace.setParent(None) self.toolspace.hide() self.toolspace.deleteLater() if self.view and hasattr(self.view, "uuid"): if self.animation_manager: self.animation_manager.remove(self.view.uuid) self.view = None self.toolspace = None def setView(self, label, update=True): # If there isn't any view for this fragment, use the first available view # of this kind of fragment. if not label: assert frag_types.has_key(self.fragment.type) assert len(frag_types[self.fragment.type].views) > 0 label = frag_types[self.fragment.type].views[0] for button in self.buttons: if label in button.toolTip(): button.visible = False else: if not button.isEnabled(): button.visible = True # assert views_list.has_key(label) self.freeView() # Create the view object. self.view = views_list[label](self.fetcher, self) if label == "histo" or label == 'pie': self.view.is_graphics_view = True if label == 'histo': self.view.chart_type = BARCHART else: self.view.chart_type = PIECHART else: self.view.is_graphics_view = False if label != "error": self.connect(self, SIGNAL("closed"), self.setClosed) if self.animation_manager: if self.view.is_graphics_view: self.connect(self.view, SIGNAL("animation_done(QString)"), self, SIGNAL("animation_done(QString)")) self.animation_manager.addView(self.view) self.connect(self.view, SIGNAL("showButtons"), self.showButtonsSlot) self.connect(self.view, SIGNAL("autoRefresh"), self.updateData) self.view.setCumulative(self.cumulative_mode) self.view.setInterval(self.interval) self.stacked.insertWidget(0, self.view) self._show_view() self.connect(self.view, SIGNAL('open_page'), self._open_page) self.connect(self.view, SIGNAL('add_filter'), self._add_filter) self.connect(self.view, SIGNAL('updating'), self._show_animation) self.connect(self.view, SIGNAL('updated'), self._show_view) self.connect(self.view, SIGNAL('EAS_Message'), self.EAS_SendMessage) # Set some features if there are available on each or each type of widget. if hasattr(self.view, 'setFrameShape'): self.view.setFrameShape(QFrame.NoFrame) self.view.setContextMenuPolicy(Qt.ActionsContextMenu) # All views can ask me to display a toolspace (a widget with all kind of # things in). self.view.title.setText(self.view.getTitle()) self.fragment.view = label self.toolspace = self.view.getToolspace() self.viewlayout.insertWidget(0, self.toolspace) self.vbox.addWidget(self.line) self.vbox.addWidget(self.stacked) # Set the new menu. for action in self.actions(): self.removeAction(action) for view_label, action in self.switch_actions.items(): action.setEnabled(view_label != self.fragment.view) for action in self.action_list: self.addAction(action) self.view.addAction(action) # Add view's eventual menu. view_actions = self.view.getActions() if view_actions: separator = QAction(self) separator.setSeparator(True) view_actions = [separator] + view_actions for action in view_actions: self.view.addAction(action) self.addAction(action) if self.has_menu_pos: self.view.addAction(self.pos_menu.menuAction()) self.addAction(self.pos_menu.menuAction()) if update: self.updateData() def setClosed(self): if self.view: self.view.setClosed() self.destructor() def errorHandler(self, e): """ This method is called when fetcher raises an error. """ # Store error in fragment, and the ErrorFragmentView will able to # load it error = exceptionAsUnicode(e) self.fragment.error = error # We keep last view in the fragment, to prevent setView() method to # put 'error' in the fragment.view string attribute. last_view = self.fragment.view self.setView('error', update=False) # load the error fragment self.fragment.view = last_view def showButtonsSlot(self): for button in self.buttons: if hasattr(button, 'visible'): if button.visible: button.setEnabled(True) else: button.setEnabled(False) def updateData(self): if hasattr(self.fragment, 'error'): self.setView(self.fragment.view, update=False) del self.fragment.error for button in self.buttons: button.setEnabled(False) self.view.requestData() def _open_page(self, *args, **kwargs): self.emit(SIGNAL('open_page'), *args, **kwargs) def _add_filter(self, *args, **kwargs): self.emit(SIGNAL('add_filter'), *args, **kwargs) def EAS_SendMessage(self, *args, **kwargs): self.emit(SIGNAL('EAS_Message'), *args, **kwargs) def _show_animation(self): self.stacked.setCurrentIndex(1) def _show_view(self): self.stacked.setCurrentIndex(0)