Пример #1
0
	def __init__(self, display, parent=None):
		super(uiSearch, self).__init__(parent)

		self.openResults = tfmlib.openResults()
		self.mkShortcut = tfmlib.shortcutFunc()
		self.escPath = tfmlib.escapeFunc()		


		# self.mkresdir()

		# Screen object then used to read monitor size
		self.screen = display

		self.txtSearch = QLineEdit(self)
		self.txtSearch.setToolTip('Seperate your tags by spaces or commas.')
		btnSearch = QPushButton('Search',self)

		btnSearch.setToolTip('Search by tags.')

		layout = QVBoxLayout()
		layout.addWidget(self.txtSearch)
		layout.addWidget(btnSearch)
		
		self.setLayout(layout)
		self.setWindowTitle('Search')

		self.setGeom(300, 75)

		btnSearch.clicked.connect(self.search)
	def __init__(self):
		super(TransformationHistoryWidget, self).__init__()

		self.actionContainer = ButtonContainer()
		self.transformationModel = TransformationModel()

		self.transformationView = TransformationListView()
		self.transformationView.setRootIsDecorated(False)
		self.transformationView.setModel(self.transformationModel)
		self.transformationView.setAttribute(Qt.WA_MacShowFocusRect, False)
		self.transformationView.clicked.connect(self.clickedTransformation)

		self._transformCount = 0

		layout = QVBoxLayout()
		layout.setSpacing(0)
		layout.setAlignment(Qt.AlignTop)
		layout.addWidget(self.transformationView)
		layout.addWidget(self.actionContainer)
		self.setLayout(layout)

		removeButton = QPushButton()
		removeButton.setIcon(QIcon(AppVars.imagePath() + "RemoveButton.png"))
		removeButton.clicked.connect(self.removeButtonClicked)
		removeButton.setToolTip("Remove the last transformation")
		self.actionContainer.addButton(removeButton)
    def __init__(self):
        super(TransformationHistoryWidget, self).__init__()

        self.actionContainer = ButtonContainer()
        self.transformationModel = TransformationModel()

        self.transformationView = TransformationListView()
        self.transformationView.setRootIsDecorated(False)
        self.transformationView.setModel(self.transformationModel)
        self.transformationView.setAttribute(Qt.WA_MacShowFocusRect, False)
        self.transformationView.clicked.connect(self.clickedTransformation)

        self._transformCount = 0

        layout = QVBoxLayout()
        layout.setSpacing(0)
        layout.setAlignment(Qt.AlignTop)
        layout.addWidget(self.transformationView)
        layout.addWidget(self.actionContainer)
        self.setLayout(layout)

        removeButton = QPushButton()
        removeButton.setIcon(QIcon(AppVars.imagePath() + "RemoveButton.png"))
        removeButton.clicked.connect(self.removeButtonClicked)
        removeButton.setToolTip("Remove the last transformation")
        self.actionContainer.addButton(removeButton)
Пример #4
0
    def __init__(self):
        generic.GenericGui.__init__(self)
        window = QWidget()
        window.setWindowTitle('quichem-pyside')

        self.compiler_view = QListWidget()
        self.compiler_view.currentRowChanged.connect(self.show_source)
        self.stacked_widget = QStackedWidget()
        self.stacked_widget.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
        self.edit = QLineEdit()
        self.edit.setPlaceholderText('Type quichem input...')
        self.edit.textChanged.connect(self.change_value)
        self.view = QWebView()
        self.view.page().mainFrame().setScrollBarPolicy(Qt.Vertical,
                                                        Qt.ScrollBarAlwaysOff)
        self.view.page().action(QWebPage.Reload).setVisible(False)
        self.view.setMaximumHeight(0)
        self.view.setUrl('qrc:/web/page.html')
        self.view.setZoomFactor(2)
        self.view.page().mainFrame().contentsSizeChanged.connect(
            self._resize_view)
        # For debugging JS:
        ## from PySide.QtWebKit import QWebSettings
        ## QWebSettings.globalSettings().setAttribute(
        ##     QWebSettings.DeveloperExtrasEnabled, True)

        button_image = QPushButton('Copy as Image')
        button_image.clicked.connect(self.set_clipboard_image)
        button_image.setToolTip('Then paste into any graphics program')
        button_word = QPushButton('Copy as MS Word Equation')
        button_word.clicked.connect(self.set_clipboard_word)
        button_html = QPushButton('Copy as Formatted Text')
        button_html.clicked.connect(self.set_clipboard_html)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        button_layout = QHBoxLayout()
        button_layout.addStretch()
        button_layout.addWidget(button_image)
        button_layout.addWidget(button_word)
        button_layout.addWidget(button_html)
        source_layout = QHBoxLayout()
        source_layout.addWidget(self.compiler_view)
        source_layout.addWidget(self.stacked_widget, 1)
        QVBoxLayout(window)
        window.layout().addWidget(self.edit)
        window.layout().addWidget(self.view)
        window.layout().addLayout(button_layout)
        window.layout().addWidget(line)
        window.layout().addLayout(source_layout, 1)

        window.show()
        window.resize(window.minimumWidth(), window.height())
        # To prevent garbage collection of internal Qt object.
        self._window = window
Пример #5
0
    def __add_button(self, object_name, icon_path, func, tooltip):
        """
        Add simple button to UI
        """

        button = QPushButton()
        button.setObjectName(object_name)
        button.setIcon(QIcon(QPixmap(icon_path)))
        button.setFixedSize(QSize(self.BUTTON_SIZE, self.BUTTON_SIZE))
        button.setIconSize(QSize(self.BUTTON_SIZE, self.BUTTON_SIZE))
        button.clicked.connect(func)

        button.setToolTip(tooltip)

        self.layout.addWidget(button)
        self.buttons[object_name] = button
Пример #6
0
class ExampleDialog( QDialog ):
    def __init__( self, parent ):
        QDialog.__init__( self, parent )
        
        self.setGeometry( 100, 100, 200, 100 )
        self.setWindowTitle( "Hello World" )
        self.setToolTip( "This is a <b>QWidget</b> widget" )
        
        self.btn = QPushButton( "Log Text", self )
        self.btn.setToolTip( "This is a <b>QPushButton</b> widget" )
        self.btn.resize( self.btn.sizeHint() )
        self.btn.clicked.connect( self.logText )

        self.lineedit = QLineEdit( "Hello World", self )
        self.lineedit.setToolTip( "Type Something" )
        
        layout = QVBoxLayout( self )
        layout.addWidget( self.lineedit )
        layout.addWidget( self.btn )
        
    def logText( self ):
        Application.LogMessage( self.lineedit.text() )
Пример #7
0
    def initUI(self):
        grp = QGroupBox('Anim Munge')
        grplay = QGridLayout()
        self.bf1mode = QCheckBox()
        grplay.addWidget(QLabel('<b>SWBF1</b>'), 0, 1)
        grplay.addWidget(self.bf1mode, 0, 2)
        grplay.addWidget(QLabel('<b>Input</b>'), 1, 1)
        grplay.addWidget(QLabel('<b>Output</b>'), 1, 3)
        self.infiles = QListWidget()
        self.infiles.setMinimumWidth(150)
        self.infiles.addItems([os.path.basename(item) for item in self.files])
        grplay.addWidget(self.infiles, 2, 1, 1, 2)
        self.outfiles = QListWidget()
        self.outfiles.setMinimumWidth(150)
        grplay.addWidget(self.outfiles, 2, 3, 1, 2)
        self.add_params = QLineEdit()
        self.add_params.setText('Additional Params')
        self.add_params.setToolTip('<b>Additional Munge Parameters.</b> Like scale 1.5')
        grplay.addWidget(self.add_params, 0, 3, 1, 2)

        self.statlabel = QLabel('<b>AnimMunger</b>')
        grplay.addWidget(self.statlabel, 4, 1, 1, 1)
        self.animname = QLineEdit()
        self.animname.setText('AnimName')
        self.animname.setToolTip('<b>Animation Name.</b> Name of the final animation files. IE: name.zafbin, name.zaabin, name.anims.')
        grplay.addWidget(self.animname, 3, 1)
        self.type_box = QComboBox()
        self.type_box.addItems(self.types)
        self.type_box.setToolTip('<b>Munge Mode.</b> This switches munge parameters.')
        grplay.addWidget(QLabel('<b>Munge Mode:</b>'), 3, 2)
        grplay.addWidget(self.type_box, 3, 3, 1, 2)
        munge_btn = QPushButton('Munge')
        munge_btn.clicked.connect(self.munge)
        munge_btn.setToolTip('<b>Munge.</b> Munges the input files with the selected mode.')
        grplay.addWidget(munge_btn, 4, 2)
        save_out = QPushButton('Save')
        save_out.clicked.connect(self.save)
        save_out.setToolTip('<b>Save.</b> Saves the output files.')
        grplay.addWidget(save_out, 4, 3)
        cancel_btn = QPushButton('Cancel')
        cancel_btn.clicked.connect(self.cancel)
        cancel_btn.setToolTip('<b>Cancel.</b> Closes the dialog and removes all temporary files.')
        grplay.addWidget(cancel_btn, 4, 4)

        grp.setLayout(grplay)

        mainlay = QVBoxLayout()
        mainlay.addWidget(grp)

        self.setLayout(mainlay)
        self.setGeometry(340, 340, 320, 300)
        self.setWindowTitle('MSH Suite - Animation Munge')
        self.show()
Пример #8
0
    def initUI(self):
        open_msh_btn = QPushButton('Open .MSH...')
        open_msh_btn.clicked.connect(self.load_msh)
        open_msh_btn.setToolTip('<b>Loads a .MSH file</b> for editing.')
        dump_msh_btn = QPushButton('Dump .MSH...')
        dump_msh_btn.clicked.connect(self.dump_msh)
        dump_msh_btn.setToolTip('<b>Dumps .MSH file information</b> into a text file.')
        munge_anim_btn = QPushButton('Munge Animation')
        munge_anim_btn.clicked.connect(self.munge_anim)
        munge_anim_btn.setToolTip('<b>Launches the AnimMunger.</b>')
        buttonslay = QGridLayout()
        buttonslay.addWidget(open_msh_btn, 1, 1)
        buttonslay.addWidget(dump_msh_btn, 1, 3)
        buttonslay.addWidget(munge_anim_btn, 3, 1)

        frame = QFrame()
        frame.setLayout(buttonslay)
        self.setCentralWidget(frame)

        self.setGeometry(200, 100, WIDTH_LAUNCH, HEIGHT_LAUNCH)
        self.setWindowTitle('MSH Suite')
        self.show()
Пример #9
0
class CC_window(QWidget):
    def __init__(self):
        super(CC_window, self).__init__()
        self.version = '0.2'
        glo = QVBoxLayout(self)
        self.Runningo = None
        self.Looping = None
        self.P = CC_thread()
        if name == 'nt':
            ficon = r_path('images\\favicon.png')
            licon = r_path('images\\logo.png')
        else:
            ficon = r_path('images/favicon.png')
            licon = r_path('images/logo.png')
        self.tf = QFont("", 13, QFont.Bold)
        self.sf = QFont("", 10, QFont.Bold)
        self.SelfIinit(QIcon(ficon))
        self.center()
        self.a_btn(licon, glo)
        self.ss_btns(glo)
        self.i_list(glo)
        self.cl_btn(glo)
        self.l_btns(glo)
        self.f_btns(glo)
        self.ds_bar(glo)
        self.setLayout(glo)
        self.activateWindow()
        self.show()

    def SelfIinit(self, icon):
        self.setWindowTitle('chrome-cut ' + self.version)
        self.setGeometry(300, 300, 200, 150)
        self.setMinimumWidth(600)
        self.setMaximumWidth(600)
        self.setMinimumHeight(500)
        self.setMaximumHeight(500)
        # Setting Icon
        self.setWindowIcon(icon)
        QToolTip.setFont(self.sf)

    def msgApp(self, title, msg):
        uinfo = QMessageBox.question(self, title, msg,
                                     QMessageBox.Yes | QMessageBox.No)
        if uinfo == QMessageBox.Yes:
            return 'y'
        if uinfo == QMessageBox.No:
            return 'n'

    def closeEvent(self, event=None):
        if self.P.isRunning():
            response = self.msgApp("Making sure",
                                   "Sure, you want to exit while looping ?")
            if response == 'y':
                if event is not None:
                    event.accept()
                self.P.stop()
                exit(0)
            else:
                if event is not None:
                    event.ignore()
        else:
            if event is not None:
                event.accept()
            exit(0)

    def center(self):
        qrect = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qrect.moveCenter(cp)
        self.move(qrect.topLeft())

    def a_btn(self, icon, glo):
        def show_about():
            Amsg = "<center>All credit reserved to the author of chrome-cut "
            Amsg += " version " + self.version
            Amsg += ", This work is a free, open-source project licensed "
            Amsg += " under Mozilla Public License version 2.0 . <br><br>"
            Amsg += " visit us for more infos and how-tos :<br> "
            Amsg += "<b><a href='https://github.io/mrf345/chrome-cut'> "
            Amsg += "https://github.io/mrf345/chrome-cut </a> </b></center>"
            Amsgb = "About chrome-cut"
            return QMessageBox.about(self, Amsgb, Amsg)

        self.abutton = QPushButton('', self)
        self.abutton.setIcon(QPixmap(icon))
        self.abutton.setIconSize(QSize(500, 100))
        self.abutton.setToolTip('About chrome-cut')
        self.abutton.clicked.connect(show_about)
        glo.addWidget(self.abutton)

    def ss_btns(self, glo):
        self.lebutton = QPushButton('Scan IP address', self)
        self.lebutton.setToolTip(
            'Insert and check if a specific IP is a valid chrome cast')
        self.lebutton.setFont(self.tf)
        self.lebutton.clicked.connect(self.sip_input)
        glo.addWidget(self.lebutton)

    def sip_input(self):
        self.lebutton.setEnabled(False)
        self.s_bar.setStyleSheet(self.s_norm)
        self.s_bar.showMessage('> Checking out the IP ..')
        msg = "<center>Enter suspected IP to check : <br><i><u>Usually it is "
        msg += "on 192.168.what_have_you.188</i></center>"
        text, okPressed = QInputDialog.getText(self, "Scan IP", msg)
        if okPressed and text != '':
            self.setCursor(Qt.BusyCursor)
            ch = is_ccast(text)
            if ch:
                self.il_add([text])
                self.unsetCursor()
                self.lebutton.setEnabled(True)
                return True
            else:
                self.s_bar.setStyleSheet(self.s_error)
                self.s_bar.showMessage(
                    '! Error: inserted IP is not chrome cast device')
                self.unsetCursor()
                self.lebutton.setEnabled(True)
                return True
        self.s_bar.clearMessage()
        self.lebutton.setEnabled(True)
        return True

    def i_list(self, glo):
        self.ci_list = QListWidget()
        self.ci_list.setToolTip("List of discovered devices")
        self.ci_list.setEnabled(False)
        self.setFont(self.sf)
        glo.addWidget(self.ci_list)

    def cl_btn(self, glo):
        self.cle_btn = QPushButton('Clear devices list')
        self.cle_btn.setToolTip("Remove all devices from the list")
        self.cle_btn.setFont(self.sf)
        self.cle_btn.setEnabled(False)
        self.cle_btn.clicked.connect(self.il_add)
        glo.addWidget(self.cle_btn)

    def l_btns(self, glo):
        hlayout = QHBoxLayout()
        self.llo = QCheckBox("Looping")
        self.llo.setToolTip(
            'Automate repeating the smae command on the smae device selected ')
        self.llo.setEnabled(False)
        self.nlo = QLineEdit()
        self.nlo.setPlaceholderText("duration in seconds. Default is 10")
        self.nlo.setEnabled(False)
        self.nlo.setToolTip("Duration of sleep after each loop")
        self.lbtn = QPushButton('Stop')
        self.lbtn.setEnabled(False)
        self.lbtn.setFont(self.tf)
        self.llo.setFont(self.sf)
        self.lbtn.setToolTip("stop on-going command or loop")
        self.llo.toggled.connect(self.loped)
        self.lbtn.clicked.connect(partial(self.inloop_state, out=True))
        hlayout.addWidget(self.llo)
        hlayout.addWidget(self.nlo)
        hlayout.addWidget(self.lbtn)
        glo.addLayout(hlayout)

    def loped(self):
        if self.Looping:
            self.Looping = None
            self.llo.setChecked(False)
            self.nlo.setEnabled(False)
        else:
            self.Looping = True
            self.llo.setChecked(True)
            self.nlo.setEnabled(True)
        return True

    def f_btns(self, glo):
        hlayout = QHBoxLayout()
        self.ksbutton = QPushButton('Kill stream', self)
        self.ksbutton.setToolTip('Kill whetever been streamed')
        self.ksbutton.setFont(self.tf)
        self.ksbutton.clicked.connect(self.k_act)
        self.sbutton = QPushButton('Stream', self)
        self.sbutton.setFont(self.tf)
        self.sbutton.setToolTip('Stream a youtube video')
        self.fbutton = QPushButton('Factory reset', self)
        self.fbutton.setFont(self.tf)
        self.fbutton.setToolTip('Factory reset the device')
        self.fbutton.clicked.connect(self.fr_act)
        self.sbutton.clicked.connect(self.yv_input)
        self.ksbutton.setEnabled(False)
        self.sbutton.setEnabled(False)
        self.fbutton.setEnabled(False)
        hlayout.addWidget(self.ksbutton)
        hlayout.addWidget(self.sbutton)
        hlayout.addWidget(self.fbutton)
        glo.addLayout(hlayout)

    def ch_dur(th=None, dur=10):
        if len(dur) >= 1:
            try:
                dur = int(dur)
            except:
                dur = None
            if dur is None or not isinstance(dur, int):
                self.s_bar.setStyleSheet(self.s_error)
                self.s_bar.showMessage(
                    '! Error: wrong duration entery, only integers')
                return None
        else:
            dur = 10
        return dur

    def k_act(self):
        if self.ci_list.count() >= 1:
            cr = self.ci_list.currentRow()
            if cr is None or cr <= 0:
                cr = 0
            ip = self.ci_list.item(cr).text()
            if self.Looping is not None:
                dur = self.ch_dur(self.nlo.text())
                if dur is None:
                    return True
                self.P = CC_thread(cancel_app, dur, ip)
                self.P.start()
                self.P.somesignal.connect(self.handleStatusMessage)
                self.P.setTerminationEnabled(True)
                self.inloop_state()
                return True
            else:
                ch = cancel_app(ip)
                if ch is None:
                    self.s_bar.setStyleSheet(self.s_error)
                    self.s_bar.showMessage('! Error: failed to kill stream ..')
                else:
                    self.s_bar.setStyleSheet(self.s_norm)
                    self.s_bar.showMessage('# Stream got killed ')
        else:
            self.s_bar.setStyleSheet(self.s_error)
            self.s_bar.showMessage('! Error: No items selected from the list')
            self.eout()
        return True

    def fr_act(self):
        if self.ci_list.count() >= 1:
            cr = self.ci_list.currentRow()
            if cr is None or cr <= 0:
                cr = 0
            ip = self.ci_list.item(cr).text()
            if self.Looping is not None:
                dur = self.ch_dur(self.nlo.text())
                if dur is None:
                    return True
                self.P = CC_thread(reset_cc, dur, ip)
                self.P.start()
                self.P.somesignal.connect(self.handleStatusMessage)
                self.P.setTerminationEnabled(True)
                self.inloop_state()
                return True
            else:
                ch = reset_cc(ip)
                if ch is None:
                    self.s_bar.setStyleSheet(self.s_error)
                    self.s_bar.showMessage(
                        '! Error: failed to factory reset ..')
                else:
                    self.s_bar.setStyleSheet(self.s_norm)
                    self.s_bar.showMessage('# Got factory reseted ')
        else:
            self.s_bar.setStyleSheet(self.s_error)
            self.s_bar.showMessage('! Error: No items selected from the list')
            self.eout()
        return True

    def y_act(self, link=None):
        if self.ci_list.count() >= 1:
            cr = self.ci_list.currentRow()
            if cr is None or cr <= 0:
                cr = 0
            ip = self.ci_list.item(cr).text()
            if self.Looping is not None:
                dur = self.ch_dur(self.nlo.text())
                if dur is None:
                    return True
                self.P = CC_thread(send_app, dur, ip, link)
                self.P.start()
                self.P.somesignal.connect(self.handleStatusMessage)
                self.P.setTerminationEnabled(True)
                self.inloop_state()
                return True
            else:
                ch = reset_cc(ip)
                if ch is None:
                    self.s_bar.setStyleSheet(self.s_error)
                    self.s_bar.showMessage('! Error: failed to stream link ..')
                else:
                    self.s_bar.setStyleSheet(self.s_norm)
                    self.s_bar.showMessage('# Streamed the link ')
        else:
            self.s_bar.setStyleSheet(self.s_error)
            self.s_bar.showMessage('! Error: No items selected from the list')
            self.eout()
        return True

    def yv_input(self):
        text, okPressed = QInputDialog.getText(
            self, "Stream youtube",
            "Enter youtube video link to be streamed :")
        if okPressed and text != '':
            ntext = text.split('?')
            if len(ntext) <= 1:
                self.s_bar.setStyleSheet(self.s_error)
                self.s_bar.showMessage('! Error: Invalid youtube linkd ')
                return False
            ntext = ntext[1]
            if ntext != '' and len(ntext) > 1 and "youtube" in text:
                self.y_act(ntext)
                return True
            else:
                self.s_bar.setStyleSheet(self.s_error)
                self.s_bar.showMessage('! Error: Invalid youtube linkd ')
        return False

    @Slot(object)
    def handleStatusMessage(self, message):
        self.s_bar.setStyleSheet(self.s_loop)
        self.s_bar.showMessage(message)

    def il_add(self, items=[]):
        if len(items) >= 1:
            self.s_bar.setStyleSheet(self.s_norm)
            for i in items:
                fitem = self.ci_list.findItems(i, Qt.MatchExactly)
                if len(fitem) >= 1:
                    self.s_bar.setStyleSheet(self.s_error)
                    self.s_bar.showMessage(
                        '! Error: Device exists in the list')
                else:
                    self.s_bar.setStyleSheet(self.s_norm)
                    self.ci_list.addItem(i)
                    self.s_bar.showMessage('# Device was found and added')
            if not self.P.isRunning():
                self.cle_btn.setEnabled(True)
                self.ci_list.setEnabled(True)
                self.llo.setEnabled(True)
                self.nlo.setEnabled(True)
                self.ksbutton.setEnabled(True)
                self.sbutton.setEnabled(True)
                self.fbutton.setEnabled(True)
        else:
            self.s_bar.setStyleSheet(self.s_norm)
            self.s_bar.showMessage('# Cleard devices list')
            self.ci_list.clear()
            self.cle_btn.setEnabled(False)
            self.ci_list.setEnabled(False)
            self.ksbutton.setEnabled(False)
            self.llo.setEnabled(False)
            self.nlo.setEnabled(False)
            self.sbutton.setEnabled(False)
            self.fbutton.setEnabled(False)
        return True

    def inloop_state(self, out=False):
        if not out:
            self.lbtn.setEnabled(True)
            self.cle_btn.setEnabled(False)
            self.ci_list.setEnabled(False)
            self.ksbutton.setEnabled(False)
            self.llo.setEnabled(False)
            self.nlo.setEnabled(False)
            self.sbutton.setEnabled(False)
            self.fbutton.setEnabled(False)
        else:
            if self.P.isRunning():
                self.P.stop()
            self.lbtn.setEnabled(False)
            self.cle_btn.setEnabled(True)
            self.ci_list.setEnabled(True)
            self.ksbutton.setEnabled(True)
            self.llo.setEnabled(True)
            self.nlo.setEnabled(True)
            self.sbutton.setEnabled(True)
            self.fbutton.setEnabled(True)
            self.s_bar.clearMessage()
        return True

    def ds_bar(self, glo):
        self.s_bar = QStatusBar()
        self.s_error = "QStatusBar{color:red;font-weight:1000;}"
        self.s_loop = "QStatusBar{color:black;font-weight:1000;}"
        self.s_norm = "QStatusBar{color:blue;font-style:italic;"
        self.s_norm += "font-weight:500;}"
        self.s_bar.setStyleSheet(self.s_norm)
        glo.addWidget(self.s_bar)

    def eout(self):
        msgg = "<center>"
        msgg += " Opps, a critical error has occurred, we will be "
        msgg += " grateful if you can help fixing it, by reporting to us "
        msgg += " at : <br><br> "
        msgg += "<b><a href='https://github.io/mrf345/chrome-cut'> "
        msgg += "https://github.io/mrf345/chrome-cut </a></b> </center>"
        mm = QMessageBox.critical(self, "Critical Error", msgg, QMessageBox.Ok)
        exit(0)
