Example #1
0
    def on_downloaded(self):

        widget = self.iface.messageBar().createMessage(
            u"Géofoncier", u"Téléchargement du RFU.")

        progress_bar = QProgressBar()
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(2)
        widget.layout().addWidget(progress_bar)

        self.iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)
        progress_bar.setValue(1)

        # https://pro.geofoncier.fr/index.php?&centre=-196406,5983255&context=metropole
        url = self.permalinkLineEdit.text()
        if not url:
            return self.abort_action(msg=u"Veuillez renseigner le permalien.")
        self.url = url

        try:
            self.download(self.url)
        except Exception as e:
            return self.abort_action(msg=e.message)

        progress_bar.setValue(2)
        self.iface.messageBar().clearWidgets()

        return
    def on_downloaded(self):

        widget = self.iface.messageBar().createMessage(u"Géofoncier", u"Téléchargement du RFU.")

        progress_bar = QProgressBar()
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(2)
        widget.layout().addWidget(progress_bar)

        self.iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)
        progress_bar.setValue(1)

        # https://pro.geofoncier.fr/index.php?&centre=-196406,5983255&context=metropole
        url = self.permalinkLineEdit.text()
        if not url:
            return self.abort_action(msg=u"Veuillez renseigner le permalien.")
        self.url = url

        try:
            self.download(self.url)
        except Exception as e:
            return self.abort_action(msg=e.message)

        progress_bar.setValue(2)
        self.iface.messageBar().clearWidgets()

        return
Example #3
0
def start_worker(worker, iface, message, with_progress=True):
    # configure the QgsMessageBar
    message_bar_item = iface.messageBar().createMessage(message)
    progress_bar = QProgressBar()
    progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
    if not with_progress:
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(0)
    cancel_button = QPushButton()
    cancel_button.setText('Cancel')
    cancel_button.clicked.connect(worker.kill)
    message_bar_item.layout().addWidget(progress_bar)
    message_bar_item.layout().addWidget(cancel_button)
    iface.messageBar().pushWidget(message_bar_item, iface.messageBar().INFO)

    # start the worker in a new thread
    # let Qt take ownership of the QThread
    thread = QThread(iface.mainWindow())
    worker.moveToThread(thread)

    worker.set_message.connect(
        lambda message: set_worker_message(message, message_bar_item))
    worker.toggle_show_progress.connect(
        lambda show: toggle_worker_progress(show, progress_bar))
    worker.toggle_show_cancel.connect(
        lambda show: toggle_worker_cancel(show, cancel_button))
    worker.finished.connect(lambda result: worker_finished(
        result, thread, worker, iface, message_bar_item))
    worker.error.connect(lambda e: worker_error(e))

    worker.progress.connect(progress_bar.setValue)
    thread.started.connect(worker.run)
    thread.start()

    return thread, message_bar_item
Example #4
0
class Popup(QDialog):
    def __init__(self, widget, parent = None):
        QDialog.__init__(self, parent)
        self.setModal(True)
        self.setWindowTitle("Plot save progress")

        layout = QVBoxLayout()
        layout.addWidget(widget)

        self.progress_bar = QProgressBar()
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(1)
        self.progress_bar.setValue(0)
        layout.addWidget(self.progress_bar)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok, Qt.Horizontal, self)
        layout.addWidget(buttons)
        
        self.setLayout(layout)

        self.connect(buttons, SIGNAL('accepted()'), self.accept)

        self.ok_button = buttons.button(QDialogButtonBox.Ok)
        self.ok_button.setEnabled(False)

    def closeEvent(self, event):
        """Ignore clicking of the x in the top right corner"""
        event.ignore()

    def keyPressEvent(self, event):
        """Ignore ESC keystrokes"""
        if not event.key() == Qt.Key_Escape:
            QDialog.keyPressEvent(self, event)
Example #5
0
class ExerciseUI(QGroupBox):

  def __init__(self, exercise):
    super(ExerciseUI, self).__init__()
    self.exercise = exercise
    self.initUI()

  def initUI(self):
    self.setTitle(self.exercise.label)
    
    self.level = QLabel(QString('Lvl. %d' % self.exercise.level))

    self.progressbar = QProgressBar()
    self.progressbar.setMinimum(0)
    self.progressbar.setMaximum(100)
    self.progressbar.setValue(self.exercise.progress)

    grid = QGridLayout()
    grid.addWidget(self.level, 0, 0)
    grid.addWidget(self.progressbar, 0, 1, 1, 9)
    for (index, step) in enumerate(self.exercise.steps):
      btn = QPushButton(QString('+') + QString.number(step))
      grid.addWidget(btn, 1, index)
      btn.clicked.connect(self.buttonClicked)

    self.setLayout(grid)

  def buttonClicked(self):
    sender = self.sender()
    step = int(str(sender.text()).lstrip('+'))
    self.exercise.add(step)
    self.level.setText(QString('Lvl. %d' % self.exercise.level))
    self.progressbar.setValue(self.exercise.progress)
Example #6
0
class RenameGui(BaseWindow, QtGui.QMainWindow):
    renameCompleted = QtCore.pyqtSignal()

    def __init__(self, session, parent=None):
        super(RenameGui, self).__init__(parent)

        self.session = session

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.renameUser.clicked.connect(self.renameUser)

        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)

        self.renameCompleted.connect(self.renameCompletedSlot)

        self.uiTranslate()

    def uiTranslate(self):
        self.setWindowTitle(strings["renameWindowTitle"])
        self.ui.newUsername.setPlaceholderText(strings["newUsernameBoxHint"])
        self.ui.renameUser.setText(strings["renameUserButtonText"])

    def renameCompletedSlot(self):
        self.progressIndicator.setVisible(False)
        self.showMessageBox.emit(strings["renameSuccessText"])

    def renameUser(self):
        self.progressIndicator.setVisible(True)

        def renameThread():
            newUsername = self.ui.newUsername.text()
            if newUsername == "":
                self.showMessageBox.emit(strings["missingFieldsErrorText"])
                return
            try:
                oldUsername = self.session.username
                self.session.renameUser(newUsername)
                for message in sharedData.messages:
                    if message.sender == oldUsername:
                        message.sender = newUsername
                    elif message.receiver == oldUsername:
                        message.receiver = newUsername
                storeMessages(self.session.username, sharedData.messages)
                storeToken(self.session.username, self.session.token)
                storeKey(self.session.username, self.session.public, self.session.private)
                storeMessages(oldUsername, None)
                storeToken(oldUsername, None)
                storeKey(oldUsername, None, None)
                self.renameCompleted.emit()
            except SecureMessagingException as error:
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                return

        Thread(target=renameThread).start()
    def startWorker(self):
        # create a new worker instance

        if self.worker is None:

            worker = UpdateRegistryWorker()

            # configure the QgsMessageBar
            messageBar = self.iface.messageBar().createMessage(u"Update Image Registry", u"Dieser Vorgang kann einige Minute dauern, bitte haben Sie geduld!")
            progressBar = QProgressBar()
            progressBar.setMinimum(0)
            progressBar.setMaximum(0)
            progressBar.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
            cancelButton = QPushButton()
            cancelButton.setText('Cancel')
            cancelButton.clicked.connect(self.killWorker)
            messageBar.layout().addWidget(progressBar)
            self.progressBar = progressBar
            messageBar.layout().addWidget(cancelButton)
            self.iface.messageBar().pushWidget(messageBar, self.iface.messageBar().INFO)
            #self.iface.messageBar().widgetRemoved
            # messageBar

            self.messageBar = messageBar

            # start the worker in a new thread
            thread = QThread()
            worker.moveToThread(thread)
            worker.finished.connect(self.workerFinished)
            worker.error.connect(self.workerError)
            #worker.progress.connect(progressBar.setValue)
            thread.started.connect(worker.run)
            thread.start()
            self.thread = thread
            self.worker = worker
Example #8
0
class ProgressDialog(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.resize(300, 75)
        self.setWindowTitle("Updating")
        self.vw = QWidget(self)
        self.vl = QVBoxLayout(self.vw)
        self.vl.setMargin(10)
        self.label = QLabel(self.vw)
        self.label.setText("<b>Downloading:</b> library.zip")
        self.vl.addWidget(self.label)
        self.horizontalLayoutWidget = QWidget()
        self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setMargin(0)
        self.progressbar = QProgressBar(self.horizontalLayoutWidget)
        self.progressbar.setFixedWidth(260)
        self.progressbar.setMinimum(0)
        self.progressbar.setMaximum(100)
        self.stopButton = QPushButton(self.horizontalLayoutWidget)
        self.stopButton.setFlat(True)
        self.stopButton.setIcon(Icons.stop)
        self.stopButton.setFixedSize(16,16)
        self.horizontalLayout.addWidget(self.progressbar)
        self.horizontalLayout.addWidget(self.stopButton)
        self.vl.addWidget(self.horizontalLayoutWidget)
        self.stopButton.clicked.connect(self.forceStop)
        
    def setValue(self,val):
        self.progressbar.setValue(val)
    def forceStop(self):
        self.emit(SIGNAL("forceStop"))
Example #9
0
class ProgressWidget(QgsMessageBar):
    def __init__(self, min, max, message, parent=None, timeout = 1.5):
        """
        Constructs a progress widget
        """
        super(self.__class__, self).__init__(parent)
        self.min = min
        self.max = max
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        if parent:
            self.setMinimumSize(parent.width(),40)
        else:
            self.setMinimumSize(766,40)
        self.setSizePolicy(sizePolicy)
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(min)
        self.progressBar.setMaximum(max)
        self.msgBarItem = QgsMessageBarItem(self.tr("INFO: "), message, self.progressBar, level=QgsMessageBar.INFO, duration=timeout)
        self.pushWidget(self.msgBarItem)
    
    def initBar(self):
        """
        Initializes the progress bar
        """
        self.progressBar.setValue(0)
    
    def step(self):
        """
        Increments the progress bar
        """
        value = self.progressBar.value() + 1
        self.progressBar.setValue(value)
        if value == self.max:
            time.sleep(1)
            self.close()
Example #10
0
class Popup(QDialog):
    def __init__(self, widget, parent = None):
        QDialog.__init__(self, parent)
        self.setModal(True)
        self.setWindowTitle("Plot save progress")

        layout = QVBoxLayout()
        layout.addWidget(widget)

        self.progress_bar = QProgressBar()
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(1)
        self.progress_bar.setValue(0)
        layout.addWidget(self.progress_bar)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok, Qt.Horizontal, self)
        layout.addWidget(buttons)
        
        self.setLayout(layout)

        self.connect(buttons, SIGNAL('accepted()'), self.accept)

        self.ok_button = buttons.button(QDialogButtonBox.Ok)
        self.ok_button.setEnabled(False)

    def closeEvent(self, event):
        """Ignore clicking of the x in the top right corner"""
        event.ignore()

    def keyPressEvent(self, event):
        """Ignore ESC keystrokes"""
        if not event.key() == Qt.Key_Escape:
            QDialog.keyPressEvent(self, event)
class ForgotPasswordUi(BaseWindow, QtGui.QMainWindow):
    requestSendingCompleted = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(ForgotPasswordUi, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.forgot.clicked.connect(self.forgot)
        self.ui.forgot.setDefault(True)
        self.shortcut = QtGui.QShortcut(QtGui.QKeySequence("Return"), self)
        self.shortcut.activated.connect(self.forgot)
        self.shortcut2 = QtGui.QShortcut(QtGui.QKeySequence("Up"), self)
        self.shortcut2.activated.connect(self.focusUp)
        self.shortcut2 = QtGui.QShortcut(QtGui.QKeySequence("Down"), self)
        self.shortcut2.activated.connect(self.focusDown)

        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)

        self.requestSendingCompleted.connect(self.requestSendingCompleteSlot)

        self.uiTranslate()

    def uiTranslate(self):
        self.setWindowTitle(strings["forgotPasswordWindowTitle"])
        self.ui.username.setPlaceholderText(strings["usernameBoxHint"])
        self.ui.email.setPlaceholderText(strings["emailBoxHint"])
        self.ui.forgot.setText(strings["forgotPasswordButtonText"])

    def requestSendingCompleteSlot(self):
        self.progressIndicator.setVisible(False)
        self.showMessageBox.emit(strings["forgotSuccessText"])

    def focusUp(self):
        self.ui.username.setFocus()

    def focusDown(self):
        self.ui.email.setFocus()

    def forgot(self):
        self.progressIndicator.setVisible(True)

        def requestSenderThread():
            if self.ui.username.text() and self.ui.email.text():
                try:
                    requestRecovery(self.ui.username.text(), self.ui.email.text())
                    self.requestSendingCompleted.emit()
                except SecureMessagingException as error:
                    self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
            else:
                self.showMessageBox.emit(strings["missingFieldsErrorText"])

        Thread(target=requestSenderThread).start()
 def launch(self):        
     progressMessageBar = self.iface.messageBar().createMessage("Obteniendo informacion del catastro...   ")
     progress = QProgressBar()
     progress.setMaximum(0)
     progress.setMinimum(0)
     progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
     progressMessageBar.layout().addWidget(progress)
     self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO)        
     self.parcelaService.procDone.connect(self.callback)
     self.parcelaService.start()
Example #13
0
class AddUserGui(BaseWindow):
    addUserCompleted = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(AddUserGui, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.adduser.clicked.connect(self.adduser)

        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)

        self.addUserCompleted.connect(self.addUserCompletedSlot)

        self.uiTranslate()

    def uiTranslate(self):
        self.setWindowTitle(strings["registerUserWindowTitle"])
        self.ui.username.setPlaceholderText(strings["usernameBoxHint"])
        self.ui.password.setPlaceholderText(strings["passwordBoxHint"])
        self.ui.email.setPlaceholderText(strings["emailBoxHint"])
        self.ui.confirm.setPlaceholderText(strings["confirmPasswordBoxHint"])
        self.ui.adduser.setText(strings["registerUserButtonText"])

    def addUserCompletedSlot(self):
        self.progressIndicator.setVisible(False)
        self.showMessageBox.emit(strings["registrationSuccessText"])

    def adduser(self):
        self.progressIndicator.setVisible(True)

        def addUserThread():
            name = self.ui.username.text()
            password = self.ui.password.text()
            confirm = self.ui.confirm.text()
            email = self.ui.email.text()
            if name == "" or password == "" or email == "":
                self.showMessageBox.emit(strings["missingFieldsErrorText"])
                return
            if password != confirm:
                self.showMessageBox.emit(strings["passwordsDontMatchErrorText"])
                return
            try:
                addUser(name, email, password)
                self.addUserCompleted.emit()
            except SecureMessagingException as error:
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                return

        Thread(target=addUserThread).start()
Example #14
0
class AsyncProgressDialog(QDialog):
    """ dialog with progress bar to be shown during the asynchronous process """
    def __init__(self, parent=None):
        super(AsyncProgressDialog, self).__init__(parent)
        self.setFixedSize(300, 40)
        self.setLayout(QBoxLayout(QBoxLayout.TopToBottom, self))
        self.progress_bar = QProgressBar(self)
        self.progress_bar.setFixedSize(280, 20)
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(10)
        self.progress_bar.setTextVisible(False)
        self.layout().addWidget(self.progress_bar)
Example #15
0
class AsyncProgressDialog(QDialog):
    """ dialog with progress bar to be shown during the asynchronous process """
    def __init__(self, parent=None):
        super(AsyncProgressDialog, self).__init__(parent)        
        self.setFixedSize(300, 40)
        self.setLayout(QBoxLayout(QBoxLayout.TopToBottom, self))
        self.progress_bar = QProgressBar(self)
        self.progress_bar.setFixedSize(280, 20)
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(10)  
        self.progress_bar.setTextVisible(False)     
        self.layout().addWidget(self.progress_bar)
Example #16
0
class QtProgressBar(QtControl, ProxyProgressBar):
    """ A Qt implementation of an Enaml ProxyProgressBar.

    """
    #: A reference to the widget created by the proxy.
    widget = Typed(QProgressBar)

    #--------------------------------------------------------------------------
    # Initialization API
    #--------------------------------------------------------------------------
    def create_widget(self):
        """ Create the underlying progress bar widget.

        """
        self.widget = QProgressBar(self.parent_widget())

    def init_widget(self):
        """ Create and initialize the underlying widget.

        """
        super(QtProgressBar, self).init_widget()
        d = self.declaration
        self.set_minimum(d.minimum)
        self.set_maximum(d.maximum)
        self.set_value(d.value)
        self.set_text_visible(d.text_visible)

    #--------------------------------------------------------------------------
    # ProxyProgressBar API
    #--------------------------------------------------------------------------
    def set_minimum(self, value):
        """ Set the minimum value of the widget.

        """
        self.widget.setMinimum(value)

    def set_maximum(self, value):
        """ Set the maximum value of the widget.

        """
        self.widget.setMaximum(value)

    def set_value(self, value):
        """ Set the value of the widget.

        """
        self.widget.setValue(value)

    def set_text_visible(self, visible):
        """ Set the text visibility on the widget.

        """
        self.widget.setTextVisible(visible)
Example #17
0
    def createProgressbar(self, loopnumber):
        """
        Create a progress bar when iterating over features
        """
        progressMessageBar = self.messageBar.createMessage(
            unicode("Chargement des données...", "utf-8"))
        progress = QProgressBar()
        progress.setMinimum(0)
        progress.setMaximum(loopnumber)
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        self.messageBar.pushWidget(progressMessageBar, self.messageBar.INFO)

        return progress
Example #18
0
 def __init__(self, iface, provincia,municipio,x,y,callback):
     #super(Ui_ProgressDialog, self).__init__(parent)
     self.thread = ParcelaService(provincia,municipio)
     self.thread.initCoords(x,y)
     self.iface = iface
     progressMessageBar = iface.messageBar().createMessage("Obteniendo informacion del catastro...   ")
     progress = QProgressBar()
     progress.setMaximum(0)
     progress.setMinimum(0)
     progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
     progressMessageBar.layout().addWidget(progress)
     iface.messageBar().pushWidget(progressMessageBar, iface.messageBar().INFO)
                 
     self.thread.procDone.connect(self.fin)        
     self.thread.start()
 def _progress_bar_factory_function(self, window_parent, editor, *args, **kwargs):
     """ Returns a QProgressBar widget for a TraitsUI window. 
     
     Used by CustomEditor(factory=_progress_bar_factory_function, args=('tuple',)
     
     Can't just return self.progress_bar one should be should be created 
     here and then set.
     
     window_parent = <PyQt4.QtGui.QBoxLayout object at ...>
     editor = <traitsui.qt4.custom_editor.CustomEditor object at ...>
     
     """
     progress_bar = QProgressBar()
     progress_bar.setMinimum(self.min)
     progress_bar.setMaximum(self.max)
     self.progress_bar = progress_bar
     return progress_bar
    def run(self):
        """Create the output shapefile."""
        gpsStatus = self.checkGpsStatus()
        if gpsStatus:
            pass
            #QMessageBox.warning(None, "Test", "Create GPS SHP")
        elif gpsStatus == None:
            QMessageBox.warning(None, "Verzeichnis", u"Es wurde kein Bildverzeichnis für diesen Film gefunden.")
            return
        else:
            QMessageBox.warning(None, "Bilder", u"Die vorhandenen Bilder enthalten keine GPS Information.")
            return

        check = QFile(self.shpFile)
        if check.exists():
            if not QgsVectorFileWriter.deleteShapeFile(self.shpFile):
                msg = 'Unable to delete existing shapefile "{}"'
                self.iface.messageBar().pushMessage(u"Error", u"Die Datei existiert bereits und kann nicht überschrieben werden (Eventuell in QGIS geladen!).", level=QgsMessageBar.CRITICAL, duration=10)
                return False

        #fields
        fields = QgsFields()
        fields.append(QgsField("bildnr", QVariant.Int))
        fields.append(QgsField("lat", QVariant.Double))
        fields.append(QgsField("lon", QVariant.Double))
        fields.append(QgsField("alt", QVariant.Double))

        writer = QgsVectorFileWriter(str(self.shpFile), "UTF-8", fields, QGis.WKBPoint, QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId))

        mb = self.iface.messageBar().createMessage(u"EXIF", u"Die EXIF Daten (Geo Koordinaten und Höhe) werden aus den Bildern ausgelesen")
        progress = QProgressBar()
        progress.setMinimum(0)
        progress.setMaximum(0)
        progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
        mb.layout().addWidget(progress)
        self.iface.messageBar().pushWidget(mb, QgsMessageBar.INFO)

        for feature in self.iter_points():
            writer.addFeature(feature)
        del writer
        self.iface.messageBar().clearWidgets()
        self.iface.messageBar().pushMessage(u"EXIF", u"Die Shape Datei wurde erfolgreich erstellt und in QGIS geladen!", level=QgsMessageBar.SUCCESS, duration=10)


        return self.shpFile
Example #21
0
    def _draw_transfer_item(self, container, filename, id, part_number, peer_ip, percent):
        items_found = container.findItems(id, Qt.MatchExactly, 1)
        item = None
        if len(items_found) > 0:

            for i in items_found:
                if i.text(4) == peer_ip and i.text(2) == str(part_number):
                    item = i
                    break

        if item:
            container.itemWidget(item, 3).setValue(percent)
        else:
            item = QTreeWidgetItem(container, QStringList([str(filename), str(id), str(part_number), "0",  str(peer_ip)]))
            progress_bar = QProgressBar()
            progress_bar.setMinimum(0)
            progress_bar.setMaximum(100)
            progress_bar.setValue(percent)
            container.setItemWidget(item, 3, progress_bar)
Example #22
0
    def __init__(self, parent):
        QProgressBar.__init__(self, parent)

        self.fLeftClickDown = False

        self.fMinimum   = 0.0
        self.fMaximum   = 1.0
        self.fRealValue = 0.0

        self.fLabel = ""
        self.fPreLabel = " "
        self.fTextCall = None

        self.setFormat("(none)")

        # Fake internal value, 10'000 precision
        QProgressBar.setMinimum(self, 0)
        QProgressBar.setMaximum(self, 10000)
        QProgressBar.setValue(self, 0)
def start_worker(worker, iface, message, with_progress=True):
    # configure the QgsMessageBar
    message_bar = iface.messageBar().createMessage(message)
    progress_bar = QProgressBar()
    progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
    if not with_progress:
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(0)
    cancel_button = QPushButton()
    cancel_button.setText('Cancel')
    cancel_button.clicked.connect(worker.kill)
    message_bar.layout().addWidget(progress_bar)
    message_bar.layout().addWidget(cancel_button)
    iface.messageBar().pushWidget(message_bar, iface.messageBar().INFO)

    # start the worker in a new thread
    # let Qt take ownership of the QThread
    thread = QThread(iface.mainWindow())
    worker.moveToThread(thread)
    
    worker.set_message.connect(lambda message: set_worker_message(
        message, message_bar_item))

    worker.toggle_show_progress.connect(lambda show: toggle_worker_progress(
        show, progress_bar))
        
    worker.toggle_show_cancel.connect(lambda show: toggle_worker_cancel(
        show, cancel_button))
        
    worker.finished.connect(lambda result: worker_finished(
        result, thread, worker, iface, message_bar))
        
    worker.error.connect(lambda e, exception_str: worker_error(
        e, exception_str, iface))
        
    worker.progress.connect(progress_bar.setValue)
    
    thread.started.connect(worker.run)
    
    thread.start()
    return thread, message_bar
Example #24
0
class ProgressDialog(QDialog):

  def __init__(self, parent, title='', info_start='', maximum=100, add=0):
    QDialog.__init__(self, parent)
    self.add=add
    self.setWindowTitle(title)
    vbox=QVBoxLayout()
    self.info=QLabel(self)
    vbox.addWidget(self.info)
    self.info.setText(info_start)
    self.progressBar=QProgressBar()
    self.progressBar.setMaximum(maximum)
    self.progressBar.setMinimum(0)
    vbox.addWidget(self.progressBar)
    self.setLayout(vbox)

  def progress(self, value):
    param=value*100+self.add
    self.progressBar.setValue(param)
    app=QApplication.instance()
    app.processEvents()
Example #25
0
File: qmap.py Project: s-chand/qmap
 def syncstarted(self):                   
     # Remove the old widget if it's still there.
     # I don't really like this. Seems hacky.
     try:
         self.iface.messageBar().popWidget(self.syncwidget)
     except RuntimeError:
         pass
     except AttributeError:
         pass
     
     self.iface.messageBar().findChildren(QToolButton)[0].setVisible(False)        
     self.syncwidget = self.iface.messageBar().createMessage("Syncing", "Sync in progress", QIcon(":/icons/syncing"))
     button = QPushButton(self.syncwidget)
     button.setCheckable(True)
     button.setText("Status")
     button.setIcon(QIcon(":/icons/syncinfo"))
     button.toggled.connect(functools.partial(self.report.setVisible))
     pro = QProgressBar()
     pro.setMaximum(0)
     pro.setMinimum(0)
     self.syncwidget.layout().addWidget(pro)
     self.syncwidget.layout().addWidget(button)
     self.iface.messageBar().pushWidget(self.syncwidget, QgsMessageBar.INFO)
Example #26
0
 def updateshows(self):
     ''' Update local shows with remote content '''
     
     label = QLabel('Updating: ')
     bar = QProgressBar()
     bar.setMinimum(0)
     bar.setMaximum(self.ui.showlist.model().rowCount())
     bar.setValue(bar.minimum())
     
     self.ui.statusbar.addWidget(label)
     self.ui.statusbar.addWidget(bar)
     
     for row in range(self.ui.showlist.model().rowCount()):
         self.backend.updateshow(self.ui.showlist.model().getshow(row).id)
         bar.setValue(row)
         
     self.ui.statusbar.removeWidget(bar)
     self.ui.statusbar.removeWidget(label)
     
     now = datetime.now()
     self.settings.set(settings.categories.application, settings.keys.lastupdated, now)
     self.setlastupdatedstatus(now)
     self.displayshowstatuses()
Example #27
0
 def syncstarted(self):                   
     # Remove the old widget if it's still there.
     # I don't really like this. Seems hacky.
     try:
         self.iface.messageBar().popWidget(self.syncwidget)
     except RuntimeError:
         pass
     except AttributeError:
         pass
     
     self.iface.messageBar().findChildren(QToolButton)[0].setVisible(False)
     self.syncwidget = self.iface.messageBar().createMessage("Syncing", "Sync in progress", QIcon(":/icons/syncing"))
     button = QPushButton(self.syncwidget)
     button.setCheckable(True)
     button.setText("Status")
     button.setIcon(QIcon(":/icons/syncinfo"))
     button.toggled.connect(functools.partial(self.report.setVisible))
     pro = QProgressBar()
     pro.setMaximum(0)
     pro.setMinimum(0)
     self.syncwidget.layout().addWidget(pro)
     self.syncwidget.layout().addWidget(button)
     self.iface.messageBar().pushWidget(self.syncwidget, QgsMessageBar.INFO)
Example #28
0
    def displayshowstatuses(self):
        ''' Set the show statuses for all shows
        This only really needs to be done at the start
        or after updating data
        '''
        
        label = QLabel('Updating status: ')
        self.ui.statusbar.addWidget(label)
        
        shows = self.backend.getlocalshows()
        
        showbar = QProgressBar()
        showbar.setMinimum(0)
        showbar.setMaximum(len(shows))
        showbar.setValue(showbar.minimum())

        self.ui.statusbar.addWidget(showbar)

        for show in shows:
            self.displayshowstatus(show.id)
            showbar.setValue(shows.index(show) + 1)

        self.ui.statusbar.removeWidget(showbar)
        self.ui.statusbar.removeWidget(label)
