Exemple #1
0
class GUI(QWidget):

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

        self.create_ui_components()
        self.compose_ui()

        # Initializing: window composition, it's contents and event handlers
        self.init_composition()
        self.init_contents()
        self.init_actions()

        self.on_start()

    def create_ui_components(self):
        """
        Create layouts and qt controls.
        """
        self.layout = QGridLayout()

        self.kanjiGroup = QGroupBox()
        self.kanjiLayout = QGridLayout()

        # Kanji ui group
        self.day, self.week, self.month, self.year = \
        QLabel(KANJI), QLabel(KANJI), QLabel(KANJI), QLabel(KANJI)

        self.dayLabel, self.weekLabel, self.monthLabel, self.yearLabel = \
        QLabel('<b>Day</b>'), QLabel('<b>Week</b>'), \
        QLabel('<b>Month</b>'), QLabel('<b>Year</b>')

        # Main layout
        self.showAbout = QPushButton('A&bout')
        # DB controls (top)
        self.showDB, self.availableDB, self.changeDB = \
        QPushButton('&Change DB (active:)'), QComboBox(), QPushButton('&Remap')
        # General controls (bottom)
        self.getAll, self.showStats, self.quitApp, self.authGen, self.methodCombo = \
        QPushButton('&Get all'), QPushButton('&Stats'), QPushButton('&Quit'), \
        QPushButton('&Auth'), QComboBox()
        # Notifications
        self.progressBar = QProgressBar()
        self.statusMessage = QLabel()
        # About
        self.aboutBox = QMessageBox()

    def compose_ui(self):
        """
        Fill layouts and groups, initialize filters.
        """
        self.kanjiLayout.addWidget(self.day, 0, 0)
        self.kanjiLayout.addWidget(self.week, 0, 1)
        self.kanjiLayout.addWidget(self.dayLabel, 1, 0)
        self.kanjiLayout.addWidget(self.weekLabel, 1, 1)

        self.kanjiLayout.addWidget(self.month, 2, 0)
        self.kanjiLayout.addWidget(self.year, 2, 1)
        self.kanjiLayout.addWidget(self.monthLabel, 3, 0)
        self.kanjiLayout.addWidget(self.yearLabel, 3, 1)

        self.kanjiGroup.setLayout(self.kanjiLayout)

        self.layout.addWidget(self.showDB, 0, 0, 1, 2)
        self.layout.addWidget(self.availableDB, 1, 0)
        self.layout.addWidget(self.changeDB, 1, 1)
        self.layout.addWidget(self.kanjiGroup, 2, 0, 1, 2)
        self.layout.addWidget(self.getAll, 3, 0)
        self.layout.addWidget(self.showStats, 3, 1)
        self.layout.addWidget(self.methodCombo, 4, 0)
        self.layout.addWidget(self.authGen, 4, 1)
        #self.layout.addWidget(self.quitApp, 5, 0, 1, 2)
        self.layout.addWidget(self.quitApp, 5, 0)
        self.layout.addWidget(self.showAbout, 5, 1)
        self.layout.addWidget(self.progressBar, 6, 0, 1, 2)
        self.layout.addWidget(self.statusMessage, 7, 0, 1, 2)

        self.setLayout(self.layout)

        self.eFilter = LabelEventFilter()

    def on_start(self):
        """
        Additional procedures run on application start.
        """
        # Let's initialize even some stuff!
        self.al = None
        self.auth_thread = None
        self.init_backend()

        choose_db(str(self.availableDB.currentText()))
        self.showDB.setText("&Change DB (active: %s)" % self.availableDB.currentText())

        self.stats = StatsUI(self.al, self)

    def init_composition(self):
        """
        Window composition and general params.
        """
        self.setWindowTitle(NAME + ' ' + __version__)
        desktop = QApplication.desktop()
        self.setGeometry((desktop.width() - WIDTH)/2,
                        (desktop.height() - HEIGHT)/2, WIDTH, HEIGHT)

    def init_contents(self):
        """
        Setting up qt controls.
        """
        self.changeDB.hide()
        self.availableDB.hide()
        self.availableDB.addItems(dbs.keys())

        self.kanjiGroup.setAlignment(Qt.AlignCenter)
        self.kanjiGroup.setStyleSheet("QGroupBox { border: 1px solid gray; border-radius: 3px; }")

        self.day.setAlignment(Qt.AlignCenter)
        self.week.setAlignment(Qt.AlignCenter)
        self.month.setAlignment(Qt.AlignCenter)
        self.year.setAlignment(Qt.AlignCenter)
        self.dayLabel.setAlignment(Qt.AlignCenter)
        self.weekLabel.setAlignment(Qt.AlignCenter)
        self.monthLabel.setAlignment(Qt.AlignCenter)
        self.yearLabel.setAlignment(Qt.AlignCenter)

        self.day.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.week.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.month.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.year.setFont(QFont(PRETTY_FONT, KANJI_SIZE))

        self.methodCombo.addItems(RandomMess.algs.keys())
        self.methodCombo.setCurrentIndex(1)

        self.statusMessage.setAlignment(Qt.AlignCenter)
        self.statusMessage.hide()
        self.statusMessage.setMaximumHeight(MESSAGE_HEIGHT)
        self.statusMessage.setStyleSheet(WARNING_STYLE)

        self.progressBar.setMaximum(0)
        self.progressBar.setMaximumHeight(PROGRESS_HEIGHT)
        self.progressBar.hide()

        QToolTip.setFont(QFont(PRETTY_FONT, TOOLTIP_FONT_SIZE))

        self.getAll.setToolTip('Randomly select all 4 kanji')
        self.methodCombo.setToolTip('Choose algorithm for randomness')
        self.authGen.setToolTip('Authorize on remote RNG services')
        self.showStats.setToolTip('Show/hide dialog with comprehensive statistics')
        self.quitApp.setToolTip('Close application')
        self.showDB.setToolTip('Show/hide available databases')
        self.availableDB.setToolTip('Available kanji frequency charts db')
        self.changeDB.setToolTip('Pick new kanji from currently selected db')

        # About dialog
        self.aboutBox.layout().itemAt(1).widget().setAlignment(Qt.AlignLeft)

        self.aboutBox.setTextFormat(Qt.RichText)
        self.aboutBox.setText('Version:\t<b>' + __version__ + '</b><br/>Python:\t<b>' + platform.python_version() + '</b>' +
                                '<br/>Platform:\t<b>' + platform.system() + ' ' + platform.release() + '</b>' +
                                '<br/>Author:\t<b>' + __author__ + '</b>' + app_about)
        self.aboutBox.setWindowTitle('About ' + app_name)
        self.aboutBox.setIconPixmap(QPixmap(paths['icon']))

    def init_actions(self):
        """
        Binding events/handlers.
        """
        self.showDB.clicked.connect(self.show_available_db)
        self.changeDB.clicked.connect(self.change_db)

        self.quitApp.clicked.connect(self.close)
        self.getAll.clicked.connect(self.get_all)
        self.authGen.clicked.connect(self.auth_task)
        self.showStats.clicked.connect(self.show_stats)
        self.methodCombo.currentIndexChanged.connect(self.update_alg)

        self.showAbout.clicked.connect(self.app_help)

        # Mouse events for labels
        self.day.setAttribute(Qt.WA_Hover, True)
        self.week.setAttribute(Qt.WA_Hover, True)
        self.month.setAttribute(Qt.WA_Hover, True)
        self.year.setAttribute(Qt.WA_Hover, True)
        self.day.installEventFilter(self.eFilter)
        self.week.installEventFilter(self.eFilter)
        self.month.installEventFilter(self.eFilter)
        self.year.installEventFilter(self.eFilter)

    ##### actions #####

    def show_stats(self):
        if self.stats.isVisible():
            self.stats.hide()
        else:
            self.stats.show()

    def show_available_db(self):
        if self.availableDB.isVisible():
            self.availableDB.hide()
            self.changeDB.hide()
        else:
            self.availableDB.show()
            self.changeDB.show()

    def change_db(self):
        try:
            choose_db(str(self.availableDB.currentText()))
            self.availableDB.hide()
            self.changeDB.hide()
            self.show_message_then_hide("DB successfully remaped!", False)
            self.showDB.setText("&Change DB (active: %s)" % self.availableDB.currentText())

            self.stats.update_stat_info()
            self.stats.refresh_plot()
        except NoDbException as e:
            self.show_message_then_hide(e.message)

    def get_all(self):
        self.random_kanji_task = RandomKanjiTask(self.al)
        self.random_kanji_task.done.connect(self.update_kanji)
        self.show_progress('Selecting kanji...')
        self.random_kanji_task.start()

    def update_kanji(self, results):
        if results['success']:
            kanji_set = results['kanji_set']
            for_a_day = kanji_set.pop()
            for_a_week = kanji_set.pop()
            for_a_month = kanji_set.pop()
            for_a_year = kanji_set.pop()

            self.day.setText(for_a_day.character)
            self.dayLabel.setText('<b>Day:</b> ' + str(for_a_day.frequency) + ' | '
                                        + str(for_a_day.dominance) + '%')
            self.week.setText(for_a_week.character)
            self.weekLabel.setText('<b>Week:</b> ' + str(for_a_week.frequency) + ' | '
                                        + str(for_a_week.dominance) + '%')
            self.month.setText(for_a_month.character)
            self.monthLabel.setText('<b>Month:</b> ' + str(for_a_month.frequency) + ' | '
                                        + str(for_a_month.dominance) + '%')
            self.year.setText(for_a_year.character)
            self.yearLabel.setText('<b>Year:</b> ' + str(for_a_year.frequency) + ' | '
                                        + str(for_a_year.dominance) + '%')

            self.kanji_tooltip(self.day)
            self.kanji_tooltip(self.week)
            self.kanji_tooltip(self.month)
            self.kanji_tooltip(self.year)

            if self.stats.isVisible():
                self.stats.update_stat_info()
                self.stats.refresh_plot()

            self.hide_message()
        else:
            self.show_message_then_hide(results['message'])

        self.hide_progress()

    def pretty_font(self):
        pass

    def update_alg(self):
        self.al.set_active(str(self.methodCombo.currentText()))

    def init_backend(self):
        self.al = RandomMess()
        self.update_alg()

    def auth_task(self):
        self.auth_thread = AuthorizationTask(self.al)
        self.auth_thread.done.connect(self.auth_complete)
        #self.auth_thread.run()
        # IT DOESN't work on windows as it should!
        self.auth_thread.start()
        self.show_progress('Authorizing on RNG services...')

    def auth_complete(self, success):
        self.hide_message()
        self.hide_progress()
        if success:
            self.show_message_then_hide("Successfully authenticated!", False)
        else:
            self.show_message_then_hide("Sorry, could not authenticate.")

    def show_message_then_hide(self, message, error=True):
        if error:
            self.statusMessage.setStyleSheet(WARNING_STYLE)
        else:
            self.statusMessage.setStyleSheet(NOTE_STYLE)

        self.statusMessage.setText(message)
        self.statusMessage.show()
        QTimer.singleShot(MESSAGE_TIMEOUT, self.hide_message)

    def show_progress(self, message):
        self.statusMessage.setStyleSheet(NOTE_STYLE)
        self.statusMessage.setText(message)
        self.statusMessage.show()
        self.progressBar.show()

    def hide_message(self):
        self.statusMessage.setText('')
        self.statusMessage.hide()

    def hide_progress(self):
        self.progressBar.hide()

    def toggle_kanji_info(self, label, info):
        label.setToolTip(info.info())

    def kanji_tooltip(self, label):
        found = JDIC.search(label.text())
        if found:
            label.setToolTip(found.info())
        else:
            label.setToolTip('No such kanji in kanjidic2!')

    def kanji_info(self, kanji):
        pass

    def app_help(self):
        self.aboutBox.show()

        #### Utility events ####

    def resizeEvent(self, QResizeEvent):
        self.updateStatsPosition()
        self.updateStatsSize()

    def moveEvent(self, QMoveEvent):
        self.updateStatsPosition()
        self.updateStatsSize()

    def updateStatsPosition(self):
        self.stats.move(self.x() + self.width() + 20, self.y())

    def updateStatsSize(self):
        self.stats.resize(QSize(self.stats.width(), self.height()))