Пример #10
0
class UsbResetter(QWidget):
    def __init__(self):
        super(UsbResetter, self).__init__()
        self.P = UR_thread()
        self.thr_counter = 0
        self.Looping = None
        self.Hidden = None
        self.Fhidden = None
        self.s_error = "QStatusBar{color:red;font-weight:1000;}"
        self.s_loop = "QStatusBar{color:black;font-weight:1000;}"
        self.s_norm = "QStatusBar{color:blue;font-style:italic;"
        self.s_norm += "font-weight:500;}"
        favicon = r_path("images/favicon.png")
        logo = r_path("images/logo.png")
        if name == 'nt':
            favicon = r_path("images\\favicon.png")
            logo = r_path("images\\logo.png")
        self.favicon = QIcon(favicon)
        self.plogo = logo
        self.logo = QIcon(logo)
        self.setStyle()
        mlayout = QVBoxLayout()
        self.setAbout(mlayout)
        self.setUlist(mlayout)
        self.setCboxs(mlayout)
        self.setReset(mlayout)
        self.setLoop(mlayout)
        self.setSb(mlayout)
        # functionalities
        self.set_list()
        self.rootWarn()
        # initiation
        self.activateWindow()
        self.setLayout(mlayout)
        self.show()

    def setSb(self, m):
        self.statusbar = QStatusBar()
        m.addWidget(self.statusbar)

    def setStyle(self):
        self.setMaximumWidth(350)
        self.setMinimumWidth(350)
        self.setMaximumHeight(340)
        self.setMinimumHeight(340)
        self.setWindowTitle("usb-resetter 1.0")
        self.setWindowIcon(self.favicon)
        self.show()

    def setAbout(self, m):
        self.pushButton = QPushButton()
        self.icon1 = QIcon()
        self.icon1.addPixmap(QPixmap(self.plogo),
                             QIcon.Normal, QIcon.Off)
        self.pushButton.setIcon(self.icon1)
        self.pushButton.setIconSize(QSize(300, 100))
        self.pushButton.clicked.connect(self.show_about)
        m.addWidget(self.pushButton)

    def setUlist(self, m):
        self.comboBox = QComboBox()
        m.addWidget(self.comboBox)

    def setCboxs(self, m):
        ml = QVBoxLayout()
        fl = QHBoxLayout()
        self.checkBox_2 = QCheckBox("Audio")
        self.checkBox_3 = QCheckBox("Mass storage")
        self.checkBox_2.setToolTip("Filter by audio devices")
        self.checkBox_3.setToolTip("Filter by mass storage devices")
        fl.addWidget(self.checkBox_2)
        fl.addWidget(self.checkBox_3)
        ml.addLayout(fl)
        sl = QHBoxLayout()
        self.checkBox_4 = QCheckBox("Network")
        self.checkBox_4.setToolTip("Filter by network devices")
        self.checkBox_5 = QCheckBox("Human interface")
        self.checkBox_5.setToolTip("Filter by Keyboard, mouse, joystick ..etc")
        sl.addWidget(self.checkBox_4)
        sl.addWidget(self.checkBox_5)
        ml.addLayout(sl)
        self.checkBox_2.clicked.connect(self.set_list)
        self.checkBox_3.clicked.connect(self.set_list)
        self.checkBox_4.clicked.connect(self.set_list)
        self.checkBox_5.clicked.connect(self.set_list)
        m.addLayout(ml)

    def setReset(self, m):
        self.pushButton_2 = QPushButton("Reset it")
        font = QFont()
        font.setPointSize(17)
        font.setWeight(75)
        font.setBold(True)
        self.pushButton_2.setFont(font)
        self.pushButton_2.clicked.connect(self.setbut_reset)
        m.addWidget(self.pushButton_2)

    def setLoop(self, m):
        ml = QHBoxLayout()
        self.checkBox = QCheckBox("Looping")
        self.checkBox.setToolTip("To repeat resetting for specified duration")
        self.lineEdit = QLineEdit()
        self.lineEdit.setToolTip("Duration in-which the resetting is done")
        self.pushButton_3 = QPushButton("Stop")
        self.pushButton_3.setToolTip("Stop looping")
        ml.addWidget(self.checkBox)
        ml.addWidget(self.lineEdit)
        ml.addWidget(self.pushButton_3)
        self.pushButton_3.setEnabled(False)
        self.lineEdit.setEnabled(False)
        self.lineEdit.setPlaceholderText("duration in seconds")
        self.checkBox.clicked.connect(self.loop_status)
        self.pushButton_3.clicked.connect(self.in_loop)
        m.addLayout(ml)

    # Functionalities

    def show_about(self):
        Amsg = "<center>All credit reserved to the author of "
        Amsg += "usb-resetter version 1.0"
        Amsg += ", This work is a free, open-source project licensed "
        Amsg += " under Mozilla Public License version 2.0 . <br><br>"
        Amsg += " visit us for more infos and how-tos :<br> "
        Amsg += "<b><a href='https://usb-resetter.github.io/'> "
        Amsg += "https://usb-resetter.github.io/ </a> </b></center>"
        Amsgb = "About usb-resetter"
        v = QMessageBox.about(self, Amsgb, Amsg)
        v = str(v)
        return v

    def closeEvent(self, event=None):
        if self.Hidden is None:
            response = QMessageBox.question(
                self,
                "Hide or close",
                "Do you want to hide the application ?",
                QMessageBox.Yes, QMessageBox.No)
            if response == QMessageBox.Yes:
                if event is not None:
                    event.ignore()
                self.Hidden = True
                self.hide()
            elif response == QMessageBox.No:
                if event is not None:
                    event.accept()
                return self.exitEvent()
            else:
                return False
        else:
            return self.exitEvent()

    def exitEvent(self):
        if self.P.isRunning():
            response = QMessageBox.question(
                self,
                "Making sure",
                "Sure, you want to exit while looping ?",
                QMessageBox.Yes, QMessageBox.No)
            if response == QMessageBox.Yes:
                self.P.stop()
                exit(0)
            else:
                return False
        else:
            exit(0)

    def get_list(self):
        ol = []
        if self.checkBox_2.isChecked():
            ol.append(1)
        if self.checkBox_3.isChecked():
            ol.append(8)
        if self.checkBox_4.isChecked():
            ol.append(2)
        if self.checkBox_5.isChecked():
            ol.append(3)
        if len(ol) >= 1:
            return listd(ol, True)
        else:
            return listd(None, True)

    def set_list(self):
        self.comboBox.clear()
        its = self.get_list()
        if len(its) >= 1:
            self.comboBox.addItems(its)
            self.pushButton_2.setEnabled(True)
            self.checkBox.setEnabled(True)
        else:
            self.pushButton_2.setEnabled(False)
            self.checkBox.setEnabled(False)
            self.lineEdit.setEnabled(False)
            self.pushButton_3.setEnabled(False)

    def setbut_reset(self):
        t = self.comboBox.currentText()
        if self.Looping is None:
            if resetit(t):
                self.statusbar.setStyleSheet(self.s_norm)
                self.statusbar.showMessage(
                    "# Done: usb device got reset")
                return True
            self.statusbar.setStyleSheet(self.s_error)
            if name != 'nt':
                self.statusbar.showMessage(
                    "# Error: maybe you need sudo permissions")
            else:
                self.statusbar.showMessage(
                    "# Error: maybe you need to add device to libusb")
            return False
        else:
            tl = self.lineEdit.text()
            self.statusbar.setStyleSheet(self.s_error)
            if len(tl) == 0:
                self.statusbar.showMessage(
                    "# Error: you must enter duration for looping")
                return False
            try:
                self.thr_counter += 1
                tl = int(tl)
                if tl < 2:
                    self.statusbar.showMessage(
                        "# Error: the least allowed value is 2")
                    return False
                self.P = UR_thread(t, tl, self.thr_counter)
                self.P.start()
                self.P.somesignal.connect(self.handleStatusMessage)
                self.P.setTerminationEnabled(True)
                self.in_loop(False)
            except:
                self.statusbar.showMessage(
                    "# Error: only valid integers allowed")
                return False

    def loop_status(self):
        if self.Looping:
            self.Looping = None
            self.lineEdit.setEnabled(False)
            self.pushButton_3.setEnabled(False)
        else:
            self.Looping = True
            self.lineEdit.setEnabled(True)
        return True

    def in_loop(self, stop=True):
        if stop:
            if self.P.isRunning():
                self.P.stop()
            self.pushButton_3.setEnabled(False)
            self.pushButton_2.setEnabled(True)
            self.checkBox.setEnabled(True)
            if self.checkBox.isChecked():
                self.lineEdit.setEnabled(True)
            self.checkBox_2.setEnabled(True)
            self.checkBox_3.setEnabled(True)
            self.checkBox_4.setEnabled(True)
            self.checkBox_5.setEnabled(True)
            self.comboBox.setEnabled(True)
        else:
            self.pushButton_3.setEnabled(True)
            self.pushButton_2.setEnabled(False)
            self.checkBox.setEnabled(False)
            self.lineEdit.setEnabled(False)
            self.checkBox_2.setEnabled(False)
            self.checkBox_3.setEnabled(False)
            self.checkBox_4.setEnabled(False)
            self.checkBox_5.setEnabled(False)
            self.comboBox.setEnabled(False)
        return True

    def rootWarn(self):
        if platform[:len(platform) - 1] == "linux":
            from os import getuid
            if getuid() != 0:
                self.statusbar.setStyleSheet(self.s_error)
                self.statusbar.showMessage(
                    "# Error: you must use sudo on Linux")

    @Slot(object)
    def handleStatusMessage(self, message):
        self.statusbar.setStyleSheet(self.s_loop)
        if message[:7] == '# Error':
            self.in_loop()
            self.statusbar.setStyleSheet(self.s_error)
        self.statusbar.showMessage(message)
Пример #11
0
class MainWindow(QMainWindow):
    '''The main window of the program'''

    def __init__(self):
        '''Initialize the main window and it's parents'''
        super(MainWindow, self).__init__()
        self._createtWidgets()
        self._initUI()
        self._makeMenu()
        self._makeConnections()
        self.fileName = None
        self.pdfName = None
        self.scriptName = None
        self.expName = None
        self.rawName = None
        self.rawExpName = None

        # Set initial number of peaks
        self.exchange.setNumPeaks(2)
        # Set matrix to symmetric by default
        self.exchange.setMatrixSymmetry(True)
        # Set the initial window.  
        self.scale.setValue(1900, 2100, False)
        # Default to rate in units of THz
        self.rate.setUnit('THz')
        # Clear button starts off inactive
        self.clear.setEnabled(False)

    def _createtWidgets(self):
        '''Creates all the widgets'''

        # Make the views
        self.plot = Plot(self)
        self.rate = RateView(parent=self)
        self.exchange = ExchangeView(parent=self)
        self.peak = PeakView(parent=self)
        self.scale = ScaleView(parent=self)

        # Create the model controller
        self.control = Controller(self)

        # Attach models to the views
        self.rate.setModel(self.control.rate)
        self.exchange.setModel(self.control.exchange, self.control.numpeaks)
        self.peak.setModel(self.control.peak)
        self.scale.setModel(self.control.scale)

        # Init the UI of all the views
        self.rate.initUI()
        self.exchange.initUI()
        self.peak.initUI()
        self.scale.initUI()

        # Last, make inter-view connections
        self.rate.makeConnections()
        self.exchange.makeConnections()
        self.peak.makeConnections()
        self.scale.makeConnections()
        self.plot.makeConnections()

        # The window will own a button to clear raw data
        self.clear = QPushButton('Clear Raw Data', self)
        self.clear.setToolTip(ttt('Remove raw data from the plot '
                                  'if there is any'))

    def _initUI(self):
        '''Sets up the layout of the window'''

        # Define a central widget and a layout for the window
        self.setCentralWidget(QWidget())
        self.mainLayout = QHBoxLayout()
        self.setWindowTitle('Spectral Exchange')

        # Make a layout for all the parameter views
        params = QVBoxLayout()
        params.addWidget(self.rate)
        params.addWidget(self.exchange)
        params.addWidget(self.peak)

        # Add the parameter dialog
        self.mainLayout.addLayout(params)

        # Add the plot 
        plot_lim = QVBoxLayout()
        plot_lim.addWidget(self.plot)
        lim_clear = QHBoxLayout()
        lim_clear.addWidget(self.scale)
        lim_clear.addWidget(self.clear)
        plot_lim.addLayout(lim_clear)
        self.mainLayout.addLayout(plot_lim)

        # Add the widgets to the central widget
        self.centralWidget().setLayout(self.mainLayout)

    def _makeConnections(self):
        '''Connect the widgets to each other'''

        # When the controller says plot, plot
        self.control.plotSpectrum.connect(self.plot.plotCalculatedData)

        # When the controller says resize x limits, do so
        self.control.newXLimits.connect(self.plot.changeScale)

        # Clear raw data if pushed
        self.clear.clicked.connect(self.clearRawData)

        # If the plot is clicked, send info to the scale widget
        self.plot.pointPicked.connect(self.scale.setSelection)

    def _makeMenu(self):
        '''Makes the menu bar for this widget'''
        # Get the menu bar object
        self.menu = self.menuBar()
        self.fileMenu = self.menu.addMenu('&File')

        # Open action
        open = QAction('&Open', self)
        open.setShortcuts(QKeySequence.Open)
        open.triggered.connect(self.openFromInput)
        open.setToolTip('Open an already made input file')
        self.fileMenu.addAction(open)

        # Save action
        save = QAction('&Save', self)
        save.setShortcuts(QKeySequence.Save)
        save.triggered.connect(self.saveToInput)
        save.setToolTip('Save settings to an input file')
        self.fileMenu.addAction(save)

        # Save action
        saveas = QAction('Save As', self)
        saveas.triggered.connect(self.saveToInputAs)
        save.setToolTip('Save settings to an input file of a new name')
        self.fileMenu.addAction(saveas)

        # Save action
        savepdf = QAction('Save as PDF', self)
        savepdf.triggered.connect(self.saveAsPDF)
        save.setToolTip('Save image to a PDF')
        self.fileMenu.addAction(savepdf)

        # Menu separator
        self.fileMenu.addSeparator()

        # Import action
        imp = QAction('&Import raw XY data', self)
        imp.setShortcut(QKeySequence('Ctrl+I'))
        imp.triggered.connect(self.importRawData)
        imp.setToolTip('Import raw data an plot alongside calculated data')
        self.fileMenu.addAction(imp)

        # Export action
        raw = QAction('Export raw XY data', self)
        raw.triggered.connect(self.exportRawData)
        raw.setToolTip('Export raw data to a file for use elsewhere')
        self.fileMenu.addAction(raw)

        # Export action
        exp = QAction('&Export calculated XY data', self)
        exp.setShortcut(QKeySequence('Ctrl+E'))
        exp.triggered.connect(self.exportXYData)
        exp.setToolTip('Export calculated data to a file for use elsewhere')
        self.fileMenu.addAction(exp)

        # Make script action
        scr = QAction('Make Sc&ript', self)
        scr.setShortcut(QKeySequence('Ctrl+R'))
        scr.triggered.connect(self.makeScript)
        scr.setToolTip('Create a python script that directly recreates this '
                       'spectrum')
        self.fileMenu.addAction(scr)

        # Menu separator
        self.fileMenu.addSeparator()

        # Quit action
        quit = QAction('&Quit', self)
        quit.setShortcuts(QKeySequence.Quit)
        quit.triggered.connect(QApplication.instance().quit)
        self.fileMenu.addAction(quit)

    #######
    # SLOTS
    #######

    def clearRawData(self):
        '''Clear the raw data from the plot'''
        self.plot.clearRawData()
        self.clear.setEnabled(False)

    def openFromInput(self):
        '''Open parameters from an input file'''
        filter = 'Input Files (*.inp);;All (*)'
        s = QFileDialog.getOpenFileName(self, 'Input File Name',
                                              '', filter)
        # Continue unless the user hit cancel
        if not s[0]:
            return
        fileName = s[0]

        # Read given input file
        try:
            args = read_input(fileName)
        except ReaderError as r:  # Error reading the input file
            error.showMessage(str(r))

        # Set the number of peaks
        npeaks = len(args.num)
        if npeaks < 2:
            error.showMessage('Need at least 2 peaks for exchange')
            return
        elif npeaks > 4:
            error.showMessage('This GUI can only handle up to 4 peaks. '
                              'Use the command-line version for an arbitrary '
                              'number of peaks')
            return
        self.exchange.setNumPeaks(npeaks)

        # Set the exchange
        matrix = ZMat(npeaks, args.exchanges, args.exchange_rates,
                      args.symmetric_exchange)
        self.exchange.setMatrixSymmetry(args.symmetric_exchange)
        self.exchange.setMatrix(matrix)

        # Set the rate
        if 'lifetime' in args:
            self.rate.setUnit(args.lifetime[1])
            self.rate.setRate(args.lifetime[0])
        else:
            self.rate.setUnit(args.rate[1])
            self.rate.setRate(args.rate[0])

        # Set the peak data
        self.peak.setPeaks(args.vib, args.Gamma_Lorentz, args.Gamma_Gauss,
                           args.heights)

        # Plot this data
        self.control.setDataForPlot()

        # Plot raw data if it exists
        if args.raw is not None:
            self.rawName = args.rawName
            self.plot.setRawData(args.raw)
            self.plot.plotRawData()
            self.clear.setEnabled(True)

        # Set the limits
        self.scale.setValue(args.xlim[0], args.xlim[1], args.reverse)

    def saveToInput(self):
        '''Save current settings to current input file if available'''
        if not self.control.hasPlot:
            error.showMessage('Cannot save.. there is no data to save yet')
            return
        if self.fileName is None:
            self.saveToInputAs()
        else:
            self.inputGen(self.fileName)

    def saveToInputAs(self):
        '''Save current settings to an input file of specified name'''
        if not self.control.hasPlot:
            error.showMessage('Cannot save.. there is no data to save yet')
            return
        filter = 'Input Files (*.inp);;All (*)'
        d = '' if self.fileName is None else self.fileName
        s = QFileDialog.getSaveFileName(self, 'Input File Name',
                                              d, filter)
        # Continue unless the user hit cancel
        if not s[0]:
            return
        self.fileName = s[0]

        # Generate the input file
        self.inputGen(self.fileName)

    def saveAsPDF(self):
        '''Save plot as a PDF'''
        if not self.control.hasPlot:
            error.showMessage('Cannot save.. there is no data to save yet')
            return
        filter = 'PDF Documents (*.pdf);;All (*)'
        d = '' if self.pdfName is None else self.pdfName
        s = QFileDialog.getSaveFileName(self, 'PDF File Name',
                                              d, filter)
        # Continue unless the user hit cancel
        if not s[0]:
            return
        self.pdfName = s[0]

        # Set up the PDF printer
        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOrientation(QPrinter.Landscape)
        printer.setOutputFileName(self.pdfName)
        printer.setCreator('RAPID')

        # Send to the plot for printing
        p = QPainter()
        p.begin(printer)
        x, y = self.plot.calculatedData()
        plt = pgplot(x, y,
                     antialias=True,
                     connect='all',
                     pen={'color': 'b', 'width': 0})
        plt.setLabel('bottom', "Frequency (Wavenumbers, cm<sup>-1</sup>)")
        plt.getAxis('bottom').setPen('k')
        plt.setLabel('left', "Intensity (Normalized)")
        plt.getAxis('left').setPen('k')
        plt.setYRange(0, 1.1, padding=0)
        plt.invertX(self.plot.reversed)
        plt.setBackground('w')  # White

        # The raw (experimental) data, if any
        if self.plot.rawData is not None:
            data = self.plot.getRawData()
            x, y = data[:,0], data[:,1]
            curve2 = PlotCurveItem(x, y,
                                   antialias=True,
                                   connect='all',
                                   pen={'color': 'g', 'width': 0})
            plt.addItem(curve2)
        plt.render(p)
        p.end()

    def exportXYData(self):
        '''Export current spectrum to XY data'''
        if not self.control.hasPlot:
            error.showMessage('Cannot export.. there is no data to export yet')
            return
        filter = 'Data Files (*.txt *.data);;All (*)'
        d = '' if self.expName is None else self.expName
        s = QFileDialog.getSaveFileName(self, 'Calculated XY Data File Name',
                                              d, filter)
        # Continue unless the user hit cancel
        if not s[0]:
            return
        self.expName = s[0]

        # Grab the XY data from the plot
        x, y = self.plot.calculatedData()
        # Save in a standard format
        try:
            write_data(x, y, self.expName)
        except (IOError, OSError) as e:
            error.showMessage(str(e))

    def exportRawData(self):
        '''Export current raw data to XY data'''
        if self.plot.rawData is None:
            error.showMessage('Cannot export.. there is no raw data to export yet')
            return
        filter = 'Data Files (*.txt *.data);;All (*)'
        d = '' if self.rawExpName is None else self.rawExpName
        s = QFileDialog.getSaveFileName(self, 'Raw XY Data File Name',
                                              d, filter)
        # Continue unless the user hit cancel
        if not s[0]:
            return
        self.rawExpName = s[0]

        # Grab the raw XY data from the plot
        data = self.plot.getRawData()
        # Save in a standard format
        try:
            write_data(data[:,0], data[:,1], self.rawExpName)
        except (IOError, OSError) as e:
            error.showMessage(str(e))

    def importRawData(self):
        '''Import data from an XY file'''
        filter = 'Data Files (*.txt *.data);;All (*)'
        d = '' if self.rawName is None else self.rawName
        s = QFileDialog.getOpenFileName(self, 'Raw XY Data File Name',
                                              d, filter)
        # Continue unless the user hit cancel
        if not s[0]:
            return
        self.rawName = s[0]

        # Load raw data and plot in a second curve
        rawData = loadtxt(str(self.rawName))
        self.plot.setRawData(rawData)
        self.plot.plotRawData()
        self.clear.setEnabled(True)

    def makeScript(self):
        '''Open parameters from an input file'''
        if not self.control.hasPlot:
            error.showMessage('Cannot save.. there is no data to save yet')
            return
        filter = 'Python Scripts (*.py)'
        d = '' if self.scriptName is None else self.scriptName
        s = QFileDialog.getSaveFileName(self, 'Python Script File Name',
                                              d, filter)
        # Continue unless the user hit cancel
        if not s[0]:
            return
        self.scriptName = s[0]

        # Get parameters needed
        xlim, rev, oldp, newp = self.control.getParametersForScript()
        x, y = self.plot.calculatedData()
        if self.clear.isEnabled():
            raw = self.plot.rawData
        else:
            raw = None
        save_script(x, y, raw, xlim, rev, oldp, newp, self.scriptName)

    def inputGen(self, fileName):
        '''Generate an input file'''

        # Open file for writing        
        try:
            fl = open(fileName, 'w')
        except (IOError, OSError) as e:
            error.showError(str(e))

        # Generate a template string to print
        s = dedent('''\
            # The rate or lifetime of the reaction
            {rate}

            # The exchange matrix
            {exchange}

            # The peak data
            {peaks}

            # The plot limits
            {limits}

            # Raw input file, if any
            {raw}
            ''')

        # Get the parameters from the underlying data
        xlim, rev, rate, exchange, peaks = self.control.getParametersForInput()

        # Create the rate string
        if rate[1] in ('s', 'ns', 'ps', 'fs'):
            lr = 'lifetime'
        else:
            lr = 'rate'
        ratestr = '{0} {1[0]:.3G} {1[1]}'.format(lr, rate)

        # Create exchange string
        exstr = []
        if not exchange[2]:
            exstr.append('nosym')
        f = 'exchange {0:d} {1:d} {2:.3f}'
        for indx, r in zip(exchange[1], exchange[0]):
            exstr.append(f.format(indx[0]+1, indx[1]+1, r))
        exstr = '\n'.join(exstr)

        # Create peak string
        peakstr = []
        f = 'peak {0:.2f} {1:.3f} L={2:.3f} G={3:.3f}'
        for p, l, g, h in zip(peaks[0], peaks[1], peaks[2], peaks[3]):
            peakstr.append(f.format(p, h, l, g))
        peakstr = '\n'.join(peakstr)
            
        # Create the limits string
        limitstr = 'xlim {0[0]:d} {0[1]:d}'.format(xlim)
        if rev:
            limitstr += '\nreverse'

        # Create the IO string
        if self.rawName is not None:
            rawstr = 'raw {0}'.format(self.rawName)
        else:
            rawstr = ''

        # Write the string to file
        fl.write(s.format(rate=ratestr, peaks=peakstr, limits=limitstr,
                          exchange=exstr, raw=rawstr))

        # Close file
        fl.close()
