Beispiel #1
0
class _QueuedMessageWidget(QWidget):
    
    cleared = pyqtSignal()
    finished = pyqtSignal()
    shown = pyqtSignal()
    closed = pyqtSignal()
    linkActivated = pyqtSignal(unicode)
    linkHovered= pyqtSignal(unicode)
    buttonClicked = pyqtSignal(QAbstractButton)
    
    def __init__(self, *args):
        QWidget.__init__(self, *args)
        self._messages = []
        self._defaultTimeout = 0
        self._defaultPixmap = QPixmap(":/enkiicons/infos.png" )
        self._defaultBackground = QBrush( QColor( 250, 230, 147 ) )
        self._defaultForeground = QBrush( QColor( 0, 0, 0 ) )
        
        # pixmap
        self.lPixmap = QLabel( self )
        self.lPixmap.setAlignment( Qt.AlignCenter )
        self.lPixmap.setSizePolicy( QSizePolicy( QSizePolicy.Maximum, QSizePolicy.Preferred ) )
        
        # message
        self.lMessage = QLabel( self )
        self.lMessage.setAlignment( Qt.AlignVCenter | Qt.AlignLeft )
        self.lMessage.setSizePolicy( QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) )
        self.lMessage.setWordWrap( True )
        self.lMessage.setOpenExternalLinks( True )
        self.lMessage.setTextInteractionFlags( Qt.TextBrowserInteraction )
        
        # button
        self.dbbButtons = QDialogButtonBox( self )
        
        # if false - buttons don't have neither text nor icons
        self.dbbButtons.setStyleSheet("dialogbuttonbox-buttons-have-icons: true;")

        self.dbbButtons.setSizePolicy( QSizePolicy( QSizePolicy.Maximum, QSizePolicy.Preferred ) )
        
        self.setSizePolicy( QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Maximum ) )
        
        # layout
        self.hbl = QHBoxLayout( self )
        self.hbl.setMargin( 0 )
        self.hbl.addWidget( self.lPixmap, 0, Qt.AlignCenter )
        self.hbl.addWidget( self.lMessage )
        self.hbl.addWidget( self.dbbButtons, 0, Qt.AlignCenter )
        
        # connections
        self.lMessage.linkActivated.connect(self.linkActivated)
        self.lMessage.linkHovered.connect(self.linkHovered)
        self.dbbButtons.clicked.connect(self.buttonClicked)

    def sizeHint(self):
        return QWidget.minimumSizeHint(self)

    def openExternalLinks(self):
        return self.lMessage.openExternalLinks()

    def defaultTimeout(self):
        return self._defaultTimeout

    def defaultPixmap(self):
        return self._defaultPixmap

    def defaultBackground(self):
        return self._defaultBackground

    def defaultForeground(self):
        return self._defaultForeground

    def currentMessageInformations(self):
        return self.currentMessagePixmap(), self.currentMessageBackground(), self.currentMessageForeground()

    def pendingMessageCount(self):
        return len(self._messages)

    def currentMessage(self):
        return self._messages[0]

    def append(self, message, milliSeconds ):
        msg = _QueuedMessage()
        msg.message = message
        if milliSeconds == -1:
            msg.milliSeconds = self._defaultTimeout
        else:
           msg.milliSeconds = milliSeconds
        msg.pixmap = self._defaultPixmap
        msg.background = self._defaultBackground
        msg.foreground = self._defaultForeground
        
        self._messages.append(msg)
            
        if  len(self._messages) == 1 :
            QTimer.singleShot( 0, self.showMessage)

    def setOpenExternalLinks(self, open ):
        self.lMessage.setOpenExternalLinks( open )

    def setDefaultTimeout(self, timeout ):
        self._defaultTimeout = timeout

    def setDefaultPixmap(self, pixmap ):
        self._defaultPixmap = pixmap

    def setDefaultBackground(self, brush ):
        self._defaultBackground = brush

    def setDefaultForeground(self, brush ):
        self._defaultForeground = brush

    def remove(self, message ):
        raise NotImplemented()  # incorrect port from cpp fresh
        if not self._messages or self._messages.first() == message:
            return

        self._messages.removeOne( message )

    def clear(self):
        self._messages.clear()
        self.lPixmap.clear()
        self.lMessage.clear()
        self.dbbButtons.clear()
        self.cleared.emit()

    def currentMessagePixmap(self):
        msg = self.currentMessage()
        if msg.pixmap.isNull():
            return self._defaultPixmap
        else:
            return msg.pixmap

    def currentMessageBackground(self):
        msg = self.currentMessage()
        if msg.background == QBrush( Qt.NoBrush ):
            return self._defaultBackground
        else:
            return msg.background

    def currentMessageForeground(self):
        msg = self.currentMessage()
        if msg.foreground == QBrush( Qt.NoBrush ):
            return self._defaultForeground
        else:
            return msg.foreground

    def paintEvent(self, event ):
        if  self.pendingMessageCount() == 0 :
            QWidget.paintEvent(self, event )
            return
        
        painter = QPainter( self )
        painter.setPen( Qt.NoPen )
        painter.setBrush( self.currentMessageBackground() )
        painter.drawRect( self.contentsRect() )

    def buttonClicked(self, button ):
        msg = self.currentMessage()
        standardButton = self.dbbButtons.standardButton( button )
        
        if msg.slot is not None:
            msg.slot(standardButton, msg)
        
        self.closeMessage()

    def showMessage(self):
        # get message
        msg = self.currentMessage()
        
        # update palette
        pal = self.lMessage.palette()
        pal.setBrush( self.lMessage.foregroundRole(), self.currentMessageForeground() )
        self.lMessage.setPalette( pal )
        
        # format widget
        self.lPixmap.setPixmap( self.currentMessagePixmap() )
        self.lMessage.setText( msg.message )
        self.lMessage.setToolTip( msg.message )
        self.lMessage.setWhatsThis( msg.message )
        
        # set buttons
        if not msg.buttons:
            msg.buttons[ QDialogButtonBox.Close ] = None

        self.dbbButtons.clear()
        
        for button in msg.buttons.keys():
            pb = self.dbbButtons.addButton( button )
            
            if button in msg.buttons:
                pb.setText( msg.buttons[ button ] )
        
        # auto close if needed
        if msg.milliSeconds == -1:
            timeout = self._defaultTimeout
        else:
            timeout =  msg.milliSeconds
        
        if  timeout > 0:
            QTimer.singleShot( timeout, self.closeMessage )
        
        # signal.emit
        self.shown.emit()

    def closeMessage(self):
        # message.emit
        self.closed.emit()
        
        # remove remove current message from hash
        self._messages = self._messages[1:]
        
        # process next if possible, clear gui
        if self._messages:
            QTimer.singleShot( 0, self.showMessage)
        else:
            QTimer.singleShot( 0, self.clearMessage)
        
        # finished.emit message if needed
        if not self._messages:
            self.finished.emit()

    def clearMessage(self):
        self.lPixmap.clear()
        self.lMessage.clear()
        self.dbbButtons.clear()