Example #29
0
class ClientDialog(QDialog):
    """a simple popup dialog for asking the player what he wants to do"""
    def __init__(self, client, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle(m18n('Choose') + ' - Kajongg')
        self.setObjectName('ClientDialog')
        self.client = client
        self.layout = QGridLayout(self)
        self.progressBar = QProgressBar()
        self.timer = QTimer()
        if not client.game.autoPlay:
            self.timer.timeout.connect(self.timeout)
        self.deferred = None
        self.buttons = []
        self.setWindowFlags(Qt.SubWindow | Qt.WindowStaysOnTopHint)
        self.setModal(False)
        self.btnHeight = 0
        self.answered = False

    def keyPressEvent(self, event):
        """ESC selects default answer"""
        if not self.client.game or self.client.game.autoPlay:
            return
        if event.key() in [Qt.Key_Escape, Qt.Key_Space]:
            self.selectButton()
            event.accept()
        else:
            for btn in self.buttons:
                if str(event.text()).upper() == btn.message.shortcut:
                    self.selectButton(btn)
                    event.accept()
                    return
            QDialog.keyPressEvent(self, event)

    def __declareButton(self, message):
        """define a button"""
        maySay = self.client.sayable[message]
        if Preferences.showOnlyPossibleActions and not maySay:
            return
        btn = DlgButton(message, self)
        btn.setAutoDefault(True)
        btn.clicked.connect(self.selectedAnswer)
        self.buttons.append(btn)

    def focusTileChanged(self):
        """update icon and tooltip for the discard button"""
        if not self.client.game:
            return
        for button in self.buttons:
            button.decorate(self.client.game.myself.handBoard.focusTile)
        for tile in self.client.game.myself.handBoard.lowerHalfTiles():
            txt = []
            for button in self.buttons:
                _, _, tileTxt = button.message.toolTip(button, tile)
                if tileTxt:
                    txt.append(tileTxt)
            txt = '<br><br>'.join(txt)
            tile.graphics.setToolTip(txt)
        if self.client.game.activePlayer == self.client.game.myself:
            Internal.field.handSelectorChanged(self.client.game.myself.handBoard)

    def checkTiles(self):
        """does the logical state match the displayed tiles?"""
        for player in self.client.game.players:
            logExposed = list()
            physExposed = list()
            physConcealed = list()
            for tile in player.bonusTiles:
                logExposed.append(tile.element)
            for tile in player.handBoard.tiles:
                if tile.yoffset == 0 or tile.element[0] in 'fy':
                    physExposed.append(tile.element)
                else:
                    physConcealed.append(tile.element)
            for meld in player.exposedMelds:
                logExposed.extend(meld.pairs)
            logConcealed = sorted(player.concealedTileNames)
            logExposed.sort()
            physExposed.sort()
            physConcealed.sort()
            assert logExposed == physExposed, '%s != %s' % (logExposed, physExposed)
            assert logConcealed == physConcealed, '%s != %s' % (logConcealed, physConcealed)

    def messages(self):
        """a list of all messages returned by the declared buttons"""
        return list(x.message for x in self.buttons)

    def proposeAction(self):
        """either intelligently or first button by default. May also
        focus a proposed tile depending on the action."""
        result = self.buttons[0]
        game = self.client.game
        if game.autoPlay or Preferences.propose:
            answer, parameter = self.client.intelligence.selectAnswer(
                self.messages())
            result = [x for x in self.buttons if x.message == answer][0]
            result.setFocus()
            if answer in [Message.Discard, Message.OriginalCall]:
                for tile in game.myself.handBoard.tiles:
                    if tile.element == parameter:
                        game.myself.handBoard.focusTile = tile
        return result

    def askHuman(self, move, answers, deferred):
        """make buttons specified by answers visible. The first answer is default.
        The default button only appears with blue border when this dialog has
        focus but we always want it to be recognizable. Hence setBackgroundRole."""
        self.move = move
        self.deferred = deferred
        for answer in answers:
            self.__declareButton(answer)
        self.focusTileChanged()
        self.show()
        self.checkTiles()
        game = self.client.game
        myTurn = game.activePlayer == game.myself
        prefButton = self.proposeAction()
        if game.autoPlay:
            self.selectButton(prefButton)
            return
        prefButton.setFocus()

        self.progressBar.setVisible(not myTurn)
        if not myTurn:
            msecs = 50
            self.progressBar.setMinimum(0)
            self.progressBar.setMaximum(game.ruleset.claimTimeout * 1000 // msecs)
            self.progressBar.reset()
            self.timer.start(msecs)

    def placeInField(self):
        """place the dialog at bottom or to the right depending on space."""
        field = Internal.field
        cwi = field.centralWidget()
        view = field.centralView
        geometry = self.geometry()
        if not self.btnHeight:
            self.btnHeight = self.buttons[0].height()
        vertical = view.width() > view.height() * 1.2
        if vertical:
            height = (len(self.buttons) + 1) * self.btnHeight * 1.2
            width = (cwi.width() - cwi.height() ) // 2
            geometry.setX(cwi.width() - width)
            geometry.setY(min(cwi.height()//3, cwi.height() - height))
        else:
            handBoard = self.client.game.myself.handBoard
            if not handBoard:
                # we are in the progress of logging out
                return
            hbLeftTop = view.mapFromScene(handBoard.mapToScene(handBoard.rect().topLeft()))
            hbRightBottom = view.mapFromScene(handBoard.mapToScene(handBoard.rect().bottomRight()))
            width = hbRightBottom.x() - hbLeftTop.x()
            height = self.btnHeight
            geometry.setY(cwi.height() - height)
            geometry.setX(hbLeftTop.x())
        for idx, btn in enumerate(self.buttons + [self.progressBar]):
            self.layout.addWidget(btn, idx+1 if vertical else 0, idx+1 if not vertical else 0)
        idx = len(self.buttons) + 2
        spacer = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.layout.addItem(spacer, idx if vertical else 0, idx if not vertical else 0)

        geometry.setWidth(width)
        geometry.setHeight(height)
        self.setGeometry(geometry)

    def showEvent(self, dummyEvent):
        """try to place the dialog such that it does not cover interesting information"""
        self.placeInField()

    def timeout(self):
        """the progressboard wants an update"""
        pBar = self.progressBar
        if isAlive(pBar):
            pBar.setValue(pBar.value()+1)
            pBar.setVisible(True)
            if pBar.value() == pBar.maximum():
                # timeout: we always return the original default answer, not the one with focus
                self.selectButton()
                pBar.setVisible(False)

    def selectButton(self, button=None):
        """select default answer. button may also be of type Message."""
        self.timer.stop()
        self.answered = True
        if button is None:
            button = self.focusWidget()
        if isinstance(button, Message):
            assert any(x.message == button for x in self.buttons)
            answer = button
        else:
            answer = button.message
        if not self.client.sayable[answer]:
            Sorry(m18n('You cannot say %1', answer.i18nName))
            return
        Internal.field.clientDialog = None
        self.deferred.callback(answer)

    def selectedAnswer(self, dummyChecked):
        """the user clicked one of the buttons"""
        game = self.client.game
        if game and not game.autoPlay:
            self.selectButton(self.sender())
Example #30
0
class HomeWidget(BaseWidget):
    def __init__(self, parent=0, *args, **kwargs):
        super(HomeWidget, self).__init__(parent=parent, *args, **kwargs)

        # inputs
        self._json_fpath = None
        self._destination_folder = self.guess_destination()
        self._from_date, self._to_date = self.guess_dates()
        self.nb_instances = 0

        self.setup_ui()

    @property
    def json_fpath(self):
        return self._json_fpath

    @json_fpath.setter
    def json_fpath(self, value):
        self._json_fpath = value
        self.json_select_button.setText(
            value if value else "Sélection fichier JSON ODK Aggregate ...")
        self.update_start_button_state()

    @property
    def destination_folder(self):
        return self._destination_folder

    @destination_folder.setter
    def destination_folder(self, value):
        self._destination_folder = value
        self.destination_select_button.setText(self.destination_folder)
        self.update_start_button_state()

    @property
    def from_date(self):
        return self._from_date

    @from_date.setter
    def from_date(self, value):
        self._from_date = value
        self.from_date_selector.setPythonDate(self.from_date)
        self.update_start_button_state()

    @property
    def to_date(self):
        return self._to_date

    @to_date.setter
    def to_date(self, value):
        self._to_date = value
        self.to_date_selector.setPythonDate(self.to_date)
        self.update_start_button_state()

    def setup_ui(self):
        # json file selector
        self.json_groupbox = QGroupBox("Export ODK Aggregate")
        layout = QGridLayout()
        self.json_select_button = PushButton("", self)
        self.json_select_button.clicked.connect(self.json_selector_clicked)
        layout.addWidget(self.json_select_button, 1, 0)
        self.json_groupbox.setLayout(layout)

        # destination folder selector
        self.destination_groupbox = QGroupBox("Destination")
        layout = QGridLayout()
        self.destination_select_button = PushButton(self.destination_folder,
                                                    self)
        self.destination_select_button.clicked.connect(
            self.destination_selector_clicked)
        layout.addWidget(self.destination_select_button, 1, 0)
        self.destination_groupbox.setLayout(layout)

        # period calendars
        today = datetime.date.today()
        self.period_groupbox = QGroupBox("Période")
        layout = QGridLayout()
        self.from_date_selector = DateTimeEdit(QDate(self.from_date))
        self.from_date_selector.dateChanged.connect(self.from_date_changed)
        self.from_date_selector.setMaximumDate(self.to_date)
        self.to_date_selector = DateTimeEdit(QDate(self.to_date))
        self.to_date_selector.dateChanged.connect(self.to_date_changed)
        self.to_date_selector.setMinimumDate(self.from_date)
        self.to_date_selector.setMaximumDate(today)
        layout.addWidget(Label("Du"), 2, 0)
        layout.addWidget(self.from_date_selector, 3, 0)
        layout.addWidget(Label("Au"), 2, 1)
        layout.addWidget(self.to_date_selector, 3, 1)
        self.period_groupbox.setLayout(layout)

        # start button
        self.start_button = PushButton("Démarrer")
        self.start_button.setEnabled(False)
        self.start_button.setDefault(True)
        self.start_button.clicked.connect(self.export_requested)

        # cancel button
        self.cancel_button = CancelPushButton("Annuler")
        self.cancel_button.setEnabled(False)
        self.cancel_button.clicked.connect(self.cancel_export)

        # grid
        self.gridBox = QGridLayout()
        self.gridBox.addWidget(self.json_groupbox, 0, 0, 1, 2)
        self.gridBox.addWidget(self.destination_groupbox, 1, 0, 1, 2)
        self.gridBox.addWidget(self.period_groupbox, 2, 0, 1, 2)
        self.gridBox.addWidget(self.start_button, 3, 0)
        self.gridBox.addWidget(self.cancel_button, 3, 1)

        vBox = QVBoxLayout()
        vBox.addLayout(self.gridBox)
        self.setLayout(vBox)

        self.json_fpath = None

    def guess_destination(self, root_only=False):
        start_folder = os.path.join(os.path.expanduser("~"), 'Desktop')
        if root_only:
            return start_folder
        return os.path.join(start_folder, Constants.DEFAULT_FOLDER_NAME)

    def guess_dates(self):
        to = datetime.date.today()
        start = to - datetime.timedelta(days=15)
        return start, to

    def update_start_button_state(self):
        self.start_button.setEnabled(
            all([
                self.json_fpath, self.destination_folder, self.from_date,
                self.to_date
            ]))

    def json_selector_clicked(self):
        # self.file_name_field.setText("Aucun fichier")
        self.start_button.setEnabled(False)
        fpath = QFileDialog.getOpenFileName(
            self, "Choisir le fichier d'export JSON", self.json_fpath
            or self.guess_destination(root_only=True),
            "Fichiers JSON (*.json)")
        self.json_fpath = os.path.abspath(fpath) if fpath else self.json_fpath

    def destination_selector_clicked(self):
        path = QFileDialog.getExistingDirectory(self,
                                                "Sélectionner le dossier",
                                                self.destination_folder)
        if path:
            self.destination_folder = os.path.abspath(path)

    def from_date_changed(self, new_date):
        self.from_date = new_date.toPyDate()

    def to_date_changed(self, new_date):
        self.to_date = new_date.toPyDate()

    def export_requested(self):
        logger.debug("export_requested")
        self.parentWidget().exporter.check_aggregate_presence()

    def display_missing_aggregate_confirmation(self):
        if MissingODKConfirmationWidget().exec_() == QDialog.Accepted:
            self.start_export()

    def start_export(self):
        logger.debug("Lancement ...")
        self.add_progressbar()
        self.start_button.setEnabled(False)
        self.cancel_button.setEnabled(True)
        self.parentWidget().exporter.parse(
            destination_folder=self.destination_folder,
            fname=self.json_fpath,
            from_date=self.from_date,
            to_date=self.to_date)

    def cancel_export(self):
        logger.debug("cancel")
        self.parentWidget().exporter.cancel()

    def update_progress_label(self, index):
        progression_label = "Export en cours...    {index}/{total}" \
                            .format(index=index,
                                    total=self.nb_instances)
        self.progression_groupbox.setTitle(progression_label)

    def add_progressbar(self):
        self.progressbar = QProgressBar()
        self.progressbar.setMinimum(0)
        self.progressbar.setMaximum(100)
        self.progressbar.reset()
        self.progressbar.setTextVisible(False)

        self.progression_groupbox = QGroupBox("...")
        progress_layout = QHBoxLayout()
        progress_layout.addWidget(self.progressbar)
        self.progression_groupbox.setLayout(progress_layout)
        self.gridBox.addWidget(self.progression_groupbox, 4, 0, 1, 2)

    def remove_progressbar(self):
        self.progression_groupbox.deleteLater()
        self.progression_groupbox = None

    @pyqtSlot(bool, int, str)
    def parsing_ended(self, succeeded, nb_instances, error_message):
        if succeeded:
            self.nb_instances = nb_instances

    @pyqtSlot(str, int)
    def exporting_instance(self, ident, index):
        logger.debug("exporting_instance")
        self.update_progress_label(index)

    @pyqtSlot(bool, int)
    def instance_completed(self, succeeded, index):
        logger.debug("instance_completed")
        pc = index * 100 // self.nb_instances
        self.progressbar.setValue(pc)

    @pyqtSlot(int, int, int, int)
    def export_ended(self, nb_instances_successful, nb_instances_failed,
                     nb_medias_successful, nb_medias_failed):
        self.cancel_button.setEnabled(False)
        self.start_button.setEnabled(True)

    @pyqtSlot()
    def export_canceled(self):
        self.remove_progressbar()
        self.cancel_button.setEnabled(False)
        self.start_button.setEnabled(True)
        QMessageBox.warning(
            self, "Export annulé !", "L'export en cours a été annulé.\n"
            "Tous les fichiers créés ont été supprimés", QMessageBox.Ok,
            QMessageBox.NoButton)
        if self.parentWidget().is_exiting:
            self.parentWidget().do_close()
Example #31
0
class Form(QMainWindow, Ui_MainWindow):
	"""IT Query Main Window."""

	def __init__(self, initIds, initErrIds, parent=None):
		"""Setup main window and populate with data(if given)."""
		super(Form, self).__init__(parent)
		self.setupUi(self)
		self.setWindowTitle("IT Query {0}".format(__version__))
		self.selectedIds = initIds
		self.errorIds = initErrIds

		LOG_LEVEL = logging.INFO
		currTime = time.localtime()
		runDate = time.strftime("%Y-%m-%d", currTime)
		self.dbPath = DB.Db.Info.Path
		LOG_FNAME = "{0}\{1}-{2}.{3}".format(self.dbPath, "itquery",
											 runDate, "txt")

		if LOG_LEVEL == logging.INFO:
			LOG_FORMAT = "%(asctime)s\t%(message)s"
		else:
			LOG_FORMAT = ("%(asctime)s - %(levelname)s - %(funcName)s "
						" - %(message)s")

		self.logger = logging.getLogger("itquery")
		self.logger.setLevel(LOG_LEVEL)
		self.handler = logging.FileHandler(LOG_FNAME)
		formatter = logging.Formatter(LOG_FORMAT)
		self.handler.setFormatter(formatter)
		self.logger.addHandler(self.handler)

		for action, slot in ((self.updateButton, self.updateSelection),
							(self.bionumericsButton, self.bnSelectFields),
							(self.itemTrackerButton, self.itSelectFields)):
			action.clicked.connect(slot)

		for action, slot in ((self.actionCollapseAll, self.collapseAll),
							(self.actionExpandAll, self.expandAll),
							(self.actionCollapseItem, self.collapseItem),
							(self.actionCherryPicking, self.cherryPicking),
							(self.actionExpandItem, self.expandItem),
							(self.actionSelectAll, self.selectAll),
							(self.actionSelectDNA, self.selectDNA),
							(self.actionSelectFrozenStock, self.selectFrozenStock),
							(self.actionSelectInvert, self.selectInvert),
							(self.actionSelectNone, self.selectNone),
							(self.actionGetAllSelected, self.getAllSelected),
							(self.actionRefresh, self.refresh),
							(self.actionAbout, self.about),
							(self.actionViewTree, self.viewTree),
							(self.actionClearLog, self.clearLog),
							(self.actionLegend, self.legend),
							(self.actionExportTraceList, self.exportTraceList),
							(self.actionExportDNAList, self.exportDNAList),
							(self.actionClose, self.close)):
			action.triggered.connect(slot)

		self.treeWidget.itemSelectionChanged.connect(self.updateInfo)
		self.viewMenu.addAction(self.logDockWidget.toggleViewAction())
		icon = QIcon(":/text-x-log.png")
		self.logDockWidget.toggleViewAction().setIcon(icon)
		self.actionSelectInBionumerics.toggled.connect(self.selectInBionumerics)

		self.userComboBox.currentIndexChanged.connect(self.userChanged)
		self.statusComboBox.currentIndexChanged.connect(self.statusChanged)

		self.treeActions = QActionGroup(self)
		self.treeActions.addAction(self.actionExpandItem)
		self.treeActions.addAction(self.actionCollapseItem)
		self.treeActions.addAction(self.actionExpandAll)
		self.treeActions.addAction(self.actionCollapseAll)

		self.selectActions = QActionGroup(self)
		self.selectActions.addAction(self.actionSelectAll)
		self.selectActions.addAction(self.actionSelectNone)
		self.selectActions.addAction(self.actionSelectInvert)
		self.selectActions.addAction(self.actionSelectDNA)
		self.selectActions.addAction(self.actionSelectFrozenStock)

		self.exportActions = QActionGroup(self)
		self.exportActions.addAction(self.actionExportDNAList)
		self.exportActions.addAction(self.actionExportTraceList)

		self.statusbar.setSizeGripEnabled(True)
		# user label at the right end of status bar
#		db = lims.DATABASE
		db = "No information"
		dbLabel  = QLabel("Database: <b>{0}</b>".format(db))
		self.statusbar.addPermanentWidget(dbLabel)
		user = os.environ.get("USERNAME") or "Demo user"
		label = QLabel("Logged in as: <b>{0}</b>".format(user))
		self.statusbar.addPermanentWidget(label)

		# restore main window state
		settings = QSettings()
		size = settings.value("MainWindow/Size",
							 QVariant(QSize(600, 500))).toSize()
		self.resize(size)
		position = settings.value("MainWindow/Position",
								 QVariant(QPoint(0, 0))).toPoint()
		self.move(position)
		self.restoreState(settings.value("MainWindow/State").toByteArray())
		splitterState = settings.value("MainWindow/SplitState").toByteArray()
		self.splitter.restoreState(splitterState)

		# selected fields
		self.dbName = bns.ConnectedDb.ConnectDb.GetList()
		regKey = "Bionumerics/{0}/SelFields".format(self.dbName)
		regBnFields = settings.value(regKey).toStringList()
		self.bnSelectedFields = [unicode(item) for item in regBnFields]

		regItFields = settings.value("ItemTracker/SelFields").toStringList()
		self.itSelectedFields = [unicode(item) for item in regItFields]

		# progress bar
		self.progressBar = QProgressBar(self)
		self.progressBar.setMaximumWidth(200)
		self.statusbar.insertPermanentWidget(0, self.progressBar)
		self.progressBar.hide()

		# initialize variables
		self.itemIds = {}
		self.itemNames = {}
		# bnFields - bionumerics information in the info panel
		self.bnFields = {}
		self.strainInfo = {}
		# maintains list of keys that are updated
		self.updatedStrains = []
		self.selectRadioButton.setChecked(True)
		self.itemProperties = {}
		self.tableResults = []
		self.getBnFields()
		self.mkInfo("{0}. Log: {1}".format(time.asctime(), LOG_FNAME))
		self.populatedTree = False
		self.populatedTable = False
		self.populatedCherry = False
		idField = "ItemTracker ID"  # Field with ItemTracker ID

		self.itemIdsAll, errors = bn.getItemIds(idField, DB.Db.Entries)
		if len(errors):
			for key, message in errors.iteritems():
				self.mkError("Key: {0}, {1}".format(key, message))
		self.database = None
		self.updateUi()

		self.proxyModel = SortFilterProxyModel(self)
		self.proxyModel.setDynamicSortFilter(True)
		self.cherryView.setModel(self.proxyModel)
		self.cherryView.setAlternatingRowColors(True)
		self.cherryView.setSortingEnabled(True)
		self.cherryView.verticalHeader().setVisible(False)
		self.cherryView.setEditTriggers(QAbstractItemView.NoEditTriggers)
		self.cherryView.horizontalHeader().setStretchLastSection(True)
		#self.populateTree() # testing
		QTimer.singleShot(0, self.populateTree)

	def bnSelectFields(self):
		"""Bionumerics field selection dialog."""
		try:
			fieldNames = bn.getFieldNames()
		except RuntimeError as e:
			self.mkError("Failed to get Bionumerics field names: {0}".format(e))

		dialog = selectfieldsdlg.selectFieldsDialog(fieldNames, self)
		if self.bnSelectedFields is not None:
			dialog.setSelected(self.bnSelectedFields)

		if dialog.exec_():
			self.bnSelectedFields = dialog.getSelected()
			self.updateInfo()

	def addCherryData(self, model, row):
		"""Inserts row into model"""
		model.insertRow(0)
		for position, value in enumerate(row):
			model.setData(model.index(0, position), value)

	def createCherryModel(self, data, parent):
		"""Creates a model for the tableview using data retrieved from the
		cherry picking database.

		"""
		total = len(data)
		self.progressBar.setMaximum(total)
		self.progressBar.show()
		model = QStandardItemModel(0, len(CHERRY_COLUMNS), parent)
		for position, column in enumerate(CHERRY_COLUMNS):
			model.setHeaderData(position, Qt.Horizontal, column)

		# get additional data for each item
		keys = [item[CHERRY_COLUMNS.index("Key")] for item in data]
		itemIds = []
		missing = []
		itemIdsAll = dict((v, k) for k, v in self.itemIdsAll.iteritems())
		for key in keys:
			if key in itemIdsAll:
				itemIds.append(itemIdsAll[key])
			else:
				missing.append(key)

		if len(missing):
			msg = ("Keys exist in cherry picking database but absent "
				"in Bionumerics {0}".format(", ".join(missing)))
			self.mkWarn(msg)

		if not len(itemIds):
			msg = "No entries in cherry picking database"
			self.statusBar().showMessage(msg, 5000)
			self.mkInfo(msg)
			return None
		itemIds = list(set(itemIds))
		(dnaData, noData, errors) = lims.GetNewestDNAForCherryPicking(itemIds)
		if len(noData):
			msg = ", ".join(str(item) for item in noData)
			self.mkWarn("{0}: {1}".format("No DNA's for these strains", msg))

		if len(errors):
			msg = ", ".join(errors)
			self.mkError(msg)

		for count, result in enumerate(data):
			result = list(result)
			key = result[0]
			if key in itemIdsAll:
				self.progressBar.setValue(count)
				#QApplication.processEvents()
				parentID = itemIdsAll[key]

				if parentID in dnaData:
					properties = dnaData[parentID]
					for value in ("ItemName", "DNA concentration", "Volume",
								 "Freezer", "Rack", "Shelf", "PlateRack",
								  "Position"):
						if value in properties:
							result.append(properties[value])
						else:
							result.append("")
			self.addCherryData(model, result)
		return model

	def cherryPicking(self):
		"""Populate the cherry picking table"""
		if self.populatedCherry:
			if not self.stackedWidget.currentIndex() == 2:
				self.stackedWidget.setCurrentIndex(2)
				self.updateUi()
			return
		self.statusbar.showMessage("Getting data from cherry picking database")

		db = DB.Db.Info.Name
		cherryData = pgdb.get_data(db)

		if not len(cherryData):
			msg = "No cherry picking entries for this database"
			self.statusbar.showMessage(msg, 5000)
			self.mkInfo(msg)
			self.stackedWidget.setCurrentIndex(2)
			self.updateUi()
			return

		self.userComboBox.clear()
		self.statusComboBox.clear()
		# filter combo boxes
		for label, combo in (("Username", self.userComboBox),
							("Status", self.statusComboBox)):
			position = CHERRY_COLUMNS.index(label)
			comboItems = set([item[position] for item in cherryData])
			combo.addItem("All")
			combo.addItems(list(comboItems))

		self.proxyModel.traceStatus = self.statusComboBox.currentText()
		self.cherryView.reset()
		self.cherryView.setDisabled(True)
		self.statusbar.showMessage("Getting data from ItemTracker")

		model = self.createCherryModel(cherryData, self)
		if not model:
			self.cherryView.setEnabled(False)
			self.filterGroupBox.setDisabled(True)
		else:
			self.proxyModel.setSourceModel(model)
			self.cherryView.setEnabled(True)
			self.filterGroupBox.setEnabled(True)

		self.cherryView.resizeColumnsToContents()
		self.updateCounts()
		self.stackedWidget.setCurrentIndex(2)  # switch view to table
		self.statusbar.clearMessage()
		self.progressBar.setValue(len(cherryData))
		self.progressBar.hide()
		self.populatedCherry = True
		self.updateUi()

	def statusChanged(self):
		"""Filter cherry picking based on current trace status from combo box."""
		self.proxyModel.setTraceStatus(self.statusComboBox.currentText())
		self.updateCounts()

	def userChanged(self):
		"""Filter cherry picking based on current user from combo box."""
		user = self.userComboBox.currentText()
		if user == "All":
			user = "******"
		regExp = QRegExp(user, Qt.CaseInsensitive, QRegExp.RegExp2)
		self.proxyModel.setFilterRegExp(regExp)
		self.updateCounts()

	def updateCounts(self):
		"""Update counts of strains, traces and DNA in cherry picking"""
		strains = []
		traces = self.proxyModel.rowCount()
		dna = []

		for i in range(traces):
			for field, totals in (("Key", strains), ("DNA", dna)):
				index = self.proxyModel.index(i, CHERRY_COLUMNS.index(field))
				data = self.proxyModel.data(index).toString().trimmed()
				if len(data) and data not in totals:
					totals.append(data)

		self.strainsLcdNumber.display(len(strains))
		self.tracesLcdNumber.display(traces)
		self.dnaLcdNumber.display(len(dna))

	def getSaveFile(self, caption=""):
		"""Opens the save file dialog and returns the file name."""
		if not len(caption):
			caption = "Save File As"

		fn = QFileDialog.getSaveFileName(self, caption, self.dbPath,
										 "Text files (*.txt);;All Files (*.*)")
		if fn:
			if QFileInfo(fn).suffix().isEmpty():
				fn += ".txt"
		return fn

	def exportTextFile(self, fh=None, header=None, data=None):
		"""Writes data to the given file. Accepts column names and the data as
		arguments

		"""
		if not fh:
			self.mkError("Could not open file for writing")
			return

		if not data:
			data = []

		if not len(data):
			self.mkWarn("No data to write")
			return

		fname = QFile(fh)
		if fname.open(QFile.WriteOnly | QFile.Text):
			txt = QTextStream(fname)
			if header:
				txt << ", ".join(col for col in header)
			txt << "\n"
			txt << "\n".join(", ".join(item) for item in data)

			msg = "File export complete: {0}".format(str(fname.fileName()))
			self.mkSuccess(msg)

	def exportDNAList(self):
		"""Export list of DNA's displayed in cherry picking."""
		data = []
		keys = []

		columns = CHERRY_COLUMNS[:]
		excludeColumns = ["Gene", "Orientation"]
		exclude = []

		for item in excludeColumns:
			exclude.append(CHERRY_COLUMNS.index(item))
			columns.remove(item)

		keyIndex = CHERRY_COLUMNS.index("Key")
		dnaIndex = CHERRY_COLUMNS.index("DNA")
		for i in range(0, self.proxyModel.rowCount()):
			# continue if key exists in keys
			index = self.proxyModel.index(i, keyIndex)
			key = self.proxyModel.data(index).toString()

			if key in keys:
				continue
			# continue if DNA column is empty
			index = self.proxyModel.index(i, dnaIndex)
			dna = self.proxyModel.data(index).toString()

			if dna.isEmpty():
				continue
			row = []
			for j in range(self.proxyModel.columnCount()):
				if j in exclude:
					continue
				index = self.proxyModel.index(i, j)
				value = self.proxyModel.data(index).toString()

				if not value.isEmpty():
					row.append(str(value))
				else:
					row.append("")
			data.append(row)
			keys.append(key)

		fh = self.getSaveFile("Export DNA List")
		self.exportTextFile(fh, columns, data)

	def exportTraceList(self):
		"""Export list of traces displayed in cherry picking."""
		data = []
		for i in range(0, self.proxyModel.rowCount()):
			row = []
			for j in range(self.proxyModel.columnCount()):
				index = self.proxyModel.index(i, j)
				value = self.proxyModel.data(index).toString()
				if not value.isEmpty():
					row.append(str(value))
				else:
					row.append("")
			data.append(row)

		fh = self.getSaveFile("Export Trace List")
		columns = CHERRY_COLUMNS[:]
		self.exportTextFile(fh, columns, data)

	def clearLog(self):
		"""Clears the log window"""
		self.logBrowser.clear()

	def closeEvent(self, event):
		"""Called on closing the window. Save settings and exit."""
		self.handler.close()
		self.logger.removeHandler(self.handler)

		if self.okToContinue():
			settings = QSettings()
			settings.setValue("MainWindow/Size", QVariant(self.size()))
			settings.setValue("MainWindow/Position", QVariant(self.pos()))
			settings.setValue("MainWindow/State", QVariant(self.saveState()))
			settings.setValue("MainWindow/SplitState",
							 self.splitter.saveState())

			bnSelectedFields = QVariant(self.bnSelectedFields) \
			if self.bnSelectedFields else QVariant()
			regkey = "Bionumerics/{0}/SelFields".format(self.dbName)
			settings.setValue(regkey, bnSelectedFields)

			itSelectedFields = QVariant(self.itSelectedFields) \
			if self.itSelectedFields else QVariant()
			settings.setValue("ItemTracker/SelFields", itSelectedFields)
		else:
			event.ignore()

	def collapseItem(self):
		"""Collapse selected item."""
		try:
			selected = self.treeWidget.selectedItems()[0]
		except IndexError:
			selected = None
			self.statusbar.showMessage("No item selected", 2000)

		if selected:
			self.treeWidget.collapseItem(selected)

	def collapseAll(self):
		"""Collapse all items."""
		self.treeWidget.collapseAll()

	def disableWidgets(self, widgets):
		"""Disable group of widgets. Does not change visibility."""
		for widget in widgets:
			if widget.isEnabled():
				widget.setDisabled(True)

	def enableWidgets(self, widgets):
		"""Enable group of widgets. Set visible if not visible."""
		for widget in widgets:
			if not widget.isEnabled():
				widget.setEnabled(True)
			if not widget.isVisible():
				widget.setVisible(True)

	def expandItem(self):
		"""Expand selected item."""
		try:
			selected = self.treeWidget.selectedItems()[0]
		except IndexError:
			selected = None
			self.statusbar.showMessage("No item selected", 2000)

		if selected:
			self.treeWidget.expandItem(selected)

	def expandAll(self):
		"""Expands all items."""
		self.treeWidget.expandAll()

	def getBnFields(self):
		"""Get bionumerics field information required for the info panel."""
		bnFields = bn.getFieldNames()
		strainFields = ["Strain", "STRAIN"]

		for field in strainFields:
			if (field in bnFields) and (field not in self.bnSelectedFields):
				self.bnSelectedFields.append(field)

		for key in self.selectedIds.values():
			if not self.bnFields.get(key):
				self.bnFields[key] = bn.getSelectedFields(key, bnFields)

	def getParent(self, item):
		"""Returns the top level parent of an item."""
		parentItem = None

		while item.parent():
			parentItem = item.parent()
			item = parentItem
		return parentItem

	def getData(self, items, itemid):
		"""Returns parent and children for data received from GetDictionary."""
		if len(items):
			children = items[itemid].keys()
			yield itemid, children
			items = items[itemid]

			for child in children:
				for res in self.getData(items, child):
					yield res
		return

	def getAllItemIds(self):
		"""Gets all ItemTracker IDs in the current Bionumerics database."""
		itemIds = {}
		field = "ItemTracker ID"
		value = None
		for i in range(len(DB.Db.Entries)):
			value = DB.Db.Entries[i].Field(field).Content
			# bugfix: don't display if ItemTracker ID contains spaces
			value = value.strip()
			if not len(value):
				continue

			key = DB.Db.Entries[i].Key
			key = key.strip()
			if key in itemIds:
				itemIds.pop(key)
				msg = "Duplicate keys in database: {0}. Not processed".format(key)
				self.mkWarn(msg)
				continue

			try:
				value = int(value)
			except (ValueError, TypeError):
				self.mkWarn("Invalid ItemTracker ID {0} for entry "
						"{1} in Bionumerics".format(value, key))

			if isinstance(value, int):
				if value in itemIds.values():
					msg = ("Duplicate ItemTracker ID: {0}. "
						"Keys: {1}, ".format(value, key))
					for k, v in itemIds.items():
						if v == value:
							itemIds.pop(k)
							msg += k
					self.mkWarn(msg)
				else:
					itemIds[key] = value

		return itemIds

	def getAllSelected(self):
		"""Get all selected items by user."""
		if self.populatedTable:
			self.stackedWidget.setCurrentIndex(1)
			self.updateUi()
			return
		msg = "Getting all selected entries from ItemTracker. Please wait..."
		self.statusbar.showMessage(msg)

		if len(self.itemIdsAll):
			try:
				self.tableResults = \
				lims.SelectAllselectedEntries(self.itemIdsAll.keys())
			except:
				raise RuntimeError
		else:
			self.mkInfo("No ItemTracker IDs to process")

		if not len(self.tableResults):
			user = os.environ.get("USERNAME")
			msg = "No selected entries for user {0}".format(user)
			self.statusbar.showMessage(msg, 5000)
			self.mkInfo(msg)
			self.stackedWidget.setCurrentIndex(1)
			self.populatedTable = False
			self.updateUi()
		else:
			QTimer.singleShot(0, self.populateTable)

	def getItemtrackerFields(self):
		"""Returns all ItemTracker fields returned from GetDictionary."""
		fields = []
		alwaysFields = ["ItemID", "ItemName", "Position"]

		for item in self.itemProperties:
			for field in self.itemProperties[item].keys():
				if (field not in fields) and (field not in alwaysFields):
					fields.append(field)
		return fields

	def getWidget(self):
		"""Returns the current active widget."""
		index = self.stackedWidget.currentIndex()
		if index == 0:
			widget = self.treeWidget
		elif index == 1:
			widget = self.selectedWidget
		elif index == 2:
			widget = self.cherryView

		return widget

	def about(self):
		"""About box."""
		import platform
		msg = """\
		<b>IT Query</b> version {0} <p>An interface to query
		ItemTracker from Bionumerics</p>Python {1} - Qt {2} -
		PyQt {3} on {4}\
		""".format(__version__, platform.python_version(),
				QT_VERSION_STR, PYQT_VERSION_STR, platform.system())

		msg += """<br>Icons from the
		<a href="http://www.oxygen-icons.org/">Oxygen project</a>
		</p>"""
		QMessageBox.about(self, "About IT Query", msg)

	def legend(self):
		"""A simple dialog displaying the color legend used in treeview."""
		dialog = legenddlg.legendDialog(self)
		dialog.exec_()

	def itSelectFields(self):
		"""ItemTracker field selection dialog."""
		fieldNames = self.getItemtrackerFields()
		dialog = selectfieldsdlg.selectFieldsDialog(fieldNames, self)

		if self.itSelectedFields is not None:
			dialog.setSelected(self.itSelectedFields)

		if dialog.exec_():
			self.itSelectedFields = dialog.getSelected()
			self.updateInfo()

	def mkWarn(self, msg):
		"""Orange color"""
		bgColor = "235,115,49"
		self.mkTable(bgColor, "WARNING", msg)

	def mkError(self, msg):
		"""Red color"""
		bgColor = "226,8,0"
		self.mkTable(bgColor, "ERROR", msg)

	def mkSuccess(self, msg):
		"""Green color"""
		bgColor = "55,164,44"
		self.mkTable(bgColor, "SUCCESS", msg)

	def mkInfo(self, msg):
		"""Blue color"""
		bgColor = "0,87,174"
		self.mkTable(bgColor, "INFO", msg)

	def mkTable(self, bgColor, status, msg):
		"""Formats message displayed in the log window."""
		formatStatus = ('<font style="color:rgb({0})"><strong>{1}</strong>'
					'</font>'.format(bgColor, status))
		self.logBrowser.append("{0}: {1}".format(formatStatus, msg))

	def okToContinue(self):
		"""Check before closing."""
		if len(self.updatedStrains):
			reply = QMessageBox(QMessageBox.Question,
			"Selection", "Entry selection in Bionumerics",
			QMessageBox.NoButton, self)

			originalButton = QPushButton("Keep Original Selection")
			updatedButton = QPushButton("Updated Items Only")
			cancelButton = QPushButton("Cancel")

			reply.addButton(originalButton, QMessageBox.ActionRole)
			reply.addButton(updatedButton, QMessageBox.ActionRole)
			reply.addButton(cancelButton, QMessageBox.RejectRole)
			reply.exec_()

			if reply.clickedButton() == cancelButton:
				return False
			elif reply.clickedButton() == originalButton:
				bn.selectEntries(self.selectedIds.values() +\
								 self.errorIds.keys())
			elif reply.clickedButton() == updatedButton:
				bn.selectEntries(self.updatedStrains)
		return True

	def populateTable(self):
		"""Populates table with data from ItemTracker."""
		self.selectedWidget.clear()
		self.selectedWidget.setSortingEnabled(False)
		numRows = len(self.tableResults)
		self.mkInfo("Selected items in ItemTracker: {0}".format(numRows))

		self.selectedWidget.setAlternatingRowColors(True)
		header = ["ItemID", "StrainID", "ItemType", "ItemName", "BacteriaItemID"]
		self.selectedWidget.setColumnCount(len(header))
		self.selectedWidget.setHeaderLabels(header)

		# use result and populate table
		for result in self.tableResults:
			properties = [unicode(i) for i in result]
			item = QTreeWidgetItem(self.selectedWidget, properties)
			item.setCheckState(0, Qt.Unchecked)

		self.selectedWidget.setSortingEnabled(True)
		for i in range(len(header)):
			self.selectedWidget.resizeColumnToContents(i)
		self.stackedWidget.setCurrentIndex(1) # switch view to table
		self.statusbar.clearMessage()
		self.populatedTable = True
		self.updateUi()

	def populateTree(self):
		"""Populates tree view with information from ItemTracker."""
		if len(self.errorIds):
			self.mkError("{0} entries do not have valid "
			"ItemTracker IDs in Bionumerics.".format(len(self.errorIds)))

			for key, msg in self.errorIds.iteritems():
				self.mkError("KEY: {0} {1}".format(key, msg))

		if not len(self.selectedIds):
			self.statusbar.showMessage("No items to process", 5000)
			return

		parents = {}
		headers = ["Items", "Selected", "SelectedBy", "Viability", "Volume",
				 "DNA concentration", "UserName", "TubePresent", "InputDate",
				 "AlternID", "Status"]

		self.treeWidget.setItemsExpandable(True)
		self.treeWidget.setAlternatingRowColors(True)
		self.treeWidget.setColumnCount(len(headers))
		self.treeWidget.setHeaderLabels(headers)

		msg = "Getting information from ItemTracker. Please wait..."
		self.statusbar.showMessage(msg)

		self.progressBar.setMinimum(0)
		self.progressBar.setMaximum(0)
		self.progressBar.show()

		(treeData, self.itemProperties,
		 message) = lims.GetDictionary((self.selectedIds.keys()))

		if len(message):
			for msg in message:
				self.mkError("ItemTracker error: {0}".format(msg))

		if not len(treeData):
			self.mkError("Could not get data from ItemTracker for"
						"selected entries")
			self.statusBar().clearMessage()
			self.progressBar.hide()
			self.updateUi()
			return

		# bugfix: If ItemType property does not exist for the first item
		# self.database is not set and tree view is not updated.
		db = None
		if not self.database:
			for item in self.itemProperties.values():
				try:
					db = item["ItemType"]
				except KeyError:
					pass

				if db == "Salmonella":
					self.database = db
					break
				elif db == "Listeria":
					self.database = db
					break

		self.progressBar.setMaximum(len(treeData))
		count = 0
		for key, value  in treeData.iteritems():
			count += 1
			self.progressBar.setValue(count)
			if not(value and isinstance(value, dict)):
				self.mkWarn("No data returned for key {0}".format(key))
				continue

			items = {}
			items[key] = value
			for results in self.getData(items, key):
				parent = parents.get(results[0])

				if not parent:
					parent_id = self.selectedIds[results[0]]
					self.strainInfo[parent_id] = {self.database:[],
												"Frozen Stock":[], "DNA":[]}
					parent = QTreeWidgetItem(self.treeWidget,
					[unicode(parent_id)])

					brush = QBrush()
					brush.setColor(Qt.blue)
					parent.setForeground(0, brush)
					parent.setIcon(0, QIcon(":/branch-closed.png"))
					parent.setData(0, Qt.CheckStateRole, QVariant())
					parents[results[0]] = parent

				for children in results[1]:
					itemName = self.itemProperties[children]["ItemName"]
					if not self.itemIds.get(itemName):
						self.itemIds[itemName] = children

					childprops = []
					childprops.append(unicode(itemName))

					for header in headers[1:]:
						try:
							childprop = self.itemProperties[children][header]

							if childprop is None or childprop == "":
								childprops.append(unicode(""))
							else:
								childprops.append(unicode(childprop))
						except KeyError:
							childprops.append(unicode(""))
							continue

					childs = parents.get(children)
					if not childs:
						childs = QTreeWidgetItem(parent, childprops)

						if self.itemProperties[children]["TubePresent"] == "-":
							childs.setBackgroundColor(0, QColor(232, 87, 82))
							childs.setForeground(0, QColor(255, 255, 255))

						if self.itemProperties[children]["Selected"] == "yes":
							childs.setBackgroundColor(0, QColor(119, 183, 83))
							childs.setForeground(0, QColor(255, 255, 255))

						itype = self.itemProperties[children]["ItemType"]
						if itype:
							self.strainInfo[parent_id][itype].append(itemName)
						parents[children] = childs
					childs.setCheckState(0, Qt.Unchecked)

		self.treeWidget.expandAll()
		for i in range(len(headers)):
			self.treeWidget.resizeColumnToContents(i)
		if not self.treeWidget.isEnabled():
			self.treeWidget.setEnabled(True)
		self.mkInfo("Processed <b>{0}</b> entries".format(len(treeData)))

		self.progressBar.setValue(len(treeData))
		self.progressBar.hide()
		self.populatedTree = True
		self.updateUi()
		self.statusbar.showMessage("Ready", 5000)

	def selectAll(self):
		"""All items are selected (checked)."""
		index = self.stackedWidget.currentIndex()
		widget = self.getWidget()
		it = QTreeWidgetItemIterator(widget, QTreeWidgetItemIterator.NotChecked)
		count = 0
		if index == 0:
			while it.value():
				if it.value().parent():
					it.value().setCheckState(0, Qt.Checked)
					count += 1
				it += 1
		elif index == 1:
			while it.value():
				it.value().setCheckState(0, Qt.Checked)
				count += 1
				it += 1
		if count:
			self.statusbar.showMessage("Selected {0} items".format(count), 3000)

	def selectDNA(self):
		"""Select all DNA items."""
		self.selectItems("DNA")

	def selectFrozenStock(self):
		"""Select all Frozen Stock items."""
		self.selectItems("Frozen Stock")

	def selectNone(self):
		"""Clears the selection."""
		widget = self.getWidget()
		it = QTreeWidgetItemIterator(widget, QTreeWidgetItemIterator.Checked)
		while it.value():
			it.value().setCheckState(0, Qt.Unchecked)
			it += 1

	def selectInvert(self):
		"""Inverts the selection."""
		index = self.stackedWidget.currentIndex()
		widget = self.getWidget()
		it = QTreeWidgetItemIterator(widget)

		if index == 0:
			while it.value():
				if it.value().parent():
					if it.value().checkState(0) == Qt.Checked:
						it.value().setCheckState(0, Qt.Unchecked)
					else:
						it.value().setCheckState(0, Qt.Checked)
				it += 1
		else:
			while it.value():
				if it.value().checkState(0) == Qt.Checked:
					it.value().setCheckState(0, Qt.Unchecked)
				else:
					it.value().setCheckState(0, Qt.Checked)
				it += 1

	def selectItems(self, itemType):
		"""Select all items of a given ItemType."""
		self.statusbar.showMessage("Selecting all {0}'s. "
								"Please wait...".format(itemType))

		items = []
		itemsAll = []
		index = self.stackedWidget.currentIndex()

		if index == 0:
			position = 0
			items = [item[itemType] for item in self.strainInfo.values()]
			for item in items:
				if len(item):
					itemsAll += item
		else:
			position = 3
			for item in self.tableResults:
				if item[2] == itemType:
					itemsAll.append(item[3])

		if not len(itemsAll):
			self.statusbar.showMessage("No {0}'s in list".format(itemType), 5000)
			return
		self.selectNone()
		widget = self.getWidget()
		it = QTreeWidgetItemIterator(widget)
		while it.value():
			if it.value().text(position) in itemsAll:
				it.value().setCheckState(0, Qt.Checked)
			it += 1
		self.statusbar.showMessage("Selected {0} {1}'s".format(len(itemsAll),
															 itemType), 3000)

	def selectInBionumerics(self, on):
		"""Selects Bionumerics entries with checked items from table view
		(get all selected)

		"""
		actionGroup = QActionGroup(self)
		actionGroup.addAction(self.actionViewTree)
		actionGroup.addAction(self.refresh_action)
		actionGroup.addAction(self.actionSelectAll)
		actionGroup.addAction(self.actionSelectInvert)
		actionGroup.addAction(self.actionSelectNone)
		actionGroup.addAction(self.actionSelectDNA)
		actionGroup.addAction(self.actionSelectFrozenStock)

		if on:
			actionGroup.setEnabled(False)
			if not len(self.itemNames):
				self.itemNames = bn.createIdMap()

			it = QTreeWidgetItemIterator(self.selectedWidget,
										 QTreeWidgetItemIterator.Checked)
			checkedItems = []
			while it.value():
				parentCode = unicode(it.value().text(4))
				bnStrain = self.itemNames[int(parentCode)]

				if bnStrain not in checkedItems:
					checkedItems.append(bnStrain)
				it += 1

			if len(checkedItems):
				bn.selectEntries(checkedItems)
			else:
				self.statusbar.showMessage("No items checked", 3000)
		else:
			actionGroup.setEnabled(True)
			bn.selectEntries(self.selectedIds.values() + self.errorIds.keys())

	def updateSelection(self):
		"""Updates selection status in ItemTracker."""
		if self.actionSelectInBionumerics.isChecked():
			self.selectInBionumerics(False)
			self.actionSelectInBionumerics.setChecked(False)

		self.updateButton.setEnabled(False)
		self.statusbar.showMessage("Updating selection. Please wait...")

		if self.selectRadioButton.isChecked():
			selectedAction = "SELECT"
		elif self.deselectRadioButton.isChecked():
			selectedAction = "DESELECT"

		checkedItems = {}
		updatedItems = []
		failedItems = []

		index = self.stackedWidget.currentIndex()
		widget = self.getWidget()
		it = QTreeWidgetItemIterator(widget, QTreeWidgetItemIterator.Checked)

		if index == 0:
			while it.value():
				itemName = unicode(it.value().text(0))
				itemId = self.itemIds[itemName]
				checkedItems[itemName] = itemId
				parentItem = self.getParent(it.value())
				strain =  unicode(parentItem.text(0))
				if strain not in self.updatedStrains:
					self.updatedStrains.append(strain)
				it += 1
		elif index == 1:
			if not len(self.itemNames):
				self.itemNames = bn.createIdMap()

			while it.value():
				itemId = unicode(it.value().text(0))
				itemName = unicode(it.value().text(3))
				checkedItems[itemName] = int(itemId)

				parentCode = unicode(it.value().text(4))
				strain = self.itemNames[int(parentCode)]
				if strain not in self.updatedStrains:
						self.updatedStrains.append(strain)
				it += 1

		if not len(checkedItems):
			self.statusbar.showMessage("No items checked", 5000)
			self.updateButton.setEnabled(True)
			return

		for itemName, itemId in checkedItems.iteritems():
			if selectedAction == "SELECT":
				result = lims.SelectItem(itemId)
			elif selectedAction == "DESELECT":
				result = lims.UnselectItem(itemId)

			if not len(result):
				updatedItems.append(itemName)
			else:
				failedItems.append(itemName)

		if len(updatedItems):
			self.mkSuccess("{0}ED {1} items".format(selectedAction,
												 len(updatedItems)))
			self.logBrowser.append("{0}".format(", ".join(updatedItems)))
			self.logger.info("{0}\t{1}".format(selectedAction, ", ".join(updatedItems)))
		if len(failedItems):
			self.mkError("{0} failed for {1} items".format(selectedAction,
														 len(failedItems)))

			self.logBrowser.append("{0}".format(", ".join(failedItems)))
			self.logger.info("{0}\t{1}".format(selectedAction,
											 ", ".join(failedItems)))

		self.updateButton.setEnabled(True)
		if len(updatedItems) or len(failedItems):
			self.populatedTree = False
			self.populatedTable = False
			self.refresh()

	def updateUi(self):
		"""Updates interface based on the view."""
		index = self.stackedWidget.currentIndex()

		# only show export actions in cherry picking
		if index != 2:
			widgets = [self.exportToolBar, self.exportActions]
			self.disableWidgets(widgets)
			for widget in widgets:
				widget.setVisible(False)

		# disable select menu in cherry picking (not implemented)
		if index == 2:
			self.selectMenu.setEnabled(False)
		else:
			self.selectMenu.setEnabled(True)

		if index == 0:  # Tree View
			self.disableWidgets([self.actionViewTree,
								self.actionSelectInBionumerics])
			self.enableWidgets([self.actionGetAllSelected,
							self.actionCherryPicking])

			for widget in [self.actionSelectInBionumerics,
						self.getSelectedToolBar]:
				widget.setVisible(False)

			#self.fieldsGroupBox.setVisible(True)
			widgets = [self.widget, self.treeWidget, self.selectGroupBox,
					self.fieldsGroupBox, self.actionLegend, self.treeToolBar,
					self.treeActions, self.selectActions]
			for widget in widgets:
				if not widget.isVisible():
					widget.setVisible(True)

			if self.populatedTree:
				self.enableWidgets(widgets)
			else:
				self.disableWidgets(widgets)

			try:
				self.treeWidget.selectedItems()[0]
			except IndexError:
				self.infoBrowser.setDisabled(True)

			self.fieldsGroupBox.setEnabled(self.infoBrowser.isEnabled())

		elif index == 1:
			self.widget.setVisible(True)
			self.enableWidgets([self.actionViewTree, self.actionCherryPicking])
			self.actionSelectInBionumerics.setVisible(True)
			self.getSelectedToolBar.setVisible(True)

			for widget in [self.actionLegend, self.fieldsGroupBox,
						 self.treeToolBar, self.treeActions]:
				widget.setVisible(False)

			self.disableWidgets([self.actionGetAllSelected, self.actionLegend,
								 self.treeToolBar, self.treeActions])

			widgets = [self.widget, self.selectedWidget, self.selectGroupBox,
					self.actionSelectInBionumerics, self.getSelectedToolBar,
					self.selectActions]

			if self.populatedTable:
				self.enableWidgets(widgets)
			else:
				self.disableWidgets(widgets)

		elif index == 2:
			self.widget.setVisible(False)  # ItemTracker and field selection
			self.actionCherryPicking.setEnabled(False)
			self.exportToolBar.setVisible(True)
			self.exportActions.setVisible(True)

			for action in [self.actionViewTree, self.actionGetAllSelected]:
				action.setEnabled(True)

			widgets = [self.selectActions, self.actionSelectInBionumerics,
					 self.actionLegend, self.treeActions, self.treeToolBar,
					 self.getSelectedToolBar]
			self.disableWidgets(widgets)
			for widget in widgets:
				widget.setVisible(False)

			widgets = [self.cherryView, self.filterGroupBox, self.lcdGroupBox,
					 self.exportActions, self.exportToolBar]

			if self.populatedCherry:
				self.enableWidgets(widgets)
			else:
				self.disableWidgets(widgets)

	def updateInfo(self):
		"""Infobar displaying ItemTracker and Bionumerics fields."""
		content = ('<table border="0" cellspacing="0" '
		'cellpadding="5" width="100%">')
		self.infoBrowser.clear()
		try:
			selected = self.treeWidget.selectedItems()[0]
		except IndexError:
			return
		else:
			self.infoBrowser.setEnabled(True)
			self.fieldsGroupBox.setEnabled(True)
		try:
			parentName = self.getParent(selected).text(0)
		except AttributeError:
			parentName = None

		if parentName:
			itemName = unicode(selected.text(0))
			itemId = self.itemIds[itemName]

			if itemId:
				content += """\
				<tr bgcolor="#85026C">
					<th colspan="2" align="left">
						<font color="white">ITEMTRACKER</font>
					</th>
				</tr>\
				"""
				count = 0
				for field, value in (("Strain", parentName),
									 ("Item&nbsp;Name", itemName),
									 ("Item&nbsp;ID", itemId)):
					if count % 2 == 0:
						content += """\
						<tr>
							<td>{0}</td>
							<td>{1}</td>
						</tr>\
						""".format(field, value)
					else:
						content += """\
						<tr bgcolor="#eee">
							<td>{0}</td>
							<td>{1}</td>
						</tr>\
						""".format(field, value)
					count += 1
			try:
				properties = self.itemProperties[int(itemId)]
			except KeyError:
				self.mkWarn("Could not get properties for "
				"ItemTracker ID {0}".format(itemId))

			if len(properties):
				try:
					location = properties["Position"]
				except KeyError:
					location = []
				if len(location):
					for field, value in (("Freezer", location[0]),
										 ("Rack", location[1]),
										 ("Shelf", location[2]),
										 ("Plate Rack", location[3]),
										 ("Position", location[4])):
						if count % 2 == 0:
							content += """\
							<tr>
								<td>{0}</td>
								<td>{1}</td>
							</tr>\
							""".format(field, value)
						else:
							content += """\
							<tr bgcolor="#eee">
								<td>{0}</td>
								<td>{1}</td>
							</tr>\
							""".format(field, value)
						count += 1

				if len(self.itSelectedFields):

					for itField in self.itSelectedFields:
						try:
							itemProperty = properties[itField]
						except KeyError:
							itemProperty = ""

						if count % 2 == 0:
							content += """\
							<tr>
								<td>{0}</td>
								<td>{1}</td>
							</tr>\
							""".format(itField, itemProperty)
						else:
							content += """\
							<tr bgcolor="#eee">
								<td>{0}</td>
								<td>{1}</td>
							</tr>\
							""".format(itField, itemProperty)
						count += 1
			else:
				content += """\
				<tr>
					<td colspan="2">No information</td>
				</tr>"""

			self.infoBrowser.setHtml(QString(content))
			content += """\
			<tr bgcolor="#CF4913">
				<th colspan="2" align="left">
					<font color="white">BIONUMERICS</font>
				</th>
			</tr>\
			"""
			strainInfo = {}
			try:
				strainInfo = self.bnFields.get(unicode(parentName))
			except KeyError:
				self.mkWarn("Could not get information for {0}".format(parentName))

			if len(strainInfo):
				count = 0
				for field in self.bnSelectedFields:

					if count % 2 == 0:
						content += """\
						<tr>
							<td>{0}</td>
							<td>{1}</td>
						</tr>\
						""".format(field, strainInfo[field])
					else:
						content += """\
						<tr bgcolor="#eee">
							<td>{0}</td>
							<td>{1}</td>
						</tr>\
						""".format(field, strainInfo[field])
					count += 1
			else:
				self.mkWarn("No information for {0}".format(parentName))
			content += "</table>"
		else:
			strainName = unicode(selected.text(0))
			itemId = None
			for ids, keys in self.selectedIds.iteritems():
				if keys == strainName:
					itemId = ids
					break
			if not itemId:
				self.infoBrowser.setHtml(QString(content))
				return

			content = """\
			<table border="0" cellpadding="5" cellspacing="0" width="100%">
				<tr bgcolor="#85026C">
					<th colspan="2" align="left">
						<font color="white">ITEMTRACKER</font>
					</th>
				</tr>
				<tr bgcolor="#eee">
					<td>AlternID</td>
					<td>{0}</td>
				</tr>
				<tr>
					<td>OriginalID</td>
					<td>{1}</td>
				</tr>\
				""".format(self.itemProperties[itemId]["AlternID"],
			self.itemProperties[itemId]["OriginalID"])

			content += "</table>"
			content += """\
			<table border="0" cellpadding="5" cellspacing="0" width="100%">
				<tr bgcolor="#BF0361">
					<th align="left">
						<font color="white">{0}</font>
					</th>
					<th align="right">
						<font color="white">{1}</font>
					</th>
				</tr>
				<tr>
					<td colspan="2">{2}</td>
				</tr>\
				""".format(self.database.upper(),
				len(self.strainInfo[strainName][self.database]),
				", ".join(self.strainInfo[strainName][self.database]))

			content += """\
			<tr bgcolor="#00438A">
				<th align="left">
					<font color="white">FROZEN STOCK</font>
				</th>
				<th align="right">
					<font color="white">{0}</font>
				</th>
			</tr>
			<tr>
				<td colspan="2">{1}</td>
			</tr>\
			""".format(len(self.strainInfo[strainName]["Frozen Stock"]),
			", ".join(self.strainInfo[strainName]["Frozen Stock"]))

			content += """\
			<tr bgcolor="#00734D">
				<th align="left">
					<font color="white">DNA</font>
				</th>
				<th align="right">
					<font color="white">{0}</font>
				</th>
			</tr>
			<tr>
				<td colspan="2">{1}</td>
			</tr>\
			""".format(len(self.strainInfo[strainName]["DNA"]),
			", ".join(self.strainInfo[strainName]["DNA"]))

			content += "</table>"
		self.infoBrowser.setHtml(QString(content))

	def viewTree(self):
		"""Toolbar button/action to switch to tree view."""
		self.selectRadioButton.setChecked(True)
		if not self.populatedTree:
			self.stackedWidget.setCurrentIndex(0)
			self.refresh()
		self.stackedWidget.setCurrentIndex(0)
		self.updateUi()

	def refresh(self):
		"""Updates view(s)."""
		index = self.stackedWidget.currentIndex()
		if index == 1:
			self.populatedTable = False
			self.selectedWidget.clear()
			self.getAllSelected()
		elif index == 0:
			self.populatedTree = False
			self.treeWidget.clear()
			self.treeWidget.setDisabled(True)
			bnField = "ItemTracker ID"
			self.selectedIds = {}
			self.errorIds = {}
			selection = DB.Db.Selection
			self.selectedIds, self.errorIds = bn.getItemIds(bnField, selection)
			if len(self.selectedIds):
				self.strainInfo = {}
				self.itemIds = {}
				self.getBnFields()
#			self.populateTree()
			QTimer.singleShot(0, self.populateTree)
		elif index == 2:
			self.populatedCherry = False
			QTimer.singleShot(0, self.cherryPicking)

		self.updateUi()
class QuadStatusBar(QHBoxLayout):
    positionChanged = pyqtSignal(int, int, int)  # x,y,z

    def __init__(self, parent=None):
        QHBoxLayout.__init__(self, parent)
        self.setContentsMargins(0, 4, 0, 0)
        self.setSpacing(0)
        self.timeControlFontSize = 12

    def showXYCoordinates(self):
        self.zLabel.setHidden(True)
        self.zSpinBox.setHidden(True)

    def showXYZCoordinates(self):
        self.zLabel.setHidden(False)
        self.zSpinBox.setHidden(False)

    def hideTimeSlider(self, flag):
        visibleBefore = not self.timeSlider.isHidden()
        self.timeSlider.setHidden(flag)
        self.timeEndButton.setHidden(flag)
        self.timeStartButton.setHidden(flag)
        self.timePreviousButton.setHidden(flag)
        self.timeNextButton.setHidden(flag)
        self._registerTimeframeShortcuts(enabled=not flag,
                                         remove=visibleBefore)

    def setToolTipTimeButtonsCrop(self, croppingFlag=False):
        if croppingFlag == True:
            self.timeStartButton.setToolTip(
                "Jump to lirst frame of current crop")
            self.timeEndButton.setToolTip("Jump to last frame of current crop")
            self.timePreviousButton.setToolTip("Previous Frame")
            self.timeNextButton.setToolTip("Next Frame")
        else:
            self.timeStartButton.setToolTip("First Frame")
            self.timeEndButton.setToolTip("Last Frame")
            self.timePreviousButton.setToolTip("Previous Frame")
            self.timeNextButton.setToolTip("Next Frame")

    def setToolTipTimeSliderCrop(self, croppingFlag=False):
        if croppingFlag == True:
            self.timeSlider.setToolTip(
                "Choose the time coordinate of the current crop.")
        else:
            self.timeSlider.setToolTip(
                "Choose the time coordinate of the current dataset.")

    def createQuadViewStatusBar(self, xbackgroundColor, xforegroundColor,
                                ybackgroundColor, yforegroundColor,
                                zbackgroundColor, zforegroundColor):
        self.xLabel, self.xSpinBox = _get_pos_widget('X', xbackgroundColor,
                                                     xforegroundColor)
        self.yLabel, self.ySpinBox = _get_pos_widget('Y', ybackgroundColor,
                                                     yforegroundColor)
        self.zLabel, self.zSpinBox = _get_pos_widget('Z', zbackgroundColor,
                                                     zforegroundColor)

        self.xSpinBox.delayedValueChanged.connect(
            partial(self._handlePositionBoxValueChanged, 'x'))
        self.ySpinBox.delayedValueChanged.connect(
            partial(self._handlePositionBoxValueChanged, 'y'))
        self.zSpinBox.delayedValueChanged.connect(
            partial(self._handlePositionBoxValueChanged, 'z'))

        self.addWidget(self.xLabel)
        self.addWidget(self.xSpinBox)
        self.addWidget(self.yLabel)
        self.addWidget(self.ySpinBox)
        self.addWidget(self.zLabel)
        self.addWidget(self.zSpinBox)

        self.addSpacing(10)

        self.crosshairsCheckbox = QCheckBox()
        self.crosshairsCheckbox.setChecked(False)
        self.crosshairsCheckbox.setCheckable(True)
        self.crosshairsCheckbox.setText("Crosshairs")
        self.addWidget(self.crosshairsCheckbox)

        self.addSpacing(10)

        self.busyIndicator = QProgressBar()
        self.busyIndicator.setMaximumWidth(200)
        self.busyIndicator.setMaximum(0)
        self.busyIndicator.setMinimum(0)
        self.busyIndicator.setVisible(False)
        self.busyIndicator.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        self.addWidget(self.busyIndicator)
        self.setStretchFactor(self.busyIndicator, 1)

        self.addStretch()

        self.addSpacing(20)

        self.timeSpinBox = DelayedSpinBox(750)

        icons_dir = os.path.dirname(volumina.__file__) + "/icons"

        self.timeStartButton = QToolButton()
        self.timeStartButton.setIcon(QIcon(icons_dir + "/skip-start.png"))
        self.addWidget(self.timeStartButton)
        self.timeStartButton.clicked.connect(self._onTimeStartButtonClicked)
        #self.timeStartButton.setFixedWidth(4*self.timeControlFontSize)

        self.timePreviousButton = QToolButton()
        self.timePreviousButton.setIcon(QIcon(icons_dir + "/play-reverse.png"))
        self.addWidget(self.timePreviousButton)
        self.timePreviousButton.clicked.connect(
            self._onTimePreviousButtonClicked)
        #self.timePreviousButton.setFixedWidth(4*self.timeControlFontSize)

        self.timeSlider = QSlider(Qt.Horizontal)
        self.timeSlider.setMinimumWidth(10)
        self.timeSlider.setMaximumWidth(200)
        self.setToolTipTimeSliderCrop()
        self.addWidget(self.timeSlider)
        self.timeSlider.valueChanged.connect(self._onTimeSliderChanged)

        self.timeNextButton = QToolButton()
        self.timeNextButton.setIcon(QIcon(icons_dir + "/play.png"))
        self.addWidget(self.timeNextButton)
        self.timeNextButton.clicked.connect(self._onTimeNextButtonClicked)
        #self.timeNextButton.setFixedWidth(4*self.timeControlFontSize)

        self.timeEndButton = QToolButton()
        self.timeEndButton.setIcon(QIcon(icons_dir + "/skip-end.png"))
        #self.timeEndButton.setFixedWidth(4*self.timeControlFontSize)

        self.setToolTipTimeButtonsCrop()
        self.addWidget(self.timeEndButton)
        self.timeEndButton.clicked.connect(self._onTimeEndButtonClicked)

        self.timeLabel = QLabel("       Time:")
        self.addWidget(self.timeLabel)

        timeControlFont = self.timeSpinBox.font()
        if self.timeControlFontSize > timeControlFont.pointSize():
            timeControlFont.setPixelSize(2 * self.timeControlFontSize)
            self.timeStartButton.setFont(timeControlFont)
            self.timeEndButton.setFont(timeControlFont)
            self.timeLabel.setFont(timeControlFont)
            self.timeSpinBox.setFont(timeControlFont)

        self.addWidget(self.timeSpinBox)
        self.timeSpinBox.delayedValueChanged.connect(
            self._onTimeSpinBoxChanged)

        self._registerTimeframeShortcuts()

    def _registerTimeframeShortcuts(self, enabled=True, remove=True):
        """ Register or deregister "," and "." as keyboard shortcuts for scrolling in time """
        mgr = ShortcutManager()
        ActionInfo = ShortcutManager.ActionInfo

        def action(key, actionInfo):
            if enabled:
                mgr.register(key, actionInfo)
            else:
                if remove:
                    mgr.unregister(actionInfo)

        action(
            "<",
            ActionInfo("Navigation", "Go to next time frame",
                       "Go to next time frame", self._onTimeNextButtonClicked,
                       self.timeNextButton, self.timeNextButton))
        action(
            ">",
            ActionInfo("Navigation", "Go to previous time frame",
                       "Go to previous time frame",
                       self._onTimePreviousButtonClicked,
                       self.timePreviousButton, self.timePreviousButton))

    def _onTimeStartButtonClicked(self):
        self.timeSpinBox.setValue(
            self.parent().parent().parent().editor.cropModel.get_roi_t()[0])

    def _onTimeEndButtonClicked(self):
        self.timeSpinBox.setValue(
            self.parent().parent().parent().editor.cropModel.get_roi_t()[1])

    def _onTimePreviousButtonClicked(self):
        self.timeSpinBox.setValue(self.timeSpinBox.value() - 1)

    def _onTimeNextButtonClicked(self):
        self.timeSpinBox.setValue(self.timeSpinBox.value() + 1)

    def _onTimeSpinBoxChanged(self):
        editor = self.parent().parent().parent().editor
        cropModel = editor.cropModel
        minValueT = cropModel.get_roi_t()[0]
        maxValueT = cropModel.get_roi_t()[1]

        if cropModel.get_scroll_time_outside_crop():
            if minValueT > self.timeSpinBox.value(
            ) or maxValueT < self.timeSpinBox.value():
                for imgView in editor.imageViews:
                    imgView._croppingMarkers._shading_item.set_paint_full_frame(
                        True)
            else:
                for imgView in editor.imageViews:
                    imgView._croppingMarkers._shading_item.set_paint_full_frame(
                        False)
            self.timeSlider.setValue(self.timeSpinBox.value())
        else:
            for imgView in editor.imageViews:
                imgView._croppingMarkers._shading_item.set_paint_full_frame(
                    False)
            if minValueT > self.timeSpinBox.value():
                self.timeSlider.setValue(minValueT)
            elif maxValueT < self.timeSpinBox.value():
                self.timeSlider.setValue(maxValueT)
            elif minValueT <= self.timeSpinBox.value(
            ) and self.timeSpinBox.value() <= maxValueT:
                self.timeSlider.setValue(self.timeSpinBox.value())

    def _onTimeSliderChanged(self):
        cropModel = self.parent().parent().parent().editor.cropModel
        minValueT = cropModel.get_roi_t()[0]
        maxValueT = cropModel.get_roi_t()[1]

        if cropModel.get_scroll_time_outside_crop():
            self.timeSpinBox.setValue(self.timeSlider.value())
        else:
            if minValueT > self.timeSlider.value():
                self.timeSpinBox.setValue(minValueT)
                self.timeSlider.setValue(minValueT)
            elif self.timeSlider.value() > maxValueT:
                self.timeSpinBox.setValue(maxValueT)
                self.timeSlider.setValue(maxValueT)
            elif minValueT <= self.timeSlider.value(
            ) and self.timeSlider.value() <= maxValueT:
                self.timeSpinBox.setValue(self.timeSlider.value())

    def _handlePositionBoxValueChanged(self, axis, value):
        new_position = [
            self.xSpinBox.value(),
            self.ySpinBox.value(),
            self.zSpinBox.value()
        ]
        changed_axis = ord(axis) - ord('x')
        new_position[changed_axis] = value
        self.positionChanged.emit(*new_position)

    def updateShape5D(self, shape5D):
        self.timeSpinBox.setMaximum(shape5D[0] - 1)
        self.xSpinBox.setMaximum(shape5D[1] - 1)
        self.ySpinBox.setMaximum(shape5D[2] - 1)
        self.zSpinBox.setMaximum(shape5D[3] - 1)

    def updateShape5Dcropped(self, shape5DcropMin, shape5Dmax):
        self.timeSpinBox.setMaximum(shape5Dmax[0] - 1)
        self.xSpinBox.setMaximum(shape5Dmax[1] - 1)
        self.ySpinBox.setMaximum(shape5Dmax[2] - 1)
        self.zSpinBox.setMaximum(shape5Dmax[3] - 1)
        self.timeSlider.setMaximum(shape5Dmax[0] - 1)

        self.timeSpinBox.setValue(shape5DcropMin[0])
        self.xSpinBox.setValue(shape5DcropMin[1])
        self.ySpinBox.setValue(shape5DcropMin[2])
        self.zSpinBox.setValue(shape5DcropMin[3])
        self.timeSlider.setValue(shape5DcropMin[0])

    def setMouseCoords(self, x, y, z):
        self.xSpinBox.setValueWithoutSignal(x)
        self.ySpinBox.setValueWithoutSignal(y)
        self.zSpinBox.setValueWithoutSignal(z)
Example #33
0
class LabelAssistDialog(QDialog):
    """
    A simple UI for showing bookmarks and navigating to them.

    FIXME: For now, this window is tied to a particular lane.
           If your project has more than one lane, then each one
           will have it's own bookmark window, which is kinda dumb.
    """
    def __init__(self, parent, topLevelOperatorView):
        super(LabelAssistDialog, self).__init__(parent)
        
        # Create thread router to populate table on main thread
        self.threadRouter = ThreadRouter(self)
        
        # Set object classification operator view
        self.topLevelOperatorView = topLevelOperatorView
        
        self.setWindowTitle("Label Assist")
        self.setMinimumWidth(500)
        self.setMinimumHeight(700)

        layout = QGridLayout() 
        layout.setContentsMargins(10, 10, 10, 10)
                       
        # Show variable importance table
        rows = 0
        columns = 4
        self.table = QTableWidget(rows, columns)   
        self.table.setHorizontalHeaderLabels(['Frame', 'Max Area', 'Min Area', 'Labels'])
        self.table.verticalHeader().setVisible(False)     
        
        # Select full row on-click and call capture double click
        self.table.setSelectionBehavior(QTableView.SelectRows);
        self.table.doubleClicked.connect(self._captureDoubleClick)
                
        layout.addWidget(self.table, 1, 0, 3, 2) 

        # Create progress bar
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(0)
        self.progressBar.hide()
        layout.addWidget(self.progressBar, 4, 0, 1, 2)

        # Create button to populate table
        self.computeButton = QPushButton('Compute object info')
        self.computeButton.clicked.connect(self._triggerTableUpdate)
        layout.addWidget(self.computeButton, 5, 0)
        
        # Create close button
        closeButton = QPushButton('Close')
        closeButton.clicked.connect(self.close)
        layout.addWidget(closeButton, 5, 1)
        
        # Set dialog layout
        self.setLayout(layout)       


    def _triggerTableUpdate(self):
        # Check that object area is included in selected features
        featureNames = self.topLevelOperatorView.SelectedFeatures.value
        
        if 'Standard Object Features' not in featureNames or 'Count' not in featureNames['Standard Object Features']:
            box = QMessageBox(QMessageBox.Warning,
                  'Warning',
                  'Object area is not a selected feature. Please select this feature on: \"Standard Object Features > Shape > Size in pixels\"',
                  QMessageBox.NoButton,
                  self)
            box.show()
            return 
        
        # Clear table
        self.table.clearContents()
        self.table.setRowCount(0)
        self.table.setSortingEnabled(False)
        self.progressBar.show()
        self.computeButton.setEnabled(False)

        def compute_features_for_frame(tIndex, t, features): 
            # Compute features and labels (called in parallel from request pool)
            roi = [slice(None) for i in range(len(self.topLevelOperatorView.LabelImages.meta.shape))]
            roi[tIndex] = slice(t, t+1)
            roi = tuple(roi)

            frame = self.topLevelOperatorView.SegmentationImages(roi).wait()           
            frame = frame.squeeze().astype(numpy.uint32, copy=False)
            
            # Dirty trick: We don't care what we're passing here for the 'image' parameter,
            # but vigra insists that we pass *something*, so we'll cast the label image as float32.
            features[t] = vigra.analysis.extractRegionFeatures(frame.view(numpy.float32),
                                                               frame,
                                                               ['Count'],
                                                               ignoreLabel=0)
            
        tIndex = self.topLevelOperatorView.SegmentationImages.meta.axistags.index('t')
        tMax = self.topLevelOperatorView.SegmentationImages.meta.shape[tIndex]     
        
        features = {}
        labels = {}

        def compute_all_features():
            # Compute features in parallel
            pool = RequestPool()
            for t in range(tMax):
                pool.add( Request( partial(compute_features_for_frame, tIndex, t, features) ) )
            pool.wait()
            
        # Compute labels
        labels = self.topLevelOperatorView.LabelInputs([]).wait()
            
        req = Request(compute_all_features)
        req.notify_finished( partial(self._populateTable, features, labels) )
        req.submit()

    @threadRouted
    def _populateTable(self, features, labels, *args):
        self.progressBar.hide()
        self.computeButton.setEnabled(True)
                
        for time, feature in features.iteritems():
            # Insert row
            rowNum = self.table.rowCount()
            self.table.insertRow(self.table.rowCount())
            
            # Get max and min object areas
            areas = feature['Count']#objectFeatures['Standard Object Features']['Count']
            maxObjArea = numpy.max(areas[numpy.nonzero(areas)])
            minObjArea = numpy.min(areas[numpy.nonzero(areas)])
            
            # Get number of labeled objects
            labelNum = numpy.count_nonzero(labels[time])
            
            # Load fram number
            item = QTableWidgetItem(str(time))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 0, item) 

            # Load max object areas
            item = QTableWidgetItemWithFloatSorting(str("{: .02f}".format(maxObjArea)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 1, item)
                
            # Load min object areas
            item = QTableWidgetItemWithFloatSorting(str("{: .02f}".format(minObjArea)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 2, item)
            
            # Load label numbers
            item = QTableWidgetItemWithFloatSorting(str("{: .01f}".format(labelNum)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 3, item)
        
        # Resize column size to fit dialog size
        self.table.horizontalHeader().setResizeMode(QHeaderView.Stretch)   
        
        # Sort by max object area
        self.table.setSortingEnabled(True)                         
        self.table.sortByColumn(1) 
        

    def _captureDoubleClick(self):
        # Navigate to selected frame
        index = self.table.selectedIndexes()[0]
        frameStr = self.table.model().data(index).toString()
        
        if frameStr:
            frameNum = int(frameStr)
            self.parent().editor.posModel.time = frameNum
Example #34
0
class MainWinGui(QtGui.QMainWindow):
    progressIndeterminate = QtCore.pyqtSignal()
    progressSet = QtCore.pyqtSignal(int)
    progressStop = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(MainWinGui, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.myName.setText(getStoredName() or "")

        self.ui.myName.textEdited.connect(self.nameChanged)

        self.communicator = Communicator(self)
        self.communicator.peersUpdated.connect(self.refreshPeers)
        self.communicator.fileReceived.connect(self.fileReceived)

        self.ui.refreshPeersButton.clicked.connect(self.discoverPeers)
        self.ui.peerList.itemClicked.connect(self.peerSelected)

        self.progressIndeterminate.connect(self.progressIndeterminateSlot)
        self.progressSet.connect(self.progressSetSlot)
        self.progressStop.connect(self.progressStopSlot)

        self.progressIndicator = QProgressBar(self.ui.statusbar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusbar.addWidget(self.progressIndicator)

    def nameChanged(self, newName):
        storeName(newName)
        self.communicator.updateName(newName)

    def progressStart(self):
        self.progressIndicator.setVisible(True)

    def progressSetSlot(self, value):
        self.progressStart()
        self.progressIndicator.setMaximum(100)
        self.progressIndicator.setValue(value)

    def progressIndeterminateSlot(self):
        self.progressStart()
        self.progressIndicator.setMaximum(0)

    def progressStopSlot(self):
        self.progressIndicator.setVisible(False)

    def show(self):
        super(MainWinGui, self).show()
        self.refreshPeers()
        self.discoverPeers()

    def discoverPeers(self):
        self.communicator.discoverPeers()

    def refreshPeers(self):
        self.ui.peerList.clear()
        for peer in self.communicator.peers:
            peer = self.communicator.peers[peer]
            peerName = QListWidgetItem(self.ui.peerList)
            peerName.peer = peer
            nameFont = QtGui.QFont()
            nameFont.setPointSize(14)
            peerDetails = QListWidgetItem(self.ui.peerList)
            peerDetails.peer = peer
            detailsFont = QtGui.QFont()
            detailsFont.setPointSize(10)
            name = peer.name
            details = ""
            if peer.publicKey is None:
                details += "Unpaired, "
            else:
                details += "Paired, "
            if peer.lastKnownIP is None:
                details += "unavailable"
            else:
                details += "available: " + peer.lastKnownIP
            peerName.setFont(nameFont)
            peerName.setText(name)
            peerDetails.setFont(detailsFont)
            peerDetails.setText(details)
            self.ui.peerList.addItem(peerName)
            self.ui.peerList.addItem(peerDetails)
            separatorItem = QListWidgetItem(self.ui.peerList)
            separatorItem.guid = peer.guid
            separatorItem.peer = None
            separatorItem.setFlags(QtCore.Qt.NoItemFlags)
            self.ui.peerList.addItem(separatorItem)

    def peerSelected(self, selectedItem):
        selectedItem.setSelected(False)
        if selectedItem.peer:
            PeerOptionsUi(self, selectedItem.peer, self.communicator).show()
        else:
            pass

    def sendFile(self, guid):
        fileName = QtGui.QFileDialog.getOpenFileName()
        if not fileName:
            return
        fileContents = open(fileName, "rb").read()
        basename = os.path.basename(fileName)
        self.communicator.sendFile(basename, fileContents, guid)

    def fileReceived(self, fileName, fileContents):
        fileName = QtGui.QFileDialog.getSaveFileName(directory=fileName)
        if not fileName:
            return
        with open(fileName, mode="wb") as file:
            file.write(fileContents)
Example #35
0
class LoadVfkPuWidget(PuWidget):
    """A widget for loading a VFK file."""

    set_text_statusbar = pyqtSignal(str, int, bool)
    set_text_browseVfkLineEdit = pyqtSignal(str)
    set_value_loadVfkProgressBar = pyqtSignal(int)

    def _setup_self(self):
        """Sets up self."""

        self.setObjectName(u'loadVfkPuWidget')

        self.gridLayout = QGridLayout(self)
        self.gridLayout.setObjectName(u'gridLayout')

        self._build_widgets()

    def _build_widgets(self):
        """Builds own widgets."""

        self.set_text_statusbar.connect(self.dW.statusBar.set_text)
        self.set_text_statusbar.emit(u'Vyberte VFK soubor.', 0, False)

        self.browseVfkLabel = QLabel(self)
        self.browseVfkLabel.setObjectName(u'browseVfkLabel')
        self.browseVfkLabel.setText(u'VFK soubor:')
        self.gridLayout.addWidget(self.browseVfkLabel, 0, 0, 1, 1)

        self.browseVfkLineEdit = QLineEdit(self)
        self.browseVfkLineEdit.setObjectName(u'browseVfkLineEdit')
        self.set_text_browseVfkLineEdit.connect(
            self._set_text_browseVfkLineEdit)
        self.browseVfkLineEdit.textChanged.connect(self._check_vfk_file_path)
        self.gridLayout.addWidget(self.browseVfkLineEdit, 0, 1, 1, 1)

        self.browseVfkPushButton = QPushButton(self)
        self.browseVfkPushButton.setObjectName(u'browseVfkPushButton')
        self.browseVfkPushButton.clicked.connect(self._browse_vfk_files)
        self.browseVfkPushButton.setText(u'Procházet')
        self.gridLayout.addWidget(self.browseVfkPushButton, 0, 2, 1, 1)

        self.gridLayout.setRowStretch(1, 1)

        self.loadVfkProgressBar = QProgressBar(self)
        self.loadVfkProgressBar.setObjectName(u'loadVfkProgressBar')
        self.loadVfkProgressBar.setMinimum(0)
        self.set_value_loadVfkProgressBar.connect(
            self._set_value_loadVfkProgressBar)
        self.set_value_loadVfkProgressBar.emit(0)
        self.gridLayout.addWidget(self.loadVfkProgressBar, 2, 0, 1, 2)

        self.loadVfkPushButton = QPushButton(self)
        self.loadVfkPushButton.setObjectName(u'loadVfkPushButton')
        self.loadVfkPushButton.clicked.connect(self._start_loading_vfk_layer)
        self.loadVfkPushButton.setText(u'Načíst')
        self.loadVfkPushButton.setDisabled(True)
        self.gridLayout.addWidget(self.loadVfkPushButton, 2, 2, 1, 1)

    def _set_text_browseVfkLineEdit(self, text):
        """Sets the text to the browseVfkLineEdit.
        
        Args:
            text (str): A text to be set.
        
        """

        self.browseVfkLineEdit.setText(text)

    def _set_value_loadVfkProgressBar(self, value):
        """Sets the value to the loadVfkProgressBar.
        
        Args:
            text (str): A value to be set.
        
        """

        self.loadVfkProgressBar.setValue(value)

    def _browse_vfk_files(self):
        """Opens a file dialog and filters VFK files."""

        title = u'Vyberte VFK soubor.'
        filters = u'.vfk (*.vfk)'

        filePath = self.dW.open_file_dialog(title, filters, True)

        if filePath:
            self.set_text_browseVfkLineEdit.emit(filePath)

    def _check_vfk_file_path(self):
        """Checks if the text in the browseVfkLineEdit is a path to a VFK file.
        
        If so, the loadVfkPushButton is enabled,
        otherwise the loadVfkPushButton is disabled.
        
        """

        tempText = self.browseVfkLineEdit.text()

        tempFileInfo = QFileInfo(tempText)

        if tempFileInfo.isFile() and tempFileInfo.suffix() in (u'vfk', u'VFK'):
            self.loadVfkPushButton.setEnabled(True)
        else:
            self.loadVfkPushButton.setEnabled(False)

    def _start_loading_vfk_layer(self):
        """Starts loading the selected VFK file in a separate thread."""

        self.set_text_statusbar.emit(
            u'Načítám VFK soubor. Tento proces může chvíli trvat...', 0, False)

        self._enable_load_widgets(False)

        filePath = self.browseVfkLineEdit.text()

        QgsApplication.processEvents()

        self.loadThread = LoadThread(filePath)
        self.loadThread.started.connect(self._run_loading_vfk_layer)
        self.loadThread.start()

    def _run_loading_vfk_layer(self, filePath):
        """Calls methods for loading a VFK layer.
        
        Disables loading widgets until the loading is finished.
        
        Args:
            filePath (str): A full path to the file.
        
        """

        try:
            self.set_value_loadVfkProgressBar.emit(0)

            fileInfo = QFileInfo(filePath)
            dbPath = QDir(fileInfo.absolutePath())\
                .filePath(fileInfo.completeBaseName() + '.db')
            layerCode = self.dW.parLayerCode
            vfkDriverName = 'VFK'
            layerName = fileInfo.completeBaseName() + '|' + layerCode

            self._create_db_file(filePath, dbPath, layerCode, vfkDriverName)

            self._open_database(dbPath)

            # SpatiaLite fix - start
            if not self.dW.fixedSqliteDriver:
                dbPath = self._create_spatialite_db_file(dbPath)
            # SpatiaLite fix - end

            self._load_vfk_layer(dbPath, layerName, layerCode, vfkDriverName)

            self.loadVfkProgressBar.setMaximum(1)
            self.set_value_loadVfkProgressBar.emit(1)

            self.set_text_statusbar.emit(u'Data byla úspešně načtena.', 0,
                                         False)
        except self.dW.puError:
            QgsApplication.processEvents()
        except:
            QgsApplication.processEvents()

            self.dW.display_error_messages(
                self, u'Error loading VFK file "{}".'.format(filePath),
                u'Chyba při načítání VFK souboru.',
                u'Chyba při načítání VFK souboru "{}".'.format(filePath))
        finally:
            QgsApplication.processEvents()
            self._enable_load_widgets(True)

    def _create_db_file(self, filePath, dbPath, layerCode, vfkDriverName):
        """Creates a database file.
        
        It checks if a database of the same name as the file exists.
        If not it creates the database with a VFK driver.
        
        Args:
            filePath (str): A full path to the file.
            dbPath (str): A full path to the database.
            layerCode (str): A code of the layer.
            vfkDriverName (str): A name of the VFK driver.
        
        Raises:
            dw.puError: When the VFK driver failed to open VFK file
                or when the SQlite driver failed to open the database.
        
        """

        QgsApplication.processEvents()

        dbInfo = QFileInfo(dbPath)

        if not dbInfo.isFile():
            self.set_text_statusbar.emit(
                u'Importuji data do SQLite databáze...', 0, False)

            QgsApplication.processEvents()

            QgsApplication.registerOgrDrivers()

            vfkDriver = ogr.GetDriverByName(vfkDriverName)
            vfkDataSource = vfkDriver.Open(filePath)

            QgsApplication.processEvents()

            if not vfkDataSource:
                raise self.dW.puError(
                    self.dW, self,
                    u'Failed to load data, "{}" is not a valid VFK datasource.'
                    .format(dbPath), u'Data nelze načíst.',
                    u'Data nelze načíst, "{}" není platný datový zdroj VFK.'.
                    format(dbPath))

            layerCount, layerNames = self._check_layer_code(
                vfkDataSource, layerCode)

            self.loadVfkProgressBar.setMaximum(layerCount)

            for i in xrange(layerCount):
                self.set_value_loadVfkProgressBar.emit(i + 1)
                self.set_text_statusbar.emit(
                    u'Načítám vrstvu {} ({}/{})...'.format(
                        layerNames[i], i + 1, layerCount), 0, False)

            QgsApplication.processEvents()

            self._build_geometry(layerCode, vfkDataSource)

            QgsApplication.processEvents()

            for vertexLayerCode in self.dW.vertexLayerCodes:
                if vertexLayerCode in layerNames:
                    self._build_geometry(vertexLayerCode, vfkDataSource)

                    QgsApplication.processEvents()

            vfkDataSource.Destroy()

        sqliteDriver = ogr.GetDriverByName('SQLite')
        sqliteDataSource = sqliteDriver.Open(dbPath)

        if not sqliteDataSource:
            raise self.dW.puError(
                self.dW, self,
                u'Failed to load data, "{}" is not a valid SQLite datasource.'.
                format(dbPath), u'Data nelze načíst.',
                u'Data nelze načíst, "{}" není platný datový zdroj SQLite.'.
                format(dbPath))

        layerCount, layerNames = self._check_layer_code(
            sqliteDataSource, layerCode)

        sqliteDataSource.Destroy()

    def _check_layer_code(self, dataSource, layerCode):
        """Checks if there is a layer code layer in the data source.
        
        Args:
            dataSource (osgeo.ogr.DataSource): A data source.
            layerCode (str): A code of the layer.
        
        Returns:
            int: A number of layers in the data source.
            list: A list of layer names in the data source.
        
        Raises:
            dw.puError: When there is no layer code layer in the data source.
        
        """

        layerCount = dataSource.GetLayerCount()

        layerNames = []

        for i in xrange(layerCount):
            layerNames.append(dataSource.GetLayer(i).GetLayerDefn().GetName())

        if layerCode not in layerNames:
            QgsApplication.processEvents()

            dataSource.Destroy()

            raise self.dW.puError(
                self.dW, self,
                u'VFK file does not contain "{}" layer, therefore it can not be '
                u'loaded by PU Plugin. The file can be '
                u'loaded by "Add Vector Layer"'.format(layerCode),
                u'VFK soubor neobsahuje vrstvu {}.'.format(layerCode),
                u'VFK soubor neobsahuje vrstvu {}, proto nemůže být '
                u'pomocí PU Pluginu načten. Data je možné načíst '
                u'pomocí "Přidat vektorovou vrstvu."'.format(layerCode))

        dataSourceInfo = (layerCount, layerNames)

        return dataSourceInfo

    def _build_geometry(self, layerCode, dataSource):
        """Builds a geometry for the layer in the data source..
        
        Args:
            layerCode (str): A code of the layer.
            dataSource (ogr.DataSource) A reference to the OGR data source.
        
        """

        codeLayer = dataSource.GetLayerByName(layerCode)

        codeLayer.GetFeatureCount(True)

        for feature in codeLayer:
            feature.GetGeometryRef()

    def _open_database(self, dbPath):
        """Opens a database.
        
        Checks if there are geometry_columns and spatial_ref_sys
        tables in the database, if not it creates and fills those tables.
        
        Checks if there are all PU columns in PAR table,
        if it it creates and fills those columns.
        
        Args:
            dbPath (str): A full path to the database.
        
        Raises:
            dw.puError: When SQLITE database driver is not available
                or when database connection fails.
        
        """

        if not QSqlDatabase.isDriverAvailable('QSQLITE'):
            raise self.dW.puError(
                self.dW, self, u'SQLITE database driver is not available.',
                u'Databázový ovladač QSQLITE není dostupný.',
                u'Databázový ovladač QSQLITE není dostupný.')

        connectionName = QUuid.createUuid().toString()
        db = QSqlDatabase.addDatabase('QSQLITE', connectionName)
        db.setDatabaseName(dbPath)
        db.open()

        if not db.open():
            raise self.dW.puError(self.dW, self,
                                  u'Database connection failed.',
                                  u'Nepodařilo se připojit k databázi.',
                                  u'Nepodařilo se připojit k databázi.')

        self.set_text_statusbar.emit(u'Kontroluji tabulky a sloupce...', 0,
                                     False)

        QgsApplication.processEvents()

        sqlQuery = QSqlQuery(db)

        sqlDir = QDir(self.pluginDir.path() + u'/data/sql')

        query = self._read_text_from_file(sqlDir.filePath(u'check_gc_srs.sql'))

        sqlQuery.exec_(query)

        QgsApplication.processEvents()

        checkGcSrsSize = 0

        while sqlQuery.next():
            checkGcSrsSize += 1

        if checkGcSrsSize < 2:
            queries = self._read_text_from_file(
                sqlDir.filePath(u'create_fill_gc_srs.sql')).split(';')

            for query in queries:
                sqlQuery.exec_(query)

                QgsApplication.processEvents()

        query = self._read_text_from_file(
            sqlDir.filePath(u'check_pu_columns_PAR.sql'))

        sqlQuery.exec_(query)

        QgsApplication.processEvents()

        columns = []

        while sqlQuery.next():
            record = sqlQuery.record()
            name = str(record.value('name'))
            columns.append(name)

        if not all(column in columns for column in self.dW.allPuColumns):
            queries = self._read_text_from_file(
                sqlDir.filePath(u'add_pu_columns_PAR.sql')).split(';')

            for query in queries:
                sqlQuery.exec_(query)

                QgsApplication.processEvents()

        queries = self._read_text_from_file(
            sqlDir.filePath(u'create_sobr_spol.sql')).split(';')

        for query in queries:
            sqlQuery.exec_(query)

        db.close()

    def _create_spatialite_db_file(self, dbPath):
        """Creates a SpatiaLite database file.
        
        Args:
            dbPath (str): A full path to the database.
        
        Returns:
            dbPath (str): A full path to the SpatiaLite database.
        
        """

        dbInfo = QFileInfo(dbPath)

        sdbPath = QDir(dbInfo.absolutePath())\
            .filePath(dbInfo.completeBaseName() + '.sdb')

        sdbInfo = QFileInfo(sdbPath)

        if not sdbInfo.isFile():
            self.set_text_statusbar.emit(
                u'Importuji data do SpatiaLite databáze...', 0, False)

            QgsApplication.processEvents()

            sqliteDriver = ogr.GetDriverByName('SQLite')
            spatialiteDataSource = sqliteDriver.CreateDataSource(
                sdbPath, ['SPATIALITE=YES'])

            sqliteDataSource = ogr.Open(dbPath)

            for layerCode in (
                    self.dW.parLayerCode, ) + self.dW.vertexLayerCodes:
                originalLayer = sqliteDataSource.GetLayerByName(layerCode)
                copiedLayer = spatialiteDataSource.CopyLayer(
                    originalLayer, layerCode, ['LAUNDER=NO'])

            sqliteDataSource.Destroy()
            spatialiteDataSource.Destroy()

        QgsApplication.processEvents()

        return sdbPath

    def _read_text_from_file(self, filePath, maxSize=2000):
        """Reads a text from the given file.
        
        Args:
            filePath (str): A full path to the file.
            maxSize (int): Maximum size of read data from the file in bytes.
        
        Returns:
            str: The text from the file.
        
        """

        file = QFile(filePath)
        file.open(QFile.ReadOnly | QFile.Text)

        text = file.readData(maxSize)

        file.close()

        return text

    def _load_vfk_layer(self, dbPath, layerName, layerCode, vfkDriverName):
        """Loads a layer of the given code from database into the map canvas.
        
        Args:
            dbPath (str): A full path to the database.
            layerName (str): A name of the layer.
            layerCode (str): A code of the layer.
            vfkDriverName (str): A name of the VFK driver.
        
        Raises:
            dw.puError: When layerCode layer is not valid.
        
        """

        self.set_text_statusbar.emit(
            u'Přidávám vrstvu {}...'.format(layerCode), 0, False)

        QgsApplication.processEvents()

        # SpatiaLite fix - start
        if not self.dW.fixedSqliteDriver:
            composedURI = QgsDataSourceURI()
            composedURI.setDatabase(dbPath)

            schema = ''
            table = layerCode
            geometryColumn = 'GEOMETRY'

            composedURI.setDataSource(schema, table, geometryColumn)

            layer = QgsVectorLayer(composedURI.uri(), layerName, 'spatialite')
        else:
            blacklistedDriver = ogr.GetDriverByName(vfkDriverName)
            blacklistedDriver.Deregister()

            composedURI = dbPath + '|layername=' + layerCode
            layer = QgsVectorLayer(composedURI, layerName, 'ogr')

            blacklistedDriver.Register()
        # SpatiaLite fix - end

        if layer.isValid():
            self._set_scale_for_features_with_no_or_invalid_geometry(layer)

            self.dW.set_layer_style(layer, layerCode)

            self._set_layer_form_config(layer)
            self._set_layer_table_config(layer)

            QgsMapLayerRegistry.instance().addMapLayer(layer)

            self._set_layer_snapping(layer)

            QgsApplication.processEvents()
        else:
            raise self.dW.puError(self.dW, self,
                                  u'Layer {} is not valid.'.format(layerCode),
                                  u'Vrstva {} není platná.'.format(layerCode),
                                  u'Vrstva {} není platná.'.format(layerCode))

    def _set_scale_for_features_with_no_or_invalid_geometry(self, layer):
        """Sets basis scale to zero for features with no or invalid geometry.
        
        Args:
            layer (QgsVectorLayer): A reference to the layer.
        
        """

        expression = QgsExpression("$geometry is null")

        features = layer.getFeatures(QgsFeatureRequest(expression))

        self.dW.set_field_value_for_features(layer, features,
                                             self.dW.puBasisScaleColumnName, 0)

    def _set_layer_form_config(self, layer):
        """Sets layer form config.
        
        Args:
            layer (QgsVectorLayer): A reference to the layer.
        
        """

        fields = layer.pendingFields()

        formConfig = layer.editFormConfig()

        for i in layer.pendingAllAttributesList():
            if fields[i].name() not in self.dW.editablePuColumns:
                formConfig.setReadOnly(i)
                formConfig.setWidgetType(i, 'Hidden')

    def _set_layer_table_config(self, layer):
        """Sets layer table config.
        
        Args:
            layer (QgsVectorLayer): A reference to the layer.
        
        """

        fields = layer.pendingFields()

        tableConfig = layer.attributeTableConfig()
        tableConfig.update(fields)

        columns = tableConfig.columns()

        for column in columns:
            if column.name not in self.dW.allVisibleColumns:
                column.hidden = True

        tableConfig.setColumns(columns)
        layer.setAttributeTableConfig(tableConfig)

    def _set_layer_snapping(self, layer):
        """Sets layer snapping.
        
        Args:
            layer (QgsVectorLayer): A reference to the layer.
        
        """

        project = QgsProject.instance()
        project.setTopologicalEditing(True)
        project.writeEntry('Digitizing', 'SnappingMode', 'advanced')
        project.writeEntry('Digitizing', 'IntersectionSnapping', Qt.Checked)
        project.setSnapSettingsForLayer(layer.id(), True, 2, 1, 10, True)

    def _enable_load_widgets(self, enableBool):
        """Sets loading widgets enabled or disabled.
        
        Sets enabled or disabled following widgets:
            browseVfkLineEdit
            browseVfkPushButton
            loadVfkPushButton
        
        Args:
            enableBool (bool): True to set enabled, False to set disabled.
        
        """

        self.browseVfkLineEdit.setEnabled(enableBool)
        self.browseVfkPushButton.setEnabled(enableBool)
        self.loadVfkPushButton.setEnabled(enableBool)
Example #36
0
class QuadStatusBar(QHBoxLayout):
    positionChanged = pyqtSignal(int, int, int) # x,y,z
    
    def __init__(self, parent=None ):
        QHBoxLayout.__init__(self, parent)
        self.setContentsMargins(0,4,0,0)
        self.setSpacing(0)
        self.timeControlFontSize = 12

    def showXYCoordinates(self):
        self.zLabel.setHidden(True)
        self.zSpinBox.setHidden(True)
        
    def showXYZCoordinates(self):
        self.zLabel.setHidden(False)
        self.zSpinBox.setHidden(False)
    
    def hideTimeSlider(self,flag):
        self.timeSlider.setHidden(flag)
        self.timeEndButton.setHidden(flag)
        self.timeStartButton.setHidden(flag)

    def setToolTipTimeButtonsCrop(self,croppingFlag=False):
        if croppingFlag==True:
            self.timeStartButton.setToolTip("Set the time coordinate to the beginning of the current crop.")
            self.timeEndButton.setToolTip("Set the time coordinate to the end of the current crop.")
            self.timePreviousButton.setToolTip("Set the time coordinate to the previous time frame.")
            self.timeNextButton.setToolTip("Set the time coordinate to the next time frame.")
        else:
            self.timeStartButton.setToolTip("Set the time coordinate to the beginning of the current dataset.")
            self.timeEndButton.setToolTip("Set the time coordinate to the end of the current dataset.")
            self.timePreviousButton.setToolTip("Set the time coordinate to the previous time frame.")
            self.timeNextButton.setToolTip("Set the time coordinate to the next time frame.")

    def setToolTipTimeSliderCrop(self,croppingFlag=False):
        if croppingFlag==True:
            self.timeSlider.setToolTip("Choose the time coordinate of the current crop.")
        else:
            self.timeSlider.setToolTip("Choose the time coordinate of the current dataset.")

    def createQuadViewStatusBar(self,
                                xbackgroundColor, xforegroundColor,
                                ybackgroundColor, yforegroundColor,
                                zbackgroundColor, zforegroundColor):
        self.xLabel, self.xSpinBox = _get_pos_widget('X',
                                                     xbackgroundColor,
                                                     xforegroundColor)
        self.yLabel, self.ySpinBox = _get_pos_widget('Y',
                                                     ybackgroundColor,
                                                     yforegroundColor)
        self.zLabel, self.zSpinBox = _get_pos_widget('Z',
                                                     zbackgroundColor,
                                                     zforegroundColor)
        
        self.xSpinBox.delayedValueChanged.connect( partial(self._handlePositionBoxValueChanged, 'x') )
        self.ySpinBox.delayedValueChanged.connect( partial(self._handlePositionBoxValueChanged, 'y') )
        self.zSpinBox.delayedValueChanged.connect( partial(self._handlePositionBoxValueChanged, 'z') )

        self.addWidget(self.xLabel)
        self.addWidget(self.xSpinBox)
        self.addWidget(self.yLabel)
        self.addWidget(self.ySpinBox)
        self.addWidget(self.zLabel)
        self.addWidget(self.zSpinBox)

        self.addSpacing(10)

        self.busyIndicator = QProgressBar()
        self.busyIndicator.setMaximumWidth(200)
        self.busyIndicator.setMaximum(0)
        self.busyIndicator.setMinimum(0)
        self.busyIndicator.setVisible(False)
        self.busyIndicator.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.addWidget( self.busyIndicator )
        self.setStretchFactor(self.busyIndicator, 1)

        self.addStretch()
        self.addSpacing(10)

        self.positionCheckBox = QCheckBox()
        self.positionCheckBox.setChecked(False)
        self.positionCheckBox.setCheckable(True)
        self.positionCheckBox.setText("Position")
        self.addWidget(self.positionCheckBox)

        self.addSpacing(20)

        self.timeSpinBox = DelayedSpinBox(750)

        self.timeStartButton = QPushButton("|<")
        self.addWidget(self.timeStartButton)
        self.timeStartButton.clicked.connect(self._onTimeStartButtonClicked)

        self.timePreviousButton = QPushButton("<")
        self.addWidget(self.timePreviousButton)
        self.timePreviousButton.clicked.connect(self._onTimePreviousButtonClicked)
        self.timePreviousButton.setFixedWidth(4*self.timeControlFontSize)

        self.timeSlider = QSlider(Qt.Horizontal)
        self.timeSlider.setMinimumWidth(10)
        self.timeSlider.setMaximumWidth(200)
        self.setToolTipTimeSliderCrop()
        self.addWidget(self.timeSlider)
        self.timeSlider.valueChanged.connect(self._onTimeSliderChanged)

        self.timeNextButton = QPushButton(">")
        self.addWidget(self.timeNextButton)
        self.timeNextButton.clicked.connect(self._onTimeNextButtonClicked)
        self.timeNextButton.setFixedWidth(4*self.timeControlFontSize)

        self.timeEndButton = QPushButton(">|")
        self.timeEndButton.setFixedWidth(4*self.timeControlFontSize)

        self.timeStartButton.setFixedWidth(4*self.timeControlFontSize)
        
        self.setToolTipTimeButtonsCrop()
        self.addWidget(self.timeEndButton)
        self.timeEndButton.clicked.connect(self._onTimeEndButtonClicked)

        self.timeLabel = QLabel("       Time:")
        self.addWidget(self.timeLabel)

        timeControlFont = self.timeSpinBox.font()
        if self.timeControlFontSize > timeControlFont.pointSize():
            timeControlFont.setPixelSize(2*self.timeControlFontSize)
            self.timeStartButton.setFont(timeControlFont)
            self.timeEndButton.setFont(timeControlFont)
            self.timeLabel.setFont(timeControlFont)
            self.timeSpinBox.setFont(timeControlFont)

        self.addWidget(self.timeSpinBox)
        self.timeSpinBox.delayedValueChanged.connect(self._onTimeSpinBoxChanged)

    def _onTimeStartButtonClicked(self):
        self.timeSpinBox.setValue(self.parent().parent().parent().editor.cropModel.get_roi_t()[0])

    def _onTimeEndButtonClicked(self):
        self.timeSpinBox.setValue(self.parent().parent().parent().editor.cropModel.get_roi_t()[1])

    def _onTimePreviousButtonClicked(self):
        self.timeSpinBox.setValue(self.timeSpinBox.value()-1)

    def _onTimeNextButtonClicked(self):
        self.timeSpinBox.setValue(self.timeSpinBox.value()+1)

    def _onTimeSpinBoxChanged(self):
        editor = self.parent().parent().parent().editor
        cropModel = editor.cropModel
        minValueT = cropModel.get_roi_t()[0]
        maxValueT = cropModel.get_roi_t()[1]

        if cropModel.get_scroll_time_outside_crop():
            if minValueT > self.timeSpinBox.value() or maxValueT < self.timeSpinBox.value():
                for imgView in editor.imageViews:
                    imgView._croppingMarkers._shading_item.set_paint_full_frame(True)
            else:
                for imgView in editor.imageViews:
                    imgView._croppingMarkers._shading_item.set_paint_full_frame(False)
            self.timeSlider.setValue(self.timeSpinBox.value())
        else:
            for imgView in editor.imageViews:
                imgView._croppingMarkers._shading_item.set_paint_full_frame(False)
            if minValueT > self.timeSpinBox.value():
                self.timeSlider.setValue(minValueT)
            elif maxValueT < self.timeSpinBox.value():
                self.timeSlider.setValue(maxValueT)
            elif minValueT <= self.timeSpinBox.value() and self.timeSpinBox.value() <= maxValueT:
                self.timeSlider.setValue(self.timeSpinBox.value())

    def _onTimeSliderChanged(self):
        cropModel = self.parent().parent().parent().editor.cropModel
        minValueT = cropModel.get_roi_t()[0]
        maxValueT = cropModel.get_roi_t()[1]

        if cropModel.get_scroll_time_outside_crop():
            self.timeSpinBox.setValue(self.timeSlider.value())
        else:
            if minValueT > self.timeSlider.value():
                self.timeSpinBox.setValue(minValueT)
                self.timeSlider.setValue(minValueT)
            elif self.timeSlider.value() > maxValueT:
                self.timeSpinBox.setValue(maxValueT)
                self.timeSlider.setValue(maxValueT)
            elif minValueT <= self.timeSlider.value() and self.timeSlider.value() <= maxValueT:
                self.timeSpinBox.setValue(self.timeSlider.value())

    def _handlePositionBoxValueChanged(self, axis, value):
        new_position = [self.xSpinBox.value(), self.ySpinBox.value(), self.zSpinBox.value()]
        changed_axis = ord(axis) - ord('x')
        new_position[changed_axis] = value
        self.positionChanged.emit(*new_position)

    def updateShape5D(self, shape5D):
        self.timeSpinBox.setMaximum(shape5D[0]-1)
        self.xSpinBox.setMaximum(shape5D[1]-1)
        self.ySpinBox.setMaximum(shape5D[2]-1)
        self.zSpinBox.setMaximum(shape5D[3]-1)

    def updateShape5Dcropped(self, shape5DcropMin, shape5Dmax):
        self.timeSpinBox.setMaximum(shape5Dmax[0]-1)
        self.xSpinBox.setMaximum(shape5Dmax[1]-1)
        self.ySpinBox.setMaximum(shape5Dmax[2]-1)
        self.zSpinBox.setMaximum(shape5Dmax[3]-1)
        self.timeSlider.setMaximum(shape5Dmax[0]-1)

        self.timeSpinBox.setValue(shape5DcropMin[0])
        self.xSpinBox.setValue(shape5DcropMin[1])
        self.ySpinBox.setValue(shape5DcropMin[2])
        self.zSpinBox.setValue(shape5DcropMin[3])
        self.timeSlider.setValue(shape5DcropMin[0])

    def setMouseCoords(self, x, y, z):
        self.xSpinBox.setValueWithoutSignal(x)
        self.ySpinBox.setValueWithoutSignal(y)
        self.zSpinBox.setValueWithoutSignal(z)
Example #37
0
class Qt4SysTrayIcon:
    def __init__(self):
        self.snapshots = snapshots.Snapshots()
        self.config = self.snapshots.config

        if len(sys.argv) > 1:
            if not self.config.set_current_profile(sys.argv[1]):
                logger.warning("Failed to change Profile_ID %s" % sys.argv[1],
                               self)

        self.qapp = qt4tools.create_qapplication(self.config.APP_NAME)

        import icon
        self.icon = icon
        self.qapp.setWindowIcon(icon.BIT_LOGO)

        self.status_icon = QSystemTrayIcon(icon.BIT_LOGO)
        #self.status_icon.actionCollection().clear()
        self.contextMenu = QMenu()

        self.menuProfileName = self.contextMenu.addAction(
            _('Profile: "%s"') % self.config.get_profile_name())
        qt4tools.set_font_bold(self.menuProfileName)
        self.contextMenu.addSeparator()

        self.menuStatusMessage = self.contextMenu.addAction(_('Done'))
        self.menuProgress = self.contextMenu.addAction('')
        self.menuProgress.setVisible(False)
        self.contextMenu.addSeparator()
        self.startBIT = self.contextMenu.addAction(icon.BIT_LOGO,
                                                   _('Start BackInTime'))
        QObject.connect(self.startBIT, SIGNAL('triggered()'), self.onStartBIT)
        self.status_icon.setContextMenu(self.contextMenu)

        self.pixmap = icon.BIT_LOGO.pixmap(24)
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)
        self.progressBar.setTextVisible(False)
        self.progressBar.resize(24, 6)
        self.progressBar.render(self.pixmap,
                                sourceRegion=QRegion(0, -14, 24, 6),
                                flags=QWidget.RenderFlags(
                                    QWidget.DrawChildren))

        self.first_error = self.config.is_notify_enabled()
        self.popup = None
        self.last_message = None

        self.timer = QTimer()
        QObject.connect(self.timer, SIGNAL('timeout()'), self.update_info)

        self.ppid = os.getppid()

    def prepare_exit(self):
        self.timer.stop()

        if not self.status_icon is None:
            self.status_icon.hide()
            self.status_icon = None

        if not self.popup is None:
            self.popup.deleteLater()
            self.popup = None

        self.qapp.processEvents()

    def run(self):
        self.status_icon.show()
        self.timer.start(500)

        logger.info("[qt4systrayicon] begin loop", self)

        self.qapp.exec_()

        logger.info("[qt4systrayicon] end loop", self)

        self.prepare_exit()

    def update_info(self):
        if not tools.is_process_alive(self.ppid):
            self.prepare_exit()
            self.qapp.exit(0)
            return

        message = self.snapshots.get_take_snapshot_message()
        if message is None and self.last_message is None:
            message = (0, _('Working...'))

        if not message is None:
            if message != self.last_message:
                self.last_message = message
                self.menuStatusMessage.setText('\n'.join(tools.wrap_line(self.last_message[1],\
                                                                         size = 80,\
                                                                         delimiters = '',\
                                                                         new_line_indicator = '') \
                                                                        ))
                self.status_icon.setToolTip(self.last_message[1])

        pg = progress.ProgressFile(self.config)
        if pg.isFileReadable():
            pg.load()
            percent = pg.get_int_value('percent')
            if percent != self.progressBar.value():
                self.progressBar.setValue(percent)
                self.progressBar.render(self.pixmap,
                                        sourceRegion=QRegion(0, -14, 24, 6),
                                        flags=QWidget.RenderFlags(
                                            QWidget.DrawChildren))
                self.status_icon.setIcon(QIcon(self.pixmap))

            self.menuProgress.setText(' | '.join(self.getMenuProgress(pg)))
            self.menuProgress.setVisible(True)
        else:
            self.status_icon.setIcon(self.icon.BIT_LOGO)
            self.menuProgress.setVisible(False)

    def getMenuProgress(self, pg):
        d = (('sent',   _('Sent:')), \
             ('speed',  _('Speed:')),\
             ('eta',    _('ETA:')) )
        for key, txt in d:
            value = pg.get_str_value(key, '')
            if not value:
                continue
            yield txt + ' ' + value

    def onStartBIT(self):
        profileID = self.config.get_current_profile()
        cmd = [
            'backintime-qt4',
        ]
        if not profileID == '1':
            cmd += ['--profile-id', profileID]
        proc = subprocess.Popen(cmd)
Example #38
0
class TabDownloads(QWidget):
    instance = None

    def __init__(self, search, parent=None):
        QWidget.__init__(self, parent)
        # Load de l'UI
        PyQt4.uic.loadUi('ui/downloads.ui', self)
        # Ajout de la progressBar
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(100)
        self.progressBar.hide()
        self.HLayout = QBoxLayout(QBoxLayout.LeftToRight)
        self.HLayout.addWidget(self.progress_label)
        self.HLayout.addWidget(self.progressBar)
        self.formLayout_3.addRow(self.HLayout)
        # Vars 
        TabDownloads.instance = self
        self.downloads        = Downloads()
        self.pos              = None
        self.download_looked  = None
        # Affichage custom
        #self.downloads_table.setStyleSheet(\
        #        "QTableView::item{ \
        #         border-right-style:solid; \
        #         border-width:0.5; \
        #         border-color: #9B9B9B; \
        #         }")
        # On autorise la creation de menu contextuel
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        # Signaux
        self.customContextMenuRequested.connect(self.contextMenu)
        self.downloads_table.itemClicked.connect(self.show_info_download)
        # Init
        self.load_downloads()
        # On remove les finis et en erreur si Config.clean_dl_list = 1
        if Configuration.clean_dl_list == 1:
            self.clean_list_Action()
        #########################################################
        # On désactive les boutons qui sont pas encore implantés
        self.button_stop_all.setEnabled(False)        
        self.button_resume_all.setEnabled(False)
        #########################################################

    def load_downloads(self):
        import xml.sax
        parser = xml.sax.make_parser()
        parser.setContentHandler(AnalyseDownloads(self.add_downloads))
        try:
            for line in open(os.path.expanduser("~") + '/.pyrex/downloads.xml'):
                parser.feed(line)
            self.downloads.save()
        except:
            pass

    def add_download(self, download):
        # Avant de filtrer on écrit le download
        #self.downloads.append(download) #TODO : pour quand on pourra resume, décommenter la ligne et ramener le save ici
                
        if download.state == 4 or download.progress == 0:
            rows = self.downloads_table.rowCount()
            self.downloads_table.insertRow(rows)
            self.downloads_table.setItem(rows, 0, MyQTableWidgetItem(download.file_share.name, download))
            self.downloads_table.setItem(rows, 1, QTableWidgetItem(download.get_progress()))
            self.downloads_table.setItem(rows, 2, QTableWidgetItem(download.state_str))
            self.downloads_table.setItem(rows, 3, QTableWidgetItem("0 ko/s"))
            self.downloads_table.setItem(rows, 5, QTableWidgetItem(download.date.strftime('%d/%m/%y')))
            self.downloads.append(download)
                    
        # TODO : à modifier probablement quand on aura le resume pour les downloads
        if download.state != 4 and download.progress == 0:
            # Signaux
            download.progressModified.connect(self.update_progress)
            download.stateChanged.connect(self.update_state)
            download.downloadFinished.connect(self.download_finished)
            download.speedModified.connect(self.update_speed)
        
        # On save
        self.downloads.save()
        
    def add_downloads(self, downloads):
        for download in downloads:
          self.add_download(download)
        
    def update_progress(self, download):
        item = self.downloads_table.findItems(download.file_share.name, Qt.MatchExactly)[0]
        row = self.downloads_table.row(item)
        self.downloads_table.item(row, 1).setText(download.get_progress())
        # On update la barre de progression si on est en train de regarder un download
        if self.download_looked == download:
            self.progressBar.setValue(int(download.progress))

    def update_speed(self, download):
        item = self.downloads_table.findItems(download.file_share.name, Qt.MatchExactly)[0]
        row = self.downloads_table.row(item)
        self.downloads_table.item(row, 3).setText(convert_speed_str(download.speed))
        
    def update_state(self, download):
        item = self.downloads_table.findItems(download.file_share.name, Qt.MatchExactly)[0]
        row = self.downloads_table.row(item)
        self.downloads_table.item(row, 2).setText(download.state_str)
        # On save
        self.downloads.save()
        
    def download_finished(self, download):
        if download.read_bytes == download.file_share.size:
            item = self.downloads_table.findItems(download.file_share.name, Qt.MatchExactly)[0]
            row = self.downloads_table.row(item)
            self.downloads_table.item(row, 2).setText("Finished!")
            self.downloads_table.item(row, 3).setText("")
            # On save
            self.downloads.save()
        else:
            print "Erreur dans le téléchargement"
            item = self.downloads_table.findItems(download.file_share.name, Qt.MatchExactly)[0]
            row = self.downloads_table.row(item)
            self.downloads_table.item(row, 2).setText("Error : invalid size :(")
            self.downloads_table.item(row, 3).setText("")
            # On save
            self.downloads.save()
            
    def contextMenu(self, pos):
        self.pos = pos
        menu = QMenu()
        # Actions 
        forceAction         = menu.addAction("Forcer la reprise")
        continueAction      = menu.addAction("Reprise")
        pauseAction         = menu.addAction("Pause")
        openAction          = menu.addAction("Ouvrir")
        abortAction         = menu.addAction("Annuler")
        supprListeAction    = menu.addAction("Supprimer de la liste")
        supprDiskAction     = menu.addAction("Supprimer de la liste et du disque")
        copyAction          = menu.addAction("Copier l'URL")
        searchAction        = menu.addAction("Rechercher des fichiers similaires")
        # On désactive les actions s'il n'y a pas de downloads
        if self.downloads == [] or self.downloads_table.currentRow() < 0:
            forceAction.setEnabled(False)
            continueAction.setEnabled(False)
            pauseAction.setEnabled(False)
            openAction.setEnabled(False)
            abortAction.setEnabled(False)
            supprListeAction.setEnabled(False)
            supprDiskAction.setEnabled(False)
            copyAction.setEnabled(False)
            searchAction.setEnabled(False)
        #########################################################
        # On désactive les boutons qui sont pas encore implantés
        forceAction.setEnabled(False)
        #continueAction.setEnabled(False)
        #pauseAction.setEnabled(False)        
        searchAction.setEnabled(False)        
        #########################################################
        # Signaux
        self.connect(forceAction, SIGNAL('triggered()'), self.force_Action)
        self.connect(continueAction, SIGNAL('triggered()'), self.continue_Action)
        self.connect(pauseAction, SIGNAL('triggered()'), self.pause_Action)
        self.connect(openAction, SIGNAL('triggered()'), self.open_Action)
        self.connect(abortAction, SIGNAL('triggered()'), self.abort_Action)
        self.connect(supprListeAction, SIGNAL('triggered()'), self.suppr_liste_Action)
        self.connect(supprDiskAction, SIGNAL('triggered()'), self.suppr_disk_Action)
        self.connect(copyAction, SIGNAL('triggered()'), self.copy_Action)
        self.connect(searchAction, SIGNAL('triggered()'), self.search_Action)
        # On affiche le menu
        menu.exec_(self.mapToGlobal(pos))
      
    def getDownloads(self):
        rows = self.downloads_table.selectionModel().selectedRows()
        return [self.downloads_table.item(row.row(), 0).download for row in rows]
          
    def force_Action(self):
        print "TODO"
        
    def continue_Action(self):
        for download in self.getDownloads():
            print "Resuming download"
            download.resume()
        self.display_resume_pause()
        
    def pause_Action(self):
        for download in self.getDownloads():
            print "Pausing download"
            download.pause()
        self.display_resume_pause()
        
    def open_Action(self):
        for download in self.getDownloads():
            open_file(download.local_path)
        
    def abort_Action(self):
        for download in self.getDownloads():
            download.stop()
        row = self.downloads_table.currentRow()
        self.downloads_table.item(row, 2).setText(u"Annulé!")
        self.downloads_table.item(row, 3).setText("")
  
    def remove_download(self, download, erase):
        download.stop()
        row = self.downloads_table.currentRow()
        # On supprime la ligne
        self.downloads_table.removeRow(row)
        # On supprime de la liste
        self.downloads.remove(download)    
        # On save
        self.downloads.save()
        if erase:
            try:
                os.remove(download.local_path)
            except OSError:
                try:
                    shutil.rmtree(download.local_path)
                except:
                    print "Erreur dans la suppression du fichier"

    def suppr_liste_Action(self):
        for download in self.getDownload():
            self.remove_download(download, False)
        
    def suppr_disk_Action(self):
        for download in self.getDownloads():
            self.remove_download(download, True)
        
    def copy_Action(self):
        pressPaper = QApplication.clipboard()
        text = '\n'.join([dl.local_path for dl in self.getDownloads()])
        pressPaper.setText(text)
        
    def search_Action(self):
        print "TODO"
        
    def show_info_download(self):
        download = self.getDownloads()[0]
        self.name_label.setText(u"Nom : {}".format(download.file_share.name))
        self.path_label.setText(u"Chemin local : {}".format(download.local_path))
        self.url_label.setText(u"URL : {}".format(download.file_share.url))
        self.size_label.setText(u"Taille : {}".format(download.file_share.str_size))   
        self.progressBar.show()     
        self.progressBar.setValue(int(download.progress))
        self.download_looked = download
        
    def clean_list_Action(self):
        remove_list = []
        for download in self.downloads:
            if download.state == 4 or download.state == 7:
                # On trouve la ligne
                item = self.downloads_table.findItems(download.file_share.name, Qt.MatchExactly)[0]
                row = self.downloads_table.row(item)
                # On la supprime
                self.downloads_table.removeRow(row)
                # On save pour après la boucle for
                remove_list.append(download)
        # On supprime de la liste
        for download in remove_list:
            self.downloads.remove(download)    
        # On save
        self.downloads.save()
                               
    def double_clicked(self, row, col):
        download = self.getDownloads()[0]
        if download:
            open_file(download.local_path)
            
    def display_resume_pause(self):
        downloads = self.getDownloads()
        pause = False
        resume = False
        if downloads:
            for download in downloads:
                if download.state == 5:
                    pause = True
                else:
                    resume = True
            self.button_pause.setEnabled(resume)
            self.button_resume.setEnabled(pause)
                    
    def clicked(self, row, col):
        self.display_resume_pause()    
        
    def resizeEvent(self, event):
        maxSize = self.downloads_table.size().width()
        # Nom Ficher : 24%
        self.downloads_table.horizontalHeader().resizeSection(0, maxSize*.24)
        # Avancement : 22%
        self.downloads_table.horizontalHeader().resizeSection(1, maxSize*.22)
        # Etat : 17%
        self.downloads_table.horizontalHeader().resizeSection(2, maxSize*.17)
        # Vitesse : 13% 
        self.downloads_table.horizontalHeader().resizeSection(3, maxSize*.13)
        # Fin : 12%
        self.downloads_table.horizontalHeader().resizeSection(4, maxSize*.12)
        event.accept()
Example #39
0
class StatusBox(QGroupBox):
    STATUS_BOX_TEXT = 'Status'

    BASE_PATH_REQUIRED_MESSAGE_TEXT = 'Fill in the base path to start scanning for files to be renamed.'
    SCAN_FILES_PROGRESS_TEXT = 'Scanning files'
    SCAN_FILES_ERROR_CAPTION_TEXT = 'Error scanning files'

    RULES_ERROR_CAPTION_TEXT = 'Error in rules'

    NO_FILES_TO_RENAME_MESSAGE_TEXT = 'No files to rename.'
    RENAME_FILES_PROGRESS_TEXT = 'Renaming files'
    RENAME_FILES_ERROR_CAPTION_TEXT = 'Error renaming files'

    NO_FILES_RENAMED_MESSAGE_TEXT = 'No files changed.'
    READY_TO_RENAME_MESSAGE_TEXT = 'Ready to rename.'
    RENAME_PROGRESS_TEXT = 'Executing rename'
    PLANNING_RENAME_ERROR_CAPTION_TEXT = 'Error while planning rename'
    RENAME_ERROR_CAPTION_TEXT = 'Error while executing rename'

    RENAME_COMPLETE_MESSAGE_TEXT = 'Rename completed.'

    READY_MESSAGE_TEXT = 'Ready.'

    ERROR_COLOR = '#ff0000'

    _status_label = None
    _status_progressbar = None

    def __init__(self, parent):
        super().__init__(self.STATUS_BOX_TEXT, parent)

        self._status_label = QLabel(self)
        self._status_progressbar = QProgressBar(self)
        self._status_progressbar.setVisible(False)
        self._status_progressbar.setMinimum(0)

        layout = QHBoxLayout(self)
        layout.addWidget(self._status_label)
        layout.addWidget(self._status_progressbar)

    @pyqtSlot(BAONStatus)
    def show_status(self, status):
        if status.scan_status == BAONStatus.IN_PROGRESS:
            self._show_progress(status.scan_status_extra, self.SCAN_FILES_PROGRESS_TEXT)
        elif status.rename_status == BAONStatus.IN_PROGRESS:
            self._show_progress(status.rename_status_extra, self.RENAME_FILES_PROGRESS_TEXT)
        elif status.execute_status == BAONStatus.IN_PROGRESS:
            self._show_progress(status.execute_status_extra, self.RENAME_PROGRESS_TEXT)
        elif status.scan_status == BAONStatus.ERROR:
            self._show_error(status.scan_status_extra, self.SCAN_FILES_ERROR_CAPTION_TEXT)
        elif status.rules_status == BAONStatus.ERROR:
            self._show_error(status.rules_status_extra, self.RULES_ERROR_CAPTION_TEXT)
        elif status.rename_status == BAONStatus.ERROR:
            self._show_error(status.rename_status_extra, self.RENAME_FILES_ERROR_CAPTION_TEXT)
        elif status.execute_status == BAONStatus.ERROR:
            if isinstance(status.execute_status_extra, MakeRenamePlanError):
                self._show_error(status.execute_status_extra, self.PLANNING_RENAME_ERROR_CAPTION_TEXT)
            else:
                self._show_error(status.execute_status_extra, self.RENAME_ERROR_CAPTION_TEXT)
        elif status.scan_status == BAONStatus.NOT_AVAILABLE:
            self._show_message(self.BASE_PATH_REQUIRED_MESSAGE_TEXT)
        elif status.rename_status == BAONStatus.NOT_AVAILABLE:
            self._show_message(self.NO_FILES_TO_RENAME_MESSAGE_TEXT)
        elif status.execute_status == BAONStatus.NOT_AVAILABLE:
            self._show_message(self.NO_FILES_RENAMED_MESSAGE_TEXT)
        elif status.execute_status == BAONStatus.WAITING_FOR_USER:
            self._show_message(self.READY_TO_RENAME_MESSAGE_TEXT)
        elif status.execute_status == BAONStatus.AVAILABLE:
            self._show_message(self.RENAME_COMPLETE_MESSAGE_TEXT)
        else:
            self._show_message(self.READY_MESSAGE_TEXT)

    def _show_message(self, format_string, *args, **kwargs):
        self._show_raw_message(format_string.format(*args, **kwargs))

    def _show_progress(self, progress, text):
        self._show_raw_message(text, progress=progress)

    def _show_error(self, error, caption=None):
        text = str(error)
        if caption is not None:
            text = caption + ': ' + text

        self._show_raw_message(text, is_error=True)

    def _show_raw_message(self, text, is_error=False, progress=None):
        self._status_label.setText(text)
        self._status_label.setStyleSheet("QLabel {{ color: {0} }}".format(self.ERROR_COLOR) if is_error else "")

        self._status_progressbar.setVisible(progress is not None)

        if progress is not None:
            if progress.is_indeterminate():
                self._status_progressbar.setMaximum(0)
            else:
                self._status_progressbar.setMaximum(progress.total)
                self._status_progressbar.setValue(progress.done)
Example #40
0
class Window(QMainWindow):
    def __init__(self,parent = None):
        QMainWindow.__init__(self,parent)
        self.resize(1024,768)
        self.setWindowTitle("Sabel")
        self.setWindowIcon(Icons.sabel)
        self.centralwidget = QWidget(self)
        self.horizontalLayout = QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setMargin(0)
        self.cmdList = config.cmds()
        self.paramList = config.params()
        
        '''A.Editor TabWidget'''
        '''This parent is for findbar and vertical layout'''
        self.editorLayoutWidget = QWidget(self)
        self.editorLayoutWidget.setMinimumWidth(800)
        self.tabWidget = EditorTab(self)
        self.editorLayout = QVBoxLayout(self.editorLayoutWidget)
        self.editorLayout.setMargin(0)
        self.editorLayout.addWidget(self.tabWidget)
        
        "0.Style Layout"
        self.styleLayoutWidget = QFrame()
        self.styleLayoutWidget.setFrameShape(QFrame.StyledPanel)
        self.styleLayout = QHBoxLayout(self.styleLayoutWidget)
        self.styleTest = QPushButton(self.styleLayoutWidget)
        self.styleTest.setText("Change Styles")
        self.styleTest.clicked.connect(self.changeStyleSheet)
        self.popWidget = Popup(self.styleLayoutWidget)
        self.styleLayout.addWidget(self.styleTest)
        self.styleLayout.addWidget(self.popWidget)
        self.styleLayout.setMargin(0)
        self.editorLayout.addWidget(self.styleLayoutWidget)
        self.styleLayoutWidget.hide()
        
        "1.Find Layout"
        self.findLayoutWidget = QFrame()
        self.findLayoutWidget.setFrameShape(QFrame.StyledPanel)
        self.findLayout = QHBoxLayout(self.findLayoutWidget)
        self.lineEdit = QLineEdit(self.findLayoutWidget)
        self.lineEdit_2 = QLineEdit(self.findLayoutWidget)
        self.findClose = QPushButton(self.findLayoutWidget)
        self.findClose.setIcon(Icons.close_view)
        self.findClose.setFlat(True)
        self.findClose.clicked.connect(self.findBarShow)
        self.find = QPushButton(self.findLayoutWidget)
        self.find.setText("Find")
        self.find.clicked.connect(self.findCurrentText)
        self.replacefind = QPushButton(self.findLayoutWidget)
        self.replacefind.setText("Replace/Find")
        self.replacefind.clicked.connect(self.replaceFindText)
        self.replace = QPushButton(self.findLayoutWidget)
        self.replace.setText("Replace")
        self.replace.clicked.connect(self.replaceCurrentText)
        self.replaceAll = QPushButton(self.findLayoutWidget)
        self.replaceAll.setText("Replace All")
        self.replaceAll.clicked.connect(self.replaceAllText)
        self.caseSensitive = QToolButton(self.findLayoutWidget)
        self.caseSensitive.setIcon(Icons.font)
        self.caseSensitive.setCheckable(True)
        self.wholeWord = QToolButton(self.findLayoutWidget)
        self.wholeWord.setText("ww")
        self.wholeWord.setCheckable(True)
        self.regex = QToolButton(self.findLayoutWidget)
        self.regex.setText("re")
        self.regex.setCheckable(True)
        self.backward = QToolButton(self.findLayoutWidget)
        self.backward.setText("bk")
        self.backward.setCheckable(True)
        self.backward.setDisabled(True)
        self.findLayout.addWidget(self.findClose)
        self.findLayout.addWidget(self.find)
        self.findLayout.addWidget(self.lineEdit)
        self.findLayout.addWidget(self.lineEdit_2)
        self.findLayout.addWidget(self.caseSensitive)
        self.findLayout.addWidget(self.wholeWord)
        self.findLayout.addWidget(self.regex)
        self.findLayout.addWidget(self.backward)
        self.findLayout.addWidget(self.replacefind)
        self.findLayout.addWidget(self.replace)
        self.findLayout.addWidget(self.replaceAll)
        self.findLayout.setMargin(0)
        self.findLayoutWidget.setMaximumHeight(25)
        self.editorLayout.addWidget(self.findLayoutWidget)
        self.findLayoutWidget.hide()
        
        
        '''B.Designer'''
        '''This parent is for widgetsbar and design layout'''
        self.designerLayoutWidget = QWidget(self)
        self.designerLayoutWidget.setMinimumWidth(800)
        self.designerWidget = Screen(self)
        self.designerLayoutWidget.hide()
        self.designerLayout = QVBoxLayout(self.designerLayoutWidget)
        self.designerLayout.setMargin(0)
        self.designerLayout.addWidget(self.designerWidget)
        
        '''C.Level Editor'''
        '''This parent is for spritesheets and level layout'''
        self.levelLayoutWidget = QWidget(self)
        self.levelLayoutWidget.setMinimumWidth(800)
        self.levelWidget = Level(self)
        self.levelLayoutWidget.hide()
        self.levelLayout = QVBoxLayout(self.levelLayoutWidget)
        self.levelLayout.setMargin(0)
        self.levelLayout.addWidget(self.levelWidget)
        
        '''D.Explorer TabWidget'''
        self.explorerTabWidget = TreeTab(self)
        #self.explorerTabWidget.setMaximumWidth(200)
        '''1.Project Tree'''
        self.tab_5 = QWidget()
        #self.tab_5.setMaximumWidth(200)
        self.VerticalLayout_2 = QVBoxLayout(self.tab_5)#QHBoxLayout(self.tab_5)
        self.VerticalLayout_2.setMargin(0)
        self.treeWidget = ProjectTree(self.tab_5)
        #self.treeWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        #self.treeWidget.horizontalScrollBar().show()
        self.VerticalLayout_2.addWidget(self.treeWidget)
        
        '''2.Outline Tree'''
        self.tab_2 = QWidget()
        #self.tab_2.setMaximumWidth(200)
        self.VerticalLayout_3 = QVBoxLayout(self.tab_2)
        self.VerticalLayout_3.setMargin(0)
        self.outlineWidget = OutlineTree(self.tab_2)
        self.outlineWidget.itemDoubleClicked.connect(self.gotoLine)
        self.VerticalLayout_3.addWidget(self.outlineWidget)
        
        '''E.Output TabWidget'''
        self.outputTabWidget = OutputTab(self)
        self.tabWidget.currentChanged.connect(self.fileChanged)
        self.explorerTabWidget.currentChanged.connect(self.closeExplorer)
        self.outputTabWidget.currentChanged.connect(self.closeConsole)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.setTabShape(0)
            
        '''1.Output layout'''
        #must check
        self.tab_6 = QWidget()
        self.horizontalLayout_2 = QVBoxLayout(self.tab_6)
        self.horizontalLayout_2.setMargin(0)
        self.textEdit = QTextEdit()
        self.inputLayout = QHBoxLayout()
        self.inputLayout.setMargin(0)
        self.fileButton = QPushButton()
        self.fileButton.setText("File")
        self.fileButton.clicked.connect(self.getFile)
        self.runButton = QPushButton()
        self.runButton.setFlat(True)
        self.runButton.setIcon(Icons.go)
        self.combo = QComboBox()
        self.combo.setFixedWidth(100)
        self.comboAdd = QPushButton()
        self.comboAdd.setIcon(Icons.add)
        self.comboAdd.setFlat(True)
        self.comboAdd.clicked.connect(self.addCmd)
        self.comboDel = QPushButton()
        self.comboDel.setIcon(Icons.close_view)
        self.comboDel.setFlat(True)
        self.comboDel.clicked.connect(self.delCmd)
        self.combo2 = QComboBox()
        self.combo2.setFixedWidth(500)
        self.combo2Add = QPushButton()
        self.combo2Add.setIcon(Icons.add)
        self.combo2Add.setFlat(True)
        self.combo2Add.clicked.connect(self.addParam)
        self.combo2Del = QPushButton()
        self.combo2Del.setIcon(Icons.close_view)
        self.combo2Del.setFlat(True)
        self.combo2Del.clicked.connect(self.delParam)
        if(self.checkHasValue(self.cmdList)):
            for cmd in self.cmdList:
                self.combo.addItem(cmd)
        else:
            self.cmdList = []
        if(self.checkHasValue(self.paramList)):
            for param in self.paramList:
                self.combo2.addItem(param)
        else:
            self.paramList = []
        
        self.horizontalLayout_2.addWidget(self.textEdit)
        self.inputLayout.addWidget(QLabel("<b>Command:</b>"))
        self.inputLayout.addWidget(self.combo)
        self.inputLayout.addWidget(self.comboAdd)
        self.inputLayout.addWidget(self.comboDel)
        self.inputLayout.addWidget(QLabel("<b>Parameters:</b>"))
        self.inputLayout.addWidget(self.combo2)
        self.inputLayout.addWidget(self.combo2Add)
        self.inputLayout.addWidget(self.combo2Del)
        self.inputLayout.addWidget(self.fileButton)
        self.inputLayout.addWidget(self.runButton)
        self.horizontalLayout_2.addLayout(self.inputLayout)
        
        '''2.Error Layout'''
        self.tab_7 = QWidget()
        self.horizontalLayout_4 = QHBoxLayout(self.tab_7)
        self.horizontalLayout_4.setMargin(0)
        self.errorTree = ErrorTree(self.tab_7)
        self.errorTree.itemDoubleClicked.connect(self.errorLine)
        self.horizontalLayout_4.addWidget(self.errorTree)
        
        '''TabWidgets tabs'''
        #self.designerWidget.addTab(QWidget(self),"")
        #self.designerWidget.setTabIcon(0,Icons.close_view)
        #self.levelWidget.addTab(QWidget(self),"")
        #self.levelWidget.setTabIcon(0,Icons.close_view)
        
        self.explorerTabWidget.addTab(self.tab_5,"Projects")
        self.explorerTabWidget.addTab(self.tab_2,"Outline")
        self.explorerTabWidget.addTab(QWidget(self),"")
        self.explorerTabWidget.setTabIcon(0,Icons.cprj)
        self.explorerTabWidget.setTabIcon(1,Icons.envvar)
        self.explorerTabWidget.setTabIcon(2,Icons.close_view)
        self.outputTabWidget.addTab(self.tab_7,"Error")
        self.outputTabWidget.addTab(self.tab_6,"Output")
        self.outputTabWidget.addTab(QWidget(self),"")
        self.outputTabWidget.setTabIcon(0,Icons.error)
        self.outputTabWidget.setTabIcon(1,Icons.console_view)
        self.outputTabWidget.setTabIcon(2,Icons.close_view)
        
        '''Splitters'''
        self.split1 = QSplitter(Qt.Horizontal)
        self.split1.addWidget(self.explorerTabWidget)
        self.split1.addWidget(self.editorLayoutWidget)
        self.split1.addWidget(self.designerLayoutWidget)
        self.split1.addWidget(self.levelLayoutWidget)
        #self.split1.addWidget(self.tab_5)
        
        self.split2 = QSplitter(Qt.Vertical)
        self.split2.addWidget(self.split1)
        self.split2.addWidget(self.outputTabWidget)
        self.horizontalLayout.addWidget(self.split2)
        
        
        '''Status Bar'''
        self.statusbar = QStatusBar(self)
        self.aboutButton = QPushButton(self)
        self.aboutButton.setFlat(True)
        self.aboutButton.setIcon(Icons.anchor)
        self.aboutButton.clicked.connect(self.about)
        self.expButton = QPushButton(self)
        self.expButton.setFlat(True)
        self.expButton.setIcon(Icons.prj)
        self.expButton.clicked.connect(self.exp)
        self.cmdButton = QPushButton(self)
        self.cmdButton.setFlat(True)
        self.cmdButton.setIcon(Icons.console_view)
        self.cmdButton.clicked.connect(self.cmd)
        self.cmdButton.setShortcut('Ctrl+D')
        self.imgButton = QPushButton(self)
        self.imgButton.setFlat(True)
        self.imgButton.setIcon(Icons.color_palette)
        self.imgButton.clicked.connect(self.design)
        self.imgButton.setShortcut('Ctrl+I')
        self.findButton = QPushButton(self)
        self.findButton.setFlat(True)
        self.findButton.setIcon(Icons.find)
        self.findButton.setShortcut("Ctrl+F")
        self.findButton.clicked.connect(self.findBarShow)
        '''
        self.zoominButton = QPushButton(self)
        self.zoominButton.setFlat(True)
        self.zoominButton.setIcon(Icons.zoomplus)
        self.zoominButton.clicked.connect(self.zoomin)
        self.zoomoutButton = QPushButton(self)
        self.zoomoutButton.setFlat(True)
        self.zoomoutButton.setIcon(Icons.zoomminus)
        self.zoomoutButton.clicked.connect(self.zoomout)
        '''

        '''Status Text,Line Text, Progress Bar and Stop Button'''
        self.statusText = QLabel("Writable")
        #self.statusText.setAlignment(Qt.AlignCenter)
        self.statusText.setFixedWidth(200)
        self.lineText = QLabel("")
        self.lineText.setFixedWidth(50)
        
        self.progressbar = QProgressBar()
        self.progressbar.setMinimum(0)
        self.progressbar.setMaximum(100)
        self.stopButton = QPushButton(self)
        self.stopButton.setFlat(True)
        self.stopButton.setIcon(Icons.stop)
        self.stopButton.clicked.connect(self.forceStop)
        self.progressbar.hide()
        self.stopButton.hide()
        self.temp = False
        self.progress = False
        self.counter = 0
        
        '''Adding all widgets to Status Bar'''
        self.statusbar.addWidget(self.aboutButton)
        self.statusbar.addWidget(self.expButton)
        self.statusbar.addWidget(self.cmdButton)
        self.statusbar.addWidget(self.imgButton)
        self.statusbar.addWidget(self.findButton)
        #self.statusbar.addWidget(QWidget(self))
        #self.statusbar.addWidget(self.zoominButton)
        #self.statusbar.addWidget(self.zoomoutButton)
        self.statusbar.addWidget(self.statusText)
        self.statusbar.addWidget(self.lineText)
        self.statusbar.addWidget(self.progressbar)
        self.statusbar.addWidget(self.stopButton)
        #self.statusbar.setFixedHeight(18)
        
        ''''Initializing Coloring Style'''
        self.initEditorStyle()
        self.initStyleSheet()
        '''Adding Cental Widget and Status Bar'''
        self.setCentralWidget(self.centralwidget)
        self.setStatusBar(self.statusbar)
        self.textEdit.setReadOnly(True)
        
        
    def initStyleSheet(self):
        import stylesheet
        self.setStyleSheet(stylesheet.mainstyl)
        self.tabWidget.tabBar().setStyleSheet(stylesheet.stletabb)
        self.explorerTabWidget.tabBar().setStyleSheet(stylesheet.stletabb)
        self.outputTabWidget.tabBar().setStyleSheet(stylesheet.stletabb)
        self.popWidget.setStyleSheet(stylesheet.popbg)
        self.popWidget.hide()
        
        
        ''' This is for changing the palette/window colors to Theme '''
    def initEditorStyle(self):
        pass
        #editStyle = config.readStyle()
        #print editStyle
        #pal = QPalette(self.explorerTabWidget.palette())
        #print pal.color(QPalette.Base).name()
        #print pal.color(QPalette.Window).name()
        #pal.setColor(QPalette.Base,self.colorStyle.paper)
        #pal.setColor(QPalette.Text,self.colorStyle.color)
        #self.explorerTabWidget.setPalette(pal)
        #self.outputTabWidget.setPalette(pal)
         
    ''' This is only for testing dont know if it works for builds '''    
    def changeStyleSheet(self):
        ''' Dynamically load the changed stylesheet.py and load the modules and change 
            the style at runtime saves countless deploys '''
        import imp
        foo = imp.load_source('stletabb', workDir+"/stylesheet.py")
        #print foo.stletabb
        #self.setStyleSheet(stylesheet.mainstyl)
        self.tabWidget.tabBar().setStyleSheet(foo.stletabb)
        self.popWidget.setStyleSheet(foo.popbg)
        if(self.popWidget.isHidden()):
            self.popWidget.showPopup()
    
    def build_project(self):
        #current_file = self.files[self.tabWidget.currentIndex()]
        prj = self.treeWidget.getProject()
        if(prj != None):
            self.treeWidget.build(prj)
            
    def run_project(self):
        #current_file = self.files[self.tabWidget.currentIndex()]
        prj = self.treeWidget.getProject()#current_file)
        if(prj != None):
            self.treeWidget.run(prj)
            
    def forceStop(self):
        self.ant.kill()
        self.progressStop()
        
    def kill(self):
        self.deleteLater()
        
#-----------------------------------------------------------------------------------#
#   Menu Actions Functions                                                          #
#-----------------------------------------------------------------------------------#
    def run(self):
        if(config.mode() == 0):
            self.sq.run()
        elif(config.mode() == 1):
            self.adb.run()
        elif(config.mode() == 2):
            self.ios.run()
        elif(config.mode() == 3):
            self.c.run()
            
    def setMode(self, action):
        if(action.text() == "Squ"):
            config.setMode(0)
            self.toolBar.action_Build.setEnabled(False)
            self.toolBar.action_Run.setEnabled(False)
        elif(action.text() == "Emo"):
            config.setMode(1)
            self.toolBar.action_Build.setEnabled(True)
            self.toolBar.action_Run.setEnabled(True)
        elif(action.text() == "Android"):
            config.setMode(2)
            self.toolBar.action_Build.setEnabled(True)
            self.toolBar.action_Run.setEnabled(True)
        elif(action.text() == "ios"):
            config.setMode(3)
            self.toolBar.action_Build.setEnabled(False)
            self.toolBar.action_Run.setEnabled(False)
            
    def openCommand(self):
        text, ok = QInputDialog.getText(self, 'Run Command', 'Command:')
        cmd = str(text)
        if ok and cmd != "":
            import subprocess
            subprocess.Popen(cmd)
     
    def about(self):
        form = DialogAbout(self)
        
    def todo(self):
        form = DialogTodo(self)
        form.show()

    def help(self):
        QMessageBox.about(self,"Help","This is about all The Help that i can Give you now")
        
    def full(self):
        if not self.isFull:
            self.setWindowState(Qt.WindowFullScreen)
            self.isFull = True
        else:
            self.setWindowState(Qt.WindowMaximized)
            self.isFull = False
            
    def android(self):
        form = DialogAndroid(self)
        form.show()
    
    def antt(self):
        form = DialogAnt(self)
        form.show()
        
    def squirrel(self):
        form = DialogSquirrel(self)
        form.show()
        
    def findBarShow(self):
        if(self.findLayoutWidget.isHidden()):
            self.findLayoutWidget.show()
        else:
            self.findLayoutWidget.hide()
            
    def exp(self):
        if(self.explorerTabWidget.isHidden()):
            self.explorerTabWidget.show()
        else:
            self.explorerTabWidget.hide()
    
    def cmd(self):
        if(self.outputTabWidget.isHidden()):
            self.outputTabWidget.show()
        else:
            self.outputTabWidget.hide()
            
    def editor(self):
        if(self.editorLayoutWidget.isHidden()):
            self.editorLayoutWidget.show()
            self.levelLayoutWidget.hide()
            self.designerLayoutWidget.hide()
            
    def design(self):
        if(self.designerLayoutWidget.isHidden()):
            self.designerLayoutWidget.show()
            self.editorLayoutWidget.hide()
            self.levelLayoutWidget.hide()
        else:
            self.designerLayoutWidget.hide()
            self.editorLayoutWidget.show()
            
    def level(self):
        if(self.levelLayoutWidget.isHidden()):
            self.levelLayoutWidget.show()
            self.editorLayoutWidget.hide()
            self.designerLayoutWidget.hide()
        else:
            self.levelLayoutWidget.hide()
            self.editorLayoutWidget.show()
            
    def closeDesigner(self,no):
        pass
        '''
        if(no == self.tiler.closeIndex()):
            if(self.tiler.isHidden()):
                self.tiler.show()
            else:
                self.tiler.setCurrentIndex(1)
                self.tiler.hide()
        '''
     
    '''The current Changed idx of outputTabWidget is passed to this a param'''   
    def closeConsole(self,no = 2):
        if(no == 2):
            if(self.outputTabWidget.isHidden()):
                self.outputTabWidget.show()
            else:
                self.outputTabWidget.setCurrentIndex(1)
                self.outputTabWidget.hide()
                
    def popOutput(self):
        if(self.outputTabWidget.isHidden()):
            self.outputTabWidget.show()
        self.outputTabWidget.setCurrentIndex(1)
    
    def popError(self):
        if(self.outputTabWidget.isHidden()):
            self.outputTabWidget.show()
        self.outputTabWidget.setCurrentIndex(0)
        
    '''The current Changed idx of explorerTabWidget is passed to this a param'''
    def closeExplorer(self,no = 2):
        if(no == 2):
            if(self.explorerTabWidget.isHidden()):
                self.explorerTabWidget.show()
            else:
                self.explorerTabWidget.setCurrentIndex(0)
                self.explorerTabWidget.hide()
        elif(no == 1):
            self.fileChanged(no)
                
    ''' This is to refresh the outline widget'''
    def fileChanged(self,no):
        if(self.explorerTabWidget.currentIndex() == 1):
            edt = self.tabWidget.widget(self.tabWidget.currentIndex())
            source = edt.text()
            self.outlineWidget.parseText(source)
           
    def statusSaving(self):
        self.statusText.setText("Saving")   
    def statusParsing(self):
        self.statusText.setText("Parsing")   
    def statusWriting(self):
        self.statusText.setText("Writable")  
    def statusRunning(self):
        self.statusText.setText("Running")   
    def statusStopping(self):
        self.statusText.setText("Stopping")
    def statusCommand(self):
        self.statusText.setText("Command")
    def statusBuilding(self):
        self.statusText.setText("Building")
    def statusInstalling(self):
        self.statusText.setText("Installing")
    def statusCleaning(self):
        self.statusText.setText("Cleaning")
    def statusCreating(self):
        self.statusText.setText("Creating")
                
    def progressStart(self):
        self.progress == True
        self.temp == True
        if(self.progressbar.isHidden()):
            self.progressbar.show()
        if(self.stopButton.isHidden()):
            self.stopButton.show()
        self.progressbar.setValue(1)
        
    def progressStop(self):
        self.progress == False
        self.temp == False
        self.progressbar.setValue(100)
        if not(self.progressbar.isHidden()):
            self.progressbar.hide()
        if not(self.stopButton.isHidden()):
            self.stopButton.hide()
              
    def progressUpdate(self):
        if(self.progress):
            if(self.temp):
                self.counter += 1
                self.progressbar.setValue(self.counter)
                if(self.counter == 100):
                    self.temp = False
            else:
                self.counter -= 1
                self.progressbar.setValue(self.counter)
                if(self.counter == 0):
                    self.temp = True
            
                
#-----------------------------------------------------------------------------------#
#   Editor Functions                                                                #
#-----------------------------------------------------------------------------------#   
    '''Search and Replace Functions'''  
    def findCurrentText(self):
        edt = self.tabWidget.widget(self.tabWidget.currentIndex())
        edt.findText(self.lineEdit.text(),self.regex.isChecked(),self.caseSensitive.isChecked(),self.wholeWord.isChecked(),self.backward.isChecked())
    def replaceCurrentText(self):
        edt = self.tabWidget.widget(self.tabWidget.currentIndex())
        edt.replaceText(self.lineEdit_2.text()) 
    def replaceFindText(self):
        edt = self.tabWidget.widget(self.tabWidget.currentIndex())
        edt.replaceText(self.lineEdit_2.text())
        self.findCurrentText()      
    def replaceAllText(self):
        edt = self.tabWidget.widget(self.tabWidget.currentIndex())
        while(edt.findText(self.lineEdit.text(),self.regex.isChecked(),self.caseSensitive.isChecked(),self.wholeWord.isChecked(),self.backward.isChecked())):
            edt.replaceText(self.lineEdit_2.text())      
    def errorLine(self,error):
        index = self.tabWidget.currentIndex()
        edt = self.tabWidget.widget(index)
        '''To prevent File item double clicking'''
        if(error.isFile() == False):
            edt.setLine(error.line)
            
    '''Font Functions'''       
    def zoomin(self):
        pass
        #for i in range(len(self.files)):
        #    self.tabWidget.widget(i).zoomin()
    def zoomout(self):
        pass
        #for i in range(len(self.files)):
        #    self.tabWidget.widget(i).zoomout()
            
    ''' Must implement Lexer '''
    def setLexer(self, action):
        pass
        #print action.text()
    
    def setApi(self, action):
        #print action.text()
        for i in range(len(self.files)): #not QString
            self.tabWidget.widget(i).setApi(str(action.text()))
    
    def setFont(self,font):
        config.setFontName(str(font.family()))
        for i in range(len(self.files)):
            self.tabWidget.widget(i).setNewFont(font)
            
    def setFontSize(self,idx):
        fontSize = idx+1
        config.setFontSize(fontSize)
        for i in range(len(self.files)):
            self.tabWidget.widget(i).setFontSize() 
            
    def gotoLine(self,item):
        edt = self.tabWidget.widget(self.tabWidget.currentIndex())
        edt.setLine(item.line)
        
    def updateLine(self,no,col):
        self.lineText.setText(str(no)+" : "+str(col))
            
    def setMargin(self):
        mar = config.margin()
        if(mar == 0): 
            config.setMargin(1)
            for i in range(len(self.files)):
                self.tabWidget.widget(i).setMargin(1)
        else:
            config.setMargin(0)
            for i in range(len(self.files)):
                self.tabWidget.widget(i).setMargin(0)
                
    ''' Toggle '''
    def setIndent(self):
        indent = config.indent()
        if(indent == 0): 
            config.setIndent(1)
            for i in range(len(self.files)):
                self.tabWidget.widget(i).setIndent(1)
        else:
            config.setIndent(0)
            for i in range(len(self.files)):
                self.tabWidget.widget(i).setIndent(0)
    ''' Toggle '''         
    def setWhiteSpace(self):
        white = config.whiteSpace()
        if(white == 0): 
            config.setWhiteSpace(1)
            for i in range(len(self.files)):
                self.tabWidget.widget(i).setWhitespaceVisibility(True)
        else:
            config.setWhiteSpace(0)
            for i in range(len(self.files)):
                self.tabWidget.widget(i).setWhitespaceVisibility(False)
    
    ''' Toggle '''         
    def setEndLine(self):
        for i in range(len(self.files)):
            edt = self.tabWidget.widget(i)
            edt.setEolVisibility(not edt.eolVisibility())
                
    def setEncoding(self, action):
        if(action.text() == "Ascii"):
            config.setAscii()
            for i in range(len(self.files)):
                self.tabWidget.widget(i).setUtf8(False)
        elif(action.text() == "Unicode"):
            config.setUnicode()
            for i in range(len(self.files)):
                self.tabWidget.widget(i).setUtf8(True)
        
    def setThreshold(self,val):
        config.setThresh(val)
        for i in range(len(self.files)):
            #print i
            self.tabWidget.widget(i).setThreshold(val)
    def setTabWidth(self,val):
        config.setTabWidth(val)
        for i in range(len(self.files)):
            #print i
            self.tabWidget.widget(i).setTabWidth(val)
    '''style Functions'''         
#-----------------------------------------------------------------------------------#
#   Command Functions                                                               #
#-----------------------------------------------------------------------------------#   
    def getFile(self):
        self.browsedialog = DialogBrowse(self)
        self.browsedialog.tree.itemDoubleClicked.connect(self.getName)
        self.browsedialog.show()
            
    def getName(self,item):
        if(item.isFile()):
                self.browsedialog.accept()
                fname = item.getPath()
                if not (fname == ""):
                    index = self.combo2.currentIndex()
                    text = str(self.combo2.itemText(index))+" "+fname
                    self.combo2.setItemText(index,text)
                    self.paramList.pop(index)
                    self.paramList.insert(index,text)
                    config.setParam(self.paramList)
                 
    def addCmd(self,index):
        text, ok = QInputDialog.getText(self, 'Add Command', 'Command:')
        if(ok):
            if(str(text) != ''):
                cmd = str(text).upper()
                self.cmdList.append(cmd)
                #print self.cmdList
                self.combo.addItem(cmd)
                config.setCmd(self.cmdList)
                config.setParam(self.paramList)
                
    def delCmd(self):
        index = self.combo.currentIndex()
        self.combo.removeItem(index)
        self.cmdList.pop(index)
        #print self.cmdList
        config.setCmd(self.cmdList)
        
    def addParam(self,index):
        text, ok = QInputDialog.getText(self, 'Add Parameters', 'Params:')
        if(ok):
            if(str(text) != ''):
                param = str(text)
                self.paramList.append(param)
                self.combo2.addItem(param)
                config.setParam(self.paramList)
                
    def delParam(self):
        index = self.combo2.currentIndex()
        self.combo2.removeItem(index)
        self.paramList.pop(index)
        config.setParam(self.paramList)
        
    def checkHasValue(self,list):
        if(list != None and len(list) != 0):
            return True
        else:
            return False
Example #41
0
    def run(self):
        """Run method that performs all the real work"""

        # show the dialog
        self.dlg.show()

        # Run the dialog event loop
        result = self.dlg.exec_()

        # See if OK was pressed
        if result:
            gradle_command = self.get_gradle_dir()
            dc_directory = self.dlg.lineEdit.text()
            print dc_directory
            if dc_directory == '':
                self.iface.messageBar().pushMessage("Error", "Please provide the directory of the Digital Connector", level=QgsMessageBar.CRITICAL)
            else:
                dc_recipe = self.track_recipe_choice()
                to_save = self.select_output_name()

                # Update DC and QGIS repo
                if self.dlg.checkBox_2.isChecked():
                    git_path = None
                    if platform.system() == 'Windows':
                        # Look in both Program Files and Program Files x86
                        for i in os.listdir('C:\\Program Files'):
                            if 'Git' in i:
                                git_path = 'C:\\Program Files\\' + i + '\\bin'
                                # No single quotes allowed in the string on Windows...
                                output = sp.call('{0}\\git pull'.format(git_path), cwd=dc_directory)
                            else:
                                pass
                        for j in  os.listdir('C:\\Program Files (x86)'):
                            if 'Git' in j:
                                git_path = 'C:\\Program Files (x86)\\' + j + '\\bin'
                                output = sp.call('{0}\\git pull'.format(git_path), cwd=dc_directory)
                            else:
                                pass 
                        # If all fails ask user             
                        if git_path == None:
                            git_path = QFileDialog.getExistingDirectory(
                                    self.dlg,
                                    "Select git path",
                                    expanduser("~"),
                                    QFileDialog.ShowDirsOnly
                                )
                            output = sp.call('{0}\\git pull'.format(git_path), cwd=dc_directory)               
                    # git pull for Mac OSX
                    elif platform.system() == 'Darwin':
                        for i in os.listdir('/usr/local/Cellar/'):
                            if 'git' in i:
                                git_path = '/usr/local/Cellar/' + i + '/' + os.listdir('/usr/local/Cellar/'+ i)[0] + \
                                                '/' + 'bin/git'
                                args = ['{0} pull'.format(git_path)]
                                output = sp.Popen(args, stdout=sp.PIPE, cwd=dc_directory, shell=True)
                            else:
                                pass
                        if git_path == None:
                            git_path = QFileDialog.getExistingDirectory(
                                    self.dlg,
                                    "Select git path",
                                    expanduser("~"),
                                    QFileDialog.ShowDirsOnly
                                )
                            args = ['{0} pull'.format(git_path)]
                            output = sp.Popen(args, stdout=sp.PIPE, cwd=dc_directory, shell=True)
                    else:
                        print 'currently the plugin only supports Mac and Windows'                    


                # check if the path corresponds to the examples folder or not. 
                # This is necessary due to the absolute paths of subprocess
                chars = set("\/")
                if any((c in chars) for c in dc_recipe):
                    pass
                else:
                    dc_recipe = '{0}/src/main/resources/executions/examples/{1}'.format(dc_directory,dc_recipe,to_save)


                # Check for -Pclear=True
                if self.dlg.checkBox.isChecked():
                    p_clear = 'true'
                else:
                    p_clear= 'false'


                # TODO need to add more error messages
                if not to_save:
                    self.iface.messageBar().pushMessage("Error", "Please choose a name for the output file", level=QgsMessageBar.CRITICAL)
                else:
                    if platform.system() == 'Windows':
                        if not gradle_command in os.environ['PATH']:
                            os.environ['PATH'] += ';' + gradle_command
                        else:
                            pass
                            
                        # No single quotes allowed in the string on Windows...
                        output = sp.call('{0} runExport -Precipe="{2}"  -Poutput="{3}" -Pclear="{4}"'.format(gradle_command + '\\gradle.bat',
                                                                                        dc_directory,dc_recipe,to_save, p_clear),
                                                                                        cwd=dc_directory)
                        # Adding the resulting layer in the QGIS Layers Panel
                        vlayer = QgsVectorLayer(to_save,to_save.split("/")[-1],"ogr")
                        QgsMapLayerRegistry.instance().addMapLayer(vlayer)   
                    else:
                        args = ["{0} runExport -Precipe='{2}'  -Poutput='{3}' -Pclear='{4}'".format(gradle_command,dc_directory,
                                                                                            dc_recipe,to_save, p_clear)]
                        output = sp.Popen(args,stdout=sp.PIPE, cwd=dc_directory, shell=True)
                        for log in iter(output.stdout.readline, b''):
                            sys.stdout.write(str(log) + '\n')

                        progressbar = QProgressBar()
                        progressbar.setMinimum(0)
                        progressbar.setMaximum(0)
                        progressbar.setValue(0)
                        progressbar.setWindowTitle("Running gradle task...")
                        progressbar.show()


                        # Adding the resulting layer in the QGIS Layers Panel
                        vlayer = QgsVectorLayer(to_save,to_save.split("/")[-1],"ogr")
                        QgsMapLayerRegistry.instance().addMapLayer(vlayer)    
class CatalogDialogTool(QObject):
    """
    Tool for managing the search and export functionality
    """

    def __init__(self, iface, dialog_ui, bbox_tool):
        """
        Constructor for the dialog tool
        :param iface: The QGIS Interface
        :param dialog_ui: The dialog GUI
        :param bbox_tool The bounding box tool
        :return: dialog tool
        """
        QObject.__init__(self, None)
        self.iface = iface
        self.dialog_ui = dialog_ui
        self.bbox_tool = bbox_tool

        self.progress_bar = None
        self.progress_message_bar = None
        self.progress_message_bar_widget = None
        self.search_thread_pool = QThreadPool()
        self.search_lock = Lock()
        self.export_thread_pool = QThreadPool()
        self.export_lock = Lock()
        self.query = None
        self.previous_credentials = None
        self.export_file = None
        self.footprint_layer = None

        self.filters = CatalogFilters(self.dialog_ui)

        self.dialog_ui.aoi_button.clicked.connect(self.aoi_button_clicked)
        self.dialog_ui.reset_button.clicked.connect(self.reset_button_clicked)
        self.dialog_ui.export_button.clicked.connect(self.export_button_clicked)
        self.bbox_tool.released.connect(self.search)
        self.model = None

    def init_progress_bar(self, progress_max):
        """
        Sets up the progress bar for search functionality
        :return: None
        """
        if not self.progress_message_bar:
            self.progress_message_bar = self.iface.messageBar().createMessage("Querying for data")
            self.progress_bar = QProgressBar()
            self.progress_bar.setMinimum(0)
            self.progress_bar.setMaximum(progress_max)
            self.progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignCenter)
            self.progress_message_bar.layout().addWidget(self.progress_bar)
            self.progress_message_bar_widget = self.iface.messageBar().pushWidget(self.progress_message_bar, self.iface.messageBar().INFO)

    def init_layers(self):
        """
        Sets up the layers for rendering the items
        :return: None
        """
        if self.footprint_layer:
            QgsMapLayerRegistry.instance().removeMapLayer(self.footprint_layer.id())

        self.footprint_layer = QgsVectorLayer("Polygon?crs=EPSG:4326", "Catalog Footprints", "memory")
        self.footprint_layer.setCrs(QgsCoordinateReferenceSystem(4326), True)
        self.footprint_layer.dataProvider().addAttributes(CatalogAcquisitionFeature.get_fields())
        QgsMapLayerRegistry.instance().addMapLayer(self.footprint_layer)

    def clear_widgets(self):
        """
        Clears the progress bar
        :return: None
        """
        self.progress_bar = None
        self.progress_message_bar = None
        if self.progress_message_bar_widget:
            self.iface.messageBar().popWidget(self.progress_message_bar_widget)
        self.progress_message_bar_widget = None

    def is_searching(self):
        """
        Check to see if the system is still searching (checks if there's work in the search thread pool)
        :return: True if searching; False otherwise
        """
        return self.get_search_active_thread_count() > 0

    def is_exporting(self):
        """
        Check to see if the system is still exporting (checks if there's work in the export thread pool)
        :return: True if searching; False otherwise
        """
        return self.get_export_active_thread_count() > 0

    def get_search_active_thread_count(self):
        """
        Gets the number of active threads in the search thread pool
        :return:
        """
        with self.search_lock:
            return self.search_thread_pool.activeThreadCount()

    def get_export_active_thread_count(self):
        """
        Gets the number of active threads in the export thread pool
        :return:
        """
        with self.export_lock:
            return self.export_thread_pool.activeThreadCount()

    def aoi_button_clicked(self):
        """
        Validates and runs the search if validation successful
        :return: None
        """
        # can't run search during export
        if self.is_exporting():
            self.iface.messageBar().pushMessage("Error", "Cannot run search while export is running.", level=QgsMessageBar.CRITICAL)
        # can't run multiple search
        elif self.is_searching():
            self.iface.messageBar().pushMessage("Error", "Cannot run a new search while a search is running.", level=QgsMessageBar.CRITICAL)
        else:
            self.bbox_tool.reset()
            self.iface.mapCanvas().setMapTool(self.bbox_tool)

    def reset_button_clicked(self):
        """
        Resets filters.
        :return: None
        """
        self.reset()

    def export_button_clicked(self):
        """
        Validates and runs the export if validation successful
        :return: None
        """
        # can't run export during search
        if self.is_searching():
            self.iface.messageBar().pushMessage("Error", "Cannot run export while search is running.", level=QgsMessageBar.CRITICAL)
        # can't run multiple exports
        elif self.is_exporting():
            self.iface.messageBar().pushMessage("Error", "Cannot run a new export while a export is running.", level=QgsMessageBar.CRITICAL)
        else:
            self.export()

    def search(self, top, bottom, left, right):
        self.search_thread_pool.waitForDone(0)

        # validate credentials if they changed
        errors = []
        username, password, api_key, max_items_to_return = SettingsOps.get_settings()
        credentials = [username, password, api_key]
        if not self.previous_credentials or self.previous_credentials != credentials:
            SettingsOps.validate_stored_info(username, password, api_key, max_items_to_return, errors)
        self.previous_credentials = credentials

        # validate filters
        if not errors:
            self.filters.validate(errors)

        if errors:
            self.iface.messageBar().pushMessage("Error", "The following errors occurred: " + "<br />".join(errors), level=QgsMessageBar.CRITICAL)
        else:
            self.init_layers()

            self.dialog_ui.tab_widget.setCurrentIndex(RESULTS_TAB_INDEX)
            
            next_x_list = self.drange_list(float(left) + INCREMENTAL_INTERVAL, float(right), INCREMENTAL_INTERVAL)
            next_y_list = self.drange_list(float(bottom) + INCREMENTAL_INTERVAL, float(top), INCREMENTAL_INTERVAL)
            self.init_progress_bar(len(next_x_list) * len(next_y_list))

            self.model = CatalogTableModel(self.dialog_ui.table_view)
            self.dialog_ui.table_view.setModel(self.model)
            self.dialog_ui.table_view.selectionModel().selectionChanged.connect(self.selection_changed)

            if not self.query:
                self.query = GBDQuery(username=username, password=password, api_key=api_key)

            filters = self.filters.get_query_filters()
            time_begin = self.filters.get_datetime_begin()
            time_end = self.filters.get_datetime_end()

            current_x = float(left)
            current_y = float(bottom)
            for next_x in next_x_list:
                for next_y in next_y_list:
                    search_runnable = CatalogSearchRunnable(self.query, self.model, self, top=next_y, left=current_x, right=next_x, bottom=current_y, 
                                                            time_begin=time_begin, time_end=time_end, filters=filters)
                    search_runnable.task_object.task_complete.connect(self.on_search_complete)
                    self.search_thread_pool.start(search_runnable)
                    current_y = next_y
                current_y = bottom
                current_x = next_x

    def reset(self):
        self.filters.remove_all()

    def export(self):
        self.export_thread_pool.waitForDone(0)
        acquisitions = None
        if self.model is not None:
            acquisitions = self.model.data

        if not acquisitions:
            self.iface.messageBar().pushMessage("Error", "No data to export.", level=QgsMessageBar.CRITICAL)
        else:
            # open file ui
            select_file_ui = QFileDialog()
            starting_file = self.export_file or os.path.expanduser("~")
            export_file = select_file_ui.getSaveFileName(None, "Choose output file", starting_file, SELECT_FILTER)

            if export_file:
                self.export_file = export_file
                self.init_progress_bar(0)
                export_runnable = CatalogExportRunnable(acquisitions, self.export_file)
                export_runnable.task_object.task_complete.connect(self.on_export_complete)
                self.export_thread_pool.start(export_runnable)

    @pyqtSlot()
    def on_search_complete(self):
        thread_count = self.get_search_active_thread_count()
        if self.progress_message_bar:
            self.progress_bar.setValue(self.progress_bar.value() + 1)
        if thread_count == 0:
            self.clear_widgets()
            self.dialog_ui.table_view.resizeColumnsToContents()

    @pyqtSlot()
    def on_export_complete(self):
        thread_count = self.get_export_active_thread_count()
        if self.progress_message_bar:
            self.progress_bar.setValue(self.progress_bar.value() + 1)
        if thread_count == 0:
            self.clear_widgets()
            self.iface.messageBar().pushMessage("Info", 'File export has completed to "%s".' % self.export_file)

    def selection_changed(self, selected, deselected):
        self.footprint_layer.startEditing()

        # draw footprints for selected rows
        selected_rows = set()
        for index in selected.indexes():
            selected_rows.add(index.row())
        for row in selected_rows:
            acquisition = self.model.get(row)
            feature_id = self.model.generate_feature_id()
            self.model.set_feature_id(acquisition, feature_id)
            feature = CatalogAcquisitionFeature(feature_id, acquisition)
            self.footprint_layer.dataProvider().addFeatures([feature])

        # remove footprints for deselected rows
        deselected_rows = set()
        for index in deselected.indexes():
            deselected_rows.add(index.row())
        feature_ids_to_remove = []
        for row in deselected_rows:
            acquisition = self.model.get(row)
            feature_id = self.model.get_feature_id(acquisition)
            feature_ids_to_remove.append(feature_id)
            self.model.remove_feature_id(acquisition)
        if feature_ids_to_remove:
            self.footprint_layer.dataProvider().deleteFeatures(feature_ids_to_remove)

        self.footprint_layer.commitChanges()
        self.footprint_layer.updateExtents()
        self.footprint_layer.triggerRepaint()

    def drange_list(self, start, stop, step):
        drange_list = []
        r = start
        while r < stop:
            drange_list.append(r)
            r += step
        if not drange_list:
            drange_list.append(stop)
        return drange_list
Example #43
0
class VmUsageBarWidget(QWidget):
    class VmUsageBarItem(QTableWidgetItem):
        def __init__(self, value, vm):
            super(VmUsageBarWidget.VmUsageBarItem, self).__init__()
            self.value = value
            self.vm = vm

        def set_value(self, value):
            self.value = value

        def __lt__(self, other):
            if self.vm.qid == 0:
                return True
            elif other.vm.qid == 0:
                return False
            elif self.value == other.value:
                return self.vm.qid < other.vm.qid
            else:
                return int(self.value) < int(other.value)

    def __init__(self,
                 min,
                 max,
                 format,
                 update_func,
                 vm,
                 load,
                 hue=210,
                 parent=None):
        super(VmUsageBarWidget, self).__init__(parent)

        self.min = min
        self.max = max
        self.update_func = update_func
        self.value = min

        self.widget = QProgressBar()
        self.widget.setMinimum(min)
        self.widget.setMaximum(max)
        self.widget.setFormat(format)

        self.widget.setStyleSheet(
                                    "QProgressBar:horizontal{" +\
                                        "border: 1px solid hsv({0}, 100, 250);".format(hue) +\
                                        "border-radius: 4px;\
                                        background: white;\
                                        text-align: center;\
                                    }\
                                    QProgressBar::chunk:horizontal {\
                                        background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, "                                                                                                      +\
                                        "stop: 0 hsv({0}, 170, 207),".format(hue) +
                                        " stop: 1 white); \
                                    }"
            )

        layout = QHBoxLayout()
        layout.addWidget(self.widget)

        self.setLayout(layout)
        self.tableItem = self.VmUsageBarItem(min, vm)

        self.update_load(vm, load)

    def update_load(self, vm, load):
        self.value = self.update_func(vm, load)
        self.widget.setValue(self.value)
        self.tableItem.set_value(self.value)
Example #44
0
    def showNodes(self):
        """
        Parse the geometry of a selected layer and show its vertices (nodes)
        """

        mr = self.layerRegistry
        # Get the selected layer for which to show nodes
        selectedIndex = self.dlg.comboLayers.currentIndex()
        selectedLayer = self.dlg.comboLayers.itemData(selectedIndex)
        registeredLayers = self.layerRegistry.mapLayersByName('Noeuds')
        featuresCount = int(selectedLayer.featureCount())

        # Remove the node layer if already existing
        if mr.mapLayersByName('Noeuds'):
            mr.removeMapLayer(mr.mapLayersByName('Noeuds')[0].id())

        # Create memory layer to display nodes
        self.nodeLayer = QgsVectorLayer("Point?crs=EPSG:2056", "Noeuds",
                                        "memory")

        self.nodeLayerProvider = self.nodeLayer.dataProvider()

        # Create rendering style
        nodeSymbol = QgsMarkerSymbolV2.defaultSymbol(
            self.nodeLayer.geometryType())

        nodeSymbol.setColor(QColor('#CC3300'))
        nodeSymbol.setSize(2.0)
        nodeRenderer = QgsSingleSymbolRendererV2(nodeSymbol)
        self.nodeLayer.setRendererV2(nodeRenderer)

        # Select features visible in current map canvas extent
        if self.dlg.chkSelectByCanvasExtent.checkState():
            extent = self.canvas.extent()

            rect = QgsRectangle(extent.xMinimum(), extent.yMinimum(),
                                extent.xMaximum(), extent.yMaximum())

            request = QgsFeatureRequest()
            request.setFilterRect(rect)
            featureIterator = selectedLayer.getFeatures(request)

        # Select all features
        else:
            featureIterator = selectedLayer.getFeatures()

        # Create progress bar
        progressMessageBar = self.messageBar.createMessage(
            unicode("Création des noeuds...", "utf-8"))
        progress = QProgressBar()
        progress.setMinimum(0)
        progress.setMaximum(featuresCount)
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        self.messageBar.pushWidget(progressMessageBar,
                                   self.iface.messageBar().INFO)

        # Iterate over feature
        k = 0
        for feature in featureIterator:
            k += 1
            progress.setValue(k)
            geom = feature.geometry()
            feat = QgsFeature()

            # Adapt procedure for each geometry type
            if (geom):
                type = geom.wkbType()
            # LineString
            if type == QGis.WKBLineString:
                for point in geom.asPolyline():
                    feat.setGeometry(QgsGeometry.fromPoint(point))
                    self.nodeLayerProvider.addFeatures([feat])
            # MultiLineString
            elif type == QGis.WKBMultiLineString:
                for line in geom.asMultiPolyline():
                    for vertex in line:
                        feat.setGeometry(
                            QgsGeometry.fromPoint(
                                QgsPoint(vertex[0], vertex[1])))
                        self.nodeLayerProvider.addFeatures([feat])
            # Polygon
            elif type == QGis.WKBPolygon:
                polygons = geom.asPolygon()
                for polygon in polygons:
                    for vertex in polygon:
                        feat.setGeometry(
                            QgsGeometry.fromPoint(
                                QgsPoint(vertex[0], vertex[1])))
                        self.nodeLayerProvider.addFeatures([feat])
            # MultiPolygon
            elif type == QGis.WKBMultiPolygon:
                multiPoly = geom.asMultiPolygon()
                for polygons in multiPoly:
                    for polygon in polygons:
                        for vertex in polygon:
                            feat.setGeometry(
                                QgsGeometry.fromPoint(
                                    QgsPoint(vertex[0], vertex[1])))
                            self.nodeLayerProvider.addFeatures([feat])
            else:
                self.messageBar.pushMessage(
                    "Cartotools : ",
                    unicode("Type de géométrie non" + "supporté: " + str(type),
                            "utf-8"),
                    level=QgsMessageBar.CRITICAL)

        self.messageBar.clearWidgets()

        self.layerRegistry.addMapLayer(self.nodeLayer)
Example #45
0
class QuadStatusBar(QHBoxLayout):
    positionChanged = pyqtSignal(int, int, int)  # x,y,z

    def __init__(self, parent=None):
        QHBoxLayout.__init__(self, parent)
        self.setContentsMargins(0, 4, 0, 0)
        self.setSpacing(0)

    def showXYCoordinates(self):
        self.zLabel.setHidden(True)
        self.zSpinBox.setHidden(True)

    def showXYZCoordinates(self):
        self.zLabel.setHidden(False)
        self.zSpinBox.setHidden(False)

    def createQuadViewStatusBar(self, xbackgroundColor, xforegroundColor,
                                ybackgroundColor, yforegroundColor,
                                zbackgroundColor, zforegroundColor):
        self.xLabel, self.xSpinBox = _get_pos_widget('X', xbackgroundColor,
                                                     xforegroundColor)
        self.yLabel, self.ySpinBox = _get_pos_widget('Y', ybackgroundColor,
                                                     yforegroundColor)
        self.zLabel, self.zSpinBox = _get_pos_widget('Z', zbackgroundColor,
                                                     zforegroundColor)

        self.xSpinBox.delayedValueChanged.connect(
            partial(self._handlePositionBoxValueChanged, 'x'))
        self.ySpinBox.delayedValueChanged.connect(
            partial(self._handlePositionBoxValueChanged, 'y'))
        self.zSpinBox.delayedValueChanged.connect(
            partial(self._handlePositionBoxValueChanged, 'z'))

        self.addWidget(self.xLabel)
        self.addWidget(self.xSpinBox)
        self.addWidget(self.yLabel)
        self.addWidget(self.ySpinBox)
        self.addWidget(self.zLabel)
        self.addWidget(self.zSpinBox)

        self.addSpacing(10)

        self.busyIndicator = QProgressBar()
        self.busyIndicator.setMaximum(0)
        self.busyIndicator.setMinimum(0)
        self.busyIndicator.setVisible(False)
        self.busyIndicator.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        self.addWidget(self.busyIndicator)
        self.setStretchFactor(self.busyIndicator, 1)

        self.addStretch()
        self.addSpacing(10)

        self.positionCheckBox = QCheckBox()
        self.positionCheckBox.setChecked(True)
        self.positionCheckBox.setCheckable(True)
        self.positionCheckBox.setText("Position")
        self.addWidget(self.positionCheckBox)

        self.addSpacing(20)

        self.timeLabel = QLabel("Time:")
        self.addWidget(self.timeLabel)

        self.timeSpinBox = DelayedSpinBox(750)
        self.addWidget(self.timeSpinBox)

    def _handlePositionBoxValueChanged(self, axis, value):
        new_position = [
            self.xSpinBox.value(),
            self.ySpinBox.value(),
            self.zSpinBox.value()
        ]
        changed_axis = ord(axis) - ord('x')
        new_position[changed_axis] = value
        self.positionChanged.emit(*new_position)

    def updateShape5D(self, shape5D):
        self.timeSpinBox.setMaximum(shape5D[0] - 1)
        self.xSpinBox.setMaximum(shape5D[1] - 1)
        self.ySpinBox.setMaximum(shape5D[2] - 1)
        self.zSpinBox.setMaximum(shape5D[3] - 1)

    def setMouseCoords(self, x, y, z):
        self.xSpinBox.setValueWithoutSignal(x)
        self.ySpinBox.setValueWithoutSignal(y)
        self.zSpinBox.setValueWithoutSignal(z)
Example #46
0
class LoginWinGui(BaseWindow, QtGui.QMainWindow):
    loginComplete = QtCore.pyqtSignal(Session)

    def __init__(self, parent=None):
        super(LoginWinGui, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.login.clicked.connect(self.login)
        self.ui.login.setDefault(True)
        self.ui.adduser.triggered.connect(self.adduser)
        self.ui.forgot.triggered.connect(self.forgot)
        QtGui.QShortcut(QtGui.QKeySequence("Return"), self).activated.connect(self.login)
        QtGui.QShortcut(QtGui.QKeySequence("Enter"), self).activated.connect(self.login)
        QtGui.QShortcut(QtGui.QKeySequence("Up"), self).activated.connect(self.focusUp)
        QtGui.QShortcut(QtGui.QKeySequence("Down"), self).activated.connect(self.focusDown)
        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)
        self.loginComplete.connect(self.loginCompleteSlot)

        self.uiTranslate()

    def uiTranslate(self):
        self.setWindowTitle(strings["loginWindowTitle"])
        self.ui.username.setPlaceholderText(strings["usernameBoxHint"])
        self.ui.password.setPlaceholderText(strings["passwordBoxHint"])
        self.ui.login.setText(strings["loginButtonText"])
        self.ui.adduser.setText(strings["registerUserWindowTitle"])
        self.ui.forgot.setText(strings["forgotPasswordWindowTitle"])
        self.ui.menuTools.setTitle(strings["toolsMenuText"])

    def loginCompleteSlot(self, session):
        self.progressIndicator.setVisible(False)
        self.mainWin = ConversationsWinGui(session)
        self.mainWin.windowClosed.connect(self.close)
        self.mainWin.loggedOut.connect(self.loggedOut)
        self.mainWin.show()
        self.hide()

    def loggedOut(self):
        self.show()
        self.mainWin.windowClosed.disconnect(self.close)
        self.mainWin.close()

    def onMainClose(self):
        pass

    def focusUp(self):
        self.ui.username.setFocus()

    def focusDown(self):
        self.ui.password.setFocus()

    def login(self):
        self.progressIndicator.setVisible(True)

        def loginThread():
            username = self.ui.username.text()
            password = self.ui.password.text()
            if username == "" or password == "":
                self.showMessageBox.emit(strings["missingFieldsErrorText"])
                return
            try:
                if storage.getToken(username) and storage.getKey(username):
                    token = storage.getToken(username)
                    public, private = storage.getKey(username)
                    newSession = Session(username, password, token, public, private)
                    storage.storeKey(newSession.username, newSession.public, newSession.private)
                else:
                    token, public, private = Session.requestNewToken(username, password)
                    newSession = Session(username, password, token, public, private)
                    storage.storeToken(newSession.username, token)
                    storage.storeKey(newSession.username, newSession.public, newSession.private)
                self.loginComplete.emit(newSession)
            except SecureMessagingException as error:
                if error.message == HTTPStrings.RESPONSE_UNAUTHORIZED:
                    storage.storeKey(username, None, None)
                    storage.storeToken(username, None)
                    loginThread()
                    return
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])

        Thread(target=loginThread).start()

    def adduser(self):
        addUserGui = AddUserGui(parent=self)
        addUserGui.show()

    def forgot(self):
        forgotUi = ForgotPasswordUi(parent=self)
        forgotUi.show()
Example #47
0
    def on_uploaded(self):

        self.uploaded.emit()

        # Create message
        widget = self.iface.messageBar().createMessage(
            u"Géofoncier", u"Envoi des modifications.")
        progress_bar = QProgressBar()
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(3)
        widget.layout().addWidget(progress_bar)
        self.iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)
        progress_bar.setValue(1)

        enr_ref_dossier, ok = QInputDialog.getText(
            self, u"Référence de dossier",
            u"Vous êtes sur le point de soumettre\n"
            u"les modifications au serveur Géofoncier.\n"
            u"Veuillez renseigner la référence du dossier.")
        if not ok:
            return self.abort_action()

        if not enr_ref_dossier:
            return self.abort_action(
                msg=u"Merci de renseigner une référence de dossier.")

        commentaire = u"Dossier %s" % enr_ref_dossier

        dossiers = self.conn.dossiersoge_dossiers(self.zone, enr_ref_dossier)
        if dossiers.code != 200:
            return self.abort_action(msg=dossiers.read())

        tree = EltTree.fromstring(dossiers.read())

        # Check if exception
        err = tree.find(r"./erreur")
        if err:
            return self.abort_action(msg=err.text)

        nb_dossiers = int(tree.find(r"./dossiers").attrib[r"total"])

        if nb_dossiers == 0:
            return self.abort_action(msg=u"Le dossier \'%s\' n'existe pas." %
                                     enr_ref_dossier)

        if nb_dossiers >= 1:
            # Prendre par défaut le dernier dossier dans la liste
            dossier_uri = tree.getiterator(
                tag=r"dossier")[nb_dossiers -
                                1].find(r"{http://www.w3.org/2005/Atom}link")
            enr_api_dossier = dossier_uri.attrib[r"href"].split(r"/")[-1][1:]

        progress_bar.setValue(2)

        # Stop editing mode
        for layer in self.layers:
            if layer.isEditable():
                layer.commitChanges()

        # Check if dataset changes
        if (self.edges_added or self.vertices_added or self.edges_removed
                or self.vertices_removed or self.edges_modified
                or self.vertices_modified):
            pass
        else:
            return self.abort_action(
                msg=u"Aucune modification des données n'est détecté.")

        # Upload, reset and re-download datasets
        try:
            log = self.upload(enr_api_dossier=enr_api_dossier,
                              commentaire=commentaire)
            self.reset()
            self.download(self.url)
        except Exception as e:
            return self.abort_action(msg=e.message)

        self.canvas.zoomToFullExtent()
        self.iface.messageBar().clearWidgets()

        return QMessageBox.information(self, r"Information", u"\r".join(log))
Example #48
0
class LabelAssistDialog(QDialog):
    """
    A simple UI for showing bookmarks and navigating to them.

    FIXME: For now, this window is tied to a particular lane.
           If your project has more than one lane, then each one
           will have it's own bookmark window, which is kinda dumb.
    """
    def __init__(self, parent, topLevelOperatorView):
        super(LabelAssistDialog, self).__init__(parent)

        # Create thread router to populate table on main thread
        self.threadRouter = ThreadRouter(self)

        # Set object classification operator view
        self.topLevelOperatorView = topLevelOperatorView

        self.setWindowTitle("Label Assist")
        self.setMinimumWidth(500)
        self.setMinimumHeight(700)

        layout = QGridLayout()
        layout.setContentsMargins(10, 10, 10, 10)

        # Show variable importance table
        rows = 0
        columns = 4
        self.table = QTableWidget(rows, columns)
        self.table.setHorizontalHeaderLabels(
            ['Frame', 'Max Area', 'Min Area', 'Labels'])
        self.table.verticalHeader().setVisible(False)

        # Select full row on-click and call capture double click
        self.table.setSelectionBehavior(QTableView.SelectRows)
        self.table.doubleClicked.connect(self._captureDoubleClick)

        layout.addWidget(self.table, 1, 0, 3, 2)

        # Create progress bar
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(0)
        self.progressBar.hide()
        layout.addWidget(self.progressBar, 4, 0, 1, 2)

        # Create button to populate table
        self.computeButton = QPushButton('Compute object info')
        self.computeButton.clicked.connect(self._triggerTableUpdate)
        layout.addWidget(self.computeButton, 5, 0)

        # Create close button
        closeButton = QPushButton('Close')
        closeButton.clicked.connect(self.close)
        layout.addWidget(closeButton, 5, 1)

        # Set dialog layout
        self.setLayout(layout)

    def _triggerTableUpdate(self):
        # Check that object area is included in selected features
        featureNames = self.topLevelOperatorView.SelectedFeatures.value

        if 'Standard Object Features' not in featureNames or 'Count' not in featureNames[
                'Standard Object Features']:
            box = QMessageBox(
                QMessageBox.Warning, 'Warning',
                'Object area is not a selected feature. Please select this feature on: \"Standard Object Features > Shape > Size in pixels\"',
                QMessageBox.NoButton, self)
            box.show()
            return

        # Clear table
        self.table.clearContents()
        self.table.setRowCount(0)
        self.table.setSortingEnabled(False)
        self.progressBar.show()
        self.computeButton.setEnabled(False)

        # Compute object features and number of labels per frame
        def compute_features():
            features = self.topLevelOperatorView.ObjectFeatures([]).wait()
            labels = self.topLevelOperatorView.LabelInputs([]).wait()
            return features, labels

        req = Request(compute_features)
        req.notify_finished(self._populateTable)
        req.submit()

    @threadRouted
    def _populateTable(self, features_and_labels):
        features, labels = features_and_labels
        self.progressBar.hide()
        self.computeButton.setEnabled(True)

        for frame, objectFeatures in features.iteritems():
            # Insert row
            rowNum = self.table.rowCount()
            self.table.insertRow(self.table.rowCount())

            # Get max and min object areas
            areas = objectFeatures['Standard Object Features']['Count']
            maxObjArea = numpy.max(areas[numpy.nonzero(areas)])
            minObjArea = numpy.min(areas[numpy.nonzero(areas)])

            # Get number of labeled objects
            labelNum = numpy.count_nonzero(labels[frame])

            # Load fram number
            item = QTableWidgetItem(str(frame))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 0, item)

            # Load max object areas
            item = QTableWidgetItemWithFloatSorting(
                str("{: .02f}".format(maxObjArea)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 1, item)

            # Load min object areas
            item = QTableWidgetItemWithFloatSorting(
                str("{: .02f}".format(minObjArea)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 2, item)

            # Load label numbers
            item = QTableWidgetItemWithFloatSorting(
                str("{: .01f}".format(labelNum)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 3, item)

        # Resize column size to fit dialog size
        self.table.horizontalHeader().setResizeMode(QHeaderView.Stretch)

        # Sort by max object area
        self.table.setSortingEnabled(True)
        self.table.sortByColumn(1)

    def _captureDoubleClick(self):
        # Navigate to selected frame
        index = self.table.selectedIndexes()[0]
        frameStr = self.table.model().data(index).toString()

        if frameStr:
            frameNum = int(frameStr)
            self.parent().editor.posModel.time = frameNum
Example #49
0
class CatalogDialogTool(QObject):
    """
    Tool for managing the search and export functionality
    """
    def __init__(self, iface, dialog_ui, bbox_tool):
        """
        Constructor for the dialog tool
        :param iface: The QGIS Interface
        :param dialog_ui: The dialog GUI
        :param bbox_tool The bounding box tool
        :return: dialog tool
        """
        QObject.__init__(self, None)
        self.iface = iface
        self.dialog_ui = dialog_ui
        self.bbox_tool = bbox_tool

        self.progress_bar = None
        self.progress_message_bar = None
        self.progress_message_bar_widget = None
        self.search_thread_pool = QThreadPool()
        self.search_lock = Lock()
        self.export_thread_pool = QThreadPool()
        self.export_lock = Lock()
        self.query = None
        self.previous_credentials = None
        self.export_file = None
        self.footprint_layer = None

        self.filters = CatalogFilters(self.dialog_ui)

        self.dialog_ui.aoi_button.clicked.connect(self.aoi_button_clicked)
        self.dialog_ui.reset_button.clicked.connect(self.reset_button_clicked)
        self.dialog_ui.export_button.clicked.connect(
            self.export_button_clicked)
        self.bbox_tool.released.connect(self.search)
        self.model = None

    def init_progress_bar(self, progress_max):
        """
        Sets up the progress bar for search functionality
        :return: None
        """
        if not self.progress_message_bar:
            self.progress_message_bar = self.iface.messageBar().createMessage(
                "Querying for data")
            self.progress_bar = QProgressBar()
            self.progress_bar.setMinimum(0)
            self.progress_bar.setMaximum(progress_max)
            self.progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignCenter)
            self.progress_message_bar.layout().addWidget(self.progress_bar)
            self.progress_message_bar_widget = self.iface.messageBar(
            ).pushWidget(self.progress_message_bar,
                         self.iface.messageBar().INFO)

    def init_layers(self):
        """
        Sets up the layers for rendering the items
        :return: None
        """
        if self.footprint_layer:
            QgsMapLayerRegistry.instance().removeMapLayer(
                self.footprint_layer.id())

        self.footprint_layer = QgsVectorLayer("Polygon?crs=EPSG:4326",
                                              "Catalog Footprints", "memory")
        self.footprint_layer.setCrs(QgsCoordinateReferenceSystem(4326), True)
        self.footprint_layer.dataProvider().addAttributes(
            CatalogAcquisitionFeature.get_fields())
        QgsMapLayerRegistry.instance().addMapLayer(self.footprint_layer)

    def clear_widgets(self):
        """
        Clears the progress bar
        :return: None
        """
        self.progress_bar = None
        self.progress_message_bar = None
        if self.progress_message_bar_widget:
            self.iface.messageBar().popWidget(self.progress_message_bar_widget)
        self.progress_message_bar_widget = None

    def is_searching(self):
        """
        Check to see if the system is still searching (checks if there's work in the search thread pool)
        :return: True if searching; False otherwise
        """
        return self.get_search_active_thread_count() > 0

    def is_exporting(self):
        """
        Check to see if the system is still exporting (checks if there's work in the export thread pool)
        :return: True if searching; False otherwise
        """
        return self.get_export_active_thread_count() > 0

    def get_search_active_thread_count(self):
        """
        Gets the number of active threads in the search thread pool
        :return:
        """
        with self.search_lock:
            return self.search_thread_pool.activeThreadCount()

    def get_export_active_thread_count(self):
        """
        Gets the number of active threads in the export thread pool
        :return:
        """
        with self.export_lock:
            return self.export_thread_pool.activeThreadCount()

    def aoi_button_clicked(self):
        """
        Validates and runs the search if validation successful
        :return: None
        """
        # can't run search during export
        if self.is_exporting():
            self.iface.messageBar().pushMessage(
                "Error",
                "Cannot run search while export is running.",
                level=QgsMessageBar.CRITICAL)
        # can't run multiple search
        elif self.is_searching():
            self.iface.messageBar().pushMessage(
                "Error",
                "Cannot run a new search while a search is running.",
                level=QgsMessageBar.CRITICAL)
        else:
            self.bbox_tool.reset()
            self.iface.mapCanvas().setMapTool(self.bbox_tool)

    def reset_button_clicked(self):
        """
        Resets filters.
        :return: None
        """
        self.reset()

    def export_button_clicked(self):
        """
        Validates and runs the export if validation successful
        :return: None
        """
        # can't run export during search
        if self.is_searching():
            self.iface.messageBar().pushMessage(
                "Error",
                "Cannot run export while search is running.",
                level=QgsMessageBar.CRITICAL)
        # can't run multiple exports
        elif self.is_exporting():
            self.iface.messageBar().pushMessage(
                "Error",
                "Cannot run a new export while a export is running.",
                level=QgsMessageBar.CRITICAL)
        else:
            self.export()

    def search(self, top, bottom, left, right):
        self.search_thread_pool.waitForDone(0)

        # validate credentials if they changed
        errors = []
        username, password, api_key, max_items_to_return = SettingsOps.get_settings(
        )
        credentials = [username, password, api_key]
        if not self.previous_credentials or self.previous_credentials != credentials:
            SettingsOps.validate_stored_info(username, password, api_key,
                                             max_items_to_return, errors)
        self.previous_credentials = credentials

        # validate filters
        if not errors:
            self.filters.validate(errors)

        if errors:
            self.iface.messageBar().pushMessage(
                "Error",
                "The following errors occurred: " + "<br />".join(errors),
                level=QgsMessageBar.CRITICAL)
        else:
            self.init_layers()

            self.dialog_ui.tab_widget.setCurrentIndex(RESULTS_TAB_INDEX)

            next_x_list = self.drange_list(
                float(left) + INCREMENTAL_INTERVAL, float(right),
                INCREMENTAL_INTERVAL)
            next_y_list = self.drange_list(
                float(bottom) + INCREMENTAL_INTERVAL, float(top),
                INCREMENTAL_INTERVAL)
            self.init_progress_bar(len(next_x_list) * len(next_y_list))

            self.model = CatalogTableModel(self.dialog_ui.table_view)
            self.dialog_ui.table_view.setModel(self.model)
            self.dialog_ui.table_view.selectionModel(
            ).selectionChanged.connect(self.selection_changed)

            if not self.query:
                self.query = GBDQuery(username=username,
                                      password=password,
                                      api_key=api_key)

            filters = self.filters.get_query_filters()
            time_begin = self.filters.get_datetime_begin()
            time_end = self.filters.get_datetime_end()

            current_x = float(left)
            current_y = float(bottom)
            for next_x in next_x_list:
                for next_y in next_y_list:
                    search_runnable = CatalogSearchRunnable(
                        self.query,
                        self.model,
                        self,
                        top=next_y,
                        left=current_x,
                        right=next_x,
                        bottom=current_y,
                        time_begin=time_begin,
                        time_end=time_end,
                        filters=filters)
                    search_runnable.task_object.task_complete.connect(
                        self.on_search_complete)
                    self.search_thread_pool.start(search_runnable)
                    current_y = next_y
                current_y = bottom
                current_x = next_x

    def reset(self):
        self.filters.remove_all()

    def export(self):
        self.export_thread_pool.waitForDone(0)
        acquisitions = None
        if self.model is not None:
            acquisitions = self.model.data

        if not acquisitions:
            self.iface.messageBar().pushMessage("Error",
                                                "No data to export.",
                                                level=QgsMessageBar.CRITICAL)
        else:
            # open file ui
            select_file_ui = QFileDialog()
            starting_file = self.export_file or os.path.expanduser("~")
            export_file = select_file_ui.getSaveFileName(
                None, "Choose output file", starting_file, SELECT_FILTER)

            if export_file:
                self.export_file = export_file
                self.init_progress_bar(0)
                export_runnable = CatalogExportRunnable(
                    acquisitions, self.export_file)
                export_runnable.task_object.task_complete.connect(
                    self.on_export_complete)
                self.export_thread_pool.start(export_runnable)

    @pyqtSlot()
    def on_search_complete(self):
        thread_count = self.get_search_active_thread_count()
        if self.progress_message_bar:
            self.progress_bar.setValue(self.progress_bar.value() + 1)
        if thread_count == 0:
            self.clear_widgets()
            self.dialog_ui.table_view.resizeColumnsToContents()

    @pyqtSlot()
    def on_export_complete(self):
        thread_count = self.get_export_active_thread_count()
        if self.progress_message_bar:
            self.progress_bar.setValue(self.progress_bar.value() + 1)
        if thread_count == 0:
            self.clear_widgets()
            self.iface.messageBar().pushMessage(
                "Info",
                'File export has completed to "%s".' % self.export_file)

    def selection_changed(self, selected, deselected):
        self.footprint_layer.startEditing()

        # draw footprints for selected rows
        selected_rows = set()
        for index in selected.indexes():
            selected_rows.add(index.row())
        for row in selected_rows:
            acquisition = self.model.get(row)
            feature_id = self.model.generate_feature_id()
            self.model.set_feature_id(acquisition, feature_id)
            feature = CatalogAcquisitionFeature(feature_id, acquisition)
            self.footprint_layer.dataProvider().addFeatures([feature])

        # remove footprints for deselected rows
        deselected_rows = set()
        for index in deselected.indexes():
            deselected_rows.add(index.row())
        feature_ids_to_remove = []
        for row in deselected_rows:
            acquisition = self.model.get(row)
            feature_id = self.model.get_feature_id(acquisition)
            feature_ids_to_remove.append(feature_id)
            self.model.remove_feature_id(acquisition)
        if feature_ids_to_remove:
            self.footprint_layer.dataProvider().deleteFeatures(
                feature_ids_to_remove)

        self.footprint_layer.commitChanges()
        self.footprint_layer.updateExtents()
        self.footprint_layer.triggerRepaint()

    def drange_list(self, start, stop, step):
        drange_list = []
        r = start
        while r < stop:
            drange_list.append(r)
            r += step
        if not drange_list:
            drange_list.append(stop)
        return drange_list
Example #50
0
class CANMonitor(QMainWindow):
    def __init__(self, app, test, parent):
        QMainWindow.__init__(self, parent)
        self.app = app
        self.lcdDict=dict()
        self.logBuffer=deque("", 1000)
        self.logBuffer2=dict()
        self.logBufferInit=dict()
        self.logEntryCount=1
        self.maxLogEntryCount=65353
        self.tableUpdateCouter=0
        self.logFile=None
        self.test=test
        self.logFileName="/tmp/candash.log"
        self.connectCANEnable=True
        self.connectGPSEnable=True
        self.replayMode=False
        self.canIdList=[0x621, 0x353, 0x351, 0x635, 0x271, 0x371, 0x623, 0x571, 0x3e5, 0x591, 0x5d1]
        self.updateGPSThread=None
        self.config=Config("candash.cfg")
        self.log=Log(False)
        font = self.font()
        font.setPointSize(14)
        self.setFont(font)
        self.ampelGruen=QIcon("images/ampel-gruen.png")
        self.ampelRot=QIcon("images/ampel-rot.png")
        self.ampelGelb=QIcon("images/ampel-gelb.png")
        self.lastCANState=canStoppedState
        self.lastGPSState=gpsStoppedState
        self.canDecoder=CANDecoder(self)

        self.initUI(parent)
    
    def clearAllLCD(self):
        for lcdList in self.lcdDict.values():
            for lcd in lcdList:
                if lcd.mode()==QLCDNumber.Bin:
                    lcd.display("00000000")
                else:
                    lcd.display(0)
                    
        self.rpmGauge.setValue(0)
        self.velGauge.setValue(0)
  
    def createLCD(self, mode):
        lcd = QLCDNumber(self)
        lcd.setMode(mode)
        lcd.setMinimumHeight(50)
        lcd.setMinimumWidth(160)
        lcd.setDigitCount(8)
        if mode==QLCDNumber.Bin:
            lcd.display("00000000")
        else:
            lcd.display(0)
        lcd.setSegmentStyle(QLCDNumber.Flat)
        lcd.setAutoFillBackground(True)
        palette = lcd.palette()
        palette.setColor(QPalette.Normal, QPalette.Foreground, Qt.blue)
        palette.setColor(QPalette.Normal, QPalette.Background, Qt.lightGray)
        lcd.setPalette(palette);
        return lcd
    
    def addLCD(self, lcd, canId, subItem):
        if not hex(canId)+":"+subItem in self.lcdDict.keys():
            lcdItemList=list()
            lcdItemList.append(lcd)
            self.lcdDict[hex(canId)+":"+subItem]=lcdItemList
        else:
            self.lcdDict[hex(canId)+":"+subItem].append(lcd)
                
    def createCANIdValueEntry(self, vbox, canId, subId, mode):        
        lcd = self.createLCD(mode)
        
        self.addLCD(lcd, canId, subId)
        
        vbox.addWidget(lcd)          
        
    def createCANIdEntry(self, form, canId, subId, label, mode):
#        hbox = QHBoxLayout()

        lbl = QLabel(self)
        lbl.setMinimumHeight(50)
        font = lbl.font()
        font.setPointSize(14)
        lbl.setFont(font)
        
        if label!=None:
            lbl.setText(label)
#            hbox.addWidget(lbl)
        
        lcd = self.createLCD(mode)
#        hbox.addWidget(lcd)

        form.addRow(lbl, lcd)
        
        self.addLCD(lcd, canId, subId)
        
#        vbox.addLayout(hbox)
        
    def createCANIdEntrySingleLine(self, form, canId, subIdList, label, mode):
#        hbox = QHBoxLayout()

        lbl = QLabel(self)
        lbl.setMinimumHeight(50)
        font = lbl.font()
        font.setPointSize(14)
        lbl.setFont(font)
        if label!=None:
            lbl.setText(label)
#            hbox.addWidget(lbl)

        hbox2=QHBoxLayout();
        
        for i in range(len(subIdList)):
            subId=subIdList[i]
            lcd = self.createLCD(mode)
            hbox2.addWidget(lcd)
            self.addLCD(lcd, canId, subId)

        form.addRow(lbl, hbox2)
#        hbox.addLayout(hbox2)
                        
#        vbox.addLayout(hbox)
        
    def createLogView(self, vbox):
        self.logView=QTableView(self)
        vbox.addWidget(self.logView)
        
        self.logViewModel=CANLogViewTableModel(self.logBuffer, self.canIdList, self)
        self.logView.setModel(self.logViewModel)
        
        header=QHeaderView(Qt.Horizontal, self.logView)
        header.setStretchLastSection(True)
        header.setResizeMode(NUMBER_COL, QHeaderView.Fixed)
        header.setResizeMode(TIME_COL, QHeaderView.Fixed)
        header.setResizeMode(ID_COL, QHeaderView.Fixed)

        self.logView.setHorizontalHeader(header)
        
        self.logView.setColumnWidth(NUMBER_COL, 80)
        self.logView.setColumnWidth(TIME_COL, 150)
        self.logView.setColumnWidth(ID_COL, 80)
        self.logView.setColumnWidth(SIZE_COL, 50)
        
    def createLogView2(self, vbox):
        self.logView2=QTableView(self)
        vbox.addWidget(self.logView2)
        
        self.logViewModel2=CANLogViewTableModel2(self.canIdList, self)
        self.logView2.setModel(self.logViewModel2)
#        self.logView2.setSortingEnabled(True)
        
        header=QHeaderView(Qt.Horizontal, self.logView2)
#        header.setStretchLastSection(True)
#        header.setClickable(True)
        header.setResizeMode(0, QHeaderView.Fixed)
        header.setResizeMode(1, QHeaderView.Fixed)

        self.logView2.setHorizontalHeader(header)
        
        self.logView2.setColumnWidth(0, 80)
        self.logView2.setColumnWidth(1, 50)
        for i in range(2, 10):
            self.logView2.setColumnWidth(i, 60)
        
    def initUI(self, parent):  
#        exitAction = QAction(QIcon(), 'Exit', self)
#        exitAction.setShortcut('Ctrl+Q')
#        exitAction.setStatusTip('Exit application')
#        exitAction.triggered.connectToCAN(self.close)

        self.statusbar=self.statusBar()
        self.progress=QProgressBar()
        self.statusbar.addPermanentWidget(self.progress)

#        menubar = self.menuBar()
#        fileMenu = menubar.addMenu('&File')
#        fileMenu.addAction(exitAction)

#        toolbar = self.addToolBar('Exit')
##        toolbar.addAction(exitAction)
#                
#        self.connectedIcon=QIcon("images/network-connect.png")
#        self.disconnectIcon=QIcon("images/network-disconnect.png")
#        self.connectAction = QAction(self.disconnectIcon , 'Connect', self)
#        self.connectAction.triggered.connect(self._connect1)
#        self.connectAction.setCheckable(True)
#        
#        toolbar.addAction(self.connectAction)
#        
#        self.gpsIcon=QIcon("images/icon_gps.gif")
#        self.reconnectGPSAction = QAction(self.gpsIcon, 'Reconnect GPS', self)
#        self.reconnectGPSAction.triggered.connect(self._reconnectGPS)
#        toolbar.addAction(self.reconnectGPSAction)
        
        mainWidget=QWidget(self)
#        mainWidget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        mainWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)        

        self.setCentralWidget(mainWidget)
        top=QVBoxLayout(mainWidget)
        
        self.tabs = MyTabWidget(self)
        top.addWidget(self.tabs)
        
        mainTab = QWidget(self)
        miscTab = QWidget(self) 
        misc2Tab=QWidget(self)
        canLogTab=QWidget(self)
        dashTab=QWidget(self)
        gpsTab=QWidget(self)
        osmTab=QWidget(self)
        debugLogTab=QWidget(self)
        
        mainTabLayout = QFormLayout(mainTab)
        miscTabLayout = QFormLayout(miscTab)
        misc2TabLayout = QFormLayout(misc2Tab)
        canLogTabLayout = QVBoxLayout(canLogTab)
        dashTabLayout = QHBoxLayout(dashTab)
        gpsTabLayout=QHBoxLayout(gpsTab)
        osmTabLayout=QVBoxLayout(osmTab)
        debugLogTabLayout=QVBoxLayout(debugLogTab)
        
        self.tabs.addTab(dashTab, "Dash") 
        self.tabs.addTab(mainTab, "Main")
        self.tabs.addTab(miscTab, "Misc 1") 
        self.tabs.addTab(misc2Tab, "Misc 2") 
        self.tabs.addTab(canLogTab, "CAN") 
        self.tabs.addTab(gpsTab, "GPS")
        self.tabs.addTab(osmTab, "OSM")
        self.tabs.addTab(debugLogTab, "Log")

        self.tabs.setCurrentIndex(0)
        
        self.debugLogWidget=DebugLogWidget(self)
        debugLogTabLayout.setAlignment(Qt.AlignLeft|Qt.AlignTop)
        self.debugLogWidget.addToWidget(debugLogTabLayout)

#        self.debugLogWidget.addLine("test")

        self.createCANIdEntry(mainTabLayout, 0x353, "0", "Drehzahl", QLCDNumber.Dec)
#        self.createCANIdEntry(mainTabLayout, 0x353, "1", "Öltemperatur", QLCDNumber.Dec)
        self.createCANIdEntry(mainTabLayout, 0x353, "1", "Kuehlwasser Temperatur", QLCDNumber.Dec)
        self.createCANIdEntry(mainTabLayout, 0x351, "0", "Geschwindigkeit", QLCDNumber.Dec)
        self.createCANIdEntry(mainTabLayout, 0x351, "1", "Außentemperatur", QLCDNumber.Dec)
        self.createCANIdEntry(miscTabLayout, 0x635, "0", "Licht, Klemme 58d", QLCDNumber.Dec)
        self.createCANIdEntry(miscTabLayout, 0x271, "0", "Zuendung", QLCDNumber.Dec)
        self.createCANIdEntrySingleLine(miscTabLayout, 0x371, ["0", "1"], "Tuerstatus", QLCDNumber.Bin)
        self.createCANIdEntry(miscTabLayout, 0x371, "2", "Blinker, Retoursgang", QLCDNumber.Bin)
        self.createCANIdEntrySingleLine(mainTabLayout, 0x623, ["0", "1", "2"], "Uhrzeit (Stunden)", QLCDNumber.Dec)        
        self.createCANIdEntry(mainTabLayout, 0x571, "0", "Batteriespannung", QLCDNumber.Dec)
        
        self.createCANIdEntry(misc2TabLayout, 0x3e5, "0", "Zuheizer 1", QLCDNumber.Bin)
        self.createCANIdEntry(misc2TabLayout, 0x3e5, "1", "Zuheizer 2", QLCDNumber.Bin)
        self.createCANIdEntry(misc2TabLayout, 0x3e5, "2", "Zuheizer 3", QLCDNumber.Bin)
        self.createCANIdEntry(misc2TabLayout, 0x3e5, "3", "Zuheizer 4", QLCDNumber.Bin)
        self.createCANIdEntry(misc2TabLayout, 0x3e5, "4", "Zuheizer 5", QLCDNumber.Bin)
        
        self.createCANIdEntry(miscTabLayout, 0x3e5, "5", "Zuheizer", QLCDNumber.Dec)
        self.createCANIdEntry(miscTabLayout, 0x591, "0", "ZV", QLCDNumber.Dec)
        self.createCANIdEntry(miscTabLayout, 0x5d1, "0", "Scheibenwischer", QLCDNumber.Dec)

        self.createCANIdEntrySingleLine(mainTabLayout, 0x351, ["2", "3"], "Wegstreckenimpuls", QLCDNumber.Dec)
        self.createCANIdEntrySingleLine(misc2TabLayout, 0x621, ["0"], "0x621", QLCDNumber.Bin)
        self.createCANIdEntrySingleLine(misc2TabLayout, 0x621, ["1", "2"], "0x621", QLCDNumber.Dec)
        
        logTabs = MyTabWidget(self)
        canLogTabLayout.addWidget(logTabs)
        
        logTabWidget1=QWidget()
        logTabWidget2=QWidget()

        logTabs.addTab(logTabWidget1, "Time")
        logTabs.addTab(logTabWidget2, "Change") 
        
        logTab1Layout = QVBoxLayout(logTabWidget1)
        self.createLogView(logTab1Layout)
        
        self.logViewFilerBox1=CANFilterBox(False, self)
        self.logViewFilerBox1.addFilterBox(logTab1Layout)
        
        self.logViewTableBox1=CANLogTableBox(self.logViewModel, self.logBuffer, None, self)
        self.logViewTableBox1.addTableBox(logTab1Layout)
        
        logTab2Layout = QVBoxLayout(logTabWidget2)
        self.createLogView2(logTab2Layout)

        self.logViewFilterBox2=CANFilterBox(True, self)
        self.logViewFilterBox2.addFilterBox(logTab2Layout)
        
        self.logViewTableBox2=CANLogTableBox(self.logViewModel2, self.logBuffer2, self.logBufferInit, self)
        self.logViewTableBox2.addTableBox(logTab2Layout)
        
        logButtonBox = QHBoxLayout()
        canLogTabLayout.addLayout(logButtonBox)
        
        self.logFileButton=QCheckBox("Log to File", self)
        self.logFileButton.setToolTip('Enable file logging')
        self.logFileButton.resize(self.logFileButton.sizeHint())
        self.logFileButton.setDisabled(self.replayMode==True)
        self.logFileButton.clicked.connect(self._enableLogFile)
        logButtonBox.addWidget(self.logFileButton)
        
        self.clearLogButton = QPushButton('Clear Log', self)
        self.clearLogButton.resize(self.clearLogButton.sizeHint())
        self.clearLogButton.setDisabled(not self.logFileAvailable() or self.replayMode==True)
        self.clearLogButton.clicked.connect(self._clearLogFile)
        logButtonBox.addWidget(self.clearLogButton)

        self.replayButton = QPushButton('Replay Log', self)
        self.replayButton.resize(self.replayButton.sizeHint())
        self.replayButton.setDisabled(not self.logFileAvailable() or self.connectCANEnable==True)
        self.replayButton.clicked.connect(self._startReplayMode)
        logButtonBox.addWidget(self.replayButton)

        self.stopReplayButton = QPushButton('Stop Replay', self)
        self.stopReplayButton.resize(self.stopReplayButton.sizeHint())
        self.stopReplayButton.setDisabled(self.replayMode==False)
        self.stopReplayButton.clicked.connect(self._stopReplayMode)
        logButtonBox.addWidget(self.stopReplayButton)
                    
                    
        velBox = QVBoxLayout()
        dashTabLayout.addLayout(velBox)
        dashTabLayout.setAlignment(Qt.AlignCenter|Qt.AlignBottom)
             
        self.velGauge=QtPngDialGauge(self, "tacho3", "tacho31.png")
        self.velGauge.setMinimum(20)
        self.velGauge.setMaximum(220)
        self.velGauge.setStartAngle(135)
        self.velGauge.setValue(0)
#        self.velGauge.setMaximumSize(400, 400)
        velBox.addWidget(self.velGauge)

        self.createCANIdValueEntry(velBox, 0x351, "0", QLCDNumber.Dec)
        
        valuesBox = QVBoxLayout()
        valuesBox.setAlignment(Qt.AlignCenter|Qt.AlignBottom)

        dashTabLayout.addLayout(valuesBox)
        self.createCANIdValueEntry(valuesBox, 0x353, "1", QLCDNumber.Dec)
        self.createCANIdValueEntry(valuesBox, 0x351, "1", QLCDNumber.Dec)
        self.createCANIdValueEntry(valuesBox, 0x571, "0", QLCDNumber.Dec)
 
        rpmBox = QVBoxLayout()
        dashTabLayout.addLayout(rpmBox)
#        rpmBox.setAlignment(Qt.AlignCenter|Qt.AlignHCenter)
        self.rpmGauge=QtPngDialGauge(self, "rpm", "rpm1.png")
        self.rpmGauge.setMinimum(0)
        self.rpmGauge.setMaximum(8000)
        self.rpmGauge.setStartAngle(125)
        self.rpmGauge.setValue(2500)
#        self.rpmGauge.setMaximumSize(400, 400)
        rpmBox.addWidget(self.rpmGauge)     
         
        self.createCANIdValueEntry(rpmBox, 0x353, "0", QLCDNumber.Dec)
        
        self.gpsBox=GPSMonitor(self)
        gpsTabLayout.setAlignment(Qt.AlignLeft|Qt.AlignTop)
        self.gpsBox.loadConfig(self.config)

        self.gpsBox.addToWidget(gpsTabLayout)

        self.osmWidget=OSMWidget(self)
        osmTabLayout.setAlignment(Qt.AlignLeft|Qt.AlignTop)

        self.osmWidget.addToWidget(osmTabLayout)
        self.osmWidget.loadConfig(self.config)
        self.osmWidget.initWorkers()
                
        self.connect(self.osmWidget.mapWidgetQt, SIGNAL("updateStatus(QString)"), self.updateStatusBarLabel)
        self.connect(self.osmWidget.downloadThread, SIGNAL("updateStatus(QString)"), self.updateStatusBarLabel)
        self.connect(self.osmWidget, SIGNAL("updateStatus(QString)"), self.updateStatusBarLabel)
        self.connect(self.osmWidget, SIGNAL("startProgress()"), self.startProgress)
        self.connect(self.osmWidget, SIGNAL("stopProgress()"), self.stopProgress)

        self.osmWidget.initHome()
        
        connectBox=QHBoxLayout()
        top.addLayout(connectBox)
        
        section="connect"
        self.connectCANButton = QCheckBox('CAN Connect', self)
        self.connectCANButton.clicked.connect(self._connectCAN)
        self.connectCANEnable=self.config.getSection(section).getboolean("CANconnect", False)
        self.connectCANButton.setChecked(self.connectCANEnable)
        self.connectCANButton.setIcon(self.ampelRot)
        connectBox.addWidget(self.connectCANButton)

        self.connectGPSButton = QCheckBox('GPS Connect', self)
        self.connectGPSButton.clicked.connect(self._connectGPS)
        self.connectGPSEnable=self.config.getSection(section).getboolean("GPSconnect", False)
        self.connectGPSButton.setChecked(self.connectGPSEnable)
        self.connectGPSButton.setIcon(self.ampelRot)
        connectBox.addWidget(self.connectGPSButton)
        
        self.setGeometry(0, 0, 900, 600)
        self.setWindowTitle("candash")
        self.show()
        
        self.updateCANThread = CANSocketWorker(self)        
        self.connect(self.updateCANThread, SIGNAL("updateStatus(QString)"), self.updateStatusBarLabel)
        self.connect(self.updateCANThread, SIGNAL("updateCANThreadState(QString)"), self.updateCANThreadState)
        self.connect(self.updateCANThread, SIGNAL("clearAllLCD()"), self.clearAllLCD)
        self.connect(self.updateCANThread, SIGNAL("connectCANFailed()"), self.connectCANFailed)
        self.connect(self.updateCANThread, SIGNAL("replayModeDone()"), self.replayModeDone)
        self.connect(self.updateCANThread, SIGNAL("processCANData(PyQt_PyObject)"), self.canDecoder.scan_can_frame)
        self._connectCAN()
        
        self.updateGPSThread=getGPSUpdateThread(self)
        if self.updateGPSThread!=None:
            self.connect(self.updateGPSThread, SIGNAL("updateStatus(QString)"), self.updateStatusBarLabel)
            self.connect(self.updateGPSThread, SIGNAL("updateGPSThreadState(QString)"), self.updateGPSThreadState)
            self.connect(self.updateGPSThread, SIGNAL("connectGPSFailed()"), self.connectGPSFailed)
            self.connect(self.updateGPSThread, SIGNAL("updateGPSDisplay(PyQt_PyObject)"), self.updateGPSDisplay)
            self._connectGPS()

    #def mousePressEvent(self, event):
    #    print("CANMonitor mousePressEvent")
    #    self.tabs.mousePressEvent(event)

    def getWidget(self, canId, subId):
        try:
            return self.lcdDict[hex(canId)+":"+subId]
        except KeyError:
            return list()
    
    def setValueDashDisplayRPM(self, value):
        if value!=self.rpmGauge.value():
            self.rpmGauge.setValue(value)

    def setValueDashDisplayVel(self, value):
        if value!=self.velGauge.value():
            self.velGauge.setValue(value)
        
    def displayIntValue(self, canId, subId, value, formatString):
        lcdList=self.getWidget(canId, subId)
        for lcdItem in lcdList:
            if lcdItem.intValue()!=int(value):
                lcdItem.display(formatString % value)
                  
    def displayBinValue(self, canId, subId, value, formatString):
        lcdList=self.getWidget(canId, subId)
        for lcdItem in lcdList:
            if lcdItem.intValue()!=int(value):
                lcdItem.display(formatString % value)
                        
    def displayFloatValue(self, canId, subId, value, formatString):
        lcdList=self.getWidget(canId, subId)
        for lcdItem in lcdList:
            if lcdItem.value()!=value:
                lcdItem.display(formatString % value)
                                 
    def addToLogView(self, line):
        tableEntry=[self.logEntryCount, self.createTimeStamp()]
        tableEntry.extend(line[0:])
        
        if self.logFile!=None:
            self.addToLogFile(tableEntry)
            
        if self.logViewTableBox1.update==True:

            canId=line[0]
            if not self.logViewFilerBox1.matchFilter(canId, line, None):
                return
        
            self.logBuffer.appendleft(tableEntry)
            self.logEntryCount=self.logEntryCount+1
            if self.logEntryCount==self.maxLogEntryCount:
                self.logEntryCount=1
        
            self.tableUpdateCouter=self.tableUpdateCouter+1
            if self.tableUpdateCouter==10:
                self.logViewModel.update(self.logBuffer, None)
                self.tableUpdateCouter=0
                
    def addToLogView2(self, line):  
        if self.logViewTableBox2.update==True:
            canId=line[0]    
            if not canId in self.logBufferInit.keys():
                self.logBufferInit[canId]=line
                
            if not self.logViewFilterBox2.matchFilter(canId, line, self.logBufferInit[canId]):
                try:
                    del self.logBuffer2[canId]
                except KeyError:
                    None
            else:
                self.logBuffer2[canId]=line
        
                self.logViewModel2.update(list(self.logBuffer2.values()), self.logBufferInit)
                     
    def createTimeStamp(self):
        stamp=datetime.fromtimestamp(time.time())
        return "".join(["%02d:%02d:%02d.%06d"%(stamp.hour, stamp.minute, stamp.second, stamp.microsecond)])
    
    def dumpLogLine(self, line):
        logLine="%s %s %s"% (line[1], hex(line[2]), line[3])
        dataLine="".join(["0x%02X " % x for x in line[4]])
        return logLine+" "+dataLine   
         
    def addToLogFile(self, line):
        if self.logFile!=None:
            self.logFile.write(self.dumpLogLine(line)+"\n")
        
    def setupLogFile(self, filePath):
        if self.logFile==None:
            self.logFile=open(filePath,"a")
            self.logFile.write("# Log started: "+time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime())+"\n")
            self.logFile.write("# -------------------------------------------------------\n")

    def closeLogFile(self):
        if self.logFile!=None:
            self.logFile.write("# Log stoped: "+time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime())+"\n")
            self.logFile.write("# -------------------------------------------------------\n")
            self.logFile.close()
            self.logFile=None

    def logFileAvailable(self):
        try:
            open(self.logFileName, "r")
            return True
        except IOError:
            return False
    def readLogFile(self):
        try:
            logFileEntries=list()
            readLogFile=open(self.logFileName, "r")
            while True:
                line=readLogFile.readline()
                if not line:
                    break
                if line[0]=="#":
                    continue
                lineParts=line.split(" ")
                strippedLen=len(lineParts)-1
                neededLineParts=lineParts[1:strippedLen]
                addLen=8-len(neededLineParts[2:])
                for _ in range(addLen):
                    neededLineParts.append("%s" % "0x00")
                logFileEntries.append(struct.pack("IIBBBBBBBB", int(neededLineParts[0], 16), int(neededLineParts[1], 10), int(neededLineParts[2], 16),
                   int(neededLineParts[3], 16),int(neededLineParts[4], 16),int(neededLineParts[5], 16),int(neededLineParts[6], 16), 
                   int(neededLineParts[7], 16), int(neededLineParts[8], 16), int(neededLineParts[9], 16)))              
            return logFileEntries
        except IOError:
            return list()
                        
    @pyqtSlot()
    def _enableFilter(self):
        self.filter=self.filterButton.isChecked()
            
        self.filterEdit.setDisabled(self.filter==False)
        self.applyFilterButton.setDisabled(self.filter==False)
        self.filterAll.setDisabled(self.filter==False)
        self.filterKnown.setDisabled(self.filter==False)
        self.filterUnknown.setDisabled(self.filter==False)
        self.filterRingIdsButton.setDisabled(self.filter==False)

    @pyqtSlot()
    def _applyFilter(self):
        if self.filter==True:
            self.filterValue=self.filterEdit.text()
        else:
            self.filterValue=""

    @pyqtSlot()
    def _cleanup(self):
        self.osmWidget._cleanup()
        self.gpsBox._cleanup()

        if self.updateCANThread.isRunning():
            self.updateCANThread.stop()
        
        if self.updateGPSThread.isRunning():
            self.updateGPSThread.stop()
            
        self.closeLogFile()
        section="connect"
        self.config.removeSection(section)
        self.config.addSection(section)
        self.config.getSection(section)["canConnect"]=str(self.connectCANEnable)
        self.config.getSection(section)["gpsConnect"]=str(self.connectGPSEnable)
        
        self.osmWidget.saveConfig(self.config)
        self.gpsBox.saveConfig(self.config)

        self.config.writeConfig()
        self.log.writeLogtoFile()
        
    @pyqtSlot()
    def _enableLogFile(self):
        if self.logFileButton.isChecked()==True:
            if self.logFile==None:
                self.setupLogFile(self.logFileName)
        else:
            self.closeLogFile()
        self.replayButton.setDisabled(not self.logFileAvailable() or self.connectCANEnable==True)
        self.clearLogButton.setDisabled(not self.logFileAvailable() or self.replayMode==True)
        
    @pyqtSlot()
    def _startReplayMode(self):
        self.closeLogFile()
        self.logFileButton.setChecked(False)
        self.replayButton.setDisabled(True)
        self.replayMode=True
        
        self.stopReplayButton.setDisabled(self.replayMode==False)
        self.logFileButton.setDisabled(self.replayMode==True)
        self.clearLogButton.setDisabled(not self.logFileAvailable() or self.replayMode==True)
        
        replayLines=self.readLogFile()
        self.logViewTableBox1._clearTable()
        self.logViewTableBox2._clearTable()
        self.updateCANThread.setup(self.app, self, self.test, True, replayLines)
            
    @pyqtSlot()
    def _stopReplayMode(self):
        self.updateCANThread.stop()
        self.replayModeDone()

    def replayModeDone(self):
        self.replayMode=False
        self.stopReplayButton.setDisabled(self.replayMode==False)
        self.replayButton.setDisabled(not self.logFileAvailable() or self.connectCANEnable==True)
        self.logFileButton.setDisabled(self.replayMode==True)
        self.clearLogButton.setDisabled(not self.logFileAvailable() or self.replayMode==True)
        
    @pyqtSlot()
    def _clearLogFile(self):
        if self.logFileAvailable():                        
            self.closeLogFile()
            os.remove(self.logFileName)
            self.logFile=None
        self._enableLogFile()
    
    @pyqtSlot()
    def _connectCAN(self):
        self.connectCANEnable=self.connectCANButton.isChecked()
        if self.replayMode==True:
            self._stopReplayMode()
            
        if self.connectCANEnable==True:
#            self.connectCANButton.setDisabled(True)
            self.logViewTableBox1._clearTable()
            self.logViewTableBox2._clearTable()
            self.updateCANThread.setup(self.app, self.connectCANEnable, self.test, False, None)

        else:
            if self.updateCANThread.isRunning():
#                self.connectCANButton.setDisabled(True)
                self.updateCANThread.stop()
            
        self.replayButton.setDisabled(not self.logFileAvailable() or self.connectCANEnable==True)
        self.connectCANButton.setChecked(self.connectCANEnable==True)
                
    @pyqtSlot()
    def _connectGPS(self):
        self.connectGPSEnable=self.connectGPSButton.isChecked()
        if self.connectGPSEnable==True:
#            self.connectGPSButton.setDisabled(True)
            self.updateGPSThread.setup(self.connectGPSEnable)
        else:
            if self.updateGPSThread.isRunning():
#                self.connectGPSButton.setDisabled(True)
                self.updateGPSThread.stop()

        self.connectGPSButton.setChecked(self.connectGPSEnable==True)
        
    @pyqtSlot()
    def _enableFilterRingIds(self):
        self.filterRingIds=self.filterRingIdsButton.isChecked()
    
    def connectCANEnabled(self):
        return self.connectCANEnable
         
    def connectCANFailed(self):
        self.connectCANEnable=False
        self.connectCANButton.setChecked(False)
#        self.connectCANButton.setDisabled(False)
        self.connectCANButton.setIcon(self.ampelRot)

    def updateStatusBarLabel(self, text):
        self.statusbar.showMessage(text)
        logLine=self.log.addLineToLog(text)
        self.debugLogWidget.addLineToLog(logLine)
        
    def stopProgress(self):
        self.progress.setMinimum(0)
        self.progress.setMaximum(1)
        self.progress.reset()
    
    def startProgress(self):
        self.progress.setMinimum(0)
        self.progress.setMaximum(0)

#    def connectCANSuccessful(self):
#        self.connectCANEnable=True
##        self.connectCANButton.setChecked(True)
##        self.connectCANButton.setDisabled(False)
#        self.connectCANButton.setIcon(self.ampelGruen)

#    def stopCANSuccesful(self):
#        self.connectCANButton.setDisabled(False)
#        self.connectCANButton.setIcon(self.ampelRot)

    def canIdIsInKnownList(self, canId):
        return canId in self.canIdList

    def updateGPSDisplay(self, gpsData):
        self.gpsBox.update(gpsData)

    def showError(self, title, text):
        msgBox=QMessageBox(QMessageBox.Warning, title, text, QMessageBox.Ok, self)
        font = self.font()
        font.setPointSize(14)
        msgBox.setFont(font)
        msgBox.exec()
        
    def connectGPSFailed(self):
        self.connectGPSButton.setChecked(False)
        self.connectGPSEnable=False
#        self.connectGPSButton.setDisabled(False)
        self.connectGPSButton.setIcon(self.ampelRot)
        self.showError("GPS Error", "Error connecing to GPS")

#    def connectGPSSuccesful(self):
##        self.connectGPSButton.setChecked(True)
#        self.connectGPSEnable=True
##        self.connectGPSButton.setDisabled(False)
#        self.connectGPSButton.setIcon(self.ampelGruen)
        
    def connectGPSEnabled(self):
        return self.connectGPSEnable
    
#    def stopGPSSuccesful(self):
#        self.connectGPSButton.setDisabled(False)
#        self.connectGPSButton.setIcon(self.ampelRot)

    def updateCANThreadState(self, state):
        if state!=self.lastCANState:
            if state==canIdleState:
                self.connectCANButton.setIcon(self.ampelGelb)
            elif state==canRunState:
                self.connectCANButton.setIcon(self.ampelGruen)
            elif state==canStoppedState:
                self.connectCANButton.setIcon(self.ampelRot)
                self.connectCANEnable=False
            self.lastCANState=state
            
    def updateGPSThreadState(self, state):
        if state!=self.lastGPSState:
            if state==gpsRunState:
                self.connectGPSButton.setIcon(self.ampelGruen)
            elif state==gpsStoppedState:
                self.connectGPSButton.setIcon(self.ampelRot)
                self.connectGPSnable=False
            self.lastGPSState=state

    def hasOSMWidget(self):
        return self.osmWidget!=None
Example #51
0
class Ui_Form (QWidget):
    '''
    Ui class. Generated with pyuic4.
    '''
    def __init__ (self, parent=None):
        
        QWidget.__init__(self, parent)
        self.timer = QTimer (self)
        
        self.image    = QImage (720, 450, QImage.Format_RGB888)
        
        self.__engine = REngineThread ()
        self.__model  = Model ()
        self.__fsm    = DebugStateMachine (self)
    
        
    def wireEngineUp (self):
        '''
        this method connects the REngine's signals.
        '''
        self.connect (self.__engine, SIGNAL ("update (float)"), self.updateImage)
        self.connect (self.__engine, SIGNAL ("thread_completed()"), self.__fsm.finaliseRender)
        self.connect (self.__engine, SIGNAL ("inters_created (PyQt_PyObject, PyQt_PyObject)"), self.widget.addIntersection)
        self.connect (self.__engine, SIGNAL ("vector_created (PyQt_PyObject, PyQt_PyObject, QString)"), self.widget.addArrow)
        self.connect (self.__engine, SIGNAL ("line_created   (PyQt_PyObject, PyQt_PyObject, QString)"), self.widget.addLine)
    
    def wireOGLViewerUp (self):
        '''
        this method connects the REngine's signals.
        '''
        self.widget.setModel (self.__model)
        
        QObject.connect (self.widget, SIGNAL ("MatrixChanged (PyQt_PyObject)"), self.displayGLMatrix)

        # call the function run regularly when the focus is on it. (60 FPS if interval = 20)
        QObject.connect (self.timer, SIGNAL ('timeout()'), self.widget.run)
    
    def freezeGLFrameRate (self):
        
        self.timer.stop ()
    
    def speedUpGLFrameRate (self):
        
        self.timer.start ()
        self.timer.setInterval (20)
        
    def setupUi (self, Form):
        
        font = QFont ()
        font.setPointSize (9)
        font.setBold (False)
        font.setWeight (50)
        
        sizePolicy = QSizePolicy (QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch (0)
        sizePolicy.setVerticalStretch (0)
        
        Form.setObjectName (_fromUtf8("Form"))
        Form.resize (971, 930)
        self.plainTextEdit = QPlainTextEdit (Form)
        self.plainTextEdit.setGeometry (QRect (740, 280, 221, 611))
        self.plainTextEdit.setObjectName (_fromUtf8 ("plainTextEdit"))
        self.plainTextEdit.setFont (font)
        
        self.widget = OGLViewer (Form)
        self.widget.setUi_Form (self)
        self.widget.setGeometry (QRect (10, 10, 720, 450))
        sizePolicy.setHeightForWidth (self.widget.sizePolicy().hasHeightForWidth())
        self.widget.setSizePolicy (sizePolicy)
        self.widget.setObjectName (_fromUtf8 ("widget"))
        
        self.wireOGLViewerUp ()
        self.wireEngineUp ()
        
        self.label_view = QLabel (Form)
        self.label_view.setGeometry  (QRect (10, 470, 720, 450))
        sizePolicy.setHeightForWidth (self.label_view.sizePolicy().hasHeightForWidth())
        self.label_view.setSizePolicy (sizePolicy)
        self.label_view.setObjectName (_fromUtf8 ("label_view"))
        self.initLabel ()          
        self.pixmap_item = self.label_view.setPixmap (QPixmap.fromImage (self.image))
        
        # buttons definitions
        
        self.renderBtn    = QPushButton (Form)
        self.pauseBtn     = QPushButton (Form)
        self.stopBtn      = QPushButton (Form)
        self.upBtn        = QPushButton (Form)
        self.downBtn      = QPushButton (Form)
        self.moreDownBtn  = QPushButton (Form)
        self.moreUpBtn    = QPushButton (Form)
        self.rightBtn     = QPushButton (Form)
        self.moreRightBtn = QPushButton (Form)
        self.leftBtn      = QPushButton (Form)
        self.furtherLeft  = QPushButton (Form)
        self.grid_switch  = QPushButton (Form)
        
        buttons_properties_list = [[self.renderBtn,    True,  QRect (740, 140, 61, 21), "render"],
                                   [self.pauseBtn,     False, QRect (740, 120, 61, 21), "pause"],
                                   [self.stopBtn,      False, QRect (740, 100, 61, 21), "stop"],
                                   [self.upBtn,        False, QRect (820, 120, 21, 21), "one_row_up"],
                                   [self.downBtn,      False, QRect (820, 140, 21, 21), "one_row_down"],
                                   [self.moreDownBtn,  False, QRect (820, 160, 21, 21), "ten_rows_down"],
                                   [self.moreUpBtn,    False, QRect (820, 100, 21, 21), "ten_rows_up"],
                                   [self.rightBtn,     False, QRect (780, 180, 21, 21), "one_column_right"],
                                   [self.moreRightBtn, False, QRect (800, 180, 21, 21), "ten_columns_right"],
                                   [self.leftBtn,      False, QRect (760, 180, 21, 21), "one_column_left"],
                                   [self.furtherLeft,  False, QRect (740, 180, 21, 21), "ten_columns_left"],
                                   [self.grid_switch,  False, QRect (870, 230, 91, 31), "grid_switch"]]
        
        for button in buttons_properties_list:
            button[0].setEnabled  (button[1])
            button[0].setGeometry (button[2])
            button[0].setFont (font)
            button[0].setObjectName (_fromUtf8 (button[3]))
        
        # other UI elements
        
        self.progressBar = QProgressBar (Form)
        self.progressBar.setGeometry (QRect (740, 901, 221, 20))
        self.progressBar.setProperty ("value", 0)
        self.progressBar.setObjectName (_fromUtf8("progressBar"))
        self.progressBar.setMinimum (0)
        self.progressBar.setMaximum (100)
        
        self.slider_label = QLabel (Form)
        self.slider_label.setGeometry (QRect(900, 260, 61, 16))
        self.slider_label.setFont(font)
        self.slider_label.setObjectName (_fromUtf8("slider_label"))
        self.slider_label.setEnabled (True)
        
        self.arrowSizeSlider = QSlider (Form)
        self.arrowSizeSlider.setGeometry (QRect (740, 258, 151, 22))
        self.arrowSizeSlider.setMinimum (2)
        self.arrowSizeSlider.setMaximum (40)
        self.arrowSizeSlider.setSingleStep (1)
        self.arrowSizeSlider.setProperty ("value", 4)
        self.arrowSizeSlider.setOrientation (Qt.Horizontal)
        self.arrowSizeSlider.setObjectName  (_fromUtf8("arrowSizeSlider"))

        self.retranslateUi (Form)
        QMetaObject.connectSlotsByName (Form)
    
    def retranslateUi (self, Form):
        
        Form.setWindowTitle       (_translate ("Form", "RayTracing Debugging Tool", None))
        
        self.renderBtn.setText    (_translate ("Form", "Render", None))
        self.pauseBtn.setText     (_translate ("Form", "Pause",  None))
        self.stopBtn.setText      (_translate ("Form", "Stop",   None))
        self.upBtn.setText        (_translate ("Form", "^",      None))
        self.downBtn.setText      (_translate ("Form", "v",      None))
        self.moreDownBtn.setText  (_translate ("Form", "+",      None))
        self.moreUpBtn.setText    (_translate ("Form", "-",      None))
        self.rightBtn.setText     (_translate ("Form", ">",      None))
        self.moreRightBtn.setText (_translate ("Form", "+",      None))
        self.leftBtn.setText      (_translate ("Form", "<",      None))
        self.furtherLeft.setText  (_translate ("Form", "-",      None))
        
        self.grid_switch.setText  (_translate ("Form", "Grid on/off", None))
        self.slider_label.setText (_translate ("Form", "Arrows size", None))
        
        self.connect (self.renderBtn,       SIGNAL ("clicked()"),        self.__fsm.startRendering)
        self.connect (self.pauseBtn,        SIGNAL ("clicked()"),        self.__fsm.pauseRendering)
        self.connect (self.stopBtn,         SIGNAL ("clicked()"),        self.__fsm.stopRendering)
        self.connect (self.arrowSizeSlider, SIGNAL ("sliderMoved(int)"), self.resizeArrows)
    
    def initLabel (self):
        
        color = QColor (250, 250, 250)
        self.image.fill (color)
        
        '''
        # test init
        for i in range (0, 200, 20):
            for x in range (i, i+20):
                for y in range (i, i+20):
                    self.image.setPixel (x,y, qRgb (0, 0, 0))
        '''
    
    def enableUIButtons (self, boolean_dict):
        '''
        method used by the debug state machine to manage the greyed-out state of buttons.
        '''
        b_dict = dict (boolean_dict)
        
        self.renderBtn.setEnabled    (b_dict['renderBtn'])
        self.pauseBtn.setEnabled     (b_dict['pauseBtn'])
        self.stopBtn.setEnabled      (b_dict['stopBtn'])
        self.upBtn.setEnabled        (b_dict['upBtn'])
        self.downBtn.setEnabled      (b_dict['downBtn'])
        self.moreDownBtn.setEnabled  (b_dict['moreDownBtn'])
        self.moreUpBtn.setEnabled    (b_dict['moreUpBtn'])
        self.rightBtn.setEnabled     (b_dict['rightBtn'])
        self.moreRightBtn.setEnabled (b_dict['moreRightBtn'])
        self.leftBtn.setEnabled      (b_dict['leftBtn'])
        self.furtherLeft.setEnabled  (b_dict['furtherLeft'])
        
        if b_dict['progressBar'] == 'completed':
            self.progressBar.setValue (100)
        elif b_dict['progressBar'] == 'reset':
            self.progressBar.reset ()
    
    def addScreenshot (self):
        '''
        it grabs a screenshot of OpenGL viewer and add it into the QImage instance.
        '''
        self.image = self.widget.grabFrameBuffer ()
        self.pixmap_item = self.label_view.setPixmap (QPixmap.fromImage (self.image))
    
    def prepAndStartEngineUp (self):
        '''
        it preps the engine and start it up.
        '''
        self.__engine.setImage (self.image)
        self.__engine.setCameraNormalMatrix (self.widget.getNormalMatrix(), self.widget.getFovy ())
        self.__engine.setModel (self.__model)
        self.__engine.start ()
    
    def addCamera (self): self.widget.addCamera ()
    def setIsStoppedFlag (self, boo):  self.__engine.setIsStoppedFlag (boo)
    def setIsPausedFlag  (self, boo):  self.__engine.setIsPausedFlag  (boo)
    def changeRenderBtnName (self, title):  self.renderBtn.setText (_translate ("Form", title, None))
    
    # listeners  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    def resizeArrows (self, e):
        self.widget.changeArrowsSize (e*0.5)
    def updateImage (self, e):
        self.pixmap_item = self.label_view.setPixmap (QPixmap.fromImage (self.image))
        self.progressBar.setValue (int(100*e))
    def displayGLMatrix (self, e):
        '''
        this method is registered to the MatrixChanged event fired from the OGLViewer
        component. It prints the model matrix. Only for debugging purposes.
        '''
        pass
Example #52
0
class dialog_auto_prog(QDialog):

    #-----------------------------------------------------------------------
    # DEFINE THE INITIALIZATION FUNCTION.
    #-----------------------------------------------------------------------

    def __init__(self, time_strt, time_stop):

        # Inherit all attributes of an instance of "QDialog".

        super(dialog_auto_prog, self).__init__()

        # Make this a non-modal dialog (i.e., allow the user to still
        # interact with the main application window).

        self.setModal(False)

        # Set the title of this dialog window.

        self.setWindowTitle('Progress')

        # Give this widget a grid layout, "self.grd".

        self.grd = QGridLayout()

        self.grd.setContentsMargins(6, 6, 6, 6)

        self.setLayout(self.grd)

        # Initialize the progress bar and set its minimum, maximum, and
        # initial values.

        self.bar = QProgressBar()

        self.bar.setMinimum(calc_time_val(time_strt))
        self.bar.setMaximum(calc_time_val(time_stop))

        self.bar.setValue(self.bar.minimum())

        # Initialize the event button.

        self.btn_exit = event_PushButton(self, 'exit', 'Close')

        # Initialize the label.

        self.lab = QLabel('Note: closing this window will *NOT* ' +
                          'interrupt the automated analysis.')

        self.lab.setWordWrap(True)

        # Row by row, add the bar and buttons to the grid layout.

        self.grd.addWidget(self.bar, 0, 0, 1, 1)
        self.grd.addWidget(self.btn_exit, 0, 1, 1, 1)

        self.grd.addWidget(self.lab, 1, 0, 1, 2)

        # Display this dialog.

        self.show()

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR UPDATING THE PROGRESS BAR.
    #-----------------------------------------------------------------------

    def updt_bar(self, time):

        # Convert this functions argument (i.e., the timestamp of the
        # current spectrum) to Unix time.

        time_curr = calc_time_val(time)

        # If necessary, adjust the minimum or maximum of the progress
        # bar based on the new timestamp.

        if (time_curr < self.bar.minimum()):
            self.bar.setMinimum(time_curr)

        if (time_curr > self.bar.maximum()):
            self.bar.setMaximum(time_curr)

        # Update the value of the progress bar.

        self.bar.setValue(time_curr)

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESPONDING TO A USER-INITIATED EVENT.
    #-----------------------------------------------------------------------

    def user_event(self, event, fnc):

        # If the close button was pressed, close this dialog.

        if (fnc == 'exit'):

            self.close()

            return