Пример #12
0
class NewWindow(QWidget):
    def __init__(self, app=None):
        super(NewWindow, self).__init__()
        self.app = app
        glo = QVBoxLayout(self)
        icp = r_path(solve_path('static/images/favicon.png'))
        # need to used objective message boxs instead of functions to set font
        self.Arial = QFont("", 12, QFont.Bold)
        self.Arials = QFont("", 10, QFont.Bold)
        # Language support variable 
        self.Language = 'en'
        self.Runningo = False
        icon = QIcon(icp)
        self.SelfIinit(icon)
        self.center()
        self.langsList(glo)
        self.set_Abutton(icp, glo)
        self.Lists(glo)
        self.Flabel(glo)
        self.set_button(glo)
        self.setLayout(glo)
        mip = self.slchange()
        self.P = rwser(mip[1].split(',')[1], mip[0], self.app)
        self.activateWindow()
        self.show()

    def SelfIinit(self, icon):
        self.setWindowTitle('Free Queue Manager ' + version)
        self.setGeometry(300, 300, 200, 150)
        self.setMinimumWidth(500)
        self.setMaximumWidth(500)
        self.setMinimumHeight(400)
        self.setMaximumHeight(400)
        # Setting Icon
        self.setWindowIcon(icon)
        QToolTip.setFont(self.Arials)

    def Flabel(self, glo):
        fontt = self.Arial
        self.ic1 = QIcon(r_path(solve_path('static/images/pause.png')))
        self.l = QLabel('Icond', self)
        self.ic1 = self.ic1.pixmap(70, 70, QIcon.Active, QIcon.On)
        self.l.setPixmap(self.ic1)
        self.l.setAlignment(Qt.AlignCenter | Qt.AlignHCenter)
        self.l.setFont(fontt)
        self.t = QLabel('Texted', self)
        self.t.setText(self.getTrans('11'))
        self.t.setOpenExternalLinks(True)
        self.t.setAlignment(Qt.AlignCenter | Qt.AlignHCenter)
        self.t.setFont(fontt)
        self.t.setToolTip(self.getTrans('9'))
        self.l.setToolTip(self.getTrans('9'))
        glo.addStretch()
        glo.addWidget(self.l)
        glo.addWidget(self.t)
        glo.addStretch()

    def langsList(self, glo):
        self.langs = {
            # languages to be displayed in select
            'en': 'English',
            'ar': 'Arabic',
            'fr': 'French',
            'it': 'Italian',
            'es': 'Spanish'
        }
        self.langs_list = QComboBox()
        self.langs_list.addItems(list(self.langs.values()))
        self.langs_list.setCurrentIndex(1)
        self.langs_list.setToolTip(self.getTrans('1'))
        self.langs_list.currentIndexChanged.connect(self.langChange)
        glo.addWidget(self.langs_list)
        
    def langChange (self):
        self.language = list(self.langs.keys())[self.langs_list.currentIndex()]
        self.langs_list.setToolTip(self.getTrans('1'))
        self.Amsgb = self.getTrans('2')
        self.abutton.setToolTip(
            self.getTrans('2')
        )
        self.mbutton.setText(self.getTrans('3'))
        self.mbutton.setToolTip(self.getTrans('4'))
        self.mbutton2.setText(self.getTrans('5'))
        self.mbutton2.setToolTip(self.getTrans('6'))
        self.sl.setToolTip(
            self.getTrans('7')
        )
        self.sl2.setToolTip(self.getTrans('8'))
        self.t.setToolTip(self.getTrans('9'))
        self.l.setToolTip(self.getTrans('9'))
        if self.Runningo:
            pp = self.slchange()
            addr = self.getTrans('10')
            addr += u"<a href='http://"
            addr += pp[1].split(',')[1] + u":" + pp[0]
            addr += u"'> http://" + pp[1].split(',')[1] + u":" + pp[0]
            addr += u"</a>"
            self.t.setText(addr)
        else:
            self.t.setText(self.getTrans('11'))
    
    def getTrans(self, index):
        lang = list(self.langs.keys())[self.langs_list.currentIndex()]
        try:
            return LANGUAGES[lang][index]
        except Exception:
            return None

    def Lists(self, glo):
        ips = self.get_ips()
        self.sl = QComboBox()
        self.sl.addItems(ips)
        self.sl.setToolTip(self.getTrans('7'))
        self.sl2 = QComboBox()
        self.get_ports()
        self.sl2.setToolTip('8')
        self.sl.currentIndexChanged.connect(self.get_ports)
        glo.addWidget(self.sl)
        glo.addWidget(self.sl2)

    def get_ports(self, nauto=True):
        d_ports = ['5000', '8080', '3000', '80', '9931']
        m_ports = []
        while len(m_ports) < 10:
            mip = self.slchange()
            for p in d_ports:
                s = socket(AF_INET, SOCK_STREAM)
                try:
                    s.bind((mip[1].split(',')[1], int(p)))
                    s.close()
                    m_ports.append(p)
                except:
                    s.close()
                d_ports.remove(p)
            s = socket(AF_INET, SOCK_STREAM)
            p = randint(1000, 9999)
            try:
                s.bind((mip[1].split(',')[1], p))
                s.close()
                m_ports.append(str(p))
            except:
                s.close()
            if len(m_ports) >= 10:
                break
        self.sl2.clear()
        self.sl2.addItems(m_ports)

    def slchange(self):
        return [self.sl2.currentText(), self.sl.currentText()]

    def set_button(self, glo):
        hlayout = QHBoxLayout()
        self.mbutton = QPushButton('Start', self)
        self.mbutton.clicked.connect(self.s_server)
        self.mbutton.setFont(self.Arials)
        self.mbutton.setIcon(QPixmap(r_path(solve_path('static/images/play.png'))))
        self.mbutton2 = QPushButton('Stop', self)
        self.mbutton2.clicked.connect(self.st_server)
        self.mbutton2.setIcon(QPixmap(r_path(solve_path('static/images/pause.png'))))
        self.mbutton.setToolTip(self.getTrans('4'))
        self.mbutton2.setToolTip(self.getTrans('6'))
        self.mbutton2.setEnabled(False)
        self.mbutton2.setFont(self.Arials)
        hlayout.addWidget(self.mbutton)
        hlayout.addWidget(self.mbutton2)
        glo.addLayout(hlayout)

    def s_server(self):
        mip = self.slchange()
        self.P = rwser(mip[1].split(',')[1], mip[0], self.app)
        self.P.setTerminationEnabled(True)
        if not self.P.isRunning():
            try:
                self.pport = mip[0]
                self.mbutton.setEnabled(False)
                self.mbutton2.setEnabled(True)
                self.sl.setEnabled(False)
                self.sl2.setEnabled(False)
                self.ic1 = QIcon(r_path(solve_path('static/images/play.png')))
                self.ic1 = self.ic1.pixmap(70, 70, QIcon.Active, QIcon.On)
                self.l.setPixmap(self.ic1)
                pp = self.slchange()
                addr = self.getTrans('10')
                addr += "<a href='http://"
                addr += pp[1].split(',')[1] + ":" + pp[0]
                addr += "'> http://" + pp[1].split(',')[1] + ":" + pp[0]
                addr += "</a>"
                self.t.setText(addr)
                self.t.setFont(self.Arial)
                self.P.start()
                self.Runningo = True
            except:
                self.eout()
        else:
            self.eout()

    def st_server(self):
        if self.P.isRunning():
            try:
                if self.P.isRunning:
                    self.P.stop()
                self.mbutton.setEnabled(True)
                self.mbutton2.setEnabled(False)
                self.sl.setEnabled(True)
                self.sl2.setEnabled(True)
                self.t.setText(self.getTrans('11'))
                # removing the last used port to avoid termination error
                cind = self.sl2.currentIndex()
                self.sl2.removeItem(cind)
                self.get_ports()
                self.Runningo = False
            except:
                self.eout()
        else:
            self.eout()

    def set_Abutton(self, icon, glo):
        def show_about(nself):
            Amsg = u" <center> "
            Amsg += self.getTrans('12') + version + u" "
            Amsg += self.getTrans('13')
            Amsg += self.getTrans('14')
            Amsg += self.getTrans('15')
            Amsg += u"<br> <b><a href='https://fqms.github.io/'>"
            Amsg += u"https://fqms.github.io </a> </b></center>"
            Amsgb = self.getTrans('2')
            return QMessageBox.about(
                self,
                Amsgb,
                Amsg)
        self.abutton = QPushButton('', self)
        self.abutton.setIcon(QPixmap(icon))
        self.abutton.setIconSize(QSize(150, 70))
        self.abutton.setToolTip(self.getTrans('2'))
        self.abutton.clicked.connect(partial(show_about, self))
        glo.addWidget(self.abutton)

    def closeEvent(self, event=None):
        if self.Runningo:
            response = self.msgApp(
                self.getTrans('16'),
                self.getTrans('17'))
            if response == 'y':
                if event is not None:
                    event.accept()
                if self.P.isRunning():
                    self.P.stop()
                sys.exit(0)
            else:
                if event is not None:
                    event.ignore()
        else:
            if event is not None:
                event.accept()
            if self.P.isRunning():
                self.P.stop()
            sys.exit(0)

    def msgApp(self, title, msg):
        uinfo = QMessageBox.question(self, title,
                                     msg, QMessageBox.Yes | QMessageBox.No)
        if uinfo == QMessageBox.Yes:
            return 'y'
        if uinfo == QMessageBox.No:
            return 'n'

    def eout(self):
        if self.P.isRunning():
            self.P.stop()
        msgg = u"<center>"
        msgg += self.getTrans('18')
        msgg += self.getTrans('19')
        msgg += u"<br><b><a href='https://fqms.github.io/'> "
        msgg += u"https://fqms.github.io </a></b> </center>"
        mm = QMessageBox.critical(
            self,
            self.getTrans('20'),
            msgg,
            QMessageBox.Ok)

    def center(self):
        qrect = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qrect.moveCenter(cp)
        self.move(qrect.topLeft())

    def get_ips(self):
        il = []
        for i in interfaces():
            try:
                if os.name != 'nt':
                    inf = i + " ,"
                else:
                    inf = ' ,'
                inf += ifaddresses(i)[2][0].get('addr')
                il.append(inf)
            except:
                pass
        return il
Пример #13
0
class TransformationFaceUI(QWidget):
    def __init__(self, oriPath, protoPath, oriPointsPath, protoPointsPath,
                 regionsPath):
        super(TransformationFaceUI, self).__init__()
        #Initialize the data or object we need

        localParas, points = preprocess(oriPath, protoPath, oriPointsPath,
                                        protoPointsPath, regionsPath, 'L2')
        self.oriImg, self.protoImg, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs = localParas
        self.oriPlotDict, self.protoPlotDict, self.oriPoints, self.protoPoints = points
        self.oriPoints = np.array(self.oriPoints)
        self.protoPoints = np.array(self.protoPoints)
        self.e = 2
        self.alpha = 1
        self.oriPath = oriPath
        self.protoPath = protoPath
        self.oriPointsPath = oriPointsPath
        self.protoPointsPath = protoPointsPath
        self.regionsPath = regionsPath
        self.transform = 'Local Affine Transformation'
        self.newImg = None
        self.initUI()

    def initUI(self):
        QToolTip.setFont(QFont('SansSerif', 10))
        self.setGeometry(300, 200, 810, 430)
        self.setWindowTitle('Transformation on Human Face')

        #Method choose combobox
        self.comboAffineLabel = QLabel(self)
        self.comboAffineLabel.setText('Transformation Method:')
        self.comboAffineLabel.setGeometry(60, 270, 230, 30)

        self.comboAffine = QComboBox(self)
        self.comboAffine.addItem("Local Affine Transformation")
        self.comboAffine.addItem("Moving Least Squares")
        self.comboAffine.addItem("Morphing")
        self.comboAffine.setGeometry(22, 290, 225, 30)
        self.comboAffine.activated[str].connect(self.affineChoiceChange)

        #The button to choose the original figure
        self.oriBtn = QPushButton('Choose Original Picture', self)
        self.oriBtn.setToolTip('Choose Original Picture')
        self.oriBtn.setGeometry(20, 330, 230, 30)
        self.oriBtn.clicked.connect(self.showOriDialog)

        #The button to choose the proto figure
        self.protoBtn = QPushButton('Choose Proto Picture', self)
        self.protoBtn.setToolTip('Choose Proto Picture')
        self.protoBtn.setGeometry(20, 365, 230, 30)
        self.protoBtn.clicked.connect(self.showProtoDialog)

        #The distance function choose combobox
        self.comboLabel = QLabel(self)
        self.comboLabel.setText('Distance Fun:')
        self.comboLabel.setGeometry(310, 280, 200, 30)

        self.comboDis = QComboBox(self)
        self.comboDis.addItem("L2")
        self.comboDis.addItem("L1")
        self.comboDis.setGeometry(410, 280, 80, 30)

        self.comboDis.activated[str].connect(self.distanceChoiceChange)

        #E choose slider

        self.eLabel = QLabel(self)
        self.eLabel.setText('E Value:0.00')
        self.eLabel.setGeometry(310, 320, 200, 30)
        self.eSld = QSlider(Qt.Horizontal, self)
        self.eSld.setRange(0, 10**5)
        self.eSld.setFocusPolicy(Qt.NoFocus)
        self.eSld.setGeometry(390, 320, 120, 30)
        self.eSld.valueChanged[int].connect(self.changeEValue)

        #alpha choose slider
        self.aLabel = QLabel(self)
        self.aLabel.setText('Alpha Value:0.00')
        self.aLabel.setGeometry(310, 360, 200, 30)
        self.aSld = QSlider(Qt.Horizontal, self)
        self.aSld.setRange(0, 10**5)
        self.aSld.setFocusPolicy(Qt.NoFocus)
        self.aSld.setGeometry(410, 360, 100, 30)
        self.aSld.valueChanged[int].connect(self.changeAlphaValue)

        # Picture show
        self.oriTextLabel = QLabel(self)
        self.protoTextLabel = QLabel(self)
        self.transTextLabel = QLabel(self)
        self.oriTextLabel.setText('The Orginal Picture')
        self.protoTextLabel.setText('The Proto Picture')
        self.transTextLabel.setText('The Picture after Transformation')

        self.oriTextLabel.move(70, 5)
        self.protoTextLabel.move(350, 5)
        self.transTextLabel.move(580, 5)

        self.oriLabel = QLabel(self)
        self.protoLabel = QLabel(self)
        self.transLabel = QLabel(self)

        pixmap = QPixmap(self.oriPath)
        pixmap2 = QPixmap(self.protoPath)
        self.oriLabel.setPixmap(pixmap)
        self.protoLabel.setPixmap(pixmap2)
        self.transLabel.setPixmap(pixmap)

        #Position setting
        self.oriLabel.setGeometry(20, 20, 230, 230)
        self.protoLabel.setGeometry(290, 20, 230, 230)
        self.transLabel.setGeometry(560, 20, 230, 230)
        self.oriLabel.setScaledContents(True)
        self.protoLabel.setScaledContents(True)
        self.transLabel.setScaledContents(True)
        #Load button
        self.loadOriBtn = QPushButton('Load Ori Points', self)
        self.loadOriBtn.setToolTip('Load Control Points From Txt File')
        self.loadOriBtn.setGeometry(550, 280, 130, 30)
        self.loadOriBtn.clicked.connect(self.showLoadOriDialog)

        self.loadProtoBtn = QPushButton('Load Proto Points', self)
        self.loadProtoBtn.setToolTip('Load Control Points From Txt File')
        self.loadProtoBtn.setGeometry(680, 280, 130, 30)
        self.loadProtoBtn.clicked.connect(self.showLoadProtoDialog)
        #Face ++ button
        self.faceBtn = QPushButton('Face++ Keypoint', self)
        self.faceBtn.setToolTip('Save the Face++ Keypoints')
        self.faceBtn.setGeometry(550, 315, 130, 30)
        self.faceBtn.clicked.connect(self.detectKeyPoints)
        #Load region Button
        self.loadRegionBtn = QPushButton('Load Regions', self)
        self.loadRegionBtn.setToolTip('Load Regions From Txt File')
        self.loadRegionBtn.setGeometry(680, 315, 130, 30)
        self.loadRegionBtn.clicked.connect(self.showLoadRegionDialog)

        #Save Button setting
        self.saveBtn = QPushButton('Save', self)
        self.saveBtn.setToolTip(
            'Transform this picture to the shape of Baboon')
        self.saveBtn.setGeometry(560, 350, 110, 40)
        self.saveBtn.clicked.connect(self.saveImg)

        #Transform action button
        self.confirmBtn = QPushButton('Generate', self)
        self.confirmBtn.setToolTip('Generate')
        self.confirmBtn.setGeometry(680, 350, 110, 40)
        self.confirmBtn.clicked.connect(self.transformAction)

        self.show()

    #Invoke face++ and save which is connected to the facebtn
    def detectKeyPoints(self):
        print(self.oriPath)
        save_points('face_keypoints_ori.txt',
                    detect((self.oriPath).encode('utf-8')))

    #Save img connected to the save button
    def saveImg(self):
        if self.newImg == None:
            QtGui.QMessageBox.information(self, "Error",
                                          "There is not transformed figure")
        result = Image.fromarray(self.newImg)
        filenames = self.oriPath.split('/')
        filenames[len(filenames) -
                  1] = 'trans_' + filenames[len(filenames) - 1]
        newPath = '/'.join(filenames)
        result.save(newPath)

    #Connected to the transform button did the deformation and show it
    def transformAction(self):

        try:
            #For different methods have different solution
            if self.transform == 'Morphing':
                self.oriImg = np.array(Image.open(self.oriPath))
                self.protoImg = np.array(Image.open(self.protoPath))
                if self.oriImg.shape != self.protoImg.shape:
                    QtGui.QMessageBox.information(
                        self, "Error",
                        "It is image morphing and required the same size of two images,please choose other images"
                    )
                    return
                newImg = morphingAction((self.oriPath).encode('utf-8'),
                                        self.protoPath.encode('utf-8'),
                                        self.protoPointsPath.encode('utf-8'),
                                        self.alpha)
            else:
                localParas, points = preprocess(self.oriPath, self.protoPath,
                                                self.oriPointsPath,
                                                self.protoPointsPath,
                                                self.regionsPath, 'L2')
                if points == None:
                    QtGui.QMessageBox.information(self, "Error", localParas)
                    return
                self.oriImg, self.protoImg, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs = localParas
                self.oriPlotDict, self.protoPlotDict, self.oriPoints, self.protoPoints = points
                if self.oriImg.shape[len(self.oriImg.shape) -
                                     1] != self.protoImg.shape[
                                         len(self.protoImg.shape) - 1]:
                    QtGui.QMessageBox.information(
                        self, "Error",
                        "The type of the figures is not the same, please choose another figure"
                    )
                    return
                if self.transform == 'Local Affine Transformation':
                    newImg = local_affine_transformation(
                        self.oriImg, self.protoImg, self.e, self.regionsPoints,
                        self.is_in_regions_fun, self.distance_funs,
                        self.affine_funs)
                elif self.transform == "Moving Least Squares":
                    newImg = affine_points_MLS(self.oriImg, self.protoImg,
                                               self.oriPoints,
                                               self.protoPoints, self.alpha)
        except BaseException:

            QtGui.QMessageBox.information(
                self, "Error",
                "There are error in the point choice or other things.")
            newImg = morphingAction((self.oriPath).encode('utf-8'),
                                    self.protoPath.encode('utf-8'),
                                    self.protoPointsPath.encode('utf-8'),
                                    self.alpha)

        self.newImg = np.uint8(newImg)
        newImg = rgb2bgr(np.uint8(newImg))

        qimage = QImage(newImg, newImg.shape[1], newImg.shape[0],
                        QImage.Format_ARGB32)
        pixmap_array = QPixmap.fromImage(qimage)
        self.transLabel.setPixmap(pixmap_array)
################################################################################################
################################################################################################
################################################################################################
################################################################################################
################################################################################################
################################################################################################
################################################################################################
################################################################################################

#The file chooser , all of the function begin with show is the same but for different parameter.

    def showProtoDialog(self):

        fname, _ = QtGui.QFileDialog.getOpenFileName(
            self, 'Open file', '/home', "Image Files (*.png *.jpg *.bmp)")
        if fname != None and fname != '':
            self.protoPath = fname
            self.protoLabel.setPixmap(QPixmap(self.protoPath))

    def showLoadOriDialog(self):

        fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
                                                     '/home',
                                                     "Text files (*.txt)")
        if fname != None and fname != '':
            self.oriPointsPath = fname

    def showLoadRegionDialog(self):

        fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
                                                     '/home',
                                                     "Text files (*.txt)")
        if fname != None and fname != '':
            self.regionsPath = fname

    def showLoadProtoDialog(self):

        fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
                                                     '/home',
                                                     "Text files (*.txt)")
        if fname != None and fname != '':
            self.protoPointsPath = fname

    def showOriDialog(self):

        fname, _ = QtGui.QFileDialog.getOpenFileName(
            self, 'Open file', '/home', "Image Files (*.png *.jpg *.bmp)")
        if fname != None and fname != '':
            self.oriPath = fname
            print(self.oriPath)
            self.oriLabel.setPixmap(QPixmap(self.oriPath))

    #Connected with eSld change the e value in LAT method
    def changeEValue(self, x):
        self.e = 4.0 * x / 10**5
        self.eLabel.setText('E Value:' + str('%.2f' % self.e))

    #Connected with aSld change the alpha value in MLS and Morphing method(but the alpha range is not the same)
    def changeAlphaValue(self, x):
        if self.transform == 'Moving Least Squares':
            self.alpha = 2.0 * x / 10**5
        elif self.transform == 'Morphing':
            self.alpha = 1.0 * x / 10**5
        self.aLabel.setText('Alpha Value:' + str('%.2f' % self.alpha))

    #Connected to the method combobox
    def affineChoiceChange(self, item):

        if self.transform in ['Moving Least Squares', 'Morphing'] and item in [
                'Moving Least Squares', 'Morphing'
        ] and item != self.transform:
            self.alpha = 0.0
            self.aSld.setValue(self.alpha)
        self.transform = item

    #Connected to the distance combobox
    def distanceChoiceChange(self, item):
        self.oriImg, self.protoImg, self.protoPoints, self.affine_funs = preprocess(
            oriPath, protoPath, oriPointsPath, protoPointsPath, item)