class SourceSelectSingle(QDialog):
    """
    Class for handling selecting the source for the projector to use.
    Uses single dialog interface.
    """
    def __init__(self, parent, projectordb, edit=False):
        """
        Build the source select dialog.

        :param projectordb: ProjectorDB session to use
        """
        log.debug('Initializing SourceSelectSingle()')
        self.projectordb = projectordb
        super(SourceSelectSingle, self).__init__(parent)
        self.edit = edit
        if self.edit:
            title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text')
        else:
            title = translate('OpenLP.SourceSelectForm', 'Select Projector Source')
        self.setObjectName('source_select_single')
        self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png'))
        self.setModal(True)
        self.edit = edit

    def exec_(self, projector, edit=False):
        """
        Override initial method so we can build the tabs.

        :param projector: Projector instance to build source list from
        """
        self.projector = projector
        self.layout = QFormLayout() if self.edit else QVBoxLayout()
        self.layout.setObjectName('source_select_tabs_layout')
        self.layout.setSpacing(10)
        self.setLayout(self.layout)
        self.setMinimumWidth(350)
        self.button_group = [] if self.edit else QButtonGroup()
        self.source_text = self.projectordb.get_source_list(projector=projector)
        keys = list(self.source_text.keys())
        keys.sort()
        key_count = len(keys)
        button_list = []
        if self.edit:
            for key in keys:
                item = QLineEdit()
                item.setObjectName('source_key_%s' % key)
                source_item = self.projectordb.get_source_by_code(code=key, projector_id=self.projector.db_item.id)
                if source_item is None:
                    item.setText(PJLINK_DEFAULT_CODES[key])
                else:
                    item.old_text = item.text()
                    item.setText(source_item.text)
                self.layout.addRow(PJLINK_DEFAULT_CODES[key], item)
                self.button_group.append(item)
            self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Reset |
                                               QtGui.QDialogButtonBox.Discard |
                                               QtGui.QDialogButtonBox.Ok |
                                               QtGui.QDialogButtonBox.Cancel)
        else:
            for key in keys:
                source_text = self.projectordb.get_source_by_code(code=key, projector_id=self.projector.db_item.id)
                text = self.source_text[key] if source_text is None else source_text.text
                button = QtGui.QRadioButton(text)
                button.setChecked(True if key == projector.source else False)
                self.layout.addWidget(button)
                self.button_group.addButton(button, int(key))
                button_list.append(key)
            self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
                                               QtGui.QDialogButtonBox.Cancel)
        self.button_box.clicked.connect(self.button_clicked)
        self.layout.addWidget(self.button_box)
        self.setMinimumHeight(key_count*25)
        set_button_tooltip(self.button_box)
        selected = super(SourceSelectSingle, self).exec_()
        return selected

    @pyqtSlot(object)
    def button_clicked(self, button):
        """
        Checks which button was clicked

        :param button: Button that was clicked
        :returns: Ok:      Saves current edits
                  Delete:  Resets text to last-saved text
                  Reset:   Reset all text to PJLink default text
                  Cancel:  Cancel text edit
        """
        if self.button_box.standardButton(button) == self.button_box.Cancel:
            self.done(0)
        elif self.button_box.standardButton(button) == self.button_box.Reset:
            self.done(100)
        elif self.button_box.standardButton(button) == self.button_box.Discard:
            self.delete_sources()
        elif self.button_box.standardButton(button) == self.button_box.Ok:
            return self.accept_me()
        else:
            return 100

    def delete_sources(self):
        msg = QtGui.QMessageBox()
        msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector'))
        msg.setInformativeText(translate('OpenLP.SourceSelectForm',
                                         'Are you sure you want to delete ALL user-defined '
                                         'source input text for this projector?'))
        msg.setStandardButtons(msg.Cancel | msg.Ok)
        msg.setDefaultButton(msg.Cancel)
        ans = msg.exec_()
        if ans == msg.Cancel:
            return
        self.projectordb.delete_all_objects(ProjectorSource, ProjectorSource.projector_id == self.projector.db_item.id)
        self.done(100)

    @pyqtSlot()
    def accept_me(self):
        """
        Slot to accept 'OK' button
        """
        projector = self.projector.db_item
        if self.edit:
            for key in self.button_group:
                code = key.objectName().split("_")[-1]
                text = key.text().strip()
                if key.text().strip().lower() == PJLINK_DEFAULT_CODES[code].strip().lower():
                    continue
                item = self.projectordb.get_source_by_code(code=code, projector_id=projector.id)
                if item is None:
                    log.debug("(%s) Adding new source text %s: %s" % (projector.ip, code, text))
                    item = ProjectorSource(projector_id=projector.id, code=code, text=text)
                else:
                    item.text = text
                    log.debug('(%s) Updating source code %s with text="%s"' % (projector.ip, item.code, item.text))
                self.projectordb.add_source(item)
            selected = 0
        else:
            selected = self.button_group.checkedId()
            log.debug('SourceSelectDialog().accepted() Setting source to %s' % selected)
        self.done(selected)