Exemple #2
0
Fichier : scj.py Projet : Ptaah/SCJ
class SCJProgress(QHBoxLayout):
    def __init__(self, parent=None, file=None, format=None, createDir=False ):
        super(SCJProgress, self).__init__(parent)
        self.format = format
        self.filename = file
        self.createDir = createDir
        self.process = SCJ(self.filename, self.format, createDir)
        self.output = QString(self.process.output)
        self.command = QStringList(self.process.command)
        self.log = QStringList()

        self.label = QLabel(self.output)
        self.label.setToolTip(self.trUtf8("Destination: %s" % self.output))
        self.bar = QProgressBar(parent)
        self.bar.setToolTip(self.trUtf8("Source: %s" % self.filename))
        self.bar.setValue(0)
        self.startbtn = QPushButton(parent) 
        self.stopbtn = QPushButton(parent)
        self.cancelbtn = QPushButton(parent)
        self.logbtn = QPushButton(parent)
        self.cancelbtn.setMinimumSize(32,32)
        self.cancelbtn.setFlat(True)
        self.startbtn.setMinimumSize(32,32)
        self.startbtn.setFlat(True)
        self.stopbtn.setMinimumSize(32,32)
        self.stopbtn.setFlat(True)
        self.label.setMinimumSize(200,32)
        self.bar.setMinimumSize(100,16)
        self.bar.setMaximumHeight(16)

        self.addWidget(self.logbtn)
        self.logbtn.hide()
        self.addWidget(self.label)
        self.addWidget(self.bar)
        self.addWidget(self.startbtn)
        self.addWidget(self.stopbtn)
        self.addWidget(self.cancelbtn)
        self.retranslateUi()

        self.connect(self.startbtn, SIGNAL("clicked()"), self.start)
        self.connect(self.stopbtn, SIGNAL("clicked()"),  self.stop)
        self.connect(self.cancelbtn, SIGNAL("clicked()"), self.remove)
        self.connect(self.logbtn, SIGNAL('clicked()'), self.showLog)
        self.connect(self.process, SIGNAL('progress(int)'), self.bar.setValue)
        self.connect(self.process, SIGNAL('error(QString)'), self.addLog)
        self.connect(self.process, SIGNAL('finished()'), self.enable)

    def retranslateUi(self):
        self.startbtn.setIcon(QIcon(u"images/play.png"))
        self.startbtn.setToolTip(self.trUtf8("Demarrer"))
        self.stopbtn.setIcon(QIcon(u"images/stop.png"))
        self.stopbtn.setToolTip(self.trUtf8("Stopper"))
        self.cancelbtn.setIcon(QIcon(u"images/remove.png"))
        self.cancelbtn.setToolTip(self.trUtf8("Annuler"))
        self.logbtn.setIcon(QIcon(u"images/log.png"))
        self.logbtn.setToolTip(self.trUtf8("Voir les details"))

    def start(self):
        self.log.clear()
        self.logbtn.hide()
        self.disable()
        self.process.start()
        self.process.resume()

    def stop(self):
        self.process.cancel()
        self.process.terminate()
        self.enable()

    def remove(self):
        self.removeWidget(self.label)
        self.removeWidget(self.bar)
        self.removeWidget(self.startbtn)
        self.removeWidget(self.stopbtn)
        self.removeWidget(self.cancelbtn)
        self.removeWidget(self.logbtn)
        self.label.hide()
        self.bar.hide()
        self.startbtn.hide()
        self.stopbtn.hide()
        self.cancelbtn.hide()
        self.logbtn.hide()
        self.emit(SIGNAL("void removed(QString)"), self.output)

    def showLog(self):
        QMessageBox.critical(None, u"Ooops", self.log.join("\n"))

    def addLog(self, log):
        self.log.append(log)
        self.logbtn.show()
        palette = QPalette()
        brush = QBrush(QColor(240, 100, 100))
        brush.setStyle(Qt.SolidPattern)
        palette.setBrush(QPalette.Normal, QPalette.Background, brush)
        self.label.setPalette(palette)
        self.label.setAutoFillBackground(True)

    def enable(self):
        self.process = SCJ(self.filename, self.format, self.createDir)
        self.output = QString(self.process.output)
        self.command = QStringList(self.process.output)
        self.connect(self.process, SIGNAL('progress(int)'), self.bar.setValue)
        self.connect(self.process, SIGNAL('error(QString)'), self.addLog)
        self.connect(self.process, SIGNAL('finished()'), self.enable)
        self.cancelbtn.setEnabled(True)
        self.startbtn.setEnabled(True)

    def disable(self):
        self.cancelbtn.setEnabled(False)
        self.startbtn.setEnabled(False)
        self.label.setAutoFillBackground(False)