class MTTFilterFileDialog(QDialog):
    def __init__(self, define_path='', define_type=None):
        super(MTTFilterFileDialog, self).__init__(get_maya_window())

        self.supported_node_type = sorted([
            node_type for (node_type, nice, attr) in MTTSettings.SUPPORTED_TYPE
        ])

        self.defined_path = (define_path if os.path.isdir(define_path)
                             or define_path == SOURCEIMAGES_TAG else None)

        self.defined_type = (define_type if define_type
                             in self.supported_node_type else None)

        self.path_edit = None
        self.filter_reset_btn = None
        self.filter_line = None
        self.parent_folder_btn = None
        self.files_model = None
        self.files_list = None
        self.bookmark_list = None
        self.bookmark_list_sel_model = None
        self.types = None

        # move window to cursor position
        win_geo = MTTSettings.value('FilterFileDialog/windowGeometry',
                                    QRect(0, 0, 400, 300))
        self.setGeometry(win_geo)
        mouse_pos = QCursor.pos()
        mouse_pos.setX(mouse_pos.x() - (win_geo.width() * 0.5))
        self.move(mouse_pos)

        self.__create_ui()

        self.filter_line.setFocus()
        self.on_change_root_path(self.defined_path or SOURCEIMAGES_TAG)

    def __create_ui(self):
        """ Create main UI """
        self.setWindowTitle(CREATE_NODE_TITLE)

        # remove window decoration if path and type is set
        if self.defined_path and self.defined_type:
            self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup)

        main_layout = QVBoxLayout(self)
        main_layout.setSpacing(1)
        main_layout.setContentsMargins(2, 2, 2, 2)

        # content layout
        content_layout = QVBoxLayout()
        self.files_model = QFileSystemModel()
        self.files_model.setNameFilterDisables(False)
        self.files_list = MTTFileList()
        self.files_list.setAlternatingRowColors(True)
        self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.files_list.selectionValidated.connect(self.do_validate_selection)
        self.files_list.goToParentDirectory.connect(self.on_go_up_parent)
        self.files_list.doubleClicked.connect(self.on_double_click)
        self.files_list.setModel(self.files_model)

        buttons_layout = QHBoxLayout()

        content_layout.addLayout(self.__create_filter_ui())
        content_layout.addWidget(self.files_list)
        content_layout.addLayout(buttons_layout)
        self.files_list.filter_line = self.filter_line

        if not self.defined_path:
            # path line
            path_layout = QHBoxLayout()
            # bookmark button
            bookmark_btn = QPushButton('')
            bookmark_btn.setFlat(True)
            bookmark_btn.setIcon(QIcon(':/addBookmark.png'))
            bookmark_btn.setToolTip('Bookmark this Folder')
            bookmark_btn.setStatusTip('Bookmark this Folder')
            bookmark_btn.clicked.connect(self.on_add_bookmark)
            # path line edit
            self.path_edit = QLineEdit()
            self.path_edit.editingFinished.connect(self.on_enter_path)
            # parent folder button
            self.parent_folder_btn = QPushButton('')
            self.parent_folder_btn.setFlat(True)
            self.parent_folder_btn.setIcon(
                QIcon(':/SP_FileDialogToParent.png'))
            self.parent_folder_btn.setToolTip('Parent Directory')
            self.parent_folder_btn.setStatusTip('Parent Directory')
            self.parent_folder_btn.clicked.connect(self.on_go_up_parent)
            # browse button
            browse_btn = QPushButton('')
            browse_btn.setFlat(True)
            browse_btn.setIcon(QIcon(':/navButtonBrowse.png'))
            browse_btn.setToolTip('Browse Directory')
            browse_btn.setStatusTip('Browse Directory')
            browse_btn.clicked.connect(self.on_browse)
            # parent widget and layout
            path_layout.addWidget(bookmark_btn)
            path_layout.addWidget(self.path_edit)
            path_layout.addWidget(self.parent_folder_btn)
            path_layout.addWidget(browse_btn)
            main_layout.addLayout(path_layout)

            # bookmark list
            bookmark_parent_layout = QHBoxLayout()
            bookmark_frame = QFrame()
            bookmark_frame.setFixedWidth(120)
            bookmark_layout = QVBoxLayout()
            bookmark_layout.setSpacing(1)
            bookmark_layout.setContentsMargins(2, 2, 2, 2)
            bookmark_frame.setLayout(bookmark_layout)
            bookmark_frame.setFrameStyle(QFrame.Sunken)
            bookmark_frame.setFrameShape(QFrame.StyledPanel)
            self.bookmark_list = MTTBookmarkList()
            self.bookmark_list.bookmarkDeleted.connect(self.do_delete_bookmark)
            self.bookmark_list.setAlternatingRowColors(True)
            self.bookmark_list.dragEnabled()
            self.bookmark_list.setAcceptDrops(True)
            self.bookmark_list.setDropIndicatorShown(True)
            self.bookmark_list.setDragDropMode(QListView.InternalMove)
            self.bookmark_list_sel_model = self.bookmark_list.selectionModel()
            self.bookmark_list_sel_model.selectionChanged.connect(
                self.on_select_bookmark)

            bookmark_layout.addWidget(self.bookmark_list)
            bookmark_parent_layout.addWidget(bookmark_frame)
            bookmark_parent_layout.addLayout(content_layout)
            main_layout.addLayout(bookmark_parent_layout)

            self.do_populate_bookmarks()

        else:
            main_layout.addLayout(content_layout)

        if not self.defined_type:
            # type layout
            self.types = QComboBox()
            self.types.addItems(self.supported_node_type)
            self.types.currentIndexChanged.connect(self.on_node_type_changed)
            if cmds.optionVar(exists='MTT_lastNodeType'):
                last = cmds.optionVar(query='MTT_lastNodeType')
                if last in self.supported_node_type:
                    self.types.setCurrentIndex(
                        self.supported_node_type.index(last))
            buttons_layout.addWidget(self.types)

        if not self.defined_path or not self.defined_type:
            create_btn = QPushButton('C&reate')
            create_btn.clicked.connect(self.accept)
            cancel_btn = QPushButton('&Cancel')
            cancel_btn.clicked.connect(self.reject)

            buttons_layout.addStretch()
            buttons_layout.addWidget(create_btn)
            buttons_layout.addWidget(cancel_btn)

    def __create_filter_ui(self):
        """ Create filter widgets """
        filter_layout = QHBoxLayout()
        filter_layout.setSpacing(1)
        filter_layout.setContentsMargins(0, 0, 0, 0)

        self.filter_reset_btn = QPushButton()
        icon = QIcon(':/filtersOff.png')
        self.filter_reset_btn.setIcon(icon)
        self.filter_reset_btn.setIconSize(QSize(22, 22))
        self.filter_reset_btn.setFixedSize(24, 24)
        self.filter_reset_btn.setToolTip('Reset filter')
        self.filter_reset_btn.setFlat(True)
        self.filter_reset_btn.clicked.connect(
            partial(self.on_filter_set_text, ''))

        self.filter_line = QLineEdit()
        self.filter_line.setPlaceholderText('Enter filter string here')
        self.filter_line.textChanged.connect(self.on_filter_change_text)

        completer = QCompleter(self)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setModel(QStringListModel([], self))
        self.filter_line.setCompleter(completer)

        filter_layout.addWidget(self.filter_reset_btn)
        filter_layout.addWidget(self.filter_line)

        return filter_layout

    def on_filter_set_text(self, text=''):
        """ Set text in filter field """
        self.filter_line.setText(text)

    def on_filter_change_text(self, text):
        """ Apply filter string """
        if len(text):
            icon = QIcon(':/filtersOn.png')
            self.filter_reset_btn.setIcon(icon)
        else:
            icon = QIcon(':/filtersOff.png')
            self.filter_reset_btn.setIcon(icon)

        self.files_model.setNameFilters([
            '*%s*' % item.strip() for item in text.split(',') if item.strip()
        ])

    def on_node_type_changed(self, index):
        cmds.optionVar(
            sv=['MTT_lastNodeType', self.supported_node_type[index]])

    def on_double_click(self, index):
        current_item = self.files_model.filePath(index)
        if os.path.isdir(current_item):
            self.on_change_root_path(current_item)
        elif os.path.isfile(current_item):
            self.accept()

    def on_change_root_path(self, current_path):
        if current_path == SOURCEIMAGES_TAG:
            current_path = os.path.join(
                cmds.workspace(query=True, rootDirectory=True),
                cmds.workspace(fileRuleEntry='sourceImages'))

        self.files_model.setRootPath(current_path)
        self.files_list.setRootIndex(self.files_model.index(current_path))
        if self.path_edit:
            self.path_edit.setText(current_path)

        if self.parent_folder_btn:
            current_dir = QDir(current_path)
            self.parent_folder_btn.setEnabled(current_dir.cdUp())

    def on_go_up_parent(self):
        current_path = QDir(self.files_model.rootPath())
        current_path.cdUp()
        self.on_change_root_path(current_path.absolutePath())

    def on_enter_path(self):
        new_path = self.path_edit.text()
        if os.path.isdir(new_path):
            self.on_change_root_path(new_path)
        else:
            self.path_edit.setText(self.files_model.rootPath())

    def on_browse(self):
        current_path = self.files_model.rootPath()
        file_dialog = QFileDialog(self, 'Select a Folder', current_path)
        file_dialog.setFileMode(QFileDialog.Directory)
        file_dialog.setOption(QFileDialog.ShowDirsOnly)

        if file_dialog.exec_():
            self.on_change_root_path(file_dialog.selectedFiles()[0])

    def on_select_bookmark(self, selected, deselected):
        current_item = selected.indexes()
        if current_item:
            self.on_change_root_path(
                self.bookmark_list.selectedItems()[0].root_path)

    def on_add_bookmark(self):
        current_path = self.files_model.rootPath()
        self.on_add_bookmark_item(
            '%s|%s' % (os.path.basename(current_path), current_path))

    def on_add_bookmark_item(self, item):
        if item == '':
            return

        current_item = MTTBookmarkItem()
        current_item.add_raw_data(item)
        current_item.setSizeHint(QSize(40, 25))
        current_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable
                              | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled)

        self.bookmark_list.addItem(current_item)

    def do_delete_bookmark(self):
        current_item = self.bookmark_list.selectedItems()
        if current_item:
            item_row = self.bookmark_list.row(current_item[0])
            self.bookmark_list.takeItem(item_row)
            del current_item[0]

    def do_save_bookmark(self):
        if not self.bookmark_list:
            return

        row_count = self.bookmark_list.count()
        ordered_list = list()

        for i in range(row_count):
            item = self.bookmark_list.item(i)
            name = item.text().replace(',', '_').replace('|', '_')
            path = item.root_path
            if name != 'sourceimages':
                ordered_list.append('%s|%s' % (name, path))

        MTTSettings.set_value('FilterFileDialog/bookmarks',
                              ','.join(ordered_list))

    def do_populate_bookmarks(self):
        bookmarks = ['sourceimages|%s' % SOURCEIMAGES_TAG]
        bookmarks.extend(
            MTTSettings.value('FilterFileDialog/bookmarks').split(','))

        for bm in bookmarks:
            self.on_add_bookmark_item(bm)

    def do_validate_selection(self):
        selection = self.files_list.selectedIndexes()
        if len(selection) == 1:
            current_path = self.files_model.filePath(selection[0])
            if os.path.isdir(current_path):
                self.on_change_root_path(current_path)
                return
        self.accept()

    def get_selected_files(self):
        selected_items = list()
        for item_index in self.files_list.selectedIndexes():
            current_path = self.files_model.filePath(item_index)
            if os.path.isfile(current_path):
                selected_items.append(current_path)
        return selected_items

    def get_node_type(self):
        return self.types.currentText() if self.types else self.defined_type

    def closeEvent(self, event):
        MTTSettings.set_value('FilterFileDialog/windowGeometry',
                              self.geometry())
        self.do_save_bookmark()

        self.deleteLater()
        event.accept()
Пример #15
0
    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # Select analysis file button
        button = QPushButton('Select analysis file', self)
        button.setToolTip('*.inp CalculiX analysis file.')
        button.move(10, 10)
        button.clicked.connect(self.on_click)

        # Text box - file path and name
        self.textbox_file_name = QLineEdit(self)
        self.textbox_file_name.move(120, 15)
        self.textbox_file_name.resize(420, 20)
        self.textbox_file_name.setText("None analysis file selected")
        self.textbox_file_name.setToolTip('Analysis file.')

        # Update button
        button1 = QPushButton('Update domains', self)
        button1.setToolTip(
            'Update naming inputs and material data from FreeCAD.')
        button1.move(10, 50)
        button1.clicked.connect(self.on_click1)

        # Domains definition

        # Label above domains definition
        label21 = QLabel('Domain 0', self)
        label21.setStyleSheet("font-weight: bold")
        label21.move(120, 50)

        label21 = QLabel('Domain 1', self)
        label21.setStyleSheet("font-weight: bold")
        label21.move(260, 50)

        label21 = QLabel('Domain 2', self)
        label21.setStyleSheet("font-weight: bold")
        label21.move(400, 50)

        label24 = QLabel('Material object', self)
        label24.move(20, 80)

        label25 = QLabel('Thickness object', self)
        label25.move(20, 110)

        label26 = QLabel('As design domain', self)
        label26.move(20, 140)

        label27 = QLabel('Stress limit [MPa]', self)
        label27.move(20, 170)

        # Combo box - select domain by material object
        self.combo = QComboBox(self)
        self.combo.setToolTip('Material object to define the domain.')
        self.combo.move(120, 80)
        self.combo.resize(140, 30)
        self.combo.currentIndexChanged.connect(self.on_change)

        self.combo1 = QComboBox(self)
        self.combo1.setToolTip('Material object to define the domain.')
        self.combo1.move(260, 80)
        self.combo1.resize(140, 30)
        self.combo1.currentIndexChanged.connect(self.on_change1)

        self.combo2 = QComboBox(self)
        self.combo2.setToolTip('Material object to define the domain.')
        self.combo2.move(400, 80)
        self.combo2.resize(140, 30)
        self.combo2.currentIndexChanged.connect(self.on_change2)

        # Combo box - select thickness object
        self.combo0t = QComboBox(self)
        self.combo0t.setToolTip(
            'Thickness object to specify if domain is for shells.')
        self.combo0t.move(120, 110)
        self.combo0t.resize(140, 30)

        self.combo1t = QComboBox(self)
        self.combo1t.setToolTip(
            'Thickness object to specify if domain is for shells.')
        self.combo1t.move(260, 110)
        self.combo1t.resize(140, 30)

        self.combo2t = QComboBox(self)
        self.combo2t.setToolTip(
            'Thickness object to specify if domain is for shells.')
        self.combo2t.move(400, 110)
        self.combo2t.resize(140, 30)

        self.textbox3 = QLineEdit(self)
        self.textbox3.move(120, 170)
        self.textbox3.resize(40, 20)
        # self.textbox3.setText("")
        self.textbox3.setToolTip(
            'Thickness [mm] of shell elements in the domain.\n'
            'This value overwrites thickness defined in FreeCAD')

        self.textbox4 = QLineEdit(self)
        self.textbox4.move(260, 170)
        self.textbox4.resize(40, 20)
        # self.textbox4.setText("")
        self.textbox4.setToolTip(
            'Thickness [mm] of shell elements in the domain.\n'
            'This value overwrites thickness defined in FreeCAD')

        self.textbox5 = QLineEdit(self)
        self.textbox5.move(400, 170)
        self.textbox5.resize(40, 20)
        # self.textbox5.setText("")
        self.textbox5.setToolTip(
            'Thickness [mm] of shell elements in the domain.\n'
            'This value overwrites thickness defined in FreeCAD')

        # Check box - design or nondesign
        self.checkbox = QCheckBox('', self)
        self.checkbox.setChecked(True)
        self.checkbox.setToolTip('Check to be the design domain.')
        self.checkbox.move(120, 140)

        self.checkbox1 = QCheckBox('', self)
        self.checkbox1.setChecked(True)
        self.checkbox1.setToolTip('Check to be the design domain.')
        self.checkbox1.move(260, 140)

        self.checkbox2 = QCheckBox('', self)
        self.checkbox2.setChecked(True)
        self.checkbox2.setToolTip('Check to be the design domain.')
        self.checkbox2.move(400, 140)

        # Text box - stress limit
        self.textbox = QLineEdit(self)
        self.textbox.move(120, 170)
        self.textbox.resize(40, 20)
        # self.textbox.setText("")
        self.textbox.setToolTip(
            'Von Mises stress [MPa] limit, when reached, material removing will stop.'
        )

        self.textbox1 = QLineEdit(self)
        self.textbox1.move(260, 170)
        self.textbox1.resize(40, 20)
        # self.textbox1.setText("")
        self.textbox1.setToolTip(
            'Von Mises stress [MPa] limit, when reached, material removing will stop.'
        )

        self.textbox2 = QLineEdit(self)
        self.textbox2.move(400, 170)
        self.textbox2.resize(40, 20)
        # self.textbox2.setText("")
        self.textbox2.setToolTip(
            'Von Mises stress [MPa] limit, when reached, material removing will stop.'
        )

        # Filters

        # Label above filter definition
        label31 = QLabel('Filter 0', self)
        label31.setStyleSheet("font-weight: bold")
        label31.move(120, 210)

        label32 = QLabel('Filter 1', self)
        label32.setStyleSheet("font-weight: bold")
        label32.move(260, 210)

        label33 = QLabel('Filter 2', self)
        label33.setStyleSheet("font-weight: bold")
        label33.move(400, 210)

        label34 = QLabel('Type', self)
        label34.move(20, 240)

        label35 = QLabel('Range [mm]', self)
        label35.move(20, 270)

        label36 = QLabel('Direction vector', self)
        label36.move(20, 300)

        label37 = QLabel('Apply to', self)
        label37.move(20, 330)

        # Combo box - select filter type
        self.combo6 = QComboBox(self)
        self.combo6.setToolTip(
            'Filters:\n'
            '"simple" to suppress checkerboard effect,\n'
            '"casting" to prescribe casting direction (opposite to milling direction)\n'
            'Recommendation: for casting use as first "casting" and as second "simple"'
        )
        self.combo6.addItem("None")
        self.combo6.addItem("simple")
        self.combo6.addItem("casting")
        self.combo6.setCurrentIndex(1)
        self.combo6.move(120, 240)
        self.combo6.currentIndexChanged.connect(self.on_change6)

        self.combo7 = QComboBox(self)
        self.combo7.setToolTip(
            'Filters:\n'
            '"simple" to suppress checkerboard effect,\n'
            '"casting" to prescribe casting direction (opposite to milling direction)\n'
            'Recommendation: for casting use as first "casting" and as second "simple"'
        )
        self.combo7.addItem("None")
        self.combo7.addItem("simple")
        self.combo7.addItem("casting")
        self.combo7.move(260, 240)
        self.combo7.currentIndexChanged.connect(self.on_change7)

        self.combo8 = QComboBox(self)
        self.combo8.setToolTip(
            'Filters:\n'
            '"simple" to suppress checkerboard effect,\n'
            '"casting" to prescribe casting direction (opposite to milling direction)\n'
            'Recommendation: for casting use as first "casting" and as second "simple"'
        )
        self.combo8.addItem("None")
        self.combo8.addItem("simple")
        self.combo8.addItem("casting")
        self.combo8.move(400, 240)
        self.combo8.currentIndexChanged.connect(self.on_change8)

        # Text box - filter range
        self.textbox6 = QLineEdit(self)
        self.textbox6.move(120, 270)
        self.textbox6.resize(50, 20)
        # self.textbox6.setText("")
        self.textbox6.setToolTip(
            'Filter range [mm], recommended two times mesh size.')

        self.textbox7 = QLineEdit(self)
        self.textbox7.move(260, 270)
        self.textbox7.resize(50, 20)
        # self.textbox7.setText("")
        self.textbox7.setToolTip(
            'Filter range [mm], recommended two times mesh size.')
        self.textbox7.setEnabled(False)

        self.textbox8 = QLineEdit(self)
        self.textbox8.move(400, 270)
        self.textbox8.resize(50, 20)
        # self.textbox8.setText("")
        self.textbox8.setToolTip(
            'Filter range [mm], recommended two times mesh size.')
        self.textbox8.setEnabled(False)

        # Text box - casting direction
        self.textbox9 = QLineEdit(self)
        self.textbox9.move(120, 300)
        self.textbox9.resize(80, 20)
        self.textbox9.setText("0, 0, 1")
        self.textbox9.setEnabled(False)
        self.textbox9.setToolTip(
            'Casting direction vector, e.g. direction in z axis:\n'
            '0, 0, 1\n\n'
            'solid              void\n'
            'XXXXXX.................\n'
            'XXX........................\n'
            'XX...........................          --> z axis\n'
            'XXXXX....................\n'
            'XXXXXXXXXXX......')

        self.textbox10 = QLineEdit(self)
        self.textbox10.move(260, 300)
        self.textbox10.resize(80, 20)
        self.textbox10.resize(80, 20)
        self.textbox10.setText("0, 0, 1")
        self.textbox10.setEnabled(False)
        self.textbox10.setToolTip(
            'Casting direction vector, e.g. direction in z axis:\n'
            '0, 0, 1\n\n'
            'solid              void\n'
            'XXXXXX.................\n'
            'XXX........................\n'
            'XX...........................          --> z axis\n'
            'XXXXX....................\n'
            'XXXXXXXXXXX......')

        self.textbox11 = QLineEdit(self)
        self.textbox11.move(400, 300)
        self.textbox11.resize(80, 20)
        self.textbox11.setText("0, 0, 1")
        self.textbox11.setEnabled(False)
        self.textbox11.setToolTip(
            'Casting direction vector, e.g. direction in z axis:\n'
            '0, 0, 1\n\n'
            'solid              void\n'
            'XXXXXX.................\n'
            'XXX........................\n'
            'XX...........................          --> z axis\n'
            'XXXXX....................\n'
            'XXXXXXXXXXX......')

        # list widget - select domains
        self.widget = QListWidget(self)
        self.widget.setToolTip(
            'Domains affected by the filter.\n'
            'Select only from domains which you defined above.')
        self.widget.move(120, 330)
        self.widget.resize(140, 120)
        self.widget.setSelectionMode(QAbstractItemView.MultiSelection)

        self.widget1 = QListWidget(self)
        self.widget1.setToolTip(
            'Domains affected by the filter.\n'
            'Select only from domains which you defined above.')
        self.widget1.move(260, 330)
        self.widget1.resize(140, 120)
        self.widget1.setSelectionMode(QAbstractItemView.MultiSelection)
        self.widget1.setEnabled(False)

        self.widget2 = QListWidget(self)
        self.widget2.setToolTip(
            'Domains affected by the filter.\n'
            'Select only from domains which you defined above.')
        self.widget2.move(400, 330)
        self.widget2.resize(140, 120)
        self.widget2.setSelectionMode(QAbstractItemView.MultiSelection)
        self.widget2.setEnabled(False)

        # Other settings
        label40 = QLabel('Other settings', self)
        label40.setStyleSheet("font-weight: bold")
        label40.move(10, 470)

        # AR, RR slider
        label41 = QLabel('Change per iteration:   low', self)
        label41.setFixedWidth(150)
        label41.move(10, 500)
        label42 = QLabel('high', self)
        label42.move(240, 500)

        self.slider = QSlider(Qt.Horizontal, self)
        self.slider.setRange(1, 3)
        self.slider.setSingleStep(1)
        self.slider.setValue(2)
        self.slider.move(150, 500)
        self.slider.resize(80, 30)
        self.slider.setToolTip(
            'Sets mass change per iteration, which is controlled as\n'
            'slow:   mass_addition_ratio=0.01,  mass_removal_ratio=0.02\n'
            'middle: mass_addition_ratio=0.015, mass_removal_ratio=0.03\n'
            'fast:   mass_addition_ratio=0.03,  mass_removal_ratio=0.06')

        # optimization base combobox
        label51 = QLabel('Optimization base', self)
        label51.move(10, 530)
        self.combo51 = QComboBox(self)
        self.combo51.setToolTip(
            'Basic principle to determine if element should remain or be removed:\n'
            '"stiffness" to maximize stiffness (minimize compliance),\n'
            '"heat" to maximize heat flow.')
        self.combo51.addItem("stiffness")
        self.combo51.addItem("heat")
        self.combo51.move(120, 530)

        # mass goal ratio
        label52 = QLabel('Mass goal ratio', self)
        label52.move(10, 560)
        self.textbox52 = QLineEdit(self)
        self.textbox52.move(120, 560)
        self.textbox52.resize(50, 20)
        self.textbox52.setText("0.4")
        self.textbox52.setToolTip(
            'Fraction of all design domains masses to be achieved;\n'
            'between 0 and 1.')

        # generate conf. file button
        button21 = QPushButton('Generate conf. file', self)
        button21.setToolTip(
            'Writes configuration file with optimization parameters.')
        button21.move(10, 600)
        button21.clicked.connect(self.on_click21)

        # edit conf. file button
        button22 = QPushButton('Edit conf. file', self)
        button22.setToolTip('Opens configuration file for hand modifications.')
        button22.move(10, 630)
        button22.clicked.connect(self.on_click22)

        # run optimization button
        button23 = QPushButton('Run optimization', self)
        button23.setToolTip('Writes configuration file and runs optimization.')
        button23.move(10, 660)
        button23.clicked.connect(self.on_click23)

        # generate conf file and run optimization button
        button24 = QPushButton('Generate conf.\nfile and run\noptimization',
                               self)
        button24.setToolTip('Writes configuration file and runs optimization.')
        button24.move(120, 600)
        button24.resize(100, 90)
        button24.clicked.connect(self.on_click24)

        # help buttons
        label41 = QLabel('Help', self)
        label41.move(440, 560)

        button31 = QPushButton('Example', self)
        button31.setToolTip(
            'https://github.com/fandaL/beso/wiki/Example-4:-GUI-in-FreeCAD')
        button31.move(440, 590)
        # button31.resize(80, 50)
        button31.clicked.connect(self.on_click31)

        button32 = QPushButton('Conf. comments', self)
        button32.setToolTip(
            'https://github.com/fandaL/beso/blob/master/beso_conf.py')
        button32.move(440, 620)
        # button32.resize(80, 50)
        button32.clicked.connect(self.on_click32)

        button33 = QPushButton('Close', self)
        button33.move(440, 690)
        # button33.resize(80, 50)
        button33.clicked.connect(self.on_click33)

        # open log file
        button40 = QPushButton('Open log file', self)
        button40.setToolTip('Opens log file in your text editor.\n'
                            '(Does not refresh automatically.)')
        button40.move(10, 690)
        button40.clicked.connect(self.on_click40)

        self.on_click1()  # first update
        self.show()