Beispiel #3
0
class RRepositoryBrowser(QDialog):

    def __init__(self, pipe, parent=None):
        QDialog.__init__(self, parent)
        mirror = robjects.r.getOption('repos')
        contrib_url = robjects.r.get('contrib.url', mode='function')
        available_packages = robjects.r.get('available.packages', mode='function')
        self.setWindowTitle("manageR - Install R Packages")
        self.setWindowIcon(QIcon(":icon"))
        p = available_packages()
        self.pipe = pipe
        self.names = QStringList(p.rownames)
        self.parent = parent
        self.packageList = QListWidget(self)
        self.packageList.setAlternatingRowColors(True)
        self.packageList.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.packageList.setSortingEnabled(True)
        self.packageList.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.packageList.setToolTip("Select packages to install")
        self.packageList.setWhatsThis("List of packages available on CRAN")
        self.packageList.insertItems(0, self.names)
        self.dependCheckbox = QCheckBox(self)
        self.dependCheckbox.setText("Install all dependencies")
        self.dependCheckbox.setChecked(True)
        self.closeCheckbox = QCheckBox(self)
        self.closeCheckbox.setText("Close dialog on completion")
        self.closeCheckbox.setChecked(False)
        filterEdit = QLineEdit(self)
        filterLabel = QLabel("Filter packages", self)
        self.outputEdit = QTextEdit(self)
        self.outputEdit.setReadOnly(True)
        self.outputEdit.setVisible(False)
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Close)
        self.buttonBox.addButton("Details >>", QDialogButtonBox.ActionRole)
        vbox = QVBoxLayout(self)
        hbox = QHBoxLayout()
        hbox.addWidget(filterLabel)
        hbox.addWidget(filterEdit)
        vbox.addLayout(hbox)
        vbox.addWidget(self.dependCheckbox)
        vbox.addWidget(self.packageList)
        vbox.addWidget(self.closeCheckbox)
        vbox.addWidget(self.outputEdit)
        vbox.addWidget(self.buttonBox)
        self.started = False
        self.setMinimumSize(80,50)

        self.connect(filterEdit, SIGNAL("textChanged(QString)"), self.filterPackages)
        #self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
        self.connect(self.buttonBox, SIGNAL("clicked(QAbstractButton*)"), self.buttonClicked)

    def buttonClicked(self, button):
        if button.text() == "Details >>":
            self.showDetails()
            button.setText("Details <<")
        elif button.text() == "Details <<":
            self.hideDetails()
            button.setText("Details >>")
        if not self.started:
            if self.buttonBox.standardButton(button) == QDialogButtonBox.Apply:
                self.installPackages()
            else:
                self.reject()

    def showDetails(self):
        self.outputEdit.setVisible(True)

    def hideDetails(self):
        self.outputEdit.setVisible(False)

    def filterPackages(self, text):
        self.packageList.clear()
        self.packageList.insertItems(0, self.names.filter(QRegExp(r"^%s" % text)))
        firstItem = self.packageList.item(0)
        if firstItem.text().startsWith(text):
            self.packageList.setCurrentItem(firstItem)