Exemple #3
0
class OrbitCorrGeneral(QtGui.QWidget):
    """
    A general orbit correction or local bump panel.
    """
    def __init__(self, bpms, cors, parent = None):
        super(OrbitCorrGeneral, self).__init__(parent)

        self.bpms, self.cors = bpms, cors
        self.sb = [bpm.sb for bpm in self.bpms]
        self.x0, self.y0 = None, None
        self._update_current_orbit()

        self.table = QTableWidget(len(self.bpms), 9)
        self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        hdview = QHeaderView(Qt.Horizontal)
        self.table.setHorizontalHeaderLabels(
            ['BPM Name', 's', "Beta X", "Beta Y",
             "Eta X", 'X Bump', 'Y Bump', "Target X", "Target Y"])
        self._twiss = getTwiss([b.name for b in self.bpms],
                               ["s", "betax", "betay", "etax"])
        for i,bpm in enumerate(self.bpms):
            it = QTableWidgetItem(bpm.name)
            it.setFlags(it.flags() & (~Qt.ItemIsEditable))
            self.table.setItem(i, 0, it)

            it = QTableWidgetItem(str(bpm.sb))
            it.setFlags(it.flags() & (~Qt.ItemIsEditable))
            #it.setMinimumWidth(80)
            self.table.setItem(i, 1, it)
            self.table.setItem(i, 2,
                               QTableWidgetItem("%.4f" % self._twiss[i,1]))
            self.table.setItem(i, 3,
                               QTableWidgetItem("%.4f" % self._twiss[i,2]))
            self.table.setItem(i, 4,
                               QTableWidgetItem("%.4f" % self._twiss[i,3]))

            for j in range(5, 9):
                it = QTableWidgetItem(str(0.0))
                it.setData(Qt.DisplayRole, str(0.0))
                it.setFlags(it.flags() | Qt.ItemIsEditable)
                self.table.setItem(i, j, it)
            # use the current orbit
            #self.table.item(i,4).setData(Qt.DisplayRole, str(self.x0[i]))
            #self.table.item(i,5).setData(Qt.DisplayRole, str(self.y0[i]))

        #self.connect(self.table, SIGNAL("cellClicked(int, int)"),
        #             self._cell_clicked)
        self.table.resizeColumnsToContents()
        #self.table.horizontalHeader().setStretchLastSection(True)
        #for i in range(4):
        #    print "width", i, self.table.columnWidth(i)
        #self.table.setColumnWidth(0, 300)
        self.table.setColumnWidth(1, 80)

        vbox1 = QtGui.QVBoxLayout()
        frmbox = QFormLayout()
        self.base_orbit_box = QtGui.QComboBox()
        #self.base_orbit_box.addItems([
        #        "Current Orbit", "All Zeros"])
        self.base_orbit_box.addItems(["All Zeros", "Current Orbit"])
        frmbox.addRow("Orbit Base", self.base_orbit_box)
        grp = QtGui.QGroupBox("Local Bump")
        grp.setLayout(frmbox)
        vbox1.addWidget(grp)

        frmbox = QFormLayout()
        hln1 = QtGui.QFrame()
        hln1.setLineWidth(3)
        hln1.setFrameStyle(QtGui.QFrame.Sunken)
        hln1.setFrameShape(QtGui.QFrame.HLine)
        frmbox.addRow(hln1)
        self.repeatbox = QSpinBox()
        self.repeatbox.setRange(1, 20)
        self.repeatbox.setValue(3)
        # or connect the returnPressed() signal
        frmbox.addRow("&Repeat correction", self.repeatbox)

        self.rcondbox = QLineEdit()
        self.rcondbox.setValidator(QDoubleValidator(0, 1, 0, self))
        self.rcondbox.setText("1e-2")
        frmbox.addRow("r&cond for SVD", self.rcondbox)

        self.scalebox = QDoubleSpinBox()
        self.scalebox.setRange(0.01, 5.00)
        self.scalebox.setSingleStep(0.01)
        self.scalebox.setValue(0.68)
        frmbox.addRow("&Scale correctors", self.scalebox)

        #hln2 = QtGui.QFrame()
        #hln2.setLineWidth(3)
        #hln2.setFrameStyle(QtGui.QFrame.Sunken)
        #hln2.setFrameShape(QtGui.QFrame.HLine)
        #frmbox.addRow(hln2)

        self.progress = QProgressBar()
        self.progress.setMaximum(self.repeatbox.value())
        self.progress.setMaximumHeight(15)
        frmbox.addRow("Progress", self.progress)
        grp = QtGui.QGroupBox("Correction")
        grp.setLayout(frmbox)
        vbox1.addWidget(grp)

        #vbox.addStretch(1.0)
        #self.qdb = QDialogButtonBox(self)
        #self.qdb.addButton("APP", QDialogButtonBox.ApplyRole)
        #self.qdb.addButton("R", QDialogButtonBox.ResetRole)
        #btn.setDefault(True)
        #self.qdb.addButton(QDialogButtonBox.Cancel)
        #self.qdb.addButton(QDialogButtonBox.Help)

        gbox = QtGui.QGridLayout()
        btn = QPushButton("Clear")
        self.connect(btn, SIGNAL("clicked()"), self.resetBumps)
        gbox.addWidget(btn, 0, 1)
        self.correctOrbitBtn = QPushButton("Apply")
        #self.correctOrbitBtn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.correctOrbitBtn.setStyleSheet("QPushButton:disabled { color: gray }");
        self.connect(self.correctOrbitBtn, SIGNAL("clicked()"), self.call_apply)
        self.correctOrbitBtn.setDefault(True)
        gbox.addWidget(self.correctOrbitBtn, 1, 1)
        gbox.setColumnStretch(0, 1)

        vbox1.addStretch()
        vbox1.addLayout(gbox)

        hbox1 = QtGui.QHBoxLayout()
        hbox1.addWidget(self.table, 2)
        hbox1.addLayout(vbox1, 0)
        self.setLayout(hbox1)

        self.connect(self.base_orbit_box,
                     SIGNAL("currentIndexChanged(QString)"),
                     self.updateTargetOrbit)
        self.connect(self.repeatbox, SIGNAL("valueChanged(int)"),
                     self.progress.setMaximum)
        self.connect(self.table, SIGNAL("cellChanged (int, int)"),
                     self.updateBump)

        #self.updateTargetOrbit(self.base_orbit_box.currentText())

    def _update_current_orbit(self):
        pvx = [bpm.pv(field="x", handle="readback")[0] for bpm in self.bpms]
        pvy = [bpm.pv(field="y", handle="readback")[0] for bpm in self.bpms]
        self.x0 = [float(v) if v.ok else np.nan for v in catools.caget(pvx)]
        self.y0 = [float(v) if v.ok else np.nan for v in catools.caget(pvy)]

    def resetBumps(self):
        jx0, jy0 = 5, 6
        for i in range(self.table.rowCount()):
            self.table.item(i, jx0).setData(Qt.DisplayRole, str(0.0))
            self.table.item(i, jy0).setData(Qt.DisplayRole, str(0.0))
        #self.updateTargetOrbit(self.base_orbit_box.currentText())

    def call_apply(self):
        #print "apply the orbit"
        obt = []
        jx, jy = 7, 8
        for i in range(self.table.rowCount()):
            x1,err = self.table.item(i, jx).data(Qt.DisplayRole).toFloat()
            y1,err = self.table.item(i, jy).data(Qt.DisplayRole).toFloat()
            obt.append([x1, y1])

        self.correctOrbitBtn.setEnabled(False)
        nrepeat = self.repeatbox.value()
        kw = { "scale": float(self.scalebox.text()),
               "rcond": float(self.rcondbox.text()) }
        self.progress.setValue(0)
        QApplication.processEvents()
        for i in range(nrepeat):
            err, msg = setLocalBump(self.bpms, self.cors, obt, **kw)
            self.progress.setValue(i+1)
            QApplication.processEvents()
            if err != 0:
                QtGui.QMessageBox.critical(
                    self, "Local Orbit Bump",
                    "ERROR: {0}\nAbort.".format(msg),
                    QtGui.QMessageBox.Ok)
                #self.progress.setValue(0)
                break

        self.correctOrbitBtn.setEnabled(True)

    def getTargetOrbit(self):
        x = [self.table.item(i,7).data(Qt.DisplayRole).toFloat()[0]
             for i in range(self.table.rowCount())]
        y = [self.table.item(i,8).data(Qt.DisplayRole).toFloat()[0]
             for i in range(self.table.rowCount())]
        return (self.sb, x), (self.sb, y)

    def updateTargetOrbit(self, baseobt):
        if baseobt == "All Zeros":
            jx0, jx1 = 5, 7
            jy0, jy1 = 6, 8
            for i in range(self.table.rowCount()):
                it0 = self.table.item(i, jx0)
                it1 = self.table.item(i, jx1)
                it1.setData(Qt.DisplayRole, it0.data(Qt.DisplayRole))
                it0 = self.table.item(i, jy0)
                it1 = self.table.item(i, jy1)
                it1.setData(Qt.DisplayRole, it0.data(Qt.DisplayRole))
        elif baseobt == "Current Orbit":
            self._update_current_orbit()
            jx0, jx1 = 5, 7
            jy0, jy1 = 6, 8
            for i in range(self.table.rowCount()):
                dx0,err = self.table.item(i, jx0).data(Qt.DisplayRole).toFloat()
                it = self.table.item(i, jx1)
                it.setData(Qt.DisplayRole, self.x0[i] + dx0)

                dy0,err = self.table.item(i, jy0).data(Qt.DisplayRole).toFloat()
                it = self.table.item(i, jy1)
                it.setData(Qt.DisplayRole, self.y0[i] + dy0)
        #self._update_orbit_plot()
        x, y = self.getTargetOrbit()
        self.emit(SIGNAL("targetOrbitChanged(PyQt_PyObject, PyQt_PyObject)"),
                  x, y)

    def updateBump(self, row, col):
        #print "updating ", row, col
        if col == 5 or col == 6:
            self.updateTargetOrbit(self.base_orbit_box.currentText())