Пример #16
0
class RunnerDialog(QDialog):

    options_added = Signal(Options)
    options_running = Signal(Options)
    options_simulated = Signal(Options)
    options_error = Signal(Options, Exception)
    results_saved = Signal(Results, str)
    results_error = Signal(Results, Exception)

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle('Runner')
        self.setMinimumWidth(750)

        # Runner
        self._runner = None

        self._running_timer = QTimer()
        self._running_timer.setInterval(500)

        # Widgets
        self._dlg_progress = QProgressDialog()
        self._dlg_progress.setRange(0, 100)
        self._dlg_progress.setModal(True)
        self._dlg_progress.hide()

        lbl_outputdir = QLabel("Output directory")
        self._txt_outputdir = DirBrowseWidget()

        max_workers = cpu_count() #@UndefinedVariable
        lbl_workers = QLabel('Number of workers')
        self._spn_workers = QSpinBox()
        self._spn_workers.setRange(1, max_workers)
        self._spn_workers.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        lbl_max_workers = QLabel('(max: %i)' % max_workers)

        self._chk_overwrite = QCheckBox("Overwrite existing results in output directory")
        self._chk_overwrite.setChecked(True)

        self._lbl_available = QLabel('Available')
        self._lst_available = QListView()
        self._lst_available.setModel(_AvailableOptionsListModel())
        self._lst_available.setSelectionMode(QListView.SelectionMode.MultiSelection)

        tlb_available = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_available.addWidget(spacer)
        act_open = tlb_available.addAction(getIcon("document-open"), "Open")
        act_open.setShortcut(QKeySequence.Open)
        tlb_available.addSeparator()
        act_remove = tlb_available.addAction(getIcon("list-remove"), "Remove")
        act_clear = tlb_available.addAction(getIcon("edit-clear"), "Clear")

        self._btn_addtoqueue = QPushButton(getIcon("go-next"), "")
        self._btn_addtoqueue.setToolTip("Add to queue")
        self._btn_addtoqueue.setEnabled(False)

        self._btn_addalltoqueue = QPushButton(getIcon("go-last"), "")
        self._btn_addalltoqueue.setToolTip("Add all to queue")
        self._btn_addalltoqueue.setEnabled(False)

        self._lbl_options = QLabel('Queued/Running/Completed')
        self._tbl_options = QTableView()
        self._tbl_options.setModel(_StateOptionsTableModel())
        self._tbl_options.setItemDelegate(_StateOptionsItemDelegate())
        self._tbl_options.setSelectionMode(QListView.SelectionMode.NoSelection)
        self._tbl_options.setColumnWidth(1, 60)
        self._tbl_options.setColumnWidth(2, 80)
        header = self._tbl_options.horizontalHeader()
        header.setResizeMode(0, QHeaderView.Interactive)
        header.setResizeMode(1, QHeaderView.Fixed)
        header.setResizeMode(2, QHeaderView.Fixed)
        header.setResizeMode(3, QHeaderView.Stretch)

        self._btn_start = QPushButton(getIcon("media-playback-start"), "Start")

        self._btn_cancel = QPushButton("Cancel")
        self._btn_cancel.setEnabled(False)

        self._btn_close = QPushButton("Close")

        self._btn_import = QPushButton("Import")
        self._btn_import.setEnabled(False)

        # Layouts
        layout = QVBoxLayout()

        sublayout = QGridLayout()
        sublayout.addWidget(lbl_outputdir, 0, 0)
        sublayout.addWidget(self._txt_outputdir, 0, 1)
        sublayout.addWidget(lbl_workers, 1, 0)

        subsublayout = QHBoxLayout()
        subsublayout.addWidget(self._spn_workers)
        subsublayout.addWidget(lbl_max_workers)
        sublayout.addLayout(subsublayout, 1, 1)
        layout.addLayout(sublayout)

        sublayout.addWidget(self._chk_overwrite, 2, 0, 1, 3)

        sublayout = QGridLayout()
        sublayout.setColumnStretch(0, 1)
        sublayout.setColumnStretch(2, 3)
        sublayout.addWidget(self._lbl_available, 0, 0)
        sublayout.addWidget(self._lst_available, 1, 0)
        sublayout.addWidget(tlb_available, 2, 0)

        subsublayout = QVBoxLayout()
        subsublayout.addStretch()
        subsublayout.addWidget(self._btn_addtoqueue)
        subsublayout.addWidget(self._btn_addalltoqueue)
        subsublayout.addStretch()
        sublayout.addLayout(subsublayout, 1, 1)

        sublayout.addWidget(self._lbl_options, 0, 2)
        sublayout.addWidget(self._tbl_options, 1, 2)
        layout.addLayout(sublayout)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(self._btn_import)
        sublayout.addWidget(self._btn_start)
        sublayout.addWidget(self._btn_cancel)
        sublayout.addWidget(self._btn_close)
        layout.addLayout(sublayout)

        self.setLayout(layout)

        # Signal
        self._running_timer.timeout.connect(self._onRunningTimer)

        act_open.triggered.connect(self._onOpen)
        act_remove.triggered.connect(self._onRemove)
        act_clear.triggered.connect(self._onClear)

        self._btn_addtoqueue.released.connect(self._onAddToQueue)
        self._btn_addalltoqueue.released.connect(self._onAddAllToQueue)
        self._btn_start.released.connect(self._onStart)
        self._btn_cancel.released.connect(self._onCancel)
        self._btn_close.released.connect(self._onClose)
        self._btn_import.released.connect(self._onImport)

        self.options_added.connect(self._onOptionsAdded)
        self.options_running.connect(self._onOptionsRunning)
        self.options_simulated.connect(self._onOptionsSimulated)
        self.options_error.connect(self._onOptionsError)
        self.results_error.connect(self._onResultsError)

        # Defaults
        settings = get_settings()
        section = settings.add_section('gui')
        if hasattr(section, 'outputdir'):
            self._txt_outputdir.setPath(section.outputdir)
        if hasattr(section, 'maxworkers'):
            self._spn_workers.setValue(int(section.maxworkers))
        if hasattr(section, 'overwrite'):
            state = True if section.overwrite.lower() == 'true' else False
            self._chk_overwrite.setChecked(state)

    def _onDialogProgressProgress(self, progress, status):
        self._dlg_progress.setValue(progress * 100)
        self._dlg_progress.setLabelText(status)

    def _onDialogProgressCancel(self):
        self._dlg_progress.hide()
        if self._options_reader_thread is None:
            return
        self._options_reader_thread.cancel()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()

    def _onDialogProgressException(self, ex):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        messagebox.exception(self, ex)

    def _onRunningTimer(self):
        self._tbl_options.model().reset()

    def _onOpen(self):
        settings = get_settings()
        curdir = getattr(settings.gui, 'opendir', os.getcwd())

        filepath, namefilter = \
            QFileDialog.getOpenFileName(self, "Open", curdir,
                                        'Options [*.xml] (*.xml)')

        if not filepath or not namefilter:
            return
        settings.gui.opendir = os.path.dirname(filepath)

        if not filepath.endswith('.xml'):
            filepath += '.xml'

        self._options_reader_thread = _OptionsReaderWrapperThread(filepath)
        self._dlg_progress.canceled.connect(self._onDialogProgressCancel)
        self._options_reader_thread.resultReady.connect(self._onOpened)
        self._options_reader_thread.progressUpdated.connect(self._onDialogProgressProgress)
        self._options_reader_thread.exceptionRaised.connect(self._onDialogProgressException)
        self._options_reader_thread.start()

        self._dlg_progress.reset()
        self._dlg_progress.show()

    def _onOpened(self, options):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        self._options_reader_thread = None

        try:
            self._lst_available.model().addOptions(options)
        except Exception as ex:
            messagebox.exception(self, ex)

    def _onRemove(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.popOptions(row)

    def _onClear(self):
        self._lst_available.model().clearOptions()

    def _onAddToQueue(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onAddAllToQueue(self):
        model = self._lst_available.model()
        for row in reversed(range(0, model.rowCount())):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onStart(self):
        outputdir = self._txt_outputdir.path()
        if not outputdir:
            QMessageBox.critical(self, 'Start', 'Missing output directory')
            return
        max_workers = self._spn_workers.value()
        overwrite = self._chk_overwrite.isChecked()
        self.start(outputdir, overwrite, max_workers)

    def _onCancel(self):
        self.cancel()

    def _onClose(self):
        if self._runner is not None:
            self._runner.close()
        self._running_timer.stop()
        self.close()

    def _onImport(self):
        list_options = self._lst_available.model().listOptions()
        if not list_options:
            return

        # Select options
        dialog = _OptionsSelector(list_options)
        if not dialog.exec_():
            return
        options = dialog.options()

        # Start importer
        outputdir = self._runner.outputdir
        max_workers = self._runner.max_workers
        importer = LocalImporter(outputdir, max_workers)

        importer.start()
        importer.put(options)

        self._dlg_progress.show()
        try:
            while importer.is_alive():
                if self._dlg_progress.wasCanceled():
                    importer.cancel()
                    break
                self._dlg_progress.setValue(importer.progress * 100)
        finally:
            self._dlg_progress.hide()

    def _onOptionsAdded(self, options):
        logging.debug('runner: optionsAdded')
        self._tbl_options.model().addOptions(options)

    def _onOptionsRunning(self, options):
        logging.debug('runner: optionsRunning')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsSimulated(self, options):
        logging.debug('runner: optionsSimulated')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsError(self, options, ex):
        logging.debug('runner: optionsError')
        self._tbl_options.model().resetOptions(options)

    def _onResultsError(self, results, ex):
        logging.debug('runner: resultsError')
        self._tbl_options.model().reset()

    def closeEvent(self, event):
        if self.is_running():
            message = 'Runner is running. Do you want to continue?'
            answer = QMessageBox.question(self, 'Runner', message,
                                          QMessageBox.Yes | QMessageBox.No)
            if answer == QMessageBox.No:
                event.ignore()
                return

        self.cancel()
        self._dlg_progress.close()

        settings = get_settings()
        section = settings.add_section('gui')

        path = self._txt_outputdir.path()
        if path:
            section.outputdir = path
        section.maxworkers = str(self._spn_workers.value())
        section.overwrite = str(self._chk_overwrite.isChecked())

        settings.write()

        event.accept()

    def addAvailableOptions(self, options):
        self._lst_available.model().addOptions(options)

    def removeAvailableOptions(self, options):
        self._lst_available.model().removeOptions(options)

    def clearAvailableOptions(self):
        self._lbl_available.model().clearOptions()

    def start(self, outputdir, overwrite, max_workers):
        self._runner = LocalRunner(outputdir=outputdir,
                                   overwrite=overwrite,
                                   max_workers=max_workers)

        self._tbl_options.setModel(_StateOptionsTableModel(self._runner))

        self._spn_workers.setEnabled(False)
        self._txt_outputdir.setEnabled(False)
        self._chk_overwrite.setEnabled(False)
        self._btn_addtoqueue.setEnabled(True)
        self._btn_addalltoqueue.setEnabled(True)
        self._btn_start.setEnabled(False)
        self._btn_cancel.setEnabled(True)
        self._btn_close.setEnabled(False)
        self._btn_import.setEnabled(True)

        self._runner.options_added.connect(self.options_added.emit)
        self._runner.options_running.connect(self.options_running.emit)
        self._runner.options_simulated.connect(self.options_simulated.emit)
        self._runner.options_error.connect(self.options_error.emit)
        self._runner.results_saved.connect(self.results_saved.emit)
        self._runner.results_error.connect(self.results_error.emit)

        self._running_timer.start()
        self._runner.start()

    def cancel(self):
        if self._runner is None:
            return
        self._runner.cancel()
        self._running_timer.stop()

        self._runner.options_added.disconnect(self.options_added.emit)
        self._runner.options_running.disconnect(self.options_running.emit)
        self._runner.options_simulated.disconnect(self.options_simulated.emit)
        self._runner.options_error.disconnect(self.options_error.emit)
        self._runner.results_saved.disconnect(self.results_saved.emit)
        self._runner.results_error.disconnect(self.results_error.emit)

        self._runner = None

        self._spn_workers.setEnabled(True)
        self._txt_outputdir.setEnabled(True)
        self._chk_overwrite.setEnabled(True)
        self._btn_addtoqueue.setEnabled(False)
        self._btn_addalltoqueue.setEnabled(False)
        self._btn_start.setEnabled(True)
        self._btn_cancel.setEnabled(False)
        self._btn_close.setEnabled(True)
        self._btn_import.setEnabled(False)

    def is_running(self):
        return self._runner is not None and self._runner.is_alive()
Пример #17
0
class PathEditor(QWidget):
    """ Custom widget with LineEdit and a Button to browse file """

    editingFinished = Signal()

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

        self.parent = parent
        self.index = index
        self.open_dialog_visible = False

        self.setFocusPolicy(Qt.StrongFocus)

        editor_layout = QHBoxLayout()
        editor_layout.setContentsMargins(0, 0, 0, 0)
        editor_layout.setSpacing(0)

        self.line_edit = LineEditor(self)
        editor_layout.addWidget(self.line_edit)

        self.button = QPushButton('')
        self.button.setIcon(QIcon(':/editor_folder'))
        self.button.setFixedSize(18, 17)
        self.button.setToolTip('Select a texture')
        self.button.setStatusTip('Select a texture')
        self.button.clicked.connect(self.select_file)
        editor_layout.addWidget(self.button)

        self.setFocusProxy(self.line_edit)
        self.setLayout(editor_layout)

    def setText(self, text):
        """ Set line edit text

        :param text: (string) text...
        """
        self.line_edit.setText(text)

    def text(self):
        """ return line edit text """
        return self.line_edit.text()

    def select_file(self):
        """ Maya Open Dialog to select file texture """
        self.open_dialog_visible = True

        if MTTSettings.value('browserFirstStart'):
            image_dir = cmds.optionVar(query='MTT_browserStartFolder')
        else:
            image_dir = cmds.workspace(query=True,
                                       rootDirectory=True) + cmds.workspace(
                                           fileRuleEntry='sourceImages')
            MTTSettings.set_value('browserFirstStart', True)

        file_path = cmds.fileDialog2(fileMode=1,
                                     startingDirectory=image_dir,
                                     caption='Select a texture',
                                     okCaption='Select')

        if file_path:
            new_path = file_path[0]
            cmds.optionVar(
                sv=['MTT_browserStartFolder',
                    os.path.dirname(new_path)])
            if MTTSettings.value('forceRelativePath'):
                new_path = convert_to_relative_path(new_path)
                # relative_path = workspace(projectPath=new_path)
                # if relative_path != new_path:
                #     new_path = '/%s' % relative_path
            self.line_edit.setText(new_path)
        self.open_dialog_visible = False
        self.close()
        self.editingFinished.emit()
        cmds.showWindow(WINDOW_NAME)
Пример #18
0
class CompareSequences(QMainWindow):
    def __init__(self):
        super(CompareSequences, self).__init__()

        self.setWindowTitle('Compare Sequences')
        self.setFixedHeight(125)

        self._ledit1 = QLineEdit()
        self._btn_pick_1 = QPushButton('...')
        self._ledit2 = QLineEdit()
        self._btn_pick_2 = QPushButton('...')
        self._btn_compare = QPushButton('Compare')
        self._progress_bar = QProgressBar(self.statusBar())

        self._setup_ui()
        self._set_connections()

    def _compare(self):
        self._toggle_ui()

        src_one = self._ledit1.text()
        src_two = self._ledit2.text()

        # TODO: put in some checks for valid sequences

        if not (src_one and src_two):
            msg = 'Please pick proper sequences.'
            print msg
            nuke.message(msg)
        else:
            read1 = nuke.createNode('Read', inpanel=False)
            read1.knob('file').fromUserText(src_one)

            read2 = nuke.createNode('Read', inpanel=False)
            read2.knob('file').fromUserText(src_two)
            read2.setXYpos(read1.xpos() + 100, read1.ypos())

            if not (read1.width() == read2.width() and read1.height() == read2.height()):
                msg = 'Sequences are not the same resolution.'
                print msg
                nuke.message(msg)
            else:
                # TODO: check for same resolution

                m = nuke.createNode('Merge2', inpanel=False)
                m.knob('operation').setValue(6)
                m.setXYpos(read1.xpos(), read2.ypos() + 100)
                m.setInput(0, read1)
                m.setInput(1, read2)

                c = nuke.createNode('CurveTool', inpanel=False)
                c.knob('operation').setValue(3)
                c.knob('ROI').fromDict(
                    {
                        'x': 0,
                        'y': 0,
                        'r': read1.width(),
                        't': read1.height()
                    }
                )

                v = nuke.createNode('Viewer')

                check = False
                frame = None

                first = read1.knob('first').value()
                last = read1.knob('last').value()

                self._progress_bar.setRange(first, last)
                for i in range(first, last + 1):
                    self._progress_bar.setValue(i)
                    nuke.execute(c, i, i)
                    data = c.knob('maxlumapixvalue').animations()
                    check = False
                    for curve in data:
                        if not curve.constant():
                            check = True
                            frame = i
                            break
                    if check:
                        break

                if not check:
                    msg = 'There is no difference.'
                else:
                    msg = 'There is a difference at frame %d.' % frame

                nuke.message(msg)

                self._progress_bar.reset()

        self._toggle_ui()

    def _pick_sequence(self):
        btn = self.sender()

        le_btn_pair = {
            self._btn_pick_1: self._ledit1,
            self._btn_pick_2: self._ledit2
        }

        clip_path = nuke.getClipname('Pick Sequence to compare')

        le_btn_pair[btn].setText(clip_path)

    def _set_connections(self):
        self._btn_pick_1.released.connect(self._pick_sequence)
        self._btn_pick_2.released.connect(self._pick_sequence)
        self._btn_compare.released.connect(self._compare)

    def _setup_ui(self):
        self._btn_pick_1.setFixedWidth(25)
        self._btn_pick_1.setToolTip('Pick first sequence.')
        self._btn_pick_2.setFixedWidth(25)
        self._btn_pick_2.setToolTip('Pick second sequence.')
        self._btn_compare.setToolTip('Compare sequences.')
        self._progress_bar.setFixedHeight(10)

        lyt_seq1 = QHBoxLayout()
        lyt_seq1.addWidget(self._ledit1)
        lyt_seq1.addWidget(self._btn_pick_1)

        lyt_seq2 = QHBoxLayout()
        lyt_seq2.addWidget(self._ledit2)
        lyt_seq2.addWidget(self._btn_pick_2)

        lyt_main = QVBoxLayout()
        lyt_main.addLayout(lyt_seq1)
        lyt_main.addLayout(lyt_seq2)
        lyt_main.addWidget(self._btn_compare)

        main_widget = QWidget()
        main_widget.setLayout(lyt_main)

        self.setCentralWidget(main_widget)

    def _toggle_ui(self):
        self._ledit1.setEnabled(not self._ledit1.isEnabled())
        self._ledit2.setEnabled(not self._ledit2.isEnabled())
        self._btn_pick_1.setEnabled(not self._btn_pick_1.isEnabled())
        self._btn_pick_2.setEnabled(not self._btn_pick_2.isEnabled())
        self._btn_compare.setEnabled(not self._btn_compare.isEnabled())
    def __create_ui(self):
        """ Create main UI """
        self.setWindowTitle(CREATE_NODE_TITLE)

        # remove window decoration if path and type is set
        if self.defined_path and self.defined_type:
            self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup)

        main_layout = QVBoxLayout(self)
        main_layout.setSpacing(1)
        main_layout.setContentsMargins(2, 2, 2, 2)

        # content layout
        content_layout = QVBoxLayout()
        self.files_model = QFileSystemModel()
        self.files_model.setNameFilterDisables(False)
        self.files_list = MTTFileList()
        self.files_list.setAlternatingRowColors(True)
        self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.files_list.selectionValidated.connect(self.do_validate_selection)
        self.files_list.goToParentDirectory.connect(self.on_go_up_parent)
        self.files_list.doubleClicked.connect(self.on_double_click)
        self.files_list.setModel(self.files_model)

        buttons_layout = QHBoxLayout()

        content_layout.addLayout(self.__create_filter_ui())
        content_layout.addWidget(self.files_list)
        content_layout.addLayout(buttons_layout)
        self.files_list.filter_line = self.filter_line

        if not self.defined_path:
            # path line
            path_layout = QHBoxLayout()
            # bookmark button
            bookmark_btn = QPushButton('')
            bookmark_btn.setFlat(True)
            bookmark_btn.setIcon(QIcon(':/addBookmark.png'))
            bookmark_btn.setToolTip('Bookmark this Folder')
            bookmark_btn.setStatusTip('Bookmark this Folder')
            bookmark_btn.clicked.connect(self.on_add_bookmark)
            # path line edit
            self.path_edit = QLineEdit()
            self.path_edit.editingFinished.connect(self.on_enter_path)
            # parent folder button
            self.parent_folder_btn = QPushButton('')
            self.parent_folder_btn.setFlat(True)
            self.parent_folder_btn.setIcon(QIcon(':/SP_FileDialogToParent.png'))
            self.parent_folder_btn.setToolTip('Parent Directory')
            self.parent_folder_btn.setStatusTip('Parent Directory')
            self.parent_folder_btn.clicked.connect(self.on_go_up_parent)
            # browse button
            browse_btn = QPushButton('')
            browse_btn.setFlat(True)
            browse_btn.setIcon(QIcon(':/navButtonBrowse.png'))
            browse_btn.setToolTip('Browse Directory')
            browse_btn.setStatusTip('Browse Directory')
            browse_btn.clicked.connect(self.on_browse)
            # parent widget and layout
            path_layout.addWidget(bookmark_btn)
            path_layout.addWidget(self.path_edit)
            path_layout.addWidget(self.parent_folder_btn)
            path_layout.addWidget(browse_btn)
            main_layout.addLayout(path_layout)

            # bookmark list
            bookmark_parent_layout = QHBoxLayout()
            bookmark_frame = QFrame()
            bookmark_frame.setFixedWidth(120)
            bookmark_layout = QVBoxLayout()
            bookmark_layout.setSpacing(1)
            bookmark_layout.setContentsMargins(2, 2, 2, 2)
            bookmark_frame.setLayout(bookmark_layout)
            bookmark_frame.setFrameStyle(QFrame.Sunken)
            bookmark_frame.setFrameShape(QFrame.StyledPanel)
            self.bookmark_list = MTTBookmarkList()
            self.bookmark_list.bookmarkDeleted.connect(self.do_delete_bookmark)
            self.bookmark_list.setAlternatingRowColors(True)
            self.bookmark_list.dragEnabled()
            self.bookmark_list.setAcceptDrops(True)
            self.bookmark_list.setDropIndicatorShown(True)
            self.bookmark_list.setDragDropMode(QListView.InternalMove)
            self.bookmark_list_sel_model = self.bookmark_list.selectionModel()
            self.bookmark_list_sel_model.selectionChanged.connect(
                self.on_select_bookmark)

            bookmark_layout.addWidget(self.bookmark_list)
            bookmark_parent_layout.addWidget(bookmark_frame)
            bookmark_parent_layout.addLayout(content_layout)
            main_layout.addLayout(bookmark_parent_layout)

            self.do_populate_bookmarks()

        else:
            main_layout.addLayout(content_layout)

        if not self.defined_type:
            # type layout
            self.types = QComboBox()
            self.types.addItems(self.supported_node_type)
            self.types.currentIndexChanged.connect(self.on_node_type_changed)
            if cmds.optionVar(exists='MTT_lastNodeType'):
                last = cmds.optionVar(query='MTT_lastNodeType')
                if last in self.supported_node_type:
                    self.types.setCurrentIndex(
                        self.supported_node_type.index(last))
            buttons_layout.addWidget(self.types)

        if not self.defined_path or not self.defined_type:
            create_btn = QPushButton('C&reate')
            create_btn.clicked.connect(self.accept)
            cancel_btn = QPushButton('&Cancel')
            cancel_btn.clicked.connect(self.reject)

            buttons_layout.addStretch()
            buttons_layout.addWidget(create_btn)
            buttons_layout.addWidget(cancel_btn)
Пример #20
0
class MainWindow(QDialog):
    """monkey_linux UI"""
    def __init__(self,parent=None):
        super(MainWindow, self).__init__()
        self.init_conf()
        self.setParent(parent)
        common.Log.info("set up ui")
        self.setup_ui()
        self.findDeviceAction.triggered.connect(self.get_device_status)
        self.deleteDeviceAction.triggered.connect(self.del_device)
        # self.storeButton.clicked.connect(self.set_conf)
        self.startButton.clicked.connect(self.start)
        self.stopButton.clicked.connect(self.stop)
        self.checkLogButton.clicked.connect(self.check)
        self.monkeyButton.clicked.connect(self.checkMonkeyLog)
        self.exportButton.clicked.connect(self.exportConf)
        self.importButton.clicked.connect(self.importConf)
        self.setAbout.triggered.connect(self.about)
        self.startTime = datetime.datetime.now()
        self.secsTime = float(1) * 60 * 60



    def setup_ui(self):
        # main window width hand height
        # self.setMinimumWidth(600)
        self.setMaximumWidth(800)
        self.setMinimumHeight(600)
        # main window title
        self.setWindowTitle(static.title)
        # file menu bar
        self.menuBar = QMenuBar()
        self.menuBar.setMaximumHeight(23)
        # self.menuFile = self.menuBar.addMenu(static.menuFile)
        # self.importAction = QAction(QIcon(static.importPNG), static.importFile, self)
        # self.exportAction = QAction(QIcon(static.exportPNG), static.exportFile, self)
        # self.menuFile.addAction(self.importAction)
        # self.menuFile.addAction(self.exportAction)
        self.setEnvActioin = QAction(QIcon(static.setPNG), static.pcSet, self)
        self.menuSet = self.menuBar.addMenu(static.menuSet)
        self.menuSet.addAction(self.setEnvActioin)

        self.setAbout = QAction(QIcon(static.setPNG), static.menuAbout, self)
        self.setAbout.setStatusTip('About')  # 状态栏提示
        self.menuHelp = self.menuBar.addMenu(static.menuHelp)
        self.menuHelp.addAction(self.setAbout)



        # set all layout
        self.hbox = QHBoxLayout(self)

        # device ========
        self.topLeft = QFrame(self)
        self.topLeft.setMaximumSize(218, 300)
        self.topLeft.setMinimumSize(218, 200)
        self.topLeft.setFrameShape(QFrame.StyledPanel)
        self.topLeftLayout = QVBoxLayout(self.topLeft)
        self.toolBar = QToolBar()
        # self.androidDeviceAction = QRadioButton('Android', self)
        # self.androidDeviceAction.setFocusPolicy(Qt.NoFocus)
        # self.ipDeviceAction = QRadioButton('IP', self)
        # self.ipDeviceAction.setFocusPolicy(Qt.NoFocus)
        # self.ipDeviceAction.move(10, 10)
        # self.ipDeviceAction.toggle()
        self.findDeviceAction = QAction(QIcon(static.findDevice), static.findDeviceButton, self)
        self.deleteDeviceAction = QAction(QIcon(static.deleteDevice), static.deleteDeviceButton, self)
        # self.toolBar.addWidget(self.androidDeviceAction)
        # self.toolBar.addWidget(self.ipDeviceAction)
        self.toolBar.addAction(self.findDeviceAction)
        self.toolBar.addAction(self.deleteDeviceAction)
        self.deviceLab = QLabel(static.deviceName, self)
        self.device = QTableWidget(1, 2)
        self.device.setHorizontalHeaderLabels(['name', 'status'])
        self.device.setColumnWidth(0, 100)
        self.device.setColumnWidth(1, 80)
        self.topLeftLayout.addWidget(self.deviceLab)
        self.topLeftLayout.addWidget(self.toolBar)

        self.topLeftLayout.addWidget(self.device)


        # set button or other for running monkey or not and status of device and log ========
        self.topRight = QFrame(self)
        self.topRight.setFrameShape(QFrame.StyledPanel)
        self.topRight.setMaximumHeight(40)
        self.startButton = QPushButton(QIcon(static.startPNG), "")
        self.stopButton = QPushButton(QIcon(static.stopPNG), "")

        self.status = QLabel(static.status)
        self.statusEdit = QLineEdit(self)
        self.statusEdit.setReadOnly(True)
        self.statusEdit.setMaximumWidth(80)
        self.statusEdit.setMinimumWidth(80)
        self.statusEdit.setText("")
        # check log
        self.checkLogButton = QPushButton(static.checkLog)
        self.checkLogButton.setMaximumHeight(20)
        self.checkLogButton.setMinimumHeight(20)
        self.checkLogButton.setMaximumWidth(60)
        self.selectLog = QLabel(static.selectlog)
        self.logfile = QComboBox()
        self.dirlist = os.listdir(os.path.join(DIR, "Result"))
        for d in self.dirlist:
            if d != "AutoMonkey.log":
                self.logfile.insertItem(0, d)
        self.logfile.setMaximumWidth(150)
        self.logfile.setMaximumHeight(20)
        self.logfile.setMinimumHeight(20)
        self.topLayout = QHBoxLayout(self.topRight)
        self.topLayout.addWidget(self.startButton)
        self.topLayout.addWidget(self.stopButton)
        self.topLayout.addWidget(self.status)
        self.topLayout.addWidget(self.statusEdit)
        self.topLayout.addWidget(self.selectLog)
        self.topLayout.addWidget(self.logfile)
        self.topLayout.addWidget(self.checkLogButton)

        # set parameter for monkey =======
        self.midRight = QFrame(self)
        self.midRight.setMaximumSize(555, 200)
        self.midRight.setMinimumSize(555, 200)
        self.midRight.setFrameShape(QFrame.StyledPanel)
        self.midRightLayout = QVBoxLayout(self.midRight)
        self.subLayout0 = QVBoxLayout()
        self.subLayout1 = QVBoxLayout()
        self.subLayout2 = QHBoxLayout()
        self.subLayout3 = QVBoxLayout()
        self.subLayout4 = QVBoxLayout()
        self.subLayout5 = QHBoxLayout()
        self.subLayout6 = QHBoxLayout()
        self.toolBar = QToolBar()
        # self.storeAction = QAction(QIcon(static.storePNG), static.storeButton, self)
        self.startAction = QAction(QIcon(static.startPNG), static.startButton, self)
        self.stopAction = QAction(QIcon(static.stopPNG), static.stopButton, self)
        # self.toolBar.addAction(self.storeAction)
        self.toolBar.addAction(self.startAction)
        self.toolBar.addAction(self.stopAction)
        self.timeLongLbl = QLabel(static.timeString, self)
        self.timeLong = QLineEdit(self)
        self.timeLong.setMaximumWidth(100)
        self.timeLong.setMinimumWidth(100)
        self.timeLong.setPlaceholderText(static.timeLong)
        self.timeLongUnit = QLabel("H")
        self.etSetLbl = QLabel(static.eventTypeSet)
        self.etSet = QTableWidget(2, 2)
        self.etSet.setMaximumHeight(150)
        self.etSet.setHorizontalHeaderLabels(['option', 'value'])
        self.etSet.horizontalHeader().setStretchLastSection(True)
        self.etSet.setItem(0, 0, QTableWidgetItem("--throttle"))
        self.etSet.setItem(0, 1, QTableWidgetItem(str(static.eventType["--throttle"])))
        # set event type percent
        self.etPercentLbl = QLabel(static.eventTpyePercent, self)
        self.etPercent = QTableWidget(2, 2)
        self.etPercent.setMaximumHeight(150)
        self.etPercent.setHorizontalHeaderLabels(['option', 'value'])
        self.etPercent.horizontalHeader().setStretchLastSection(True)
        self.etPercent.setItem(0, 0, QTableWidgetItem("--pct-touch"))
        self.etPercent.setItem(0, 1, QTableWidgetItem(str(static.eventPercent["--pct-touch"])))
        self.etPercent.setItem(1, 0, QTableWidgetItem("--pct-motion"))
        self.etPercent.setItem(1, 1, QTableWidgetItem(str(static.eventPercent["--pct-motion"])))
        # self.storeButton = QPushButton(QIcon(static.storePNG), static.storeButton)
        # self.storeButton.setToolTip(static.storeButton)
        self.exportButton = QPushButton(QIcon(static.exportPNG), static.exportFile)
        self.exportButton.setToolTip(static.exportFile)
        self.importButton = QPushButton(QIcon(static.importPNG), static.importFile)
        self.importButton.setToolTip(static.importFile)
        self.subLayout2.addWidget(self.timeLongLbl)
        self.subLayout2.addWidget(self.timeLong)
        self.subLayout2.addWidget(self.timeLongUnit)
        self.subLayout2.addWidget(QLabel(" " * 300))
        # self.subLayout2.addWidget(self.storeButton)
        self.subLayout2.addWidget(self.exportButton)
        self.subLayout2.addWidget(self.importButton)

        self.subLayout0.addLayout(self.subLayout2)
        self.subLayout3.addWidget(self.etSetLbl)
        self.subLayout3.addWidget(self.etSet)
        self.subLayout4.addWidget(self.etPercentLbl)
        self.subLayout4.addWidget(self.etPercent)
        self.subLayout5.addLayout(self.subLayout0)
        self.subLayout6.addLayout(self.subLayout3)
        self.subLayout6.addLayout(self.subLayout4)
        self.midRightLayout.addLayout(self.subLayout5)
        self.midRightLayout.addLayout(self.subLayout6)

        # log ========
        self.bottom = QFrame(self)
        self.bottom.setFrameShape(QFrame.StyledPanel)
        # log information
        self.logInfo = QLabel(static.logInfo)
        # information filter
        self.logFilter = QLabel(static.logFilter)
        self.monkeyButton = QPushButton(static.openMonkeyLog)
        self.combo = QComboBox()
        for i in range(len(static.logLevel)):
            self.combo.addItem(static.logLevel[i])
        self.combo.setMaximumWidth(55)
        self.combo.setMaximumHeight(20)
        self.combo.setMinimumHeight(20)
        # information details
        self.bottomLayout = QVBoxLayout(self.bottom)
        self.subLayout = QHBoxLayout()
        self.subLayout.addWidget(self.logInfo)
        for i in range(10):
            self.subLayout.addWidget(QLabel(""))
        self.subLayout.addWidget(self.monkeyButton)
        self.subLayout.addWidget(self.logFilter)
        self.subLayout.addWidget(self.combo)
        self.bottomLayout.addLayout(self.subLayout)
        self.tabwidget = TabWidget()
        self.tabwidget.setMinimumHeight(100)
        self.bottomLayout.addWidget(self.tabwidget)

        # splitter mainWindow ++++++++++++++++++++++++++++++++++++
        self.splitter2 = QSplitter(Qt.Vertical)
        self.splitter2.addWidget(self.topRight)
        self.splitter2.addWidget(self.midRight)
        self.splitter0 = QSplitter(Qt.Horizontal)
        self.splitter0.addWidget(self.topLeft)
        self.splitter0.addWidget(self.splitter2)
        self.splitter1 = QSplitter(Qt.Vertical)
        self.splitter1.addWidget(self.menuBar)
        self.splitter1.addWidget(self.splitter0)
        self.splitter1.addWidget(self.bottom)
        self.hbox.addWidget(self.splitter1)
        self.setLayout(self.hbox)
        self.show()

    def about(self):
        common.showDialog(static.menuAbout, static.dialogAbout)

    def init_conf(self):
        common.Log.info("init monkey conf")
        with open(monkeyConfFile, "w") as f:
            f.write("deviceList = []" + "\n")
            f.write("times = " + static.times + "\n")
            f.write("--throttle = " + static.eventType["--throttle"] + "\n")
            f.write("--pct-touch = " + static.eventPercent["--pct-touch"] + "\n")
            f.write("--pct-motion = " + static.eventPercent["--pct-motion"] + "\n")

    def setup_env(self):
        pass

    def _set_eventType(self, confFile):
        try:
            option = self.etSet.item(0, 0).text()
            value = self.etSet.item(0, 1).text()
            if value > "0":
                with open(confFile, 'a+') as f:
                    f.write(option + " = " + value + "\n")
        except AttributeError, e:
            pass
Пример #21
0
class NewWindow(QWidget):
    def __init__(self, app=None):
        super(NewWindow, self).__init__()
        self.app = app
        glo = QVBoxLayout(self)
        if os.name == 'nt':
            icp = r_path('static\\images\\favicon.png')
        else:
            icp = r_path('static/images/favicon.png')
        # need to used objective message boxs instead of functions to set font
        self.Arial = QFont("", 15, QFont.Bold)
        self.Arials = QFont("", 10, QFont.Bold)
        # Language support varibels used by translate func
        self.Arabic = None
        self.Runningo = False
        icon = QIcon(icp)
        self.SelfIinit(icon)
        self.center()
        self.Llists(glo)
        self.set_Abutton(icp, glo)
        self.Lists(glo)
        self.Flabel(glo)
        self.set_button(glo)
        self.setLayout(glo)
        mip = self.slchange()
        self.P = rwser(mip[1].split(',')[1], mip[0], self.app)
        self.activateWindow()
        self.show()

    def SelfIinit(self, icon):
        self.setWindowTitle('Free Queue Manager ' + version)
        self.setGeometry(300, 300, 200, 150)
        self.setMinimumWidth(500)
        self.setMaximumWidth(500)
        self.setMinimumHeight(400)
        self.setMaximumHeight(400)
        # Setting Icon
        self.setWindowIcon(icon)
        QToolTip.setFont(self.Arials)

    def Flabel(self, glo):
        fontt = self.Arial
        if os.name == 'nt':
            self.ic1 = QIcon(r_path('static\\images\\pause.png'))
        else:
            self.ic1 = QIcon(r_path('static/images/pause.png'))
        self.l = QLabel('Icond', self)
        self.ic1 = self.ic1.pixmap(70, 70, QIcon.Active, QIcon.On)
        self.l.setPixmap(self.ic1)
        self.l.setAlignment(Qt.AlignCenter | Qt.AlignHCenter)
        self.l.setFont(fontt)
        self.t = QLabel('Texted', self)
        self.t.setText("Server is <u> Not running </u> <br>")
        self.t.setOpenExternalLinks(True)
        self.t.setAlignment(Qt.AlignCenter | Qt.AlignHCenter)
        self.t.setFont(fontt)
        self.t.setToolTip('Status of the server')
        self.l.setToolTip('Status of the server')
        glo.addStretch()
        glo.addWidget(self.l)
        glo.addWidget(self.t)
        glo.addStretch()

    def Lists(self, glo):
        ips = self.get_ips()
        self.sl = QComboBox()
        self.sl.addItems(ips)
        self.sl.setToolTip(
            'Select network interface with ip, so the server runs on it')
        self.sl2 = QComboBox()
        self.get_ports()
        self.sl2.setToolTip('Select a port, so server runs through it')
        self.sl.currentIndexChanged.connect(self.get_ports)
        glo.addWidget(self.sl)
        glo.addWidget(self.sl2)

    def get_ports(self, nauto=True):
        d_ports = ['5000', '8080', '3000', '80', '9931']
        m_ports = []
        while len(m_ports) < 10:
            mip = self.slchange()
            for p in d_ports:
                s = socket(AF_INET, SOCK_STREAM)
                try:
                    s.bind((mip[1].split(',')[1], int(p)))
                    s.close()
                    m_ports.append(p)
                except:
                    s.close()
                d_ports.remove(p)
            s = socket(AF_INET, SOCK_STREAM)
            p = randint(1000, 9999)
            try:
                s.bind((mip[1].split(',')[1], p))
                s.close()
                m_ports.append(str(p))
            except:
                s.close()
            if len(m_ports) >= 10:
                break
        self.sl2.clear()
        self.sl2.addItems(m_ports)

    def Llists(self, glo):
        hlayout = QHBoxLayout()
        self.lebutton = QPushButton('English', self)
        self.lebutton.setToolTip('Change language to English')
        self.lebutton.setEnabled(False)
        self.lebutton.setFont(self.Arials)
        self.labutton = QPushButton('Arabic', self)
        self.labutton.setFont(self.Arials)
        if os.name == 'nt':
            self.lebutton.setIcon(
                QPixmap(r_path('static\\images\\english.png')))
            self.labutton.setIcon(QPixmap(
                r_path('static\\images\\arabic.png')))
        else:
            self.lebutton.setIcon(QPixmap(r_path('static/images/english.png')))
            self.labutton.setIcon(QPixmap(r_path('static/images/arabic.png')))
        self.labutton.setToolTip('Change language to Arabic')
        self.labutton.setEnabled(True)
        self.lebutton.clicked.connect(partial(self.translate, ar=False))
        self.labutton.clicked.connect(self.translate)
        hlayout.addWidget(self.lebutton)
        hlayout.addWidget(self.labutton)
        glo.addLayout(hlayout)

    def slchange(self):
        return [self.sl2.currentText(), self.sl.currentText()]

    def set_button(self, glo):
        hlayout = QHBoxLayout()
        self.mbutton = QPushButton('Start', self)
        self.mbutton.clicked.connect(self.s_server)
        self.mbutton.setFont(self.Arials)
        if os.name == 'nt':
            self.mbutton.setIcon(QPixmap(r_path('static\\images\\play.png')))
        else:
            self.mbutton.setIcon(QPixmap(r_path('static/images/play.png')))
        self.mbutton2 = QPushButton('Stop', self)
        self.mbutton2.clicked.connect(self.st_server)
        if os.name == 'nt':
            self.mbutton2.setIcon(QPixmap(r_path('static\\images\\pause.png')))
        else:
            self.mbutton2.setIcon(QPixmap(r_path('static/images/pause.png')))
        self.mbutton.setToolTip('Start the server')
        self.mbutton2.setToolTip('Stop the server')
        self.mbutton2.setEnabled(False)
        self.mbutton2.setFont(self.Arials)
        hlayout.addWidget(self.mbutton)
        hlayout.addWidget(self.mbutton2)
        glo.addLayout(hlayout)

    def s_server(self):
        mip = self.slchange()
        self.P = rwser(mip[1].split(',')[1], mip[0], self.app)
        self.P.setTerminationEnabled(True)
        if not self.P.isRunning():
            try:
                self.pport = mip[0]
                self.mbutton.setEnabled(False)
                self.mbutton2.setEnabled(True)
                self.sl.setEnabled(False)
                self.sl2.setEnabled(False)
                if os.name == 'nt':
                    self.ic1 = QIcon(r_path('static\\images\\play.png'))
                else:
                    self.ic1 = QIcon(r_path('static/images/play.png'))
                self.ic1 = self.ic1.pixmap(70, 70, QIcon.Active, QIcon.On)
                self.l.setPixmap(self.ic1)
                if self.Arabic is None:
                    pp = self.slchange()
                    addr = "Server is <u>Running</u> <br>"
                    addr += " On : <a href='http://"
                    addr += pp[1].split(',')[1] + ":" + pp[0]
                    addr += "'> http://" + pp[1].split(',')[1] + ":" + pp[0]
                    addr += "</a>"
                    self.t.setText(addr)
                    self.t.setFont(self.Arial)
                else:
                    pp = self.slchange()
                    addr = u"الخدمة <u>مشغــلة</u> و تبث على : <br>"
                    addr += u"<a href='http://"
                    addr += pp[1].split(',')[1] + u":" + pp[0]
                    addr += u"'> http://" + pp[1].split(',')[1] + u":" + pp[0]
                    addr += u"</a>"
                    self.t.setText(addr)
                    self.t.setFont(self.Arial)
                self.P.start()
                self.Runningo = True
            except:
                self.eout()
        else:
            self.eout()

    def st_server(self):
        if self.P.isRunning():
            try:
                if self.P.isRunning:
                    self.P.stop()
                self.mbutton.setEnabled(True)
                self.mbutton2.setEnabled(False)
                self.sl.setEnabled(True)
                self.sl2.setEnabled(True)
                if self.Arabic is None:
                    self.t.setText("Server is <u> Not running </u> <br>")
                else:
                    self.t.setText(u"الــخـدمة <u>متــوقفــة</u><br>")
                # removing the last used port to avoid termination error
                cind = self.sl2.currentIndex()
                self.sl2.removeItem(cind)
                self.get_ports()
                self.Runningo = False
            except:
                self.eout()
        else:
            self.eout()

    def set_Abutton(self, icon, glo):
        def show_about(nself):
            if nself.Arabic is None:
                Amsg = "<center>All credit reserved to the author of FQM "
                Amsg += " version " + version
                Amsg += ", This work is a free, open-source project licensed "
                Amsg += " under Mozilla Public License version 2.0 . <br><br>"
                Amsg += " visit us for more infos and how-tos :<br> "
                Amsg += "<b><a href='https://fqms.github.io/'> "
                Amsg += "https://fqms.github.io/ </a> </b></center>"
                Amsgb = "About FQM"
            else:
                Amsg = u" <center> "
                Amsg += u" إدارة الحشود الحر النسخة " + version + u" "
                Amsg += u"حقوق نشر هذا البرنامج محفوظة و تخضع "
                Amsg += u" لرخصة البرامج الحرة و مفتوحة المصدر "
                Amsg += u" Mozilla Public License version 2.0 . "
                Amsg += u"<br><br> "
                Amsg += u"للمزيد من المعلومات و الشروحات , قم بزيارة :"
                Amsg += u"<br> <b><a href='https://fqms.github.io/'>"
                Amsg += u"https://fqms.github.io </a> </b></center>"
                Amsgb = u"عن النظام"
            return QMessageBox.about(self, Amsgb, Amsg)

        self.abutton = QPushButton('', self)
        self.abutton.setIcon(QPixmap(icon))
        self.abutton.setIconSize(QSize(150, 70))
        self.abutton.setToolTip('About FQM')
        self.abutton.clicked.connect(partial(show_about, self))
        glo.addWidget(self.abutton)

    def closeEvent(self, event=None):
        if self.Runningo:
            if self.Arabic is None:
                response = self.msgApp(
                    "Exiting while running",
                    "Are you really sure, you want to exit ?")
            else:
                response = self.msgApp(
                    u"تأكيد الخروج",
                    u"تريد بالفعل , الخروج و إيقاف البرنامج ؟")
            if response == 'y':
                if event is not None:
                    event.accept()
                if self.P.isRunning():
                    self.P.stop()
                sys.exit(0)
            else:
                if event is not None:
                    event.ignore()
        else:
            if event is not None:
                event.accept()
            if self.P.isRunning():
                self.P.stop()
            sys.exit(0)

    def msgApp(self, title, msg):
        uinfo = QMessageBox.question(self, title, msg,
                                     QMessageBox.Yes | QMessageBox.No)
        if uinfo == QMessageBox.Yes:
            return 'y'
        if uinfo == QMessageBox.No:
            return 'n'

    def eout(self):
        if self.P.isRunning():
            self.P.stop()
        if self.Arabic is None:
            msgg = "<center>"
            msgg += " Opps, a critical error has occurred, we will be "
            msgg += " grateful if you can help fixing it, by reporting to us "
            msgg += " at : <br><br> "
            msgg += "<b><a href='https://fqms.github.io/'> "
            msgg += "https://fqms.github.io/ </a></b> </center>"
            mm = QMessageBox.critical(self, "Critical Error", msgg,
                                      QMessageBox.Ok)
        else:
            msgg = u"<center>"
            msgg += u"حدث خطأ فادح في تشغيل النظام , سنكون شاكرين لك إن "
            msgg += u"قمت بتبليغنا عنه , ليتم إصلاحه في أقرب وقت "
            msgg += u"<br>"
            msgg += u"<br><b><a href='https://fqms.github.io/'> "
            msgg += u"https://fqms.github.io </a></b> </center>"
            mm = QMessageBox.critical(self, u"خطأ في التشغيل", msgg,
                                      QMessageBox.Ok)

    def center(self):
        qrect = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qrect.moveCenter(cp)
        self.move(qrect.topLeft())

    def get_ips(self):
        il = []
        for i in interfaces():
            try:
                if os.name != 'nt':
                    inf = i + " ,"
                else:
                    inf = ' ,'
                inf += ifaddresses(i)[2][0].get('addr')
                il.append(inf)
            except:
                pass
        return il

    def translate(self, ar=True):
        if ar:
            self.Arabic = "arabic"
            self.labutton.setEnabled(False)
            self.labutton.setText(u"العربية")
            self.labutton.setToolTip(u"تغير اللغة إلى العربية")
            self.lebutton.setText(u"الإنجليزية")
            self.lebutton.setToolTip(u"تغير اللغة إلى الإنجليزية")
            self.lebutton.setEnabled(True)
            self.Amsgb = u"عن النظام"
            self.abutton.setToolTip(u"عن النظام")
            self.mbutton.setText(u"تشغــيل")
            self.mbutton.setToolTip(u"تشغيل الخدمة")
            self.mbutton2.setText(u"إيــقاف")
            self.mbutton2.setToolTip(u"إيقاف الخدمة")
            self.sl.setToolTip(u"إختار عنوان IP ليتم بث الخدمة عليه")
            self.sl2.setToolTip(u"إختار منفذ ليتم بث الخدمة من خلاله")
            self.t.setToolTip(u"حالة الخدمة ")
            self.l.setToolTip(u"حالة الخدمة ")
            if self.Runningo:
                pp = self.slchange()
                addr = u"الخدمة <u>مشغــلة</u> و تبث على : <br>"
                addr += u"<a href='http://"
                addr += pp[1].split(',')[1] + u":" + pp[0]
                addr += u"'> http://" + pp[1].split(',')[1] + u":" + pp[0]
                addr += u"</a>"
                self.t.setText(addr)
            else:
                self.t.setText(u"الــخـدمة <u>متــوقفــة</u><br>")
        else:
            self.Arabic = None
            self.lebutton.setEnabled(False)
            self.lebutton.setText("English")
            self.lebutton.setToolTip('Change language to English')
            self.labutton.setEnabled(True)
            self.labutton.setText("Arabic")
            self.labutton.setToolTip('Change language to Arabic')
            self.Amsgb = "About FQM"
            self.abutton.setToolTip('About FQM')
            self.mbutton.setText("Start")
            self.mbutton.setToolTip("Start the server")
            self.mbutton2.setText("Stop")
            self.mbutton2.setToolTip("Stop the server")
            self.sl.setToolTip(
                'Select network interface with ip, so the server runs on it')
            self.sl2.setToolTip('Select a port, so server runs through it')
            self.t.setToolTip('Status of the server')
            self.l.setToolTip('Status of the server')
            if self.Runningo:
                pp = self.slchange()
                addr = "Server is <u>Running</u> <br>"
                addr += " On : <a href='http://"
                addr += pp[1].split(',')[1] + ":" + pp[0]
                addr += "'> http://" + pp[1].split(',')[1] + ":" + pp[0]
                addr += "</a>"
                self.t.setText(addr)
            else:
                self.t.setText("Server is <u> Not running </u> <br>")
class Deformation_GUI(QWidget):
    #Initialize the variable
    def __init__(self, oriPath, protoPath, oriPointsPath, protoPointsPath,
                 regionsPath):
        super(Deformation_GUI, self).__init__()
        localParas, points = preprocess(oriPath, protoPath, oriPointsPath,
                                        protoPointsPath, regionsPath, 'L2')
        self.oriImg, self.protoImg, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs = localParas
        self.oriPlotDict, self.protoPlotDict, self.oriPoints, self.protoPoints = points
        self.oriPoints = np.array(self.oriPoints)
        self.protoPoints = np.array(self.protoPoints)
        self.e = 2
        self.alpha = 1
        self.oriPath = oriPath
        self.protoPath = protoPath
        self.oriPointsPath = ''
        self.protoPointsPath = ''
        self.regionsPath = regionsPath
        self.transform = 'Morphing'
        self.newImg = None
        self.initUI()

    #Initialize the GUI
    def initUI(self):
        #Set Window
        QToolTip.setFont(QFont('Serif', 10))
        self.setGeometry(280, 210, 800, 450)
        self.setWindowTitle('Image Registration Based on Control Points')
        #Set Algorithm
        self.comboAffineLabel = QLabel(self)
        self.comboAffineLabel.setText('Algorithm:')
        self.comboAffineLabel.setGeometry(60, 270, 230, 30)
        self.comboAffine = QComboBox(self)
        self.comboAffine.addItem("Morphing")
        self.comboAffine.addItem("Local Affine Transformation")
        self.comboAffine.addItem("Moving Least Squares")
        self.comboAffine.setGeometry(22, 290, 225, 30)
        self.comboAffine.activated[str].connect(self.affineChoiceChange)
        #Choose Human Face Image
        self.oriBtn = QPushButton('Human Face Image', self)
        self.oriBtn.setToolTip('Human Face Image')
        self.oriBtn.setGeometry(20, 330, 230, 30)
        self.oriBtn.clicked.connect(self.showOriDialog)
        #Choose Ape or another Human image
        self.protoBtn = QPushButton('Ape or Human image', self)
        self.protoBtn.setToolTip('Ape or Human image')
        self.protoBtn.setGeometry(310, 330, 230, 30)
        self.protoBtn.clicked.connect(self.showProtoDialog)
        #parameter e
        self.eLabel = QLabel(self)
        self.eLabel.setText('E Value:0.00')
        self.eLabel.setGeometry(550, 300, 200, 30)
        self.eSld = QSlider(Qt.Horizontal, self)
        self.eSld.setRange(0, 10**5)
        self.eSld.setFocusPolicy(Qt.NoFocus)
        self.eSld.setGeometry(550, 330, 120, 30)
        self.eSld.valueChanged[int].connect(self.changeEValue)
        #parameter alpha
        self.aLabel = QLabel(self)
        self.aLabel.setText('Alpha Value:0.00')
        self.aLabel.setGeometry(680, 300, 200, 30)
        self.aSld = QSlider(Qt.Horizontal, self)
        self.aSld.setRange(0, 10**5)
        self.aSld.setFocusPolicy(Qt.NoFocus)
        self.aSld.setGeometry(680, 330, 100, 30)
        self.aSld.valueChanged[int].connect(self.changeAlphaValue)
        # The Image
        self.oriTextLabel = QLabel(self)
        self.protoTextLabel = QLabel(self)
        self.transTextLabel = QLabel(self)
        self.oriTextLabel.setText('The Human Image')
        self.protoTextLabel.setText('The Ape or another Human Image')
        self.transTextLabel.setText('Deformation Image')
        self.oriTextLabel.move(70, 5)
        self.protoTextLabel.move(350, 5)
        self.transTextLabel.move(580, 5)
        self.oriLabel = QLabel(self)
        self.protoLabel = QLabel(self)
        self.transLabel = QLabel(self)
        pixmap = QPixmap(self.oriPath)
        pixmap2 = QPixmap(self.protoPath)
        self.oriLabel.setPixmap(pixmap)
        self.protoLabel.setPixmap(pixmap2)
        self.transLabel.setPixmap(pixmap)
        #Set Position
        self.oriLabel.setGeometry(20, 20, 230, 230)
        self.protoLabel.setGeometry(290, 20, 230, 230)
        self.transLabel.setGeometry(560, 20, 230, 230)
        self.oriLabel.setScaledContents(True)
        self.protoLabel.setScaledContents(True)
        self.transLabel.setScaledContents(True)
        #import points
        self.loadOriBtn = QPushButton('Deformed Points', self)
        self.loadOriBtn.setToolTip('Load Control Points From Txt File')
        self.loadOriBtn.setGeometry(20, 365, 230, 30)
        self.loadOriBtn.clicked.connect(self.showLoadOriDialog)
        self.loadProtoBtn = QPushButton('Control Points', self)
        self.loadProtoBtn.setToolTip('Load Control Points From Txt File')
        self.loadProtoBtn.setGeometry(310, 365, 230, 30)
        self.loadProtoBtn.clicked.connect(self.showLoadProtoDialog)
        #Deformed
        self.confirmBtn = QPushButton('Deformed', self)
        self.confirmBtn.setToolTip('Deformed')
        self.confirmBtn.setGeometry(580, 365, 150, 30)
        self.confirmBtn.clicked.connect(self.transformAction)
        self.show()

    #Deformed Generate
    def transformAction(self):

        try:
            #three algorithm
            if self.transform == 'Morphing':
                self.oriImg = np.array(Image.open(self.oriPath))
                self.protoImg = np.array(Image.open(self.protoPath))
                newImg = morphingAction((self.oriPath).encode('utf-8'),
                                        self.protoPath.encode('utf-8'),
                                        self.oriPointsPath.encode('utf-8'),
                                        self.protoPointsPath.encode('utf-8'),
                                        self.alpha)
            else:
                localParas, points = preprocess(self.oriPath, self.protoPath,
                                                self.oriPointsPath,
                                                self.protoPointsPath,
                                                self.regionsPath, 'L2')
                if points == None:
                    QtGui.QMessageBox.information(self, "Error", localParas)
                    return
                self.oriImg, self.protoImg, self.regionsPoints, self.is_in_regions_fun, self.distance_funs, self.affine_funs = localParas
                self.oriPlotDict, self.protoPlotDict, self.oriPoints, self.protoPoints = points
                if self.oriImg.shape[len(self.oriImg.shape) -
                                     1] != self.protoImg.shape[
                                         len(self.protoImg.shape) - 1]:
                    QtGui.QMessageBox.information(
                        self, "Error",
                        "The type of the figures is not the same, please choose another figure"
                    )
                    return
                if self.transform == 'Local Affine Transformation':
                    newImg = local_affine(self.oriImg, self.protoImg, self.e,
                                          self.regionsPoints,
                                          self.is_in_regions_fun,
                                          self.distance_funs, self.affine_funs)
                elif self.transform == "Moving Least Squares":
                    newImg = MLS(self.oriImg, self.protoImg, self.oriPoints,
                                 self.protoPoints, self.alpha)
        except BaseException:
            QtGui.QMessageBox.information(
                self, "Error",
                "There are error in the point choice or other things.")
            newImg = morphingAction((self.oriPath).encode('utf-8'),
                                    self.protoPath.encode('utf-8'),
                                    self.oriPointsPath.encode('utf-8'),
                                    self.protoPointsPath.encode('utf-8'),
                                    self.alpha)

        self.newImg = np.uint8(newImg)
        newImg = rgb2bgr(np.uint8(newImg))
        qimage = QImage(newImg, newImg.shape[1], newImg.shape[0],
                        QImage.Format_ARGB32)
        pixmap_array = QPixmap.fromImage(qimage)
        self.transLabel.setPixmap(pixmap_array)

    def showProtoDialog(self):
        fname, _ = QtGui.QFileDialog.getOpenFileName(
            self, 'Open file', '/home', "Image Files (*.png *.jpg *.bmp)")
        if fname != None and fname != '':
            self.protoPath = fname
            self.protoLabel.setPixmap(QPixmap(self.protoPath))

    def showLoadOriDialog(self):
        fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
                                                     '/home',
                                                     "Text files (*.txt)")
        if fname != None and fname != '':
            self.oriPointsPath = fname

    def showLoadProtoDialog(self):
        fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
                                                     '/home',
                                                     "Text files (*.txt)")
        if fname != None and fname != '':
            self.protoPointsPath = fname
        else:
            self.protoPointsPath = ''

    def showOriDialog(self):
        fname, _ = QtGui.QFileDialog.getOpenFileName(
            self, 'Open file', '/home', "Image Files (*.png *.jpg *.bmp)")
        if fname != None and fname != '':
            self.oriPath = fname
            print(self.oriPath)
            self.oriLabel.setPixmap(QPixmap(self.oriPath))

    #e value in Local Affine Algorithm
    def changeEValue(self, x):
        self.e = 4.0 * x / 10**5
        self.eLabel.setText('E Value:' + str('%.2f' % self.e))

    #alpha value in MLS and Morphing Algorithm
    #the alpha range is  different
    def changeAlphaValue(self, x):
        if self.transform == 'Moving Least Squares':
            self.alpha = 2.0 * x / 10**5
        elif self.transform == 'Morphing':
            self.alpha = 1.0 * x / 10**5
        self.aLabel.setText('Alpha Value:' + str('%.2f' % self.alpha))

    # 3 Algorithm
    def affineChoiceChange(self, item):
        if self.transform in ['Moving Least Squares', 'Morphing'] and item in [
                'Moving Least Squares', 'Morphing'
        ] and item != self.transform:
            self.alpha = 0.0
            self.aSld.setValue(self.alpha)
        self.transform = item