#        else:
#            self.packageList.clearSelection()

    def currentPackages(self):
        return [unicode(item.text()) for item in self.packageList.selectedItems()]

    def installPackages(self):
        pkgs = self.currentPackages()
        count = len(pkgs)
        if count < 1:
            QMessageBox.warning(self, "manageR - Warning",
            "Please choose at least one valid package")
            return False
        pkgs = QStringList(pkgs).join("','")
        checked = self.dependCheckbox.isChecked()
        if checked: depends = "TRUE"
        else: depends = "FALSE"
        self.pipe.send("install.packages(c('%s'), dependencies=%s, repos=%s)" 
            % (pkgs, depends, robjects.r.getOption("repos")))
        self.started = True
        self.startTimer(30)
        return True

    def timerEvent(self, e):
        if self.started:
            try:
                output = self.pipe.recv()
                if output is None:
                    self.started=False
                    self.killTimer(e.timerId())
                else:
                    self.printOutput(output)
            except EOFError:
                pass
        QApplication.processEvents()

    def printOutput(self, output):
        self.outputEdit.insertPlainText(output)
        self.outputEdit.ensureCursorVisible()
class SourceSelectTabs(QDialog):
    """
    Class for handling selecting the source for the projector to use.
    Uses tabbed interface.
    """
    def __init__(self, parent, projectordb, edit=False):
        """
        Build the source select dialog using tabbed interface.

        :param projectordb: ProjectorDB session to use
        """
        log.debug('Initializing SourceSelectTabs()')
        super(SourceSelectTabs, self).__init__(parent)
        self.setMinimumWidth(350)
        self.projectordb = projectordb
        self.edit = edit
        if self.edit:
            title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text')
        else:
            title = translate('OpenLP.SourceSelectForm', 'Select Projector Source')
        self.setWindowTitle(title)
        self.setObjectName('source_select_tabs')
        self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png'))
        self.setModal(True)
        self.layout = QVBoxLayout()
        self.layout.setObjectName('source_select_tabs_layout')
        if is_macosx():
            self.tabwidget = QTabWidget(self)
        else:
            self.tabwidget = FingerTabWidget(self)
        self.tabwidget.setObjectName('source_select_tabs_tabwidget')
        self.tabwidget.setUsesScrollButtons(False)
        if is_macosx():
            self.tabwidget.setTabPosition(QTabWidget.North)
        else:
            self.tabwidget.setTabPosition(QTabWidget.West)
        self.layout.addWidget(self.tabwidget)
        self.setLayout(self.layout)

    def exec_(self, projector):
        """
        Override initial method so we can build the tabs.

        :param projector: Projector instance to build source list from
        """
        self.projector = projector
        self.source_text = self.projectordb.get_source_list(projector=projector)
        self.source_group = source_group(projector.source_available, self.source_text)
        # self.source_group = {'4': {'41': 'Storage 1'}, '5': {"51": 'Network 1'}}
        self.button_group = [] if self.edit else QButtonGroup()
        keys = list(self.source_group.keys())
        keys.sort()
        if self.edit:
            for key in keys:
                (tab, button_count, buttonchecked) = Build_Tab(group=self.button_group,
                                                               source_key={key: self.source_group[key]},
                                                               default=self.projector.source,
                                                               projector=self.projector,
                                                               projectordb=self.projectordb,
                                                               edit=self.edit)
                thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key])
                if buttonchecked:
                    self.tabwidget.setCurrentIndex(thistab)
            self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Reset |
                                               QtGui.QDialogButtonBox.Discard |
                                               QtGui.QDialogButtonBox.Ok |
                                               QtGui.QDialogButtonBox.Cancel)
        else:
            for key in keys:
                (tab, button_count, buttonchecked) = Build_Tab(group=self.button_group,
                                                               source_key={key: self.source_group[key]},
                                                               default=self.projector.source,
                                                               projector=self.projector,
                                                               projectordb=self.projectordb,
                                                               edit=self.edit)
                thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key])
                if buttonchecked:
                    self.tabwidget.setCurrentIndex(thistab)
            self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
                                               QtGui.QDialogButtonBox.Cancel)
        self.button_box.clicked.connect(self.button_clicked)
        self.layout.addWidget(self.button_box)
        set_button_tooltip(self.button_box)
        selected = super(SourceSelectTabs, self).exec_()
        return selected

    @pyqtSlot(object)
    def button_clicked(self, button):
        """
        Checks which button was clicked

        :param button: Button that was clicked
        :returns: Ok:      Saves current edits
                  Delete:  Resets text to last-saved text
                  Reset:   Reset all text to PJLink default text
                  Cancel:  Cancel text edit
        """
        if self.button_box.standardButton(button) == self.button_box.Cancel:
            self.done(0)
        elif self.button_box.standardButton(button) == self.button_box.Reset:
            self.done(100)
        elif self.button_box.standardButton(button) == self.button_box.Discard:
            self.delete_sources()
        elif self.button_box.standardButton(button) == self.button_box.Ok:
            return self.accept_me()
        else:
            return 100

    def delete_sources(self):
        msg = QtGui.QMessageBox()
        msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector'))
        msg.setInformativeText(translate('OpenLP.SourceSelectForm',
                                         'Are you sure you want to delete ALL user-defined '
                                         'source input text for this projector?'))
        msg.setStandardButtons(msg.Cancel | msg.Ok)
        msg.setDefaultButton(msg.Cancel)
        ans = msg.exec_()
        if ans == msg.Cancel:
            return
        self.projectordb.delete_all_objects(ProjectorSource, ProjectorSource.projector_id == self.projector.db_item.id)
        self.done(100)

    def accept_me(self):
        """
        Slot to accept 'OK' button
        """
        projector = self.projector.db_item
        if self.edit:
            for key in self.button_group:
                code = key.objectName().split("_")[-1]
                text = key.text().strip()
                if key.text().strip().lower() == PJLINK_DEFAULT_CODES[code].strip().lower():
                    continue
                item = self.projectordb.get_source_by_code(code=code, projector_id=projector.id)
                if item is None:
                    log.debug("(%s) Adding new source text %s: %s" % (projector.ip, code, text))
                    item = ProjectorSource(projector_id=projector.id, code=code, text=text)
                else:
                    item.text = text
                    log.debug('(%s) Updating source code %s with text="%s"' % (projector.ip, item.code, item.text))
                self.projectordb.add_source(item)
            selected = 0
        else:
            selected = self.button_group.checkedId()
            log.debug('SourceSelectTabs().accepted() Setting source to %s' % selected)
        self.done(selected)