Exemple #4
0
class GUI(QWidget):
    def __init__(self, parent=None):
        super(GUI, self).__init__(parent)

        self.create_ui_components()
        self.compose_ui()

        # Initializing: window composition, it's contents and event handlers
        self.init_composition()
        self.init_contents()
        self.init_actions()

        self.on_start()

    def create_ui_components(self):
        """
        Create layouts and qt controls.
        """
        self.layout = QGridLayout()

        self.kanjiGroup = QGroupBox()
        self.kanjiLayout = QGridLayout()

        # Kanji ui group
        self.day, self.week, self.month, self.year = \
        QLabel(KANJI), QLabel(KANJI), QLabel(KANJI), QLabel(KANJI)

        self.dayLabel, self.weekLabel, self.monthLabel, self.yearLabel = \
        QLabel('<b>Day</b>'), QLabel('<b>Week</b>'), \
        QLabel('<b>Month</b>'), QLabel('<b>Year</b>')

        # Main layout
        self.showAbout = QPushButton('A&bout')
        # DB controls (top)
        self.showDB, self.availableDB, self.changeDB = \
        QPushButton('&Change DB (active:)'), QComboBox(), QPushButton('&Remap')
        # General controls (bottom)
        self.getAll, self.showStats, self.quitApp, self.authGen, self.methodCombo = \
        QPushButton('&Get all'), QPushButton('&Stats'), QPushButton('&Quit'), \
        QPushButton('&Auth'), QComboBox()
        # Notifications
        self.progressBar = QProgressBar()
        self.statusMessage = QLabel()
        # About
        self.aboutBox = QMessageBox()

    def compose_ui(self):
        """
        Fill layouts and groups, initialize filters.
        """
        self.kanjiLayout.addWidget(self.day, 0, 0)
        self.kanjiLayout.addWidget(self.week, 0, 1)
        self.kanjiLayout.addWidget(self.dayLabel, 1, 0)
        self.kanjiLayout.addWidget(self.weekLabel, 1, 1)

        self.kanjiLayout.addWidget(self.month, 2, 0)
        self.kanjiLayout.addWidget(self.year, 2, 1)
        self.kanjiLayout.addWidget(self.monthLabel, 3, 0)
        self.kanjiLayout.addWidget(self.yearLabel, 3, 1)

        self.kanjiGroup.setLayout(self.kanjiLayout)

        self.layout.addWidget(self.showDB, 0, 0, 1, 2)
        self.layout.addWidget(self.availableDB, 1, 0)
        self.layout.addWidget(self.changeDB, 1, 1)
        self.layout.addWidget(self.kanjiGroup, 2, 0, 1, 2)
        self.layout.addWidget(self.getAll, 3, 0)
        self.layout.addWidget(self.showStats, 3, 1)
        self.layout.addWidget(self.methodCombo, 4, 0)
        self.layout.addWidget(self.authGen, 4, 1)
        #self.layout.addWidget(self.quitApp, 5, 0, 1, 2)
        self.layout.addWidget(self.quitApp, 5, 0)
        self.layout.addWidget(self.showAbout, 5, 1)
        self.layout.addWidget(self.progressBar, 6, 0, 1, 2)
        self.layout.addWidget(self.statusMessage, 7, 0, 1, 2)

        self.setLayout(self.layout)

        self.eFilter = LabelEventFilter()

    def on_start(self):
        """
        Additional procedures run on application start.
        """
        # Let's initialize even some stuff!
        self.al = None
        self.auth_thread = None
        self.init_backend()

        choose_db(str(self.availableDB.currentText()))
        self.showDB.setText("&Change DB (active: %s)" %
                            self.availableDB.currentText())

        self.stats = StatsUI(self.al, self)

    def init_composition(self):
        """
        Window composition and general params.
        """
        self.setWindowTitle(NAME + ' ' + __version__)
        desktop = QApplication.desktop()
        self.setGeometry((desktop.width() - WIDTH) / 2,
                         (desktop.height() - HEIGHT) / 2, WIDTH, HEIGHT)

    def init_contents(self):
        """
        Setting up qt controls.
        """
        self.changeDB.hide()
        self.availableDB.hide()
        self.availableDB.addItems(dbs.keys())

        self.kanjiGroup.setAlignment(Qt.AlignCenter)
        self.kanjiGroup.setStyleSheet(
            "QGroupBox { border: 1px solid gray; border-radius: 3px; }")

        self.day.setAlignment(Qt.AlignCenter)
        self.week.setAlignment(Qt.AlignCenter)
        self.month.setAlignment(Qt.AlignCenter)
        self.year.setAlignment(Qt.AlignCenter)
        self.dayLabel.setAlignment(Qt.AlignCenter)
        self.weekLabel.setAlignment(Qt.AlignCenter)
        self.monthLabel.setAlignment(Qt.AlignCenter)
        self.yearLabel.setAlignment(Qt.AlignCenter)

        self.day.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.week.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.month.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.year.setFont(QFont(PRETTY_FONT, KANJI_SIZE))

        self.methodCombo.addItems(RandomMess.algs.keys())
        self.methodCombo.setCurrentIndex(1)

        self.statusMessage.setAlignment(Qt.AlignCenter)
        self.statusMessage.hide()
        self.statusMessage.setMaximumHeight(MESSAGE_HEIGHT)
        self.statusMessage.setStyleSheet(WARNING_STYLE)

        self.progressBar.setMaximum(0)
        self.progressBar.setMaximumHeight(PROGRESS_HEIGHT)
        self.progressBar.hide()

        QToolTip.setFont(QFont(PRETTY_FONT, TOOLTIP_FONT_SIZE))

        self.getAll.setToolTip('Randomly select all 4 kanji')
        self.methodCombo.setToolTip('Choose algorithm for randomness')
        self.authGen.setToolTip('Authorize on remote RNG services')
        self.showStats.setToolTip(
            'Show/hide dialog with comprehensive statistics')
        self.quitApp.setToolTip('Close application')
        self.showDB.setToolTip('Show/hide available databases')
        self.availableDB.setToolTip('Available kanji frequency charts db')
        self.changeDB.setToolTip('Pick new kanji from currently selected db')

        # About dialog
        self.aboutBox.layout().itemAt(1).widget().setAlignment(Qt.AlignLeft)

        self.aboutBox.setTextFormat(Qt.RichText)
        self.aboutBox.setText('Version:\t<b>' + __version__ +
                              '</b><br/>Python:\t<b>' +
                              platform.python_version() + '</b>' +
                              '<br/>Platform:\t<b>' + platform.system() + ' ' +
                              platform.release() + '</b>' +
                              '<br/>Author:\t<b>' + __author__ + '</b>' +
                              app_about)
        self.aboutBox.setWindowTitle('About ' + app_name)
        self.aboutBox.setIconPixmap(QPixmap(paths['icon']))

    def init_actions(self):
        """
        Binding events/handlers.
        """
        self.showDB.clicked.connect(self.show_available_db)
        self.changeDB.clicked.connect(self.change_db)

        self.quitApp.clicked.connect(self.close)
        self.getAll.clicked.connect(self.get_all)
        self.authGen.clicked.connect(self.auth_task)
        self.showStats.clicked.connect(self.show_stats)
        self.methodCombo.currentIndexChanged.connect(self.update_alg)

        self.showAbout.clicked.connect(self.app_help)

        # Mouse events for labels
        self.day.setAttribute(Qt.WA_Hover, True)
        self.week.setAttribute(Qt.WA_Hover, True)
        self.month.setAttribute(Qt.WA_Hover, True)
        self.year.setAttribute(Qt.WA_Hover, True)
        self.day.installEventFilter(self.eFilter)
        self.week.installEventFilter(self.eFilter)
        self.month.installEventFilter(self.eFilter)
        self.year.installEventFilter(self.eFilter)

    ##### actions #####

    def show_stats(self):
        if self.stats.isVisible():
            self.stats.hide()
        else:
            self.stats.show()

    def show_available_db(self):
        if self.availableDB.isVisible():
            self.availableDB.hide()
            self.changeDB.hide()
        else:
            self.availableDB.show()
            self.changeDB.show()

    def change_db(self):
        try:
            choose_db(str(self.availableDB.currentText()))
            self.availableDB.hide()
            self.changeDB.hide()
            self.show_message_then_hide("DB successfully remaped!", False)
            self.showDB.setText("&Change DB (active: %s)" %
                                self.availableDB.currentText())

            self.stats.update_stat_info()
            self.stats.refresh_plot()
        except NoDbException as e:
            self.show_message_then_hide(e.message)

    def get_all(self):
        self.random_kanji_task = RandomKanjiTask(self.al)
        self.random_kanji_task.done.connect(self.update_kanji)
        self.show_progress('Selecting kanji...')
        self.random_kanji_task.start()

    def update_kanji(self, results):
        if results['success']:
            kanji_set = results['kanji_set']
            for_a_day = kanji_set.pop()
            for_a_week = kanji_set.pop()
            for_a_month = kanji_set.pop()
            for_a_year = kanji_set.pop()

            self.day.setText(for_a_day.character)
            self.dayLabel.setText('<b>Day:</b> ' + str(for_a_day.frequency) +
                                  ' | ' + str(for_a_day.dominance) + '%')
            self.week.setText(for_a_week.character)
            self.weekLabel.setText('<b>Week:</b> ' +
                                   str(for_a_week.frequency) + ' | ' +
                                   str(for_a_week.dominance) + '%')
            self.month.setText(for_a_month.character)
            self.monthLabel.setText('<b>Month:</b> ' +
                                    str(for_a_month.frequency) + ' | ' +
                                    str(for_a_month.dominance) + '%')
            self.year.setText(for_a_year.character)
            self.yearLabel.setText('<b>Year:</b> ' +
                                   str(for_a_year.frequency) + ' | ' +
                                   str(for_a_year.dominance) + '%')

            self.kanji_tooltip(self.day)
            self.kanji_tooltip(self.week)
            self.kanji_tooltip(self.month)
            self.kanji_tooltip(self.year)

            if self.stats.isVisible():
                self.stats.update_stat_info()
                self.stats.refresh_plot()

            self.hide_message()
        else:
            self.show_message_then_hide(results['message'])

        self.hide_progress()

    def pretty_font(self):
        pass

    def update_alg(self):
        self.al.set_active(str(self.methodCombo.currentText()))

    def init_backend(self):
        self.al = RandomMess()
        self.update_alg()

    def auth_task(self):
        self.auth_thread = AuthorizationTask(self.al)
        self.auth_thread.done.connect(self.auth_complete)
        #self.auth_thread.run()
        # IT DOESN't work on windows as it should!
        self.auth_thread.start()
        self.show_progress('Authorizing on RNG services...')

    def auth_complete(self, success):
        self.hide_message()
        self.hide_progress()
        if success:
            self.show_message_then_hide("Successfully authenticated!", False)
        else:
            self.show_message_then_hide("Sorry, could not authenticate.")

    def show_message_then_hide(self, message, error=True):
        if error:
            self.statusMessage.setStyleSheet(WARNING_STYLE)
        else:
            self.statusMessage.setStyleSheet(NOTE_STYLE)

        self.statusMessage.setText(message)
        self.statusMessage.show()
        QTimer.singleShot(MESSAGE_TIMEOUT, self.hide_message)

    def show_progress(self, message):
        self.statusMessage.setStyleSheet(NOTE_STYLE)
        self.statusMessage.setText(message)
        self.statusMessage.show()
        self.progressBar.show()

    def hide_message(self):
        self.statusMessage.setText('')
        self.statusMessage.hide()

    def hide_progress(self):
        self.progressBar.hide()

    def toggle_kanji_info(self, label, info):
        label.setToolTip(info.info())

    def kanji_tooltip(self, label):
        found = JDIC.search(label.text())
        if found:
            label.setToolTip(found.info())
        else:
            label.setToolTip('No such kanji in kanjidic2!')

    def kanji_info(self, kanji):
        pass

    def app_help(self):
        self.aboutBox.show()

        #### Utility events ####

    def resizeEvent(self, QResizeEvent):
        self.updateStatsPosition()
        self.updateStatsSize()

    def moveEvent(self, QMoveEvent):
        self.updateStatsPosition()
        self.updateStatsSize()

    def updateStatsPosition(self):
        self.stats.move(self.x() + self.width() + 20, self.y())

    def updateStatsSize(self):
        self.stats.resize(QSize(self.stats.width(), self.height()))