Пример #23
0
class NodeLister(QFrame):
    def __init__(self):
        super(NodeLister, self).__init__()

        self.setWindowTitle('Node Lister')

        self._btn_refresh = QPushButton('Refresh')
        self._btn_expand = QPushButton('Expand/Collapse')
        self._tree = NodeTree()
        self._ledit_search = QLineEdit()

        self._expand_state = False

        self._setup_ui()
        self._set_connections()

    def _expand_toggle(self):
        self._expand_state = not self._expand_state
        if self._expand_state:
            self._tree.expandAll()
        else:
            self._tree.collapseAll()

    def _filter_list(self):
        search_strings = str(self._ledit_search.text()).split()
        proxy = self._tree.model()
        model = proxy.sourceModel()
        show_rows = list()
        node_rows = list()
        rows = model.get_rows()
        class_rows = filter(lambda x: type(x) == ClassRow, rows)
        for class_row in class_rows:
            node_rows.extend(class_row.get_node_rows())

        for row in class_rows + node_rows:
            item = row.first_item()
            index = model.indexFromItem(item)
            proxy_index = proxy.mapFromSource(index)
            self._tree.setRowHidden(proxy_index.row(), proxy_index.parent(), False)

        if search_strings:
            for search_item in search_strings:
                for row in node_rows:
                    if search_item.strip().lower() in row.get_item('Node').text().lower():
                        show_rows.append(row)

            self._tree.expandAll()
            self._expand_state = True

            show_class_rows = list(set(map(lambda x: x.get_parent_class_row(), show_rows)))

            for row in node_rows:
                if row not in show_rows:
                    item = row.first_item()
                    index = model.indexFromItem(item)
                    proxy_index = proxy.mapFromSource(index)
                    self._tree.setRowHidden(proxy_index.row(), proxy_index.parent(), True)
            for row in class_rows:
                if row not in show_class_rows:
                    item = row.first_item()
                    index = model.indexFromItem(item)
                    proxy_index = proxy.mapFromSource(index)
                    self._tree.setRowHidden(proxy_index.row(), proxy_index.parent(), True)
        else:
            self._tree.collapseAll()
            self._expand_state = False

    def _refresh(self):
        model = self._tree.model().sourceModel()
        nodes = nuke.allNodes()

        node_dict = {}

        for node in nodes:
            if node.Class() not in node_dict.keys():
                node_dict[node.Class()] = []
            node_dict[node.Class()].append(node)

        model.clear_rows()

        model.populate(node_dict)

    def _set_connections(self):
        self._btn_refresh.released.connect(self._refresh)
        self._ledit_search.textChanged.connect(self._filter_list)
        self._btn_expand.released.connect(self._expand_toggle)

    def _setup_ui(self):
        self._btn_refresh.setIcon(QIcon(':qrc/images/Refresh.png'))
        self._btn_refresh.setToolTip('Populate tree with nodes')
        self._btn_expand.setToolTip('Toggle expanding and collapsing the tree')
        self._ledit_search.setToolTip('Search by node name')

        lyt_refresh = QHBoxLayout()
        lyt_refresh.addWidget(self._btn_refresh)
        lyt_refresh.addWidget(self._btn_expand)

        lyt_search = QHBoxLayout()
        lbl_search = QLabel('Name Search')
        lyt_search.addWidget(lbl_search)
        lyt_search.addWidget(self._ledit_search)

        lyt_main = QVBoxLayout()
        lyt_main.addLayout(lyt_refresh)
        lyt_main.addWidget(self._tree)
        lyt_main.addLayout(lyt_search)

        self.setLayout(lyt_main)
Пример #24
0
class PathEditor(QWidget):
    """ Custom widget with LineEdit and a Button to browse file """

    editingFinished = Signal()

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

        self.parent = parent
        self.index = index
        self.open_dialog_visible = False

        self.setFocusPolicy(Qt.StrongFocus)

        editor_layout = QHBoxLayout()
        editor_layout.setContentsMargins(0, 0, 0, 0)
        editor_layout.setSpacing(0)

        self.line_edit = LineEditor(self)
        editor_layout.addWidget(self.line_edit)

        self.button = QPushButton('')
        self.button.setIcon(QIcon(':/editor_folder'))
        self.button.setFixedSize(18, 17)
        self.button.setToolTip('Select a texture')
        self.button.setStatusTip('Select a texture')
        self.button.clicked.connect(self.select_file)
        editor_layout.addWidget(self.button)

        self.setFocusProxy(self.line_edit)
        self.setLayout(editor_layout)

    def setText(self, text):
        """ Set line edit text

        :param text: (string) text...
        """
        self.line_edit.setText(text)

    def text(self):
        """ return line edit text """
        return self.line_edit.text()

    def select_file(self):
        """ Maya Open Dialog to select file texture """
        self.open_dialog_visible = True

        if MTTSettings.value('browserFirstStart'):
            image_dir = cmds.optionVar(query='MTT_browserStartFolder')
        else:
            image_dir = cmds.workspace(query=True,
                                       rootDirectory=True) + cmds.workspace(
                fileRuleEntry='sourceImages')
            MTTSettings.set_value('browserFirstStart', True)

        file_path = cmds.fileDialog2(fileMode=1, startingDirectory=image_dir,
                                     caption='Select a texture',
                                     okCaption='Select')

        if file_path:
            new_path = file_path[0]
            cmds.optionVar(
                sv=['MTT_browserStartFolder', os.path.dirname(new_path)])
            if MTTSettings.value('forceRelativePath'):
                new_path = convert_to_relative_path(new_path)
                # relative_path = workspace(projectPath=new_path)
                # if relative_path != new_path:
                #     new_path = '/%s' % relative_path
            self.line_edit.setText(new_path)
        self.open_dialog_visible = False
        self.close()
        self.editingFinished.emit()
        cmds.showWindow(WINDOW_NAME)
    def __create_ui(self):
        """ Create main UI """
        self.setWindowTitle(CREATE_NODE_TITLE)

        # remove window decoration if path and type is set
        if self.defined_path and self.defined_type:
            self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup)

        main_layout = QVBoxLayout(self)
        main_layout.setSpacing(1)
        main_layout.setContentsMargins(2, 2, 2, 2)

        # content layout
        content_layout = QVBoxLayout()
        self.files_model = QFileSystemModel()
        self.files_model.setNameFilterDisables(False)
        self.files_list = MTTFileList()
        self.files_list.setAlternatingRowColors(True)
        self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.files_list.selectionValidated.connect(self.do_validate_selection)
        self.files_list.goToParentDirectory.connect(self.on_go_up_parent)
        self.files_list.doubleClicked.connect(self.on_double_click)
        self.files_list.setModel(self.files_model)

        buttons_layout = QHBoxLayout()

        content_layout.addLayout(self.__create_filter_ui())
        content_layout.addWidget(self.files_list)
        content_layout.addLayout(buttons_layout)
        self.files_list.filter_line = self.filter_line

        if not self.defined_path:
            # path line
            path_layout = QHBoxLayout()
            # bookmark button
            bookmark_btn = QPushButton('')
            bookmark_btn.setFlat(True)
            bookmark_btn.setIcon(QIcon(':/addBookmark.png'))
            bookmark_btn.setToolTip('Bookmark this Folder')
            bookmark_btn.setStatusTip('Bookmark this Folder')
            bookmark_btn.clicked.connect(self.on_add_bookmark)
            # path line edit
            self.path_edit = QLineEdit()
            self.path_edit.editingFinished.connect(self.on_enter_path)
            # parent folder button
            self.parent_folder_btn = QPushButton('')
            self.parent_folder_btn.setFlat(True)
            self.parent_folder_btn.setIcon(
                QIcon(':/SP_FileDialogToParent.png'))
            self.parent_folder_btn.setToolTip('Parent Directory')
            self.parent_folder_btn.setStatusTip('Parent Directory')
            self.parent_folder_btn.clicked.connect(self.on_go_up_parent)
            # browse button
            browse_btn = QPushButton('')
            browse_btn.setFlat(True)
            browse_btn.setIcon(QIcon(':/navButtonBrowse.png'))
            browse_btn.setToolTip('Browse Directory')
            browse_btn.setStatusTip('Browse Directory')
            browse_btn.clicked.connect(self.on_browse)
            # parent widget and layout
            path_layout.addWidget(bookmark_btn)
            path_layout.addWidget(self.path_edit)
            path_layout.addWidget(self.parent_folder_btn)
            path_layout.addWidget(browse_btn)
            main_layout.addLayout(path_layout)

            # bookmark list
            bookmark_parent_layout = QHBoxLayout()
            bookmark_frame = QFrame()
            bookmark_frame.setFixedWidth(120)
            bookmark_layout = QVBoxLayout()
            bookmark_layout.setSpacing(1)
            bookmark_layout.setContentsMargins(2, 2, 2, 2)
            bookmark_frame.setLayout(bookmark_layout)
            bookmark_frame.setFrameStyle(QFrame.Sunken)
            bookmark_frame.setFrameShape(QFrame.StyledPanel)
            self.bookmark_list = MTTBookmarkList()
            self.bookmark_list.bookmarkDeleted.connect(self.do_delete_bookmark)
            self.bookmark_list.setAlternatingRowColors(True)
            self.bookmark_list.dragEnabled()
            self.bookmark_list.setAcceptDrops(True)
            self.bookmark_list.setDropIndicatorShown(True)
            self.bookmark_list.setDragDropMode(QListView.InternalMove)
            self.bookmark_list_sel_model = self.bookmark_list.selectionModel()
            self.bookmark_list_sel_model.selectionChanged.connect(
                self.on_select_bookmark)

            bookmark_layout.addWidget(self.bookmark_list)
            bookmark_parent_layout.addWidget(bookmark_frame)
            bookmark_parent_layout.addLayout(content_layout)
            main_layout.addLayout(bookmark_parent_layout)

            self.do_populate_bookmarks()

        else:
            main_layout.addLayout(content_layout)

        if not self.defined_type:
            # type layout
            self.types = QComboBox()
            self.types.addItems(self.supported_node_type)
            self.types.currentIndexChanged.connect(self.on_node_type_changed)
            if cmds.optionVar(exists='MTT_lastNodeType'):
                last = cmds.optionVar(query='MTT_lastNodeType')
                if last in self.supported_node_type:
                    self.types.setCurrentIndex(
                        self.supported_node_type.index(last))
            buttons_layout.addWidget(self.types)

        if not self.defined_path or not self.defined_type:
            create_btn = QPushButton('C&reate')
            create_btn.clicked.connect(self.accept)
            cancel_btn = QPushButton('&Cancel')
            cancel_btn.clicked.connect(self.reject)

            buttons_layout.addStretch()
            buttons_layout.addWidget(create_btn)
            buttons_layout.addWidget(cancel_btn)