Exemple #5
0
class OrbitCorrGeneral(QtGui.QWidget):
    """
    A general orbit correction or local bump panel.
    """
    def __init__(self, bpms, cors, parent = None):
        super(OrbitCorrGeneral, self).__init__(parent)

        self.bpms, self.cors = bpms, cors
        self.sb = [bpm.sb for bpm in self.bpms]
        self.x0, self.y0 = None, None
        self._update_current_orbit()

        self.table = QTableWidget(len(self.bpms), 9)
        self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        hdview = QHeaderView(Qt.Horizontal)
        self.table.setHorizontalHeaderLabels(
            ['BPM Name', 's', "Beta X", "Beta Y",
             "Eta X", 'X Bump', 'Y Bump', "Target X", "Target Y"])
        self._twiss = getTwiss([b.name for b in self.bpms],
                               ["s", "betax", "betay", "etax"])
        for i,bpm in enumerate(self.bpms):
            it = QTableWidgetItem(bpm.name)
            it.setFlags(it.flags() & (~Qt.ItemIsEditable))
            self.table.setItem(i, 0, it)

            it = QTableWidgetItem(str(bpm.sb))
            it.setFlags(it.flags() & (~Qt.ItemIsEditable))
            #it.setMinimumWidth(80)
            self.table.setItem(i, 1, it)
            self.table.setItem(i, 2,
                               QTableWidgetItem("%.4f" % self._twiss[i,1]))
            self.table.setItem(i, 3,
                               QTableWidgetItem("%.4f" % self._twiss[i,2]))
            self.table.setItem(i, 4,
                               QTableWidgetItem("%.4f" % self._twiss[i,3]))

            for j in range(5, 9):
                it = QTableWidgetItem(str(0.0))
                it.setData(Qt.DisplayRole, str(0.0))
                it.setFlags(it.flags() | Qt.ItemIsEditable)
                self.table.setItem(i, j, it) 
            # use the current orbit 
            #self.table.item(i,4).setData(Qt.DisplayRole, str(self.x0[i]))
            #self.table.item(i,5).setData(Qt.DisplayRole, str(self.y0[i]))

        #self.connect(self.table, SIGNAL("cellClicked(int, int)"),
        #             self._cell_clicked)
        self.table.resizeColumnsToContents()
        #self.table.horizontalHeader().setStretchLastSection(True)
        #for i in range(4):
        #    print "width", i, self.table.columnWidth(i)
        #self.table.setColumnWidth(0, 300)
        self.table.setColumnWidth(1, 80)

        vbox1 = QtGui.QVBoxLayout()
        frmbox = QFormLayout()
        self.base_orbit_box = QtGui.QComboBox()
        #self.base_orbit_box.addItems([
        #        "Current Orbit", "All Zeros"])
        self.base_orbit_box.addItems(["All Zeros", "Current Orbit"])
        frmbox.addRow("Orbit Base", self.base_orbit_box)
        grp = QtGui.QGroupBox("Local Bump")
        grp.setLayout(frmbox)
        vbox1.addWidget(grp)

        frmbox = QFormLayout()
        hln1 = QtGui.QFrame()
        hln1.setLineWidth(3)
        hln1.setFrameStyle(QtGui.QFrame.Sunken)
        hln1.setFrameShape(QtGui.QFrame.HLine)
        frmbox.addRow(hln1)
        self.repeatbox = QSpinBox()
        self.repeatbox.setRange(1, 20)
        self.repeatbox.setValue(3)
        # or connect the returnPressed() signal
        frmbox.addRow("&Repeat correction", self.repeatbox)

        self.rcondbox = QLineEdit()
        self.rcondbox.setValidator(QDoubleValidator(0, 1, 0, self))
        self.rcondbox.setText("1e-2")
        frmbox.addRow("r&cond for SVD", self.rcondbox)

        self.scalebox = QDoubleSpinBox()
        self.scalebox.setRange(0.01, 5.00)
        self.scalebox.setSingleStep(0.01)
        self.scalebox.setValue(0.68)
        frmbox.addRow("&Scale correctors", self.scalebox)

        #hln2 = QtGui.QFrame()
        #hln2.setLineWidth(3)
        #hln2.setFrameStyle(QtGui.QFrame.Sunken)
        #hln2.setFrameShape(QtGui.QFrame.HLine)
        #frmbox.addRow(hln2)

        self.progress = QProgressBar()
        self.progress.setMaximum(self.repeatbox.value())
        self.progress.setMaximumHeight(15)
        frmbox.addRow("Progress", self.progress)
        grp = QtGui.QGroupBox("Correction")
        grp.setLayout(frmbox)
        vbox1.addWidget(grp)

        #vbox.addStretch(1.0)
        #self.qdb = QDialogButtonBox(self)
        #self.qdb.addButton("APP", QDialogButtonBox.ApplyRole)
        #self.qdb.addButton("R", QDialogButtonBox.ResetRole)
        #btn.setDefault(True)
        #self.qdb.addButton(QDialogButtonBox.Cancel)
        #self.qdb.addButton(QDialogButtonBox.Help)

        gbox = QtGui.QGridLayout()
        btn = QPushButton("Clear")
        self.connect(btn, SIGNAL("clicked()"), self.resetBumps)
        gbox.addWidget(btn, 0, 1)
        self.correctOrbitBtn = QPushButton("Apply")
        #self.correctOrbitBtn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.correctOrbitBtn.setStyleSheet("QPushButton:disabled { color: gray }");
        self.connect(self.correctOrbitBtn, SIGNAL("clicked()"), self.call_apply)
        self.correctOrbitBtn.setDefault(True)
        gbox.addWidget(self.correctOrbitBtn, 1, 1)
        gbox.setColumnStretch(0, 1)

        vbox1.addStretch()
        vbox1.addLayout(gbox)
        
        hbox1 = QtGui.QHBoxLayout()
        hbox1.addWidget(self.table, 2)
        hbox1.addLayout(vbox1, 0)
        self.setLayout(hbox1)

        self.connect(self.base_orbit_box,
                     SIGNAL("currentIndexChanged(QString)"), 
                     self.updateTargetOrbit)
        self.connect(self.repeatbox, SIGNAL("valueChanged(int)"),
                     self.progress.setMaximum)
        self.connect(self.table, SIGNAL("cellChanged (int, int)"),
                     self.updateBump)

        #self.updateTargetOrbit(self.base_orbit_box.currentText())

    def _update_current_orbit(self):
        pvx = [bpm.pv(field="x", handle="readback")[0] for bpm in self.bpms]
        pvy = [bpm.pv(field="y", handle="readback")[0] for bpm in self.bpms]
        self.x0 = [float(v) if v.ok else np.nan for v in catools.caget(pvx)]
        self.y0 = [float(v) if v.ok else np.nan for v in catools.caget(pvy)]

    def resetBumps(self):
        jx0, jy0 = 5, 6
        for i in range(self.table.rowCount()):
            self.table.item(i, jx0).setData(Qt.DisplayRole, str(0.0))
            self.table.item(i, jy0).setData(Qt.DisplayRole, str(0.0))
        #self.updateTargetOrbit(self.base_orbit_box.currentText())

    def call_apply(self):
        #print "apply the orbit"
        obt = []
        jx, jy = 7, 8
        for i in range(self.table.rowCount()):
            x1,err = self.table.item(i, jx).data(Qt.DisplayRole).toFloat()
            y1,err = self.table.item(i, jy).data(Qt.DisplayRole).toFloat()
            obt.append([x1, y1])

        self.correctOrbitBtn.setEnabled(False)
        nrepeat = self.repeatbox.value()
        kw = { "scale": float(self.scalebox.text()),
               "rcond": float(self.rcondbox.text()) }
        self.progress.setValue(0)
        QApplication.processEvents()
        for i in range(nrepeat):
            err, msg = setLocalBump(self.bpms, self.cors, obt, **kw)
            self.progress.setValue(i+1)
            QApplication.processEvents()
            if err != 0:
                QtGui.QMessageBox.critical(
                    self, "Local Orbit Bump", 
                    "ERROR: {0}\nAbort.".format(msg),
                    QtGui.QMessageBox.Ok)
                #self.progress.setValue(0)
                break
       
        self.correctOrbitBtn.setEnabled(True)

    def getTargetOrbit(self):
        x = [self.table.item(i,7).data(Qt.DisplayRole).toFloat()[0]
             for i in range(self.table.rowCount())]
        y = [self.table.item(i,8).data(Qt.DisplayRole).toFloat()[0]
             for i in range(self.table.rowCount())]
        return (self.sb, x), (self.sb, y)

    def updateTargetOrbit(self, baseobt):
        if baseobt == "All Zeros":
            jx0, jx1 = 5, 7
            jy0, jy1 = 6, 8
            for i in range(self.table.rowCount()):
                it0 = self.table.item(i, jx0)
                it1 = self.table.item(i, jx1)
                it1.setData(Qt.DisplayRole, it0.data(Qt.DisplayRole))
                it0 = self.table.item(i, jy0)
                it1 = self.table.item(i, jy1)
                it1.setData(Qt.DisplayRole, it0.data(Qt.DisplayRole))
        elif baseobt == "Current Orbit":
            self._update_current_orbit()
            jx0, jx1 = 5, 7
            jy0, jy1 = 6, 8
            for i in range(self.table.rowCount()):
                dx0,err = self.table.item(i, jx0).data(Qt.DisplayRole).toFloat()
                it = self.table.item(i, jx1)
                it.setData(Qt.DisplayRole, self.x0[i] + dx0)

                dy0,err = self.table.item(i, jy0).data(Qt.DisplayRole).toFloat()
                it = self.table.item(i, jy1)
                it.setData(Qt.DisplayRole, self.y0[i] + dy0)
        #self._update_orbit_plot()
        x, y = self.getTargetOrbit()
        self.emit(SIGNAL("targetOrbitChanged(PyQt_PyObject, PyQt_PyObject)"),
                  x, y)

    def updateBump(self, row, col):
        #print "updating ", row, col
        if col == 5 or col == 6:
            self.updateTargetOrbit(self.base_orbit_box.currentText())