class MTTFilterFileDialog(QDialog):
    def __init__(self, define_path='', define_type=None):
        super(MTTFilterFileDialog, self).__init__(get_maya_window())

        self.supported_node_type = sorted(
            [node_type
             for (node_type, nice, attr) in MTTSettings.SUPPORTED_TYPE])

        self.defined_path = (
            define_path
            if os.path.isdir(define_path) or define_path == SOURCEIMAGES_TAG
            else None)

        self.defined_type = (
            define_type
            if define_type in self.supported_node_type
            else None)

        self.path_edit = None
        self.filter_reset_btn = None
        self.filter_line = None
        self.parent_folder_btn = None
        self.files_model = None
        self.files_list = None
        self.bookmark_list = None
        self.bookmark_list_sel_model = None
        self.types = None

        # move window to cursor position
        win_geo = MTTSettings.value(
            'FilterFileDialog/windowGeometry', QRect(0, 0, 400, 300))
        self.setGeometry(win_geo)
        mouse_pos = QCursor.pos()
        mouse_pos.setX(mouse_pos.x() - (win_geo.width() * 0.5))
        self.move(mouse_pos)

        self.__create_ui()

        self.filter_line.setFocus()
        self.on_change_root_path(self.defined_path or SOURCEIMAGES_TAG)

    def __create_ui(self):
        """ Create main UI """
        self.setWindowTitle(CREATE_NODE_TITLE)

        # remove window decoration if path and type is set
        if self.defined_path and self.defined_type:
            self.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup)

        main_layout = QVBoxLayout(self)
        main_layout.setSpacing(1)
        main_layout.setContentsMargins(2, 2, 2, 2)

        # content layout
        content_layout = QVBoxLayout()
        self.files_model = QFileSystemModel()
        self.files_model.setNameFilterDisables(False)
        self.files_list = MTTFileList()
        self.files_list.setAlternatingRowColors(True)
        self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.files_list.selectionValidated.connect(self.do_validate_selection)
        self.files_list.goToParentDirectory.connect(self.on_go_up_parent)
        self.files_list.doubleClicked.connect(self.on_double_click)
        self.files_list.setModel(self.files_model)

        buttons_layout = QHBoxLayout()

        content_layout.addLayout(self.__create_filter_ui())
        content_layout.addWidget(self.files_list)
        content_layout.addLayout(buttons_layout)
        self.files_list.filter_line = self.filter_line

        if not self.defined_path:
            # path line
            path_layout = QHBoxLayout()
            # bookmark button
            bookmark_btn = QPushButton('')
            bookmark_btn.setFlat(True)
            bookmark_btn.setIcon(QIcon(':/addBookmark.png'))
            bookmark_btn.setToolTip('Bookmark this Folder')
            bookmark_btn.setStatusTip('Bookmark this Folder')
            bookmark_btn.clicked.connect(self.on_add_bookmark)
            # path line edit
            self.path_edit = QLineEdit()
            self.path_edit.editingFinished.connect(self.on_enter_path)
            # parent folder button
            self.parent_folder_btn = QPushButton('')
            self.parent_folder_btn.setFlat(True)
            self.parent_folder_btn.setIcon(QIcon(':/SP_FileDialogToParent.png'))
            self.parent_folder_btn.setToolTip('Parent Directory')
            self.parent_folder_btn.setStatusTip('Parent Directory')
            self.parent_folder_btn.clicked.connect(self.on_go_up_parent)
            # browse button
            browse_btn = QPushButton('')
            browse_btn.setFlat(True)
            browse_btn.setIcon(QIcon(':/navButtonBrowse.png'))
            browse_btn.setToolTip('Browse Directory')
            browse_btn.setStatusTip('Browse Directory')
            browse_btn.clicked.connect(self.on_browse)
            # parent widget and layout
            path_layout.addWidget(bookmark_btn)
            path_layout.addWidget(self.path_edit)
            path_layout.addWidget(self.parent_folder_btn)
            path_layout.addWidget(browse_btn)
            main_layout.addLayout(path_layout)

            # bookmark list
            bookmark_parent_layout = QHBoxLayout()
            bookmark_frame = QFrame()
            bookmark_frame.setFixedWidth(120)
            bookmark_layout = QVBoxLayout()
            bookmark_layout.setSpacing(1)
            bookmark_layout.setContentsMargins(2, 2, 2, 2)
            bookmark_frame.setLayout(bookmark_layout)
            bookmark_frame.setFrameStyle(QFrame.Sunken)
            bookmark_frame.setFrameShape(QFrame.StyledPanel)
            self.bookmark_list = MTTBookmarkList()
            self.bookmark_list.bookmarkDeleted.connect(self.do_delete_bookmark)
            self.bookmark_list.setAlternatingRowColors(True)
            self.bookmark_list.dragEnabled()
            self.bookmark_list.setAcceptDrops(True)
            self.bookmark_list.setDropIndicatorShown(True)
            self.bookmark_list.setDragDropMode(QListView.InternalMove)
            self.bookmark_list_sel_model = self.bookmark_list.selectionModel()
            self.bookmark_list_sel_model.selectionChanged.connect(
                self.on_select_bookmark)

            bookmark_layout.addWidget(self.bookmark_list)
            bookmark_parent_layout.addWidget(bookmark_frame)
            bookmark_parent_layout.addLayout(content_layout)
            main_layout.addLayout(bookmark_parent_layout)

            self.do_populate_bookmarks()

        else:
            main_layout.addLayout(content_layout)

        if not self.defined_type:
            # type layout
            self.types = QComboBox()
            self.types.addItems(self.supported_node_type)
            self.types.currentIndexChanged.connect(self.on_node_type_changed)
            if cmds.optionVar(exists='MTT_lastNodeType'):
                last = cmds.optionVar(query='MTT_lastNodeType')
                if last in self.supported_node_type:
                    self.types.setCurrentIndex(
                        self.supported_node_type.index(last))
            buttons_layout.addWidget(self.types)

        if not self.defined_path or not self.defined_type:
            create_btn = QPushButton('C&reate')
            create_btn.clicked.connect(self.accept)
            cancel_btn = QPushButton('&Cancel')
            cancel_btn.clicked.connect(self.reject)

            buttons_layout.addStretch()
            buttons_layout.addWidget(create_btn)
            buttons_layout.addWidget(cancel_btn)

    def __create_filter_ui(self):
        """ Create filter widgets """
        filter_layout = QHBoxLayout()
        filter_layout.setSpacing(1)
        filter_layout.setContentsMargins(0, 0, 0, 0)

        self.filter_reset_btn = QPushButton()
        icon = QIcon(':/filtersOff.png')
        self.filter_reset_btn.setIcon(icon)
        self.filter_reset_btn.setIconSize(QSize(22, 22))
        self.filter_reset_btn.setFixedSize(24, 24)
        self.filter_reset_btn.setToolTip('Reset filter')
        self.filter_reset_btn.setFlat(True)
        self.filter_reset_btn.clicked.connect(
            partial(self.on_filter_set_text, ''))

        self.filter_line = QLineEdit()
        self.filter_line.setPlaceholderText('Enter filter string here')
        self.filter_line.textChanged.connect(self.on_filter_change_text)

        completer = QCompleter(self)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setModel(QStringListModel([], self))
        self.filter_line.setCompleter(completer)

        filter_layout.addWidget(self.filter_reset_btn)
        filter_layout.addWidget(self.filter_line)

        return filter_layout

    def on_filter_set_text(self, text=''):
        """ Set text in filter field """
        self.filter_line.setText(text)

    def on_filter_change_text(self, text):
        """ Apply filter string """
        if len(text):
            icon = QIcon(':/filtersOn.png')
            self.filter_reset_btn.setIcon(icon)
        else:
            icon = QIcon(':/filtersOff.png')
            self.filter_reset_btn.setIcon(icon)

        self.files_model.setNameFilters(
            ['*%s*' % item.strip() for item in text.split(',') if item.strip()])

    def on_node_type_changed(self, index):
        cmds.optionVar(sv=['MTT_lastNodeType', self.supported_node_type[index]])

    def on_double_click(self, index):
        current_item = self.files_model.filePath(index)
        if os.path.isdir(current_item):
            self.on_change_root_path(current_item)
        elif os.path.isfile(current_item):
            self.accept()

    def on_change_root_path(self, current_path):
        if current_path == SOURCEIMAGES_TAG:
            current_path = os.path.join(
                cmds.workspace(query=True, rootDirectory=True),
                cmds.workspace(fileRuleEntry='sourceImages')
            )

        self.files_model.setRootPath(current_path)
        self.files_list.setRootIndex(self.files_model.index(current_path))
        if self.path_edit:
            self.path_edit.setText(current_path)

        if self.parent_folder_btn:
            current_dir = QDir(current_path)
            self.parent_folder_btn.setEnabled(current_dir.cdUp())

    def on_go_up_parent(self):
        current_path = QDir(self.files_model.rootPath())
        current_path.cdUp()
        self.on_change_root_path(current_path.absolutePath())

    def on_enter_path(self):
        new_path = self.path_edit.text()
        if os.path.isdir(new_path):
            self.on_change_root_path(new_path)
        else:
            self.path_edit.setText(self.files_model.rootPath())

    def on_browse(self):
        current_path = self.files_model.rootPath()
        file_dialog = QFileDialog(self, 'Select a Folder', current_path)
        file_dialog.setFileMode(QFileDialog.Directory)
        file_dialog.setOption(QFileDialog.ShowDirsOnly)

        if file_dialog.exec_():
            self.on_change_root_path(file_dialog.selectedFiles()[0])

    def on_select_bookmark(self, selected, deselected):
        current_item = selected.indexes()
        if current_item:
            self.on_change_root_path(
                self.bookmark_list.selectedItems()[0].root_path)

    def on_add_bookmark(self):
        current_path = self.files_model.rootPath()
        self.on_add_bookmark_item(
            '%s|%s' % (os.path.basename(current_path), current_path))

    def on_add_bookmark_item(self, item):
        if item == '':
            return

        current_item = MTTBookmarkItem()
        current_item.add_raw_data(item)
        current_item.setSizeHint(QSize(40, 25))
        current_item.setFlags(
            Qt.ItemIsEnabled | Qt.ItemIsEditable |
            Qt.ItemIsSelectable | Qt.ItemIsDragEnabled
        )

        self.bookmark_list.addItem(current_item)

    def do_delete_bookmark(self):
        current_item = self.bookmark_list.selectedItems()
        if current_item:
            item_row = self.bookmark_list.row(current_item[0])
            self.bookmark_list.takeItem(item_row)
            del current_item[0]

    def do_save_bookmark(self):
        if not self.bookmark_list:
            return

        row_count = self.bookmark_list.count()
        ordered_list = list()

        for i in range(row_count):
            item = self.bookmark_list.item(i)
            name = item.text().replace(',', '_').replace('|', '_')
            path = item.root_path
            if name != 'sourceimages':
                ordered_list.append('%s|%s' % (name, path))

        MTTSettings.set_value(
            'FilterFileDialog/bookmarks', ','.join(ordered_list))

    def do_populate_bookmarks(self):
        bookmarks = ['sourceimages|%s' % SOURCEIMAGES_TAG]
        bookmarks.extend(
            MTTSettings.value('FilterFileDialog/bookmarks').split(','))

        for bm in bookmarks:
            self.on_add_bookmark_item(bm)

    def do_validate_selection(self):
        selection = self.files_list.selectedIndexes()
        if len(selection) == 1:
            current_path = self.files_model.filePath(selection[0])
            if os.path.isdir(current_path):
                self.on_change_root_path(current_path)
                return
        self.accept()

    def get_selected_files(self):
        selected_items = list()
        for item_index in self.files_list.selectedIndexes():
            current_path = self.files_model.filePath(item_index)
            if os.path.isfile(current_path):
                selected_items.append(current_path)
        return selected_items

    def get_node_type(self):
        return self.types.currentText() if self.types else self.defined_type

    def closeEvent(self, event):
        MTTSettings.set_value(
            'FilterFileDialog/windowGeometry', self.geometry())
        self.do_save_bookmark()

        self.deleteLater()
        event.accept()
Пример #27
0
class TransferPanel(QWidget):
    '''
    Transfer Panel
    
    This Panel is the main dialog box for the Dive Computer Transfer GUI
    '''
    def __init__(self, parent=None):
        super(TransferPanel, self).__init__(parent)
        
        self._logbook = None
        self._logbookName = 'None'
        self._logbookPath = None
        
        self._createLayout()
        
        self._readSettings()
        self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName)
        
    def _createLayout(self):
        'Create the Widget Layout'
        
        self._txtLogbook = QLineEdit()
        self._txtLogbook.setReadOnly(True)
        self._lblLogbook = QLabel(self.tr('&Logbook File:'))
        self._lblLogbook.setBuddy(self._txtLogbook)
        self._btnBrowse = QPushButton('...')
        self._btnBrowse.clicked.connect(self._btnBrowseClicked)
        self._btnBrowse.setStyleSheet('QPushButton { min-width: 24px; max-width: 24px; }')
        self._btnBrowse.setToolTip(self.tr('Browse for a Logbook'))
        
        self._cbxComputer = QComboBox()
        self._lblComputer = QLabel(self.tr('Dive &Computer:'))
        self._lblComputer.setBuddy(self._cbxComputer)
        self._btnAddComputer = QPushButton(QPixmap(':/icons/list-add.png'), self.tr(''))
        self._btnAddComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }')
        self._btnAddComputer.clicked.connect(self._btnAddComputerClicked)
        self._btnRemoveComputer = QPushButton(QPixmap(':/icons/list-remove.png'), self.tr(''))
        self._btnRemoveComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }')
        self._btnRemoveComputer.clicked.connect(self._btnRemoveComputerClicked)
        
        hbox = QHBoxLayout()
        hbox.addWidget(self._btnAddComputer)
        hbox.addWidget(self._btnRemoveComputer)
        
        gbox = QGridLayout()
        gbox.addWidget(self._lblLogbook, 0, 0)
        gbox.addWidget(self._txtLogbook, 0, 1)
        gbox.addWidget(self._btnBrowse, 0, 2)
        gbox.addWidget(self._lblComputer, 1, 0)
        gbox.addWidget(self._cbxComputer, 1, 1)
        gbox.addLayout(hbox, 1, 2)
        gbox.setColumnStretch(1, 1)
        
        self._pbTransfer = QProgressBar()
        self._pbTransfer.reset()
        self._txtStatus = QTextEdit()
        self._txtStatus.setReadOnly(True)
        
        self._btnTransfer = QPushButton(self.tr('&Transfer Dives'))
        self._btnTransfer.clicked.connect(self._btnTransferClicked)
        
        self._btnExit = QPushButton(self.tr('E&xit'))
        self._btnExit.clicked.connect(self.close)
        
        hbox = QHBoxLayout()
        hbox.addWidget(self._btnTransfer)
        hbox.addStretch()
        hbox.addWidget(self._btnExit)
        
        vbox = QVBoxLayout()
        vbox.addLayout(gbox)
        vbox.addWidget(self._pbTransfer)
        vbox.addWidget(self._txtStatus)
        vbox.addLayout(hbox)
        
        self.setLayout(vbox)
        
    def _closeLogbook(self):
        'Close the current Logbook'
        if self._logbook is None:
            return
        
        self._logbook = None
        self._logbookName = 'None'
        self._logbookPath = None
        
        self._txtLogbook.clear()
        self._cbxComputer.setModel(None)
        
        self._writeSettings()
        self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName)
        
    def _openLogbook(self, path):
        'Open an existing Logbook'
        if self._logbook is not None:
            self._closeLogbook()
            
        if not os.path.exists(path):
            QMessageBox.critical(self, self.tr('Missing Logbook'), 
                self.tr('Logbook File "%s" does not exist.') % path)
            return
        
        #TODO: Handle a Schema Upgrade in a user-friendly manner
        self._logbook = Logbook(path, auto_update=False)
        self._logbookName = os.path.basename(path)
        self._logbookPath = path
        
        self._txtLogbook.setText(self._logbookPath)
        self._cbxComputer.setModel(DiveComputersModel(self._logbook))
        
        self._writeSettings()
        self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName)
        
    def _readSettings(self):
        'Read main window settings from the configuration'
        settings = QSettings()
        settings.beginGroup('MainWindow')
        max = settings.value('max')
        size = settings.value('size')
        pos = settings.value('pos')
        file = settings.value('file')
        settings.endGroup()
        
        # Size and Position the Main Window
        if size is not None:
            self.resize(size)
        if pos is not None:
            self.move(pos)
            
        # HAX because QVariant is not exposed in PySide and the default
        # coercion to string is just stupid
        if max is not None and (max == 'true'):
            self.showMaximized()
        
        # Open the Logbook
        if file is not None:
            self._openLogbook(file)
        
    def _writeSettings(self):
        'Write settings to the configuration'
        settings = QSettings()
        settings.beginGroup('MainWindow')
        settings.setValue('pos', self.pos())
        settings.setValue('size', self.size())
        settings.setValue('max', self.isMaximized())
        settings.setValue('file', self._logbookPath)
        settings.endGroup()
        
    def closeEvent(self, e):
        'Intercept an OnClose event'
        self._writeSettings()
        e.accept()
        
    #--------------------------------------------------------------------------
    # Slots
    
    @QtCore.Slot()
    def _btnAddComputerClicked(self):
        'Add a Dive Computer'
        dc = AddDiveComputerWizard.RunWizard(self)
        
        if dc is not None:
            self._logbook.session.add(dc)
            self._logbook.session.commit()
            self._cbxComputer.model().reload()
            self._cbxComputer.setCurrentIndex(self._cbxComputer.findText(dc.name))
    
    @QtCore.Slot()
    def _btnRemoveComputerClicked(self):
        'Remove a Dive Computer'
        idx = self._cbxComputer.currentIndex()
        dc = self._cbxComputer.itemData(idx, Qt.UserRole+0)
        if QMessageBox.question(self, self.tr('Delete Dive Computer?'), 
                    self.tr('Are you sure you want to delete "%s"?') % dc.name,
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) == QMessageBox.Yes:
            self._logbook.session.delete(dc)
            self._logbook.session.commit()
            self._cbxComputer.model().reload()
    
    @QtCore.Slot()
    def _btnBrowseClicked(self):
        'Browse for a Logbook File'
        if self._logbook is not None:
            dir = os.path.dirname(self._logbookPath)
        else:
            dir = os.path.expanduser('~')
        
        fn = QFileDialog.getOpenFileName(self,
            caption=self.tr('Select a Logbook file'), dir=dir,
            filter='Logbook Files (*.lbk);;All Files(*.*)')[0]    
        if fn == '':
            return
        if not os.path.exists(fn):
            if QMessageBox.question(self, self.tr('Create new Logbook?'), 
                    self.tr('Logbook "%s" does not exist. Would you like to create it?') % os.path.basename(fn),
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) != QMessageBox.Yes:
                return
            Logbook.Create(fn)
        self._openLogbook(fn)
        
    @QtCore.Slot()
    def _btnTransferClicked(self):
        'Transfer Dives'
        idx = self._cbxComputer.currentIndex()
        dc = self._cbxComputer.itemData(idx, Qt.UserRole+0)
        
        if self._logbook.session.dirty:
            print "Flushing dirty session"
            self._logbook.rollback()
        
        self._txtLogbook.setEnabled(False)
        self._btnBrowse.setEnabled(False)
        self._cbxComputer.setEnabled(False)
        self._btnAddComputer.setEnabled(False)
        self._btnRemoveComputer.setEnabled(False)
        self._btnTransfer.setEnabled(False)
        self._btnExit.setEnabled(False)
        
        self._txtStatus.clear()
        
        thread = QThread(self)
        
        #FIXME: ZOMG HAX: Garbage Collector will eat TransferWorker when moveToThread is called
        #NOTE: Qt.QueuedConnection is important...
        self.worker = None
        self.worker = TransferWorker(dc)
        thread.started.connect(self.worker.start, Qt.QueuedConnection)
        self.worker.moveToThread(thread)
        self.worker.finished.connect(self._transferFinished, Qt.QueuedConnection)
        self.worker.finished.connect(self.worker.deleteLater, Qt.QueuedConnection)
        self.worker.finished.connect(thread.deleteLater, Qt.QueuedConnection)
        self.worker.progress.connect(self._transferProgress, Qt.QueuedConnection)
        self.worker.started.connect(self._transferStart, Qt.QueuedConnection)
        self.worker.status.connect(self._transferStatus, Qt.QueuedConnection)
        
        thread.start()
        
    @QtCore.Slot(str)
    def _transferStatus(self, msg):
        'Transfer Status Message'
        self._txtStatus.append(msg)
        
    @QtCore.Slot(int)
    def _transferStart(self, nBytes):
        'Transfer Thread Stated'
        if nBytes > 0:
            self._pbTransfer.setMaximum(nBytes)
        else:
            self._pbTransfer.setMaximum(100)
        self._pbTransfer.reset()
        
    @QtCore.Slot(int)
    def _transferProgress(self, nTransferred):
        'Transfer Thread Progress Event'
        self._pbTransfer.setValue(nTransferred)
        
    @QtCore.Slot(models.Dive)
    def _transferParsed(self, dive):
        'Transfer Thread Parsed Dive'
        self._logbook.session.add(dive)
        
    @QtCore.Slot()
    def _transferFinished(self):
        'Transfer Thread Finished'
        self._logbook.session.commit()
        
        self._txtLogbook.setEnabled(True)
        self._btnBrowse.setEnabled(True)
        self._cbxComputer.setEnabled(True)
        self._btnAddComputer.setEnabled(True)
        self._btnRemoveComputer.setEnabled(True)
        self._btnTransfer.setEnabled(True)
        self._btnExit.setEnabled(True)