class _TransferWidget(QFrame):
    cancel = pyqtSignal()
    cancelBeforeTransfer = pyqtSignal(int) # transfer ID
    retry = pyqtSignal(object, object, int) # filesOrData, peerID, transfer ID
    
    def __init__(self, parent, logger, filesOrData, name, targetDir, numFiles, totalSize, peerID, transferID, down):
        super(_TransferWidget, self).__init__(parent)
        
        self.logger = logger
        self._filesOrData = filesOrData
        self._targetDir = targetDir
        self._numFiles = numFiles
        self._totalSize = totalSize
        self._targetFile = None
        self._peerID = peerID
        self._transferID = transferID
        self._transferring = True
        self._down = down
        self._success = False
        self._connectedToThread = False
        self._currentFile = None
        
        self._initLayout()
        
        if type(filesOrData) is list and len(filesOrData) is 1:
            self._setCurrentFile(filesOrData[0])
        elif name:
            f = NamedTemporaryFile(suffix=name, delete=True)
            f.flush()
            self._setCurrentFile(f.name, name)
            f.close()
        else:
            self._setCurrentFile(None)
        self.reset()
        
    def _initLayout(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(5, 5, 5, 5)
        layout.setSpacing(0)
        
        nameLayout = QHBoxLayout()
        nameLayout.setContentsMargins(0, 0, 0, 0)
        
        self._fileIconLabel = QLabel(self)
        nameLayout.addWidget(self._fileIconLabel, 0, Qt.AlignLeft)
        
        self._nameLabel = QLabel(self)
        nameLayout.addSpacing(5)
        nameLayout.addWidget(self._nameLabel, 1, Qt.AlignLeft)
        
        layout.addLayout(nameLayout)
        
        progressWidget = QWidget(self)
        progressLayout = QHBoxLayout(progressWidget)
        progressLayout.setSpacing(5)
        progressLayout.setContentsMargins(0, 0, 0, 0)
        
        iconLabel = QLabel(progressWidget)
        if self._down:
            picFile = get_settings().get_resource("images", "down.png")
        else:
            picFile = get_settings().get_resource("images", "up.png")
        iconLabel.setPixmap(QPixmap(picFile))
        iconLabel.setFixedSize(15,15)
        progressLayout.addWidget(iconLabel, 0, Qt.AlignBottom)
        
        self._progress = QProgressBar(progressWidget)
        self._progress.setMinimum(0)
        self._progress.setMaximum(100)
        if getPlatform() == PLATFORM_MAC:
            self._progress.setAttribute(Qt.WA_MacMiniSize)
            self._progress.setMaximumHeight(16)
        progressLayout.addWidget(self._progress, 1)
        
        self._button = QPushButton(progressWidget)
        self._button.clicked.connect(self._buttonClicked)
        progressLayout.addSpacing(5)
        progressLayout.addWidget(self._button, 0, Qt.AlignCenter)
        
        layout.addWidget(progressWidget, 0, Qt.AlignBottom)
        
        self._statusLabel = QLabel(self)
        if getPlatform() == PLATFORM_MAC:
            self._statusLabel.setAttribute(Qt.WA_MacSmallSize)
        layout.addWidget(self._statusLabel)
        
        self.setObjectName(u"__transfer_widget")
        self.setFrameShape(QFrame.StyledPanel)
        self.setStyleSheet("QFrame#__transfer_widget{border-width: 1px; border-top-style: none; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-color:palette(mid)}");
            
        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        
    def reset(self):
        self._transferring = True
        self._statusLabel.setText(u"Waiting for data..." if self._down else u"Waiting for peer...")
        self._checkButtonFunction()
        self._progress.setMaximum(0)
        
    def isFinished(self):
        return not self._transferring
    
    def isSuccessful(self):
        return self._success
    
    def getFilePath(self):
        if self._numFiles is 1:
            return self._currentFile
        
    def _setFileIcon(self, curPath):
        if os.path.exists(curPath):
            fileInfo = QFileInfo(curPath)
            iconProvider = QFileIconProvider()
            icon = iconProvider.icon(fileInfo)
            self._fileIconLabel.setPixmap(icon.pixmap(16,16))
        
    def _setCurrentFile(self, path, dispName=None):
        if get_peers() is not None:
            peerName = get_peers().getDisplayedPeerName(self._peerID)
        else:
            peerName = u"<unknown peer>"
            
        if not path:
            if self._down:
                text = u"%d %s (total %s) \u2190 %s"
            else:
                text = u"%d %s (total %s) \u2192 %s"
            text = text % (self._numFiles, u"file" if self._numFiles is 1 else "files", formatSize(self._totalSize), peerName)
        else:
            if self._down:
                text = u"%s (%stotal %s) \u2190 %s"
            else:
                text = u"%s (%stotal %s) \u2192 %s"
            if dispName is None:
                dispName = os.path.basename(path)
            
            numFilesS = u"" if self._numFiles is 1 else u"%d files, " % self._numFiles
            text = text % (dispName, numFilesS, formatSize(self._totalSize), peerName)
            self._setFileIcon(path)
            
        self._currentFile = path
        self._nameLabel.setText(text)
        
    def _setIcon(self, baseName):
        if baseName is None:
            self._button.setStyleSheet("""
                QPushButton {min-width: 15px;
                             max-width: 15px;
                             min-height: 15px;
                             max-height: 15px;
                             margin: 0px;
                             padding: 0px;
                             border:none;
                }
            """)
        else:
            defPath = get_settings().get_resource("images", "%s32.png" % baseName)
            pressPath = get_settings().get_resource("images", "%s32p.png" % baseName)
            self._button.setStyleSheet("""
                QPushButton {min-width: 15px;
                             max-width: 15px;
                             min-height: 15px;
                             max-height: 15px;
                             margin: 0px;
                             padding: 0px;
                             border:none;
                             border-image: url(%s);
                }
                QPushButton:pressed {
                             border-image: url(%s);
                }
            """ % (defPath, pressPath)
            )
        
    def _checkButtonFunction(self):
        if self._transferring:
            self._setIcon("cancel")
        elif self._down:
            if self._success:
                self._setIcon("reveal")
            else:
                self._setIcon(None)
        else:
            if self._success:
                self._setIcon("reveal")
            else:
                self._setIcon("retry")
    
    def _reveal(self):
        filePath = self.getFilePath()
        if filePath:
            revealFile(filePath, self.logger)
        elif self._down:
            openFile(self._targetDir, self.logger)
        elif self._currentFile and os.path.exists(self._currentFile):
            revealFile(self._currentFile, self.logger)
    
    def _buttonClicked(self):
        if self._transferring:
            if self._connectedToThread:
                self.cancel.emit()
            else:
                self.cancelBeforeTransfer.emit(self._transferID)
        elif self._down:
            if self._success:
                self._reveal()
        else:
            if self._success:
                self._reveal()
            else:
                self.retry.emit(self._filesOrData, self._peerID, self._transferID)
                
    @loggingSlot(object, int)
    def nextFile(self, nameOrPath, _size):
        self._setCurrentFile(nameOrPath)
        
    def connectDataThread(self, dataThread):
        if not dataThread.isRunning():
            self.transferError(dataThread, u"Transfer didn't start.")
            return
        self._connectedToThread = True
        dataThread.progressChanged.connect(self.progressChanged)
        dataThread.errorOnTransfer.connect(self.transferError)
        dataThread.successfullyTransferred.connect(self.successfullyTransferred)
        dataThread.transferCanceled.connect(self.transferCanceled)
        dataThread.nextFile.connect(self.nextFile)
        self.cancel.connect(dataThread.cancelTransfer)

    def disconnectDataThread(self, dataThread):
        if self._connectedToThread:
            self._connectedToThread = False   
            dataThread.progressChanged.disconnect(self.progressChanged)
            dataThread.errorOnTransfer.disconnect(self.transferError)
            dataThread.successfullyTransferred.disconnect(self.successfullyTransferred)
            dataThread.transferCanceled.disconnect(self.transferCanceled)
            dataThread.nextFile.disconnect(self.nextFile)
            self.cancel.disconnect(dataThread.cancelTransfer)
    
    @loggingSlot(int, int)
    def progressChanged(self, newVal, maxVal):
        if newVal is 0:
            self._transferring = True
            self._progress.setMaximum(maxVal)
            self._statusLabel.setText(u"Receiving data" if self._down else u"Sending data")
        self._progress.setValue(newVal)
    
    @pyqtSlot(QThread)
    @loggingSlot(QThread, object)
    def successfullyTransferred(self, thread, _path=None):
        self._transferring = False
        self._success = True
        self._statusLabel.setText(u"Transfer finished successfully")
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
    
    @loggingSlot(QThread, object)
    def transferError(self, thread, message=None):
        if not self._transferring:
            return
        self._transferring = False
        self._statusLabel.setText(u"Error transferring file (%s)" % message)
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
        if self._progress.maximum() == 0:
            self._progress.setMaximum(100)
    
    @loggingSlot(QThread)
    def transferCanceled(self, thread):
        self._transferring = False
        self._statusLabel.setText(u"Transfer canceled")
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
        
    def canceledBeforeTransfer(self, isTimeout):
        self._progress.setMaximum(100)
        self._transferring = False
        if isTimeout:
            self._statusLabel.setText(u"Transfer timed out")
        else:
            self._statusLabel.setText(u"Transfer canceled")
        self._checkButtonFunction()
class MessageDialog(QWidget):
	def __init__(self, mailList, jobID = '', sec = 0, parent = None):
		QWidget.__init__(self, parent)
		self.prnt = parent
		self.jobID = jobID
		self.sec = sec
		self.frozen = False
		self.tr = self.prnt.prnt.tr
		self.setWindowTitle(self.tr._translate('M@il Checker : MailView Dialog'))
		self.setStyleSheet("QWidget {background: rgba(235,240,255,128);}")
		self.mailList = QLabel(mailList)
		self.layout = QVBoxLayout()
		self.buttonLayout = QHBoxLayout()
		
		self.ok = QPushButton(QIcon.fromTheme("dialog-ok"), "", self)
		self.cancel = QPushButton(QIcon.fromTheme("dialog-cancel"), "", self)
		self.freezMSG = QPushButton(QIcon.fromTheme("layer-visible-on"), '', self)
		self.freezMSG.setToolTip(self.tr._translate('Freez message'))
		self.ok.setMaximumHeight(15)
		self.freezMSG.setMaximumHeight(15)
		self.cancel.setMaximumHeight(15)
		self.ok.clicked.connect(self.accepted)
		self.freezMSG.clicked.connect(self.freez)
		self.cancel.clicked.connect(self.rejected)
		self.buttonLayout.addWidget(self.ok)
		self.buttonLayout.addWidget(self.freezMSG)
		self.buttonLayout.addWidget(self.cancel)

		self.layout.addWidget(self.mailList)
		if sec :
			self.lifetime = QProgressBar()
			self.lifetime.setOrientation(Qt.Horizontal)
			self.lifetime.setMinimum(0)
			self.lifetime.setMaximum(sec)
			self.lifetime.setValue(sec)
			self.lifetime.setMaximumHeight(7)
			self.layout.addWidget(self.lifetime)
			self.lifetimeID = self.startTimer(1000)
		self.layout.addItem(self.buttonLayout)

		self.setLayout(self.layout)
		self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
		self.setMinimumWidth(100)

	def accepted(self):
		self.prnt.prnt.viewJob.emit(self.jobID)
		if self.prnt.prnt.SoundEnabled :
			self.prnt.prnt.sound.Accepted.play()
		self.close()

	def rejected(self, common = False):
		if self.prnt.prnt.SoundEnabled and not common :
			self.prnt.prnt.sound.Cleared.play()
		self.close()

	def freez(self, common = False):
		if self.sec : self.killTimer(self.lifetimeID)
		self.setStyleSheet("QWidget {background: rgba(100,175,255,25);}")
		self.frozen = True
		self.freezMSG.setEnabled(False)
		if self.prnt.prnt.SoundEnabled and not common :
			self.prnt.prnt.sound.Frozen.play()

	def timerEvent(self, ev):
		if ev.type()==QEvent.Timer :
			value = self.lifetime.value()
			#print ev.timerId(), value
			if value > self.lifetime.minimum() :
				self.lifetime.setValue(value-1)
			else :
				self.close()

	def isFrozen(self): return self.frozen

	def closeEvent(self, ev):
		if ev.type()==QEvent.Close :
			if self.sec : self.killTimer(self.lifetimeID)
			self.prnt.checkEmpty.emit(self.jobID)
			self.prnt.prnt.clearJob.emit(self.jobID)
			ev.accept()
		else : ev.ignore()