Exemplo n.º 1
0
class ToggleButton:
    def __init__(self, frame_text: str, checkbox_text: str = 'Default'):
        self.box = QVBoxLayout()
        self.lbl = QLabel(frame_text)

        self.checkbox = QCheckBox(checkbox_text)
        self.checkbox.setCheckState(Qt.Unchecked)

        self.numeric = QSpinBox()
        self.numeric.setValue(-1)

        self.box.addWidget(self.lbl)
        self.box.addWidget(self.numeric)
        self.box.addWidget(self.checkbox)

        self.checkbox.stateChanged.connect(self.checkbox_toggle)
        self.numeric.valueChanged.connect(self.numeric_change)

        self.use_default = False
        self.value = -1

    @Slot()
    def checkbox_toggle(self, checked):
        self.use_default = self.checkbox.checkState() == Qt.Checked
        self.numeric.setDisabled(self.use_default)

    @Slot()
    def numeric_change(self, checked):
        self.value = self.numeric.value()
Exemplo n.º 2
0
class SecondaryFilters(QWidget, ListenerNode):
    def __init__(self, listeners_pool, *args, **kwargs):
        super(SecondaryFilters, self).__init__(*args, **kwargs)
        ListenerNode.__init__(self, 'secondary-filters', listeners_pool)

        self.group_by_month = QCheckBox('Por mes')
        self.group_by_type = QCheckBox('Por tipo de gasto')

        layout = QVBoxLayout()
        self.setLayout(layout)

        inner_layout = QHBoxLayout()
        inner_layout.addWidget(self.group_by_month)
        inner_layout.addWidget(self.group_by_type)

        group_box = QGroupBox('Agrupaciones')
        group_box.setLayout(inner_layout)

        layout.addWidget(group_box)

        self.group_by_month.stateChanged.connect(self.grouping_changed)
        self.group_by_type.stateChanged.connect(self.grouping_changed)

    def grouping_changed(self):
        month_status = self.group_by_month.checkState()
        type_status = self.group_by_type.checkState()

        if month_status == QtCore.Qt.CheckState.Unchecked and type_status == QtCore.Qt.CheckState.Unchecked:
            criteria = 'expenses_raw'
        elif month_status == QtCore.Qt.CheckState.Unchecked and type_status == QtCore.Qt.CheckState.Checked:
            criteria = 'expenses_by_type'
        elif month_status == QtCore.Qt.CheckState.Checked and type_status == QtCore.Qt.CheckState.Unchecked:
            criteria = 'expenses_by_month'
        elif month_status == QtCore.Qt.CheckState.Checked and type_status == QtCore.Qt.CheckState.Checked:
            criteria = 'expenses_by_type_and_month'

        self.send_event('view-expenses-screen', 'add_table', criteria)
 def show_commit_session_prompt(self):
     """Shows the commit session message box."""
     config = self._data_store._toolbox._config
     commit_at_exit = config.get("settings", "commit_at_exit")
     if commit_at_exit == "0":
         # Don't commit session and don't show message box
         return
     elif commit_at_exit == "1":  # Default
         # Show message box
         msg = QMessageBox(self)
         msg.setIcon(QMessageBox.Question)
         msg.setWindowTitle("Commit pending changes")
         msg.setText(
             "The current session has uncommitted changes. Do you want to commit them now?"
         )
         msg.setInformativeText(
             "WARNING: If you choose not to commit, all changes will be lost."
         )
         msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
         chkbox = QCheckBox()
         chkbox.setText("Do not ask me again")
         msg.setCheckBox(chkbox)
         answer = msg.exec_()
         chk = chkbox.checkState()
         if answer == QMessageBox.Yes:
             self.show_commit_session_dialog()
             if chk == 2:
                 # Save preference into config file
                 config.set("settings", "commit_at_exit", "2")
         else:
             if chk == 2:
                 # Save preference into config file
                 config.set("settings", "commit_at_exit", "0")
     elif commit_at_exit == "2":
         # Commit session and don't show message box
         self.show_commit_session_dialog()
     else:
         config.set("settings", "commit_at_exit", "1")
     return
Exemplo n.º 4
0
class MainWidget(QWidget):

    format_dict = {
        "JPEG(jpg)": "jpeg",
        "WebP": "webp",
        "Gif": "gif",
        "PNG": "png"
    }

    def __init__(self, parent):
        super().__init__()
        self.par = parent
        self.InitUI()

    def InitUI(self):
        self.selected_dir = str()
        self.option_array = [1, 0, 0, 0]
        self.main_layout = QVBoxLayout()
        self.make_dir_groupbox()
        self.make_func_groupbox()
        self.make_sys_layout()
        self.status_bar = QStatusBar()
        self.setEnabled(True)

        self.setLayout(self.main_layout)

    def make_dir_groupbox(self):
        dir_groupbox = QGroupBox("Select Directory")
        dir_layout = QVBoxLayout()
        self.loaded_dir_label = QLabel(self.selected_dir)
        self.loaded_dir_label.setStyleSheet("max-height: 24px;"
                                            "background-color: #FFFFFF;"
                                            "border-style: solid;"
                                            "border-width: 1px;"
                                            "border-color: #000000")
        dir_layout.addWidget(self.loaded_dir_label)
        self.load_dir_button = QPushButton("Load Directory", self)
        self.load_dir_button.clicked.connect(self.load_dir)
        dir_layout.addWidget(self.load_dir_button)
        dir_groupbox.setLayout(dir_layout)
        self.main_layout.addWidget(dir_groupbox)

    def make_func_groupbox(self):
        func_layout = QHBoxLayout()

        self.encode_widget = RadioBox(encode_dict)
        encode_layout = self.encode_widget.make_radio_box("UTF-8 with BOM")
        self.encode_groupbox = QGroupBox("Encode to: ")
        self.encode_groupbox.setLayout(encode_layout)
        self.encode_groupbox.setCheckable(True)
        self.encode_groupbox.clicked.connect(self.option_set)
        func_layout.addWidget(self.encode_groupbox)

        self.fmt_groupbox = QGroupBox("Convert image format")
        fmt_hbox = QHBoxLayout()
        self.format_widget_from = RadioBox(self.format_dict)
        format_layout_from = self.format_widget_from.make_radio_box("WebP")
        fmt_from_groupbox = QGroupBox("Convert image from: ")
        fmt_from_groupbox.setLayout(format_layout_from)
        fmt_hbox.addWidget(fmt_from_groupbox)

        self.format_widget_to = RadioBox(self.format_dict)
        format_layout_to = self.format_widget_to.make_radio_box("PNG")
        fmt_to_groupbox = QGroupBox("Convert image to: ")
        fmt_to_groupbox.setLayout(format_layout_to)
        fmt_hbox.addWidget(fmt_to_groupbox)
        self.fmt_groupbox.setLayout(fmt_hbox)
        self.fmt_groupbox.setCheckable(True)
        func_layout.addWidget(self.fmt_groupbox)

        option_groupbox = QGroupBox("OPTION: ")
        option_layout = QVBoxLayout()
        self.change_txt_yn = QCheckBox("Change image ext in CSV/ERB", self)
        self.change_txt_yn.toggle()
        self.change_txt_yn.clicked.connect(self.option_set)
        self.backup_yn = QCheckBox("Place files in Result directory", self)
        self.backup_yn.clicked.connect(self.option_set)

        option_layout.addWidget(self.change_txt_yn)
        option_layout.addWidget(self.backup_yn)
        option_groupbox.setLayout(option_layout)
        func_layout.addWidget(option_groupbox)

        self.main_layout.addLayout(func_layout)

    def make_sys_layout(self):
        sys_layout = QHBoxLayout()
        self.run_button = QPushButton("RUN", self)
        self.run_button.setEnabled(False)
        self.run_button.clicked.connect(self.run_process)
        self.prog_bar = QProgressBar()
        self.prog_bar.setMinimum(0)
        sys_layout.addWidget(self.prog_bar)
        sys_layout.stretch(1)
        sys_layout.addWidget(self.run_button)
        self.main_layout.addLayout(sys_layout)

    def load_dir(self):
        f_dialog = QFileDialog(self, "불러올 폴더를 선택하세요.", os.path.curdir)
        f_dialog.setFileMode(QFileDialog.DirectoryOnly)
        self.selected_dir = f_dialog.getExistingDirectory(
            self, "불러올 폴더를 선택하세요.")
        if not self.selected_dir:
            self.selected_dir = str()
            self.run_button.setEnabled(False)
        else:
            self.run_button.setEnabled(True)
        self.loaded_dir_label.setText(self.selected_dir)
        return self.selected_dir

    def option_set(self):
        if not self.encode_groupbox.isChecked():
            self.change_txt_yn.setEnabled(False)
        else:
            self.change_txt_yn.setEnabled(True)
        self.option_array[0] = self.change_txt_yn.checkState()
        self.option_array[1] = self.backup_yn.checkState()
        self.option_array[2] = self.encode_groupbox.isChecked()
        self.option_array[3] = self.fmt_groupbox.isChecked()
        return self.option_array

    def run_process(self):
        self.option_set()
        self.setEnabled(False)
        target_array = (
            self.encode_widget.result,
            self.format_widget_from.result,
            self.format_widget_to.result,
            self.selected_dir,
        )
        bar_array = (self.prog_bar, self.status_bar)
        self.threadclass = MyThread(target_array, bar_array, self.option_array,
                                    self)
        self.work_started = 0
        self.threadclass.processed.connect(self.progbar_set)
        self.threadclass.finished.connect(self.donebox)
        self.threadclass.start()

    def open_result(self):
        if self.option_array[1]:
            result_path = "Result\\"
        else:
            result_path = self.selected_dir
        os.startfile(result_path)

    @Slot(int)
    def progbar_set(self, progress_stat):
        if not self.work_started:
            self.prog_bar.setMaximum(progress_stat)
            self.work_started += 1
        else:
            self.prog_bar.setValue(progress_stat)

    @Slot(bool)
    def donebox(self):
        msgbox = QMessageBox(
            QMessageBox.Warning,
            "Done!",
            "Do you want to quit?",
            buttons=QMessageBox.Yes | QMessageBox.No,
            parent=self,
        )
        open_result = msgbox.addButton("Open Result Folder",
                                       QMessageBox.AcceptRole)
        msgbox.setDefaultButton(QMessageBox.Yes)
        close_yn = msgbox.exec_()
        if close_yn == QMessageBox.No:
            self.threadclass.wait()
            # debugpy.debug_this_thread()
            self.close()
            self.par.intiGUI()
        else:
            if close_yn == QMessageBox.AcceptRole:
                self.open_result()
            QCoreApplication.instance().quit()
Exemplo n.º 5
0
class daemon(confStack):
	def __init_stack__(self):
		self.dbg=True
		self._debug("daemon load")
		self.description=(_("Openmeetings daemon setup"))
		self.menu_description=(_("Conifgure openmeetings service setup"))
		self.icon=('openmeetings')
		self.tooltip=(_("Start/stop the service or launch at boot"))
		self.index=2
		self.enabled=True
		self.level='system'
		self.n4d=n4d()
#		self.hideControlButtons()
		self.setStyleSheet(self._setCss())
	#def __init__
	
	def _load_screen(self):

		box=QGridLayout()
		self.btn_service=QPushButton()
		self.btn_service.setCheckable(True)
		self.btn_service.toggled.connect(self._ctrlRun)
		box.addWidget(self.btn_service,0,0,1,1,Qt.AlignCenter)
		self.chk_startup=QCheckBox(_("Launch at startup"))
		self.chk_startup.setTristate(False)
		box.addWidget(self.chk_startup,1,0,1,1,Qt.AlignTop)
		self.chk_kurento=QCheckBox(_("Disable videconference (remove webcam and microphone support)"))
		self.chk_kurento.setTristate(False)
		box.addWidget(self.chk_kurento,2,0,1,1,Qt.AlignTop)
		self.setLayout(box)
		self.updateScreen()
		return(self)
	#def _load_screen

	def _check_isRunning(self):
		cmd=["/usr/sbin/lliurex-openmeetings-service","status"]
		a=subprocess.check_output(cmd).decode().strip()
		if a=="STOPPED":
			return False
		else:
			return True
	#def _check_isRunning

	def _ctrlRun(self,*args):
		if self._check_isRunning():
			self.n4d.n4dQuery("LliurexOpenmeetings","remote_service_stop")
		else:
			self.n4d.n4dQuery("LliurexOpenmeetings","remote_service_start")
		self.updateScreen()
	#def _ctrlRun

	def _getServiceStatus(self):
		if os.path.isfile("/etc/systemd/system/lliurex-openmeetings.service"):
			return True
		else:
			return False
	#def _getStatus

	def _ctrlService(self,*args):
		self.updateScreen()
	#def _ctrlService

	def updateScreen(self):
		if self._check_isRunning():
			self.btn_service.setText(_("Stop service"))
			self.btn_service.setStyleSheet("background:red;color:white")
		else:
			self.btn_service.setText(_("Start service"))
			self.btn_service.setStyleSheet("background:green;color:black")

		self.chk_startup.setChecked(False)
		if self._getServiceStatus():
			self.chk_startup.setChecked(True)
		return True
	#def _udpate_screen
	
	def writeConfig(self):
		if self.chk_startup.checkState():
			cmd=["/bin/systemctl","enable","lliurex-openmeetings"]
		else:
			cmd=["/bin/systemctl","disable","lliurex-openmeetings"]
		subprocess.run(cmd)
		
		if self.chk_kurento.checkState():
			cmd=["/bin/systemctl","disable","kurento-media-server"]
		else:
			cmd=["/bin/systemctl","enable","kurento-media-server"]
		subprocess.run(cmd)
		return True
	#def writeConfig

	def _setCss(self):
		css="""
			#error{
				color:white;
			}"""
		return(css)
Exemplo n.º 6
0
class MemDumpWindow(QWidget):

    kill_signal = Signal(bool)

    def __init__(self, qmp, base=0, max=constants['block_size']):
        super().__init__()

        self.flag = False
        self.threshold = 2048 # number of resident bytes

        self.qmp = qmp
        self.init_ui()

        self.baseAddress = base
        self.maxAddress = self.baseAddress

        self.delta = 4 # adds a small buffer area for scrolling action to happen

        self.sem = QSemaphore(1) # semaphore for controlling access to the enabling / disabling of the scroll listening
        self.pos = self.chr_display.verticalScrollBar().value()

        self.highlight_sem = QSemaphore(1) # semaphore for controlling access to highlighting state
        self.is_highlighted = False
        self.highlight_addr = 0

        self.endian = Endian.little
        self.endian_sem = QSemaphore(1)

        self.hash = randint(0, 0xfffffffffffffff)

        icon = QIcon('package/icons/nasa.png')
        self.setWindowIcon(icon)

        self.max_size = 0xfffffffffffffff

        self.qmp.pmem.connect(self.update_text)
        self.grab_data(val=self.baseAddress, size=min(max, constants['block_size'] + base)-self.baseAddress)

        self.t = MyThread(self)
        self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True))
        self.qmp.stateChanged.connect(self.t.halt)
        self.t.running = self.qmp.running
        self.t.start()

        self.show()
        

    def init_ui(self):   
        self.hbox = QHBoxLayout() # holds widgets for refresh button, desired address, and size to grab
        self.vbox = QVBoxLayout() # main container
        self.lower_hbox = QSplitter() # holds memory views
        self.lower_container = QHBoxLayout() # holds  lower_hbox and the endian_vbox
        self.endian_vbox = QVBoxLayout()

        self.hbox.addWidget(QLabel('Address:'))
        self.address = QLineEdit()
        self.hbox.addWidget(self.address)

        self.hbox.addWidget(QLabel('Size:'))
        self.size = QLineEdit()
        self.hbox.addWidget(self.size)

        self.hbox.addWidget(QLabel('Grouping:'))
        self.grouping = QComboBox()
        self.grouping.addItems(['1','2','4','8'])
        self.hbox.addWidget(self.grouping)

        self.search = QPushButton('Search')
        self.search.clicked.connect(lambda:self.find(self.address.text(), constants['block_size']))
        self.hbox.addWidget(self.search)

        self.refresh = QPushButton('Refresh')
        self.refresh.clicked.connect(lambda:self.grab_data(val=self.address.text(), size=self.size.text(), grouping=self.grouping.currentText(), refresh=True))
        self.hbox.addWidget(self.refresh)

        self.save = QPushButton('Save')
        self.save.clicked.connect(lambda: self.save_to_file())
        self.disable_save(self.qmp.running)
        self.qmp.stateChanged.connect(self.disable_save)
        self.hbox.addWidget(self.save)

        self.auto_refresh = QCheckBox('Auto Refresh')
        self.auto_refresh.setCheckState(Qt.CheckState.Checked)
        self.auto_refresh.stateChanged.connect(self.auto_refresh_check)
        self.hbox.addWidget(self.auto_refresh)

        self.vbox.addLayout(self.hbox)
        
        # textbox for addresses
        self.addresses = QTextEdit()
        self.addresses.setReadOnly(True)
        self.addresses.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.addresses.setLineWrapMode(QTextEdit.NoWrap)
        self.addresses.setCurrentFont(QFont('Courier New'))
        self.addresses.setGeometry(0,0,150,500)
        self.lower_hbox.addWidget(self.addresses)

        # textbox for hex display of memory
        self.mem_display = QTextEdit()
        self.mem_display.setReadOnly(True)
        self.mem_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.mem_display.setLineWrapMode(QTextEdit.NoWrap)
        self.mem_display.setCurrentFont(QFont('Courier New'))
        self.mem_display.setGeometry(0,0,600,500)
        self.lower_hbox.addWidget(self.mem_display)
        
        # textbox for char display of memory
        self.chr_display = QTextEdit()
        self.chr_display.setReadOnly(True)
        self.chr_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.chr_display.setLineWrapMode(QTextEdit.NoWrap)
        self.chr_display.setCurrentFont(QFont('Courier New'))
        self.mem_display.setGeometry(0,0,400,500)
        self.lower_hbox.addWidget(self.chr_display)

        self.lower_container.addWidget(self.lower_hbox)

        self.mem_display.verticalScrollBar().valueChanged.connect(self.addresses.verticalScrollBar().setValue) #synchronizes addresses's scroll bar to mem_display's 
        self.addresses.verticalScrollBar().valueChanged.connect(self.mem_display.verticalScrollBar().setValue) #synchronizes mem_display's scroll to addresses's, allowing for searching for addresses to scrol mem_display to the desired point 
        self.chr_display.verticalScrollBar().valueChanged.connect(self.mem_display.verticalScrollBar().setValue)  
        self.mem_display.verticalScrollBar().valueChanged.connect(self.chr_display.verticalScrollBar().setValue)  

        self.chr_display.verticalScrollBar().valueChanged.connect(self.handle_scroll) # allows us to do scrolling

        # setting up endiannes selection buttons
        self.little = QRadioButton("Little Endian")
        self.little.click()
        self.little.clicked.connect(lambda:self.change_endian(Endian.little))
        self.big = QRadioButton("Big Endian")
        self.big.clicked.connect(lambda:self.change_endian(Endian.big))
        self.endian_vbox.addWidget(self.little)
        self.endian_vbox.addWidget(self.big)
        self.endian_vbox.addSpacing(400)

        self.lower_container.addLayout(self.endian_vbox)

        self.vbox.addLayout(self.lower_container)
        self.vbox.setSpacing(10)
        self.setLayout(self.vbox)
        self.setWindowTitle("Memory Dump")
        self.setGeometry(100, 100, 1550, 500)

    def disable_save(self, val):
        self.save.setEnabled(not val)

    def save_to_file(self):
        try:
            filename = QFileDialog().getSaveFileName(self, 'Save', '.', options=QFileDialog.DontUseNativeDialog)
        except Exception as e:
            return

        if filename[0] == '':
            return

        args = {
            'val': self.baseAddress,
            'size': self.maxAddress - self.baseAddress,
            'filename': filename[0]
        }

        self.qmp.command('pmemsave', args=args)
        



    def auto_refresh_check(self, value):
        if self.auto_refresh.checkState() == Qt.CheckState.Checked and not self.t.isRunning():
            self.t = MyThread(self)
            self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True))
            self.t.start()
        elif self.auto_refresh.checkState() == Qt.CheckState.Unchecked:
            self.kill_signal.emit(True)


    def closeEvent(self, event):
        self.kill_signal.emit(True)
        self.qmp.pmem.disconnect(self.update_text)
        while True:
            if self.sem.tryAcquire(1, 1):
                break
            self.sem.release(10)
        event.accept()


    def update_text(self, value):
        if not value or value['hash'] != self.hash: # semaphore must be held before entering this function
            return
        byte = value['vals']
        if self.refresh:
            self.clear_highlight()
            self.addresses.clear()  # clearing to refresh data, other regions will be refilled through scrolling
            self.mem_display.clear()
            self.chr_display.clear()
            
        s = [''] * ceil((len(byte) / (16))) # hex representation of memory
        addresses =  '' # addresses
        count = self.baseAddress # keeps track of each 16 addresses
        if self.pos == self.max:  # scrolling down
            count = self.maxAddress 

        self.maxAddress = max(count + (len(byte)), self.maxAddress)
 

        first = True
        chars = [''] * len(s) # char represenation of memory
        index = 0
        self.endian_sem.acquire()
        nums = ''
        for tup in byte:
            b = tup['val']
            if count % 16 == 0:
                if first:
                    addresses += f'0x{count:08x}' 
                    first = False
                else:
                    addresses += f'\n0x{count:08x}' 

                    index += 1
            count += 1
             
            if self.endian == Endian.big:
                if tup['ismapped']:
                    nums = f'{b:02x}' + nums
                    chars[index] += f'{char_convert(b):3}'
                else:
                    nums = '**' + nums
                    chars[index] += f'{".":3}'

            elif self.endian == Endian.little:  
                if tup['ismapped']:     
                    nums += f'{b:02x}'      
                    chars[index] = f'{char_convert(b):3}' + chars[index]
                else:
                    nums = '**' + nums
                    chars[index] = f'{".":3}' + chars[index]

            if count % self.group == 0:
                if self.endian == Endian.big:
                    s[index] += nums + ' '
                elif self.endian == Endian.little:
                     s[index] = nums + ' ' + s[index]
                nums = ''
                #print(f'"{s[index]}"')
        self.endian_sem.release()

        s = '\n'.join(s)
        chars = '\n'.join(chars)

        scroll_goto = self.pos

        if self.pos > self.max - self.delta:  # scrolling down
            self.addresses.append(addresses)
            self.mem_display.append(s)
            self.chr_display.append(chars)
            if self.flag:
                self.flag = False
                scroll_goto = (1 - constants['block_size'] / self.threshold) * self.max
            else:
                scroll_goto = self.max

        elif self.pos < self.min + self.delta:    # scrolling  up
            addr_cur = self.addresses.textCursor()
            mem_cur = self.mem_display.textCursor()
            chr_cur = self.chr_display.textCursor()

            addr_cur.setPosition(0)
            mem_cur.setPosition(0)
            chr_cur.setPosition(0)

            self.addresses.setTextCursor(addr_cur)
            self.mem_display.setTextCursor(mem_cur)
            self.chr_display.setTextCursor(chr_cur)

            self.addresses.insertPlainText(addresses + '\n')
            self.mem_display.insertPlainText(s + '\n')
            self.chr_display.insertPlainText(chars + '\n')
            
            if self.flag:
                self.flag = False
                scroll_goto = (constants['block_size'] / self.threshold) * self.max
            else:
                scroll_goto = self.chr_display.verticalScrollBar().maximum() - self.max

        else:
            self.addresses.setPlainText(addresses)
            self.mem_display.setPlainText(s)
            self.chr_display.setPlainText(chars)

        self.highlight_sem.acquire()
        if self.is_highlighted:
            self.highlight_sem.release()
            self.highlight(self.highlight_addr, self.group)
        else:
            self.highlight_sem.release()

        self.chr_display.verticalScrollBar().setValue(scroll_goto)
        self.chr_display.verticalScrollBar().valueChanged.connect(self.handle_scroll)
        self.sem.release()


    def grab_data(self, val=0, size=constants['block_size'], grouping=1, refresh=False):       
        if val == None:
            val = 0
        if size == None:
            size = 1024

        if type(val) == str:
            try:
                val = int(val, 0)
            except Exception:
                val = 0
        
        if type(size) == str:
            try:
                size = int(size, 0)
            except Exception:
                size = constants['block_size']

        if type(grouping) == str:
            try:
                grouping = int(grouping, 0)
            except:
                grouping = 1

        if grouping not in [1, 2, 4, 8]:
            grouping = 1

        if val < 0:
            val = 0
        if val >= self.max_size:
            return
        if size < 0:
            size = constants['block_size']
        if size > self.threshold:
            size = self.threshold
        

        self.sem.acquire()

        val = val - (val % 16)
        if val < self.baseAddress or refresh:
            self.baseAddress = val
        if size % 16 != 0:
            size = size + (16 - (size % 16))
        if val + size > self.max_size:
            size = self.max_size - val
        
        try:
            self.chr_display.verticalScrollBar().valueChanged.disconnect(self.handle_scroll)
        except:
            pass
        self.pos = self.chr_display.verticalScrollBar().value()
        self.max = self.chr_display.verticalScrollBar().maximum()
        self.min = self.chr_display.verticalScrollBar().minimum()
        self.group = grouping

        self.refresh = refresh
        if refresh: 
            self.maxAddress = self.baseAddress
            
            self.highlight_sem.acquire()
            if self.is_highlighted and self.highlight_addr not in range(val, val + size):
                self.is_highlighted = False
                self.pos = 0
            self.highlight_sem.release()

        args = {
                'addr': val,
                'size': size,
                'hash': self.hash,
                'grouping': 1
                }
        self.qmp.command('get-pmem', args=args)


    def find(self, addr, size):
        try:
            addr = int(addr, 0)
        except ValueError as e:
            print(e)
            return
        if self.baseAddress <= addr and addr <= self.maxAddress:
            group = self.grouping.currentText()
            try:
                group = int(group, 0)
                if group not in [1, 2, 4, 8]:
                    group = 1
            except:
                group = 1
            self.highlight(addr, group)
            
        else:
            self.highlight_sem.acquire()
            self.is_highlighted = True
            self.highlight_addr = addr
            self.highlight_sem.release()
            self.grab_data(val=addr, size=size, refresh=True )


    def clear_highlight(self):
        fmt = QTextCharFormat()
        fmt.setFont('Courier New')
        # clearing past highlights
        addr_cur = self.addresses.textCursor()  # getting cursors
        mem_cur = self.mem_display.textCursor()
        chr_cur = self.chr_display.textCursor()

        addr_cur.select(QTextCursor.Document)   # selecting entire document
        mem_cur.select(QTextCursor.Document)
        chr_cur.select(QTextCursor.Document)
        
        addr_cur.setCharFormat(fmt) # adding format
        mem_cur.setCharFormat(fmt)
        chr_cur.setCharFormat(fmt)


    def highlight(self, addr, group):
        self.clear_highlight()
        
        # adding new highlights
        fmt = QTextCharFormat()
        fmt.setBackground(Qt.cyan)
        fmt.setFont('Courier New')

        addr_block = self.addresses.document().findBlockByLineNumber((addr - self.baseAddress) // 16) # gets linenos 
        mem_block = self.mem_display.document().findBlockByLineNumber((addr - self.baseAddress) // 16)
        chr_block = self.chr_display.document().findBlockByLineNumber((addr - self.baseAddress) // 16)

        addr_cur = self.addresses.textCursor()  # getting cursors
        mem_cur = self.mem_display.textCursor()
        chr_cur = self.chr_display.textCursor()


        char_offset = 0
        mem_offset = 0
        self.endian_sem.acquire()
        if self.endian == Endian.big:
            mem_offset = ((addr % 16) // group) * (2 * group + 1)
            char_offset = (addr % 16) * 3
        elif self.endian == Endian.little:
            mem_offset = (((16 / group) - 1 )* (2 * group + 1)) - ((addr % 16) // group) * (2 * group + 1)
            char_offset = (15*3) - ((addr % 16) * 3)
        self.endian_sem.release()
        addr_cur.setPosition(addr_block.position()) # getting positions
        mem_cur.setPosition(mem_block.position() + mem_offset) # gives character offset within 16 byte line
        chr_cur.setPosition(chr_block.position() + char_offset) # sets position of char

        chr_text = self.chr_display.toPlainText()
        if chr_text[chr_cur.position()] == '\\' and chr_cur.position() + 1 < len(chr_text) and chr_text[chr_cur.position() + 1] in ['0', 'n', 't']:
            chr_cur.setPosition(chr_cur.position() + 2, mode=QTextCursor.KeepAnchor) 
        else:
            chr_cur.setPosition(chr_cur.position() + 1, mode=QTextCursor.KeepAnchor) 


        addr_cur.select(QTextCursor.LineUnderCursor)    # selects whole line
        mem_cur.select(QTextCursor.WordUnderCursor)     # selects just one word

        addr_cur.setCharFormat(fmt) # setting format
        mem_cur.setCharFormat(fmt)
        chr_cur.setCharFormat(fmt)

        self.addresses.setTextCursor(addr_cur)
        self.mem_display.setTextCursor(mem_cur)
        self.chr_display.setTextCursor(chr_cur)
        
        self.highlight_sem.acquire()
        self.is_highlighted = True
        self.highlight_addr = addr
        self.highlight_sem.release()


    def handle_scroll(self):
        if self.baseAddress > 0 and self.chr_display.verticalScrollBar().value() < self.chr_display.verticalScrollBar().minimum() + self.delta:
            size = constants['block_size']
            if self.maxAddress - self.baseAddress >= self.threshold:
                self.flag = True
                self.grab_data(val=self.baseAddress - constants['block_size'], size=self.threshold, refresh=True, grouping=self.grouping.currentText())
                return
            if self.baseAddress < size:
                size = self.baseAddress
            self.grab_data(val=self.baseAddress-size, size=size, grouping=self.grouping.currentText())
        elif self.chr_display.verticalScrollBar().value() > self.chr_display.verticalScrollBar().maximum() - self.delta and self.maxAddress <= self.max_size:
            if self.maxAddress - self.baseAddress >= self.threshold:
                self.flag = True
                self.grab_data(val=self.baseAddress + constants['block_size'], size=self.threshold, refresh=True, grouping=self.grouping.currentText())
            else:
                self.grab_data(val=self.maxAddress, grouping=self.grouping.currentText())
      
      
    def change_endian(self, endian):
        self.endian_sem.acquire()
        if endian == Endian.little:
            self.endian = endian
        elif endian == Endian.big:
            self.endian = endian
        self.endian_sem.release()
Exemplo n.º 7
0
class AudioInfoDialog(QDialog):
    def __init__(self,
                 audios_name,
                 audios_delay,
                 audios_language,
                 audios_track_name,
                 audios_set_default,
                 audios_set_forced,
                 audios_default_value_delay,
                 audios_default_value_language,
                 audios_default_value_track_name,
                 audios_default_value_set_default,
                 audios_default_value_set_forced,
                 audio_set_default_disabled=False,
                 audio_set_forced_disabled=False,
                 disable_edit=False,
                 parent=None):
        super().__init__(parent)
        self.window_title = "Audio Info"
        self.state = "no"
        self.audios_count = len(audios_delay)

        self.messageIcon = QLabel()
        self.audio_tab_comboBox = InfoCellDialogTabComboBox(
            hint="Audios Groups")
        for i in range(self.audios_count):
            self.audio_tab_comboBox.addItem("Audio #" + str(i + 1))
        self.audio_tab_comboBox.setCurrentIndex(0)
        self.audio_tab_comboBox.currentIndexChanged.connect(
            self.update_current_audio_index)
        self.current_audio_index = 0

        self.disable_edit = disable_edit
        self.current_audio_name = audios_name
        self.current_audio_language = audios_language
        self.current_audio_delay = audios_delay
        self.current_audio_track_name = audios_track_name
        self.current_audio_set_default = audios_set_default
        self.current_audio_set_forced = audios_set_forced

        self.default_audio_language = audios_default_value_language
        self.default_audio_delay = audios_default_value_delay
        self.default_audio_track_name = audios_default_value_track_name
        self.default_audio_set_default = audios_default_value_set_default
        self.default_audio_set_forced = audios_default_value_set_forced

        self.audio_set_default_disabled = audio_set_default_disabled
        self.audio_set_forced_disabled = audio_set_forced_disabled

        self.audio_name_label = QLabel("Audio Name:")
        self.audio_name_value = QLabel(
            str(self.current_audio_name[self.current_audio_index]))
        width_to_be_fixed = 0
        for i in range(len(self.current_audio_name)):
            width_to_be_fixed = max(
                width_to_be_fixed,
                self.audio_name_value.fontMetrics().boundingRect(
                    self.current_audio_name[i]).width())
        self.audio_name_value.setFixedWidth(width_to_be_fixed + 10)
        self.audio_delay_label = QLabel("Audio Delay:")
        self.audio_delay_spin = QDoubleSpinBox()
        self.setup_audio_delay_spin()

        self.audio_language_label = QLabel("Audio Language:")
        self.audio_language_comboBox = QComboBox()
        self.setup_audio_language_comboBox()

        self.audio_track_name_label = QLabel("Audio Track Name:")
        self.audio_track_name_lineEdit = QLineEdit()
        self.setup_audio_track_name_lineEdit()

        self.audio_set_forced_label = QLabel("Audio Forced State:")
        self.audio_set_forced_checkBox = QCheckBox()
        self.setup_audio_set_forced_checkBox()

        self.audio_set_default_label = QLabel("Audio Default State:")
        self.audio_set_default_checkBox = QCheckBox()
        self.setup_audio_set_default_checkBox()

        self.yes_button = QPushButton("OK")
        self.no_button = QPushButton("Cancel")
        self.reset_button = QPushButton("Reset To Default")

        self.buttons_layout = QHBoxLayout()
        self.audio_delay_layout = QHBoxLayout()
        self.audio_language_layout = QHBoxLayout()
        self.audio_track_name_layout = QHBoxLayout()
        self.audio_set_default_layout = QHBoxLayout()
        self.audio_set_forced_layout = QHBoxLayout()
        self.buttons_layout.addWidget(QLabel(""), stretch=3)
        self.buttons_layout.addWidget(self.reset_button, stretch=2)
        self.buttons_layout.addWidget(self.yes_button, stretch=2)
        self.buttons_layout.addWidget(self.no_button, stretch=2)
        self.buttons_layout.addWidget(QLabel(""), stretch=3)
        self.audio_setting_layout = QGridLayout()
        self.audio_editable_setting_layout = QFormLayout()
        self.audio_editable_setting_layout.addRow(self.audio_name_label,
                                                  self.audio_name_value)
        self.audio_editable_setting_layout.addRow(
            self.audio_track_name_label, self.audio_track_name_lineEdit)
        self.audio_editable_setting_layout.addRow(self.audio_language_label,
                                                  self.audio_language_comboBox)
        self.audio_editable_setting_layout.addRow(self.audio_delay_label,
                                                  self.audio_delay_spin)
        self.audio_editable_setting_layout.addRow(
            self.audio_set_default_label, self.audio_set_default_checkBox)
        self.audio_editable_setting_layout.addRow(
            self.audio_set_forced_label, self.audio_set_forced_checkBox)
        self.audio_setting_layout.addWidget(self.audio_tab_comboBox, 0, 0)
        self.audio_setting_layout.addLayout(self.audio_editable_setting_layout,
                                            1, 0, 5, 2)
        self.audio_setting_layout.addWidget(self.messageIcon, 1, 3, 5, -1)

        self.main_layout = QGridLayout()
        self.main_layout.addLayout(self.audio_setting_layout, 0, 0, 2, 3)
        self.main_layout.addLayout(self.buttons_layout, 2, 0, 1, -1)
        self.main_layout.setContentsMargins(20, 20, 20, 20)
        self.setLayout(self.main_layout)

        self.setup_ui()
        self.signal_connect()

    def setup_ui(self):
        self.disable_question_mark_window()
        self.messageIcon.setPixmap(
            QtGui.QPixmap(GlobalFiles.AudioIconPath).scaledToHeight(100))
        self.set_dialog_values()
        self.set_default_buttons()
        if self.audio_set_default_disabled:
            self.audio_set_default_disable()
        if self.audio_set_forced_disabled:
            self.audio_set_forced_disable()
        if self.disable_edit:
            self.audio_track_name_lineEdit.setEnabled(False)
            self.audio_language_comboBox.setEnabled(False)
            self.audio_delay_spin.setEnabled(False)
            self.audio_set_default_checkBox.setEnabled(False)
            self.audio_set_forced_checkBox.setEnabled(False)
            self.reset_button.setEnabled(False)

        self.setup_tool_tip_hint_audio_set_default()
        self.setup_tool_tip_hint_audio_set_forced()

    def signal_connect(self):
        self.audio_track_name_lineEdit.textEdited.connect(
            self.update_current_audio_track_name)
        self.audio_delay_spin.editingFinished.connect(
            self.update_current_audio_delay)
        self.audio_language_comboBox.currentTextChanged.connect(
            self.update_current_audio_language)
        self.audio_set_default_checkBox.stateChanged.connect(
            self.update_current_audio_set_default)
        self.audio_set_forced_checkBox.stateChanged.connect(
            self.update_current_audio_set_forced)
        self.yes_button.clicked.connect(self.click_yes)
        self.no_button.clicked.connect(self.click_no)
        self.reset_button.clicked.connect(self.reset_audio_setting)

    def click_yes(self):
        self.state = "yes"
        self.close()

    def click_no(self):
        self.state = "no"
        self.close()

    def set_dialog_values(self):
        self.setWindowTitle(self.window_title)
        self.setWindowIcon(GlobalFiles.InfoSettingIcon)

    def disable_question_mark_window(self):
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, on=False)

    def increase_message_font_size(self, value):
        message_font = self.message.font()
        message_font.setPointSize(self.message.fontInfo().pointSize() + value)
        self.message.setFont(message_font)

    def set_default_buttons(self):
        self.yes_button.setDefault(True)
        self.yes_button.setFocus()

    def showEvent(self, a0: QtGui.QShowEvent) -> None:
        super().showEvent(a0)
        self.setFixedSize(self.size())

    def setup_audio_track_name_lineEdit(self):
        self.audio_track_name_lineEdit.setClearButtonEnabled(True)
        self.audio_track_name_lineEdit.setText(
            self.current_audio_track_name[self.current_audio_index])

    def setup_audio_language_comboBox(self):
        self.audio_language_comboBox.addItems(AllAudiosLanguages)
        self.audio_language_comboBox.setCurrentIndex(
            AllAudiosLanguages.index(
                self.current_audio_language[self.current_audio_index]))
        self.audio_language_comboBox.setMaxVisibleItems(8)
        self.audio_language_comboBox.setStyleSheet(
            "QComboBox { combobox-popup: 0; }")

    def setup_audio_delay_spin(self):
        # self.audio_delay_spin.setMaximumWidth(screen_size.width() // 16)
        self.audio_delay_spin.setDecimals(3)
        self.audio_delay_spin.setMinimum(-9999.0)
        self.audio_delay_spin.setMaximum(9999.0)
        self.audio_delay_spin.setSingleStep(0.5)
        self.audio_delay_spin.setValue(
            float(self.current_audio_delay[self.current_audio_index]))

    def setup_audio_set_default_checkBox(self):
        self.audio_set_default_checkBox.setText("Set Default")
        self.audio_set_default_checkBox.setChecked(
            bool(self.current_audio_set_default[self.current_audio_index]))

    def setup_audio_set_forced_checkBox(self):
        self.audio_set_forced_checkBox.setText("Set Forced")
        self.audio_set_forced_checkBox.setChecked(
            bool(self.current_audio_set_forced[self.current_audio_index]))

    def update_current_audio_track_name(self):
        self.current_audio_track_name[self.current_audio_index] = str(
            self.audio_track_name_lineEdit.text())

    def update_current_audio_delay(self):
        self.current_audio_delay[self.current_audio_index] = round(
            self.audio_delay_spin.value(), 5)

    def update_current_audio_language(self):
        self.current_audio_language[self.current_audio_index] = str(
            self.audio_language_comboBox.currentText())

    def update_current_audio_set_default(self):
        new_state = self.audio_set_default_checkBox.checkState() == Qt.Checked
        self.current_audio_set_default[self.current_audio_index] = new_state
        if new_state:
            for i in range(len(self.current_audio_set_default)):
                if i != self.current_audio_index:
                    self.current_audio_set_default[i] = False

    def update_current_audio_set_forced(self):
        new_state = self.audio_set_forced_checkBox.checkState() == Qt.Checked
        self.current_audio_set_forced[self.current_audio_index] = new_state
        if new_state:
            for i in range(len(self.current_audio_set_forced)):
                if i != self.current_audio_index:
                    self.current_audio_set_forced[i] = False

    def reset_audio_setting(self):
        self.current_audio_language[
            self.current_audio_index] = self.default_audio_language[
                self.current_audio_index]
        self.current_audio_delay[
            self.current_audio_index] = self.default_audio_delay[
                self.current_audio_index]
        self.current_audio_track_name[
            self.current_audio_index] = self.default_audio_track_name[
                self.current_audio_index]
        self.current_audio_set_default[
            self.current_audio_index] = self.default_audio_set_default[
                self.current_audio_index]
        self.current_audio_set_forced[
            self.current_audio_index] = self.default_audio_set_forced[
                self.current_audio_index]

        self.audio_language_comboBox.setCurrentIndex(
            AllAudiosLanguages.index(
                self.current_audio_language[self.current_audio_index]))
        self.audio_delay_spin.setValue(
            float(self.current_audio_delay[self.current_audio_index]))
        self.audio_track_name_lineEdit.setText(
            self.current_audio_track_name[self.current_audio_index])
        self.audio_set_default_checkBox.setChecked(
            bool(self.current_audio_set_default[self.current_audio_index]))
        self.audio_set_forced_checkBox.setChecked(
            bool(self.current_audio_set_forced[self.current_audio_index]))

    def audio_set_default_disable(self):
        self.audio_set_default_checkBox.setDisabled(True)

    def audio_set_forced_disable(self):
        self.audio_set_forced_checkBox.setDisabled(True)

    def setup_tool_tip_hint_audio_set_default(self):
        if self.audio_set_default_checkBox.isEnabled():
            self.audio_set_default_checkBox.setToolTip(
                "<nobr>set this audio to be the default audio track "
                "when play")
            self.audio_set_default_checkBox.setToolTipDuration(12000)
        else:
            self.audio_set_default_checkBox.setToolTip(
                "<nobr>set this audio to be the default audio track when play<br><b>Disabled</b> because "
                "option "
                "<b>make this audio default</b> is enabled on mux setting tab "
            )
            self.audio_set_default_checkBox.setToolTipDuration(12000)

    def setup_tool_tip_hint_audio_set_forced(self):
        if self.audio_set_forced_checkBox.isEnabled():
            self.audio_set_forced_checkBox.setToolTip(
                "<nobr>set this audio to be the forced audio track when "
                "play")
            self.audio_set_forced_checkBox.setToolTipDuration(12000)
        else:
            self.audio_set_forced_checkBox.setToolTip(
                "<nobr>set this audio to be the forced audio track when play<br><b>Disabled</b> because "
                "option "
                "<b>make this audio default and forced</b> is enabled on mux setting tab "
            )
            self.audio_set_forced_checkBox.setToolTipDuration(12000)

    def update_current_audio_index(self, new_index):
        self.current_audio_index = new_index
        self.audio_delay_spin.setValue(
            float(self.current_audio_delay[self.current_audio_index]))
        self.audio_set_default_checkBox.setChecked(
            bool(self.current_audio_set_default[self.current_audio_index]))
        self.audio_set_forced_checkBox.setChecked(
            bool(self.current_audio_set_forced[self.current_audio_index]))
        self.audio_language_comboBox.setCurrentIndex(
            AllAudiosLanguages.index(
                self.current_audio_language[self.current_audio_index]))
        self.audio_track_name_lineEdit.setText(
            self.current_audio_track_name[self.current_audio_index])
        self.audio_name_value.setText(
            str(self.current_audio_name[self.current_audio_index]))

    def execute(self):
        self.exec_()
Exemplo n.º 8
0
class SaveTab(QWidget):
    def __init__(self, parent):
        """Initialize the save tab
        """

        super(SaveTab, self).__init__(parent)

        self.prefs = parent.prefs
        self.order_options = {'SortedOrder': 'Sorted (based on IDD file)',
                              'OriginalOrderTop': 'Original order (With new objects on top)',
                              'OriginalOrderBottom': 'Original order (With new objects on bottom)'}
        self.format_options = {'UseSpecialFormat': 'Use special formatting for some objects',
                               'None': 'Do not use special formatting'}

        # Sort Order Code
        order_label = QLabel("Save Order for Objects:")
        self.order_edit = QComboBox(self)
        self.order_edit.addItems(list(self.order_options.values()))
        self.order_edit.setMaximumWidth(350)
        order_setting = self.order_options[self.prefs['sort_order']]
        self.order_edit.setCurrentIndex(self.order_edit.findText(order_setting))
        self.order_edit.currentIndexChanged.connect(self.update_order)

        format_label = QLabel("Special Formatting:")
        self.format_edit = QComboBox(self)
        self.format_edit.addItems(list(self.format_options.values()))
        self.format_edit.setMaximumWidth(350)
        format_setting = self.format_options[self.prefs['special_formatting']]
        self.format_edit.setCurrentIndex(self.format_edit.findText(format_setting))
        self.order_edit.currentIndexChanged.connect(self.update_format)

        self.save_group_box = QGroupBox("Default Save Options")
        save_box = QVBoxLayout()
        save_box.addWidget(order_label)
        save_box.addWidget(self.order_edit)
        save_box.addSpacing(10)
        save_box.addWidget(format_label)
        save_box.addWidget(self.format_edit)
        save_box.addStretch(1)
        self.save_group_box.setLayout(save_box)
        self.save_group_box.setEnabled(False)

        # Save additional options code
        self.save_units_check = QCheckBox('Units to display by default (SI vs IP)', self)
        checked_header = Qt.Checked if self.prefs['save_units'] == 1 else Qt.Unchecked
        self.save_units_check.setCheckState(checked_header)
        self.save_units_check.stateChanged.connect(self.update)
        self.save_hidden_classes_check = QCheckBox('Whether empty classes are hidden', self)
        checked_cells = Qt.Checked if self.prefs['save_hidden_classes'] == 1 else Qt.Unchecked
        self.save_hidden_classes_check.setCheckState(checked_cells)
        self.save_hidden_classes_check.stateChanged.connect(self.update)
        self.save_groups_check = QCheckBox('Whether to hide group headers', self)
        checked_groups = Qt.Checked if self.prefs['save_hide_groups'] == 1 else Qt.Unchecked
        self.save_groups_check.setCheckState(checked_groups)
        self.save_groups_check.stateChanged.connect(self.update)

        # Save additional options group box code
        self.save_additional_group_box = QGroupBox("Save Additional Options in IDF File")
        save_additional_box = QVBoxLayout()
        save_additional_box.addWidget(self.save_units_check)
        save_additional_box.addWidget(self.save_hidden_classes_check)
        save_additional_box.addWidget(self.save_groups_check)
        save_additional_box.addStretch(1)
        self.save_additional_group_box.setLayout(save_additional_box)

        # Main layout code
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.save_additional_group_box)
        main_layout.addSpacing(10)
        main_layout.addWidget(self.save_group_box)
        main_layout.addStretch(1)
        self.setLayout(main_layout)

    def update_order(self):
        text = self.order_edit.currentText()
        for key, val in list(self.order_options.items()):
            if val == text:
                to_save = key
        self.prefs['sort_order'] = to_save

    def update_format(self):
        text = self.format_edit.currentText()
        for key, val in self.format_options.items():
            if val == text:
                to_save = key
        self.prefs['format'] = to_save

    def update(self):
        self.prefs['save_units'] = 1 if self.save_units_check.checkState() else 0
        self.prefs['save_hidden_classes'] = 1 if self.save_hidden_classes_check.checkState() else 0
        self.prefs['save_hide_groups'] = 1 if self.save_groups_check.checkState() else 0
Exemplo n.º 9
0
class MyGui(QWidget, GitCmd):
    def __init__(self, title="Create By ZZZ", path=DEFAULT_GIT_REPO):
        super(MyGui, self).__init__()
        GitCmd.__init__(self, path)  # 初始化命令
        self.show_info = None
        self.cmd_history = None
        self.cmd_history_cmd_list = list()
        # 复选框
        self.check_box_select_all = None
        self.check_box = list()
        self.check_box_button = None
        # 默认值
        self.show_log_num = DEFAULT_GIT_LOG_NUM
        self.file_list = DEFAULT_GIT_ADD_LIST
        self.gridLayout = QGridLayout(self)
        self.setGeometry(100, 100, 800, 700)
        self.setWindowTitle(title)
        # 记录当前widget最大行号
        self.max_line_no = 0

    # - - - - - - - - -  - - - - - - - - -  - - - - - - - - -  - - - - - - - - -
    # 显示信息相关
    def add_info_text(self):
        # 添加消息显示框,我们使用列表方式显示
        self.show_info = QListWidget()
        self.show_info.setFixedSize(800, 600)
        self.gridLayout.addWidget(self.show_info, 0, 0, 1, 4)
        # 单击触发绑定的槽函数
        self.show_info.itemClicked.connect(self.text_block_clicked)

        # 命令行显示,我们使用下拉框
        self.cmd_history = QComboBox()
        self.gridLayout.addWidget(self.cmd_history, 1, 0, 1, 4)
        # 设置行号
        self.max_line_no = 2

    def add_cmd(self, cmd):
        if len(self.cmd_history_cmd_list) < 10:
            self.cmd_history_cmd_list.append(cmd)
        else:
            self.cmd_history_cmd_list = self.cmd_history_cmd_list[1:].append(cmd)
        self.cmd_history.clear()
        self.cmd_history.addItems(reversed(self.cmd_history_cmd_list))

    def update_cmd(self, extra: str):
        cur_cmd = self.cmd_history.currentText().split(" ")
        new_cmd = cur_cmd[:2] + [extra]  # 拆分出来git和后面的命令,拼接参数
        if cur_cmd:
            self.cmd_history.setItemText(0, " ".join(new_cmd))

    # 对每一行都进行上色
    def my_print(self, text_list: list, background: list):
        # self.show_info.clear() 这个可以清空显示
        self.show_info.addItems([".  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  . .  .  .  .  .  .  .  .  "
                                 ".  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  . .  .  .  .  .  .  .  .  "])
        for ind in range(len(text_list)):
            item = QListWidgetItem('%s' % text_list[ind])
            item.setBackground(QColor(background[ind]))  # 上色
            self.show_info.addItem(item)
        self.show_info.scrollToBottom()  # 自动到最后行

    @staticmethod
    def text_block_clicked(item):
        # 这里没有什么要做的
        # QMessageBox.information(self, "命令历史", "你选择了: " + item.text())
        pass
    # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

    # - - - - - - - - -  - - - - - - - - -  - - - - - - - - -  - - - - - - - - -
    # 添加按钮
    def add_git_button(self):
        cmd_add = QPushButton('Git Add')
        cmd_reset = QPushButton('Git Reset')
        cmd_status = QPushButton('Git Status')
        cmd_log = QPushButton('Git Log')
        cmd_run = QPushButton('Run Cmd')
        line_no = self.max_line_no
        self.gridLayout.addWidget(cmd_add, line_no, 0)
        self.gridLayout.addWidget(cmd_reset, line_no, 1)
        self.gridLayout.addWidget(cmd_status, line_no, 2)
        self.gridLayout.addWidget(cmd_log, line_no, 3)
        self.gridLayout.addWidget(cmd_run, line_no + 1, 0)
        self.max_line_no = self.max_line_no + 2
        cmd_log.clicked.connect(self.git_log)
        cmd_add.clicked.connect(self.git_add)
        cmd_reset.clicked.connect(self.git_reset)
        cmd_status.clicked.connect(self.git_status)
        cmd_run.clicked.connect(self.run_git)

    def run_git(self):
        cur_cmd = self.cmd_history.currentText()
        # 执行代码
        if cur_cmd.startswith("git add"):
            result, background = self.cmd_git_add(self.file_list)
            self.my_print(result, background)
        elif cur_cmd.startswith("git status"):
            result, background = self.cmd_git_status()
            self.my_print(result, background)
        elif cur_cmd.startswith("git log"):
            result, background = self.cmd_git_log(self.show_log_num)
            self.my_print(result, background)
        elif cur_cmd.startswith("git reset"):
            result, background = self.cmd_git_reset(self.file_list)
            self.my_print(result, background)

    def git_log(self):
        # 日常清理
        self.cleanup()
        # 记录命令
        self.add_cmd("git log -" + self.show_log_num)
        # 可以直接运行
        self.run_git()

    def git_add(self):
        # 日常清理
        self.cleanup()
        # 文件选择
        files = self.get_file_list_by_status()
        self.create_check_box(files)
        # 记录命令
        self.add_cmd("git add .")

    def git_status(self):
        # 日常清理
        self.cleanup()
        # 记录命令
        self.add_cmd("git status")
        # 可以直接运行
        self.run_git()

    def git_reset(self):
        # 日常清理
        self.cleanup()
        # 文件选择
        files = self.get_file_list_by_status()
        self.create_check_box(files)
        # 记录命令
        self.add_cmd("git reset .")

    # - - - - - - - - -  - - - - - - - - -  - - - - - - - - -  - - - - - - - - -
    # 创建复选框
    def create_check_box(self, opt_list: list):
        # 创建
        self.check_box_select_all = QCheckBox('全选')
        # lambda可以传参:lambda: self.check_box_changes_all(<参数>)
        self.check_box_select_all.stateChanged.connect(lambda: self.check_box_changes_all())
        for ind in range(len(opt_list)):
            self.check_box.append(QCheckBox(opt_list[ind]))
            self.check_box[ind].stateChanged.connect(lambda: self.check_box_changes())
        # self.check_box_button = QPushButton('提交')
        # 布局
        ind = self.max_line_no
        self.gridLayout.addWidget(self.check_box_select_all, ind, 0)
        ind = ind + 1
        for check_box in self.check_box:
            self.gridLayout.addWidget(check_box, ind, 0)
            ind = ind + 1
        # self.gridLayout.addWidget(self.check_box_button, ind, 0)
        # 添加按钮回调
        # self.check_box_button.clicked.connect(self.check_box_ok)
        # 更新行号
        # self.max_line_no = ind + 1
        self.max_line_no = ind

    def check_box_ok(self):
        # 清除小部件
        if self.check_box:
            self.file_list.clear()
            for check_box in self.check_box:
                # 更新列表
                # if check_box.checkState() == Qt.Checked:
                #     self.file_list.append(check_box.text())
                # 清除
                check_box.deleteLater()
            self.check_box.clear()
        if self.check_box_select_all:
            self.check_box_select_all.deleteLater()
            self.check_box_select_all = None
        if self.check_box_button:
            self.check_box_button.deleteLater()
            self.check_box_button = None

    def check_box_changes_all(self):
        if self.check_box_select_all.checkState() == Qt.Checked:
            for check_box in self.check_box:
                check_box.setChecked(True)
        elif self.check_box_select_all.checkState() == Qt.Unchecked:
            for check_box in self.check_box:
                check_box.setChecked(False)

    def check_box_changes(self):
        all_checked = True
        # one_checked = False
        self.file_list.clear()
        for check_box in self.check_box:
            if not check_box.isChecked():
                all_checked = False  # 只要有一个没勾选
            else:
                self.file_list.append(check_box.text())  # 更新列表
            # else:
            #     one_checked = True  # 只要有一个勾选
        if all_checked:
            self.check_box_select_all.setCheckState(Qt.Checked)
        # elif one_checked:
            # self.check_box_select_all.setTristate()  # 设置为3态选择框
            # self.check_box_select_all.setCheckState(Qt.PartiallyChecked)
        # else:
        #   self.check_box_select_all.setTristate()  # 设置为3态选择框
        #   self.check_box_select_all.setCheckState(Qt.Unchecked)

        # 更新命令
        files = " ".join(self.file_list)
        self.update_cmd(files)

    # - - - - - - - - -  - - - - - - - - -  - - - - - - - - -  - - - - - - - - -
    # 清理临时的小部件
    def cleanup(self):
        self.check_box_ok()

    # - - - - - - - - -  - - - - - - - - -  - - - - - - - - -  - - - - - - - - -
    # 例子
    def addButtonExample(self):
        # 创建一些小部件放在顶级窗口中
        btn = QPushButton('press me')
        text = QLineEdit('enter text')
        listw = QListWidget()
        listw.addItems(["aa", "bb", "cc"])
        # self.gridLayout = QGridLayout(self)
        # 将部件添加到布局中的适当位置,
        # addWidget参数:Widget实例, 起始row, 起始column, 占多少行(高度),占多少列(宽度)
        self.gridLayout.addWidget(btn, 0, 0)
        self.gridLayout.addWidget(text, 1, 0)
        self.gridLayout.addWidget(listw, 2, 0)
        # self.setLayout(self.gridLayout)

    # 画图1
    def linePlot(self):
        plt1 = pg.PlotWidget()
        plt1.plot([i for i in range(10)], [i * i for i in range(10)])
        self.gridLayout.addWidget(plt1, 0, 1, 1, 1)

    # 画图2
    def scatterPlot(self):
        plt2 = pg.PlotWidget()
        x = np.random.normal(size=1000)
        y = np.random.normal(size=1000)
        plt2.plot(x, y, pen=None, symbol="o")
        self.gridLayout.addWidget(plt2, 1, 1, 1, 1)

    # 画图3
    def three_curves(self):
        plt3 = pg.PlotWidget(title="Three plot curves")
        x = np.arange(1000)
        y = np.random.normal(size=(3, 1000))
        for i in range(3):
            plt3.plot(x, y[i], pen=(i, 3))  # setting pen=(i,3) 自动创建3个不同颜色的笔
        self.gridLayout.addWidget(plt3, 2, 1, 1, 1)
Exemplo n.º 10
0
class MainWindow(QWidget):
    def __init__(self, appctx):
        super().__init__()

        self.appctx = appctx
        self.api = None
        self.settings = Settings()
        self.gateway = Gateway()
        self.timers: Dict[str, QTimer] = {}

        self.init_ui()

    def init_ui(self):
        self.vbox = QVBoxLayout()
        self.hbox = QHBoxLayout()

        # Set layout
        self.setLayout(self.vbox)

        # Group list
        vbox3 = QVBoxLayout()
        group_frame = QGroupBox("Device Groups")
        group_frame.setLayout(QVBoxLayout())
        self.group_list = QListWidget()
        self.group_list.itemPressed.connect(self.group_selected)
        group_frame.layout().addWidget(self.group_list)
        vbox3.addWidget(group_frame)

        # Sliders
        self.group_toggle = QCheckBox("Power")
        self.group_toggle.setEnabled(False)
        vbox3.addWidget(self.group_toggle)
        vbox3.addWidget(QLabel("Brightness"))
        self.group_brightness_slider = QSlider(Qt.Orientation.Horizontal)
        self.group_brightness_slider.setEnabled(False)
        self.group_brightness_slider.sliderMoved.connect(
            self.group_brightness_changed)
        vbox3.addWidget(self.group_brightness_slider)
        vbox3.addWidget(QLabel("Color Temperature"))
        self.group_color_slider = QSlider(Qt.Orientation.Horizontal)
        self.group_color_slider.setEnabled(False)
        self.group_color_slider.sliderMoved.connect(self.group_color_changed)
        vbox3.addWidget(self.group_color_slider)

        self.hbox.addLayout(vbox3)

        # moods
        mood_frame = QGroupBox("Moods")
        mood_frame.setLayout(QVBoxLayout())
        self.mood_list = QListWidget()
        self.mood_list.itemPressed.connect(self.mood_selected)
        mood_frame.layout().addWidget(self.mood_list)

        self.hbox.addWidget(mood_frame)

        # Devices in group
        vbox2 = QVBoxLayout()

        device_frame = QGroupBox("Devices in Group")
        device_frame.setLayout(QVBoxLayout())
        self.device_list = QListWidget()
        self.device_list.setEnabled(False)
        self.device_list.itemPressed.connect(self.device_selected)
        device_frame.layout().addWidget(self.device_list)
        vbox2.addWidget(device_frame)

        # Sliders
        self.device_toggle = QCheckBox("Power")
        self.device_toggle.setEnabled(False)
        vbox2.addWidget(self.device_toggle)
        vbox2.addWidget(QLabel("Brightness"))
        self.brightness_slider = QSlider(Qt.Orientation.Horizontal)
        self.brightness_slider.setEnabled(False)
        self.brightness_slider.sliderMoved.connect(self.brightness_changed)
        vbox2.addWidget(self.brightness_slider)
        vbox2.addWidget(QLabel("Color Temperature"))
        self.color_slider = QSlider(Qt.Orientation.Horizontal)
        self.color_slider.setEnabled(False)
        self.color_slider.sliderMoved.connect(self.color_changed)
        vbox2.addWidget(self.color_slider)

        self.hbox.addLayout(vbox2)
        self.vbox.addLayout(self.hbox)

        # Settings button
        icon = QIcon(resource_path('icons/settings.png'))
        self.settings_button = QPushButton(icon, "Settings")
        self.settings_button.pressed.connect(self.settings_pressed)
        self.vbox.addWidget(self.settings_button)

        self.setWindowTitle('TradfriGUI')
        self.re_init()

    def re_init(self):
        if self.settings.gateway_ip is None or self.settings.gateway_ip == '':
            self.settings_pressed()
        self.api = get_api(self.settings)

        self.device_list.clear()
        self.group_list.clear()

        if self.api is None:
            return

        groups = self.api(self.gateway.get_groups())
        if len(groups) == 0:
            self.group_list.setEnabled(False)
            # TODO: load devices directly

        for group in groups:
            item = self.api(group)
            list_item = QListWidgetItem(item.name, self.group_list)
            setattr(list_item, 'api_item', item)

    def group_selected(self):
        current_item = self.group_list.currentItem()
        item = getattr(current_item, 'api_item', None)
        if item is None:
            return
        # refresh from gateway
        item = self.api(self.gateway.get_group(item.id))

        # load moods
        self.mood_list.clear()
        moods = self.api(item.moods())
        for m in moods:
            mood = self.api(m)
            list_item = QListWidgetItem(mood.name, self.mood_list)
            setattr(list_item, 'api_item', mood)

        # load devices
        devices = item.members()
        self.device_list.clear()

        # determine shared state and add devices to list
        state = False
        color_temp = False
        min_color = 10000
        max_color = 0
        color = []
        brightness = []
        for d in devices:
            device = self.api(d)
            if device.has_light_control:
                if device.light_control.lights[0].state:
                    state = True
                if device.light_control.can_set_dimmer:
                    if device.light_control.lights[0].state:
                        brightness.append(
                            device.light_control.lights[0].dimmer)
                    else:
                        brightness.append(0)
                if device.light_control.can_set_temp:
                    color_temp = True
                    min_color = min(min_color, device.light_control.min_mireds)
                    max_color = max(max_color, device.light_control.max_mireds)
                    color.append(device.light_control.lights[0].color_temp)
            list_item = QListWidgetItem(device.name, self.device_list)
            setattr(list_item, 'api_item', device)

        if len(brightness) > 0:
            brightness = int(sum(brightness) / len(brightness))
        else:
            brightness = 0

        if len(color) > 0:
            color = int(sum(color) / len(color))
        else:
            color = min_color

        # enable device list and controls
        self.device_list.setEnabled(True)

        self.group_brightness_slider.setEnabled(True)
        self.group_brightness_slider.setMinimum(0)
        self.group_brightness_slider.setMaximum(254)
        self.group_brightness_slider.setSingleStep(16)
        self.group_brightness_slider.setValue(brightness)

        if color_temp:
            self.group_color_slider.setEnabled(True)
            self.group_color_slider.setMinimum(min_color)
            self.group_color_slider.setMaximum(max_color)
            self.group_color_slider.setSingleStep(
                int((max_color - min_color) / 10))
            self.group_color_slider.setValue(color)
        else:
            self.group_color_slider.setEnabled(False)

        self.group_toggle.setEnabled(True)
        try:
            self.group_toggle.stateChanged.disconnect(self.group_toggled)
        except RuntimeError:
            pass  # Disconnect failed because nothing was connected
        self.group_toggle.setCheckState(
            Qt.CheckState.Checked if state else Qt.CheckState.Unchecked)
        self.group_toggle.stateChanged.connect(self.group_toggled)

        self.brightness_slider.setEnabled(False)
        self.color_slider.setEnabled(False)
        self.device_toggle.setEnabled(False)

    def device_selected(self):
        current_item = self.device_list.currentItem()
        item = getattr(current_item, 'api_item', None)
        if item is None:
            return
        # refresh from gateway
        item = self.api(self.gateway.get_device(item.id))

        # enable appropriate controls
        if item.has_light_control:
            ctrl = item.light_control
            if ctrl.can_set_dimmer:
                self.brightness_slider.setEnabled(True)
                self.brightness_slider.setMinimum(0)
                self.brightness_slider.setMaximum(254)
                self.brightness_slider.setSingleStep(16)
                self.brightness_slider.setValue(ctrl.lights[0].dimmer)
            else:
                self.brightness_slider.setEnabled(False)
            if ctrl.can_set_temp:
                self.color_slider.setEnabled(True)
                self.color_slider.setMinimum(ctrl.min_mireds)
                self.color_slider.setMaximum(ctrl.max_mireds)
                self.color_slider.setSingleStep(
                    int((ctrl.max_mireds - ctrl.min_mireds) / 10))
                self.color_slider.setValue(ctrl.lights[0].color_temp)
            else:
                self.color_slider.setEnabled(False)
            self.device_toggle.setEnabled(True)
            try:
                self.device_toggle.stateChanged.disconnect(self.device_toggled)
            except RuntimeError:
                pass  # disconnect failed because nothing was connected
            self.device_toggle.setCheckState(
                Qt.CheckState.Checked if ctrl.lights[0].state else Qt.
                CheckState.Unchecked)
            self.device_toggle.stateChanged.connect(self.device_toggled)
        else:
            self.brightness_slider.setEnabled(False)
            self.color_slider.setEnabled(False)
            self.device_toggle.setEnabled(False)

    def mood_selected(self):
        current_group = self.group_list.currentItem()
        group = getattr(current_group, 'api_item', None)
        if group is None:
            return
        # refresh from gateway
        group = self.api(self.gateway.get_group(group.id))

        current_mood = self.mood_list.currentItem()
        mood = getattr(current_mood, 'api_item', None)
        if mood is None:
            return

        self.api(group.activate_mood(mood.id))

    def group_brightness_changed(self):
        current_item = self.group_list.currentItem()
        if current_item is None:
            return
        item = getattr(current_item, 'api_item', None)
        command = item.set_dimmer(self.group_brightness_slider.value(),
                                  transition_time=2)

        self.queue_command('group_brightness', command)

    def group_color_changed(self):
        current_item = self.group_list.currentItem()
        if current_item is None:
            return
        item = getattr(current_item, 'api_item', None)

        command = item.set_color_temp(self.group_color_slider.value(),
                                      transition_time=2)

        self.queue_command('group_color', command)

    def brightness_changed(self):
        current_item = self.device_list.currentItem()
        if current_item is None:
            return
        item = getattr(current_item, 'api_item', None)
        command = item.light_control.set_dimmer(self.brightness_slider.value(),
                                                transition_time=2)

        self.queue_command('device_brightness_{}'.format(item.id), command)

    def color_changed(self):
        current_item = self.device_list.currentItem()
        if current_item is None:
            return
        item = getattr(current_item, 'api_item', None)
        command = item.light_control.set_color_temp(self.color_slider.value(),
                                                    transition_time=2)

        self.queue_command('device_color_{}'.format(item.id), command)

    def device_toggled(self):
        current_item = self.device_list.currentItem()
        if current_item is None:
            return
        item = getattr(current_item, 'api_item', None)
        command = item.light_control.set_state(
            self.device_toggle.checkState() == Qt.CheckState.Checked)
        self.api(command)

    def group_toggled(self):
        current_item = self.group_list.currentItem()
        if current_item is None:
            return
        item = getattr(current_item, 'api_item', None)
        command = item.set_state(
            self.group_toggle.checkState() == Qt.CheckState.Checked)
        self.api(command)

    def settings_pressed(self):
        config = ConfigWindow(self.appctx, self)
        config.setWindowModality(Qt.ApplicationModal)
        config.exec_()

        # reload settings
        self.settings = config.settings

        # re-initialize window
        self.re_init()

    def queue_command(self, name, command):
        timer = self.timers.get(name, None)
        if timer is None:
            timer = QTimer()
            timer.setInterval(200)
            timer.setSingleShot(True)
            timer.timeout.connect(self.timeout)
            timer.start()

        setattr(timer, 'command', command)
        self.timers[name] = timer

    def timeout(self):
        remove = []
        for key, item in self.timers.items():
            if item.isActive() == False:
                cmd = getattr(item, 'command')
                self.api(cmd)
                remove.append(key)
        for key in remove:
            del self.timers[key]
class FilewriterCommandWidget(QWidget):
    """
    Used for the required and optional fields when saving a filewriter command JSON file.
    """
    def __init__(self, parent=None):
        super(FilewriterCommandWidget, self).__init__()
        self.setParent(parent)
        self.setLayout(QFormLayout())

        self.nexus_file_name_edit = QLineEdit()

        self.ok_button = QPushButton("Ok")
        if parent is not None:
            self.ok_button.clicked.connect(parent.close)

        self.broker_line_edit = QLineEdit()
        self.broker_line_edit.setPlaceholderText("broker:port")

        self.ok_validator = CommandDialogOKValidator()
        self.ok_validator.is_valid.connect(self.ok_button.setEnabled)

        filename_validator = CommandDialogFileNameValidator()
        self.nexus_file_name_edit.setValidator(filename_validator)
        filename_validator.is_valid.connect(
            partial(
                validate_line_edit,
                self.nexus_file_name_edit,
                tooltip_on_reject=
                f"Invalid NeXus file name - Should end with {HDF_FILE_EXTENSIONS}",
            ))
        filename_validator.is_valid.connect(
            self.ok_validator.set_filename_valid)
        filename_validator.is_valid.emit(False)

        broker_validator = NameValidator([])
        self.broker_line_edit.setValidator(broker_validator)
        broker_validator.is_valid.connect(
            partial(
                validate_line_edit,
                self.broker_line_edit,
                tooltip_on_reject="Broker is required",
            ))
        broker_validator.is_valid.connect(self.ok_validator.set_broker_valid)
        broker_validator.is_valid.emit(False)

        self.start_time_enabled = QCheckBox()
        self.start_time_picker = QDateTimeEdit(QDateTime.currentDateTime())
        self.start_time_picker.setDisplayFormat(TIME_FORMAT)
        self.start_time_enabled.stateChanged.connect(
            partial(self.state_changed, True))
        self.start_time_enabled.setChecked(True)

        self.stop_time_enabled = QCheckBox()
        self.stop_time_picker = QDateTimeEdit(QDateTime.currentDateTime())
        self.stop_time_picker.setDisplayFormat(TIME_FORMAT)
        self.stop_time_enabled.stateChanged.connect(
            partial(self.state_changed, False))
        self.stop_time_enabled.setChecked(False)
        self.state_changed(False, Qt.CheckState.Unchecked)

        self.service_id_lineedit = QLineEdit()
        self.service_id_lineedit.setPlaceholderText("(Optional)")
        self.abort_on_uninitialised_stream_checkbox = QCheckBox()
        self.use_swmr_checkbox = QCheckBox()
        self.use_swmr_checkbox.setChecked(True)

        self.layout().addRow("nexus_file_name", self.nexus_file_name_edit)
        self.layout().addRow("broker", self.broker_line_edit)
        self.layout().addRow("specify start time?", self.start_time_enabled)
        self.layout().addRow("start_time", self.start_time_picker)
        self.layout().addRow("specify stop time?", self.stop_time_enabled)
        self.layout().addRow("stop_time", self.stop_time_picker)
        self.layout().addRow("service_id", self.service_id_lineedit)
        self.layout().addRow("abort_on_uninitialised_stream",
                             self.abort_on_uninitialised_stream_checkbox)
        self.layout().addRow("use_hdf_swmr", self.use_swmr_checkbox)
        self.layout().addRow(self.ok_button)

    def state_changed(self, is_start_time: bool, state: Qt.CheckState):
        if state != Qt.CheckState.Checked:
            self.start_time_picker.setEnabled(
                False) if is_start_time else self.stop_time_picker.setEnabled(
                    False)
        else:
            self.start_time_picker.setEnabled(
                True) if is_start_time else self.stop_time_picker.setEnabled(
                    True)

    def get_arguments(
        self,
    ) -> Tuple[str, str, Union[str, None], Union[str, None], str, bool, bool]:
        """
        gets the arguments of required and optional fields for the filewriter command.
        :return: Tuple containing all of the fields.
        """
        return (
            self.nexus_file_name_edit.text(),
            self.broker_line_edit.text(),
            self.start_time_picker.dateTime().toMSecsSinceEpoch()
            if self.start_time_enabled.checkState() == Qt.CheckState.Checked
            else None,
            self.stop_time_picker.dateTime().toMSecsSinceEpoch()
            if self.stop_time_enabled.checkState() == Qt.CheckState.Checked
            else None,
            self.service_id_lineedit.text(),
            self.abort_on_uninitialised_stream_checkbox.checkState() ==
            Qt.CheckState.Checked,
            self.use_swmr_checkbox.checkState() == Qt.CheckState.Checked,
        )
Exemplo n.º 12
0
class ChartWin(QMainWindow):
    parent = None
    sheets = None
    num_param = 0
    row = 0

    canvas = None

    NavigationToolbar.toolitems = (
        ('Home', 'Reset original view', 'home', 'home'),
        # ('Back', 'Back to previous view', 'back', 'back'),
        # ('Forward', 'Forward to next view', 'forward', 'forward'),
        (None, None, None, None),
        ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'),
        ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'),
        # ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),
        (None, None, None, None),
        ('Save', 'Save the figure', 'filesave', 'save_figure'),
    )

    def __init__(self, parent: QMainWindow, sheets: ExcelSPC, num_param: int,
                 row: int):
        super().__init__(parent=parent)
        self.icons = Icons()

        self.parent = parent
        self.sheets = sheets
        self.num_param = num_param
        self.row = row

        self.initUI()
        self.setWindowIcon(QIcon(self.icons.CHART))

    # -------------------------------------------------------------------------
    #  initUI - UI initialization
    #
    #  argument
    #    (none)
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def initUI(self):
        # ----------------
        #  Create toolbar
        toolbar = QToolBar()
        self.addToolBar(toolbar)

        # Add buttons to toolbar
        btn_before: QToolButton = QToolButton()
        btn_before.setIcon(QIcon(self.icons.LEFT))
        btn_before.setStyleSheet("QToolButton {margin: 0 5px;}")
        btn_before.setStatusTip('goto previous PARAMETER')
        btn_before.clicked.connect(self.prev_chart)
        toolbar.addWidget(btn_before)

        # Add buttons to toolbar
        btn_after: QToolButton = QToolButton()
        btn_after.setIcon(QIcon(self.icons.RIGHT))
        btn_after.setStyleSheet("QToolButton {margin: 0 5px;}")
        btn_after.setStatusTip('go to next PARAMETER')
        btn_after.clicked.connect(self.next_chart)
        toolbar.addWidget(btn_after)

        toolbar.addSeparator()

        self.check_update = QCheckBox('Hide Spec Limit(s)', self)
        self.check_update.setStyleSheet("QCheckBox {margin: 0 5px;}")
        self.checkbox_state()
        self.check_update.stateChanged.connect(self.update_status)
        toolbar.addWidget(self.check_update)

        # spacer to expand
        spacer: QWidget = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        toolbar.addWidget(spacer)

        # ComboBox to choose PowerPoint format
        self.ppt_format = bwidget.BComboBox(self)
        self.ppt_format.setText('PPT Format')
        self.ppt_format.addItems(['Default', 'Custom'])
        self.ppt_format.currentIndexChanged(self.selectionComboChange)
        toolbar.addWidget(self.ppt_format)

        toolbar.addSeparator()

        self.check_all_slides = QCheckBox('All parameters', self)
        toolbar.addWidget(self.check_all_slides)

        # PowerPoint
        but_ppt: QToolButton = QToolButton()
        but_ppt.setIcon(QIcon(self.icons.PPT))
        but_ppt.setStatusTip('generate PowerPoint slide(s)')
        but_ppt.clicked.connect(self.OnPPT)
        toolbar.addWidget(but_ppt)

        # ------------
        #  Status Bar
        self.statusbar = QStatusBar()
        self.setStatusBar(self.statusbar)

        self.create_chart()

        self.show()

    # for combobox testing
    def selectionComboChange(self, i):
        sender = self.sender()
        print("Current index", i, "selection changed ", sender.currentText())

    # -------------------------------------------------------------------------
    #  checkbox_state
    #
    #  argument
    #    (none)
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def checkbox_state(self):
        if self.sheets.get_SL_flag(self.row):
            self.check_update.setCheckState(Qt.Checked)
        else:
            self.check_update.setCheckState(Qt.Unchecked)

    # -------------------------------------------------------------------------
    #  update_status
    #
    #  argument
    #    state :
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def update_status(self, state):
        sender = self.sender()
        if sender.checkState() == Qt.Checked:
            flag_new: bool = True
        else:
            flag_new: bool = False
        flag_old = self.sheets.get_SL_flag(self.row)
        if flag_new is not flag_old:
            self.sheets.set_SL_flag(self.row, flag_new)
            self.create_chart()

    # -------------------------------------------------------------------------
    #  create_chart
    #
    #  argument
    #    (none)
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def create_chart(self):
        # Canvas for SPC Chart
        if self.canvas is not None:
            # CentralWidget
            self.takeCentralWidget()
            del self.canvas
            # DockWidget
            self.removeDockWidget(self.dock)
            self.dock.deleteLater()
            del self.navtoolbar

        # PART Number & PARAMETER Name
        name_part, name_param = self.get_part_param(self.row)
        self.updateTitle(name_part, name_param)
        # CentralWidget
        self.canvas: FigureCanvas = self.gen_chart(name_part, name_param)
        self.setCentralWidget(self.canvas)

        # DockWidget
        self.navtoolbar: NavigationToolbar = NavigationToolbar(
            self.canvas, self)
        self.dock: QDockWidget = QDockWidget('Navigation Toolbar')
        self.dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.dock.setWidget(self.navtoolbar)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.dock)

        # update row selection of 'Master' sheet
        self.parent.setMasterRowSelect(self.row)

    # -------------------------------------------------------------------------
    #  get_part_param - get PART No & PARAMETER Name from sheet
    #
    #  argument
    #    row   : row object on the Master Table
    #
    #  return
    #    part  : PART Name
    #    param : PPARAMETER Name
    # -------------------------------------------------------------------------
    def get_part_param(self, row: int):
        df_master: pd.DataFrame = self.sheets.get_master()
        df_row: pd.Series = df_master.iloc[row]
        part: str = df_row['Part Number']
        param: str = df_row['Parameter Name']

        return part, param

    # -------------------------------------------------------------------------
    #  updateTitle - update window title
    #
    #  argument
    #    part  : PART name
    #    param : PARAMETER name
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def updateTitle(self, part: str, param: str):
        self.setWindowTitle(part + ' : ' + param)

    # -------------------------------------------------------------------------
    #  gen_chart - generate chart
    #
    #  argument
    #    part  : PART Number
    #    param : Parameter Name
    #    sheet : data sheet from Excel file
    #
    #  return
    #    canvas : generated chart
    # -------------------------------------------------------------------------
    def gen_chart(self, part: str, param: str):
        # create PowerPoint file
        info = {
            'PART': part,
            'PARAM': param,
        }
        trend: Trend = Trend(self, self.sheets, self.row)
        figure = trend.get(info)
        canvas: FigureCanvas = FigureCanvas(figure)

        return canvas

    # -------------------------------------------------------------------------
    #  next_chart
    #
    #  argument
    #    event :
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def next_chart(self, event: bool):
        if self.row >= self.num_param - 1:
            self.row = self.num_param - 1
            return

        self.row += 1
        self.update_chart()

    # -------------------------------------------------------------------------
    #  prev_chart
    #
    #  argument
    #    event :
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def prev_chart(self, event: bool):
        if self.row <= 0:
            self.row: int = 0
            return

        self.row -= 1
        self.update_chart()

    # -------------------------------------------------------------------------
    #  update_chart
    #
    #  argument
    #    (none)
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def update_chart(self):
        self.checkbox_state()
        self.create_chart()

    # -------------------------------------------------------------------------
    #  OnPPT
    # -------------------------------------------------------------------------
    def OnPPT(self, event):
        template_path: str = 'template/template.pptx'
        image_path: str = tempfile.NamedTemporaryFile(suffix='.png').name
        save_path: str = tempfile.NamedTemporaryFile(suffix='.pptx').name

        # check box is checked?
        if self.check_all_slides.checkState() == Qt.Checked:
            # loop fpr all parameters
            loop = range(self.num_param)
        else:
            # This is single loop
            loop = [self.row]

        for row in loop:
            # get Parameter Name & PART Number
            name_part, name_param = self.get_part_param(row)
            # print(row + 1, name_part, name_param)

            # create PowerPoint file
            info = {
                'PART': name_part,
                'PARAM': name_param,
                'IMAGE': image_path,
            }

            # create chart
            trend = Trend(self, self.sheets, row)
            figure = trend.get(info)

            dateObj = trend.get_last_date()
            # print(dateObj)
            # print(type(dateObj))
            if dateObj is None:
                info['Date of Last Lot Received'] = 'n/a'
            elif type(dateObj) is float:
                if math.isnan(dateObj):
                    info['Date of Last Lot Received'] = 'n/a'
                else:
                    info['Date of Last Lot Received'] = str(dateObj)
            elif type(dateObj) is str:
                info['Date of Last Lot Received'] = dateObj
            else:
                info['Date of Last Lot Received'] = dateObj.strftime(
                    '%m/%d/%Y')

            # create PNG file of plot
            figure.savefig(image_path)

            # gen_ppt(template_path, image_path, save_path, info)
            if self.check_all_slides.checkState() == Qt.Checked and row > 0:
                template_path = save_path

            ppt_obj = PowerPoint(template_path)
            ppt_obj.add_slide(self.sheets, info)
            ppt_obj.save(save_path)

        # open created file
        self.open_file_with_app(save_path)

    # -------------------------------------------------------------------------
    #  open_file_with_app
    #
    #  argument
    #    name_file : filename to open with associated application
    #
    #  return
    #    (none)
    # -------------------------------------------------------------------------
    def open_file_with_app(self, name_file):
        path = pathlib.PurePath(name_file)

        if platform.system() == 'Linux':
            app_open = 'xdg-open'
        else:
            # Windows Explorer can cover all cases to start application with file
            app_open = 'explorer'

        subprocess.Popen([app_open, path])
Exemplo n.º 13
0
class TopicSelection(QWidget):

    #recordSettingsSelected = Signal(bool, list)
    recordSettingsSelected = SIGNAL(str)

    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Select the topics you want to record")
        self.resize(500, 700)

        self.topic_list = []
        self.selected_topics = []
        self.items_list = []

        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)

        self.from_nodes_button = QPushButton("From Nodes", self)
        self.from_nodes_button.clicked.connect(self.onFromNodesButtonClicked)

        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.main_vlayout.addWidget(self.from_nodes_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = QCheckBox("All", self)
        self.item_all.stateChanged.connect(self.updateList)
        self.selection_vlayout.addWidget(self.item_all)
        topic_data_list = master.getPublishedTopics('')
        topic_data_list.sort()
        for topic, datatype in topic_data_list:
            self.addCheckBox(topic)

        self.main_widget.setLayout(self.selection_vlayout)

        self.area.setWidget(self.main_widget)
        self.show()

    def addCheckBox(self, topic):
        self.topic_list.append(topic)
        item = QCheckBox(topic, self)
        item.stateChanged.connect(lambda x: self.updateList(x, topic))
        self.items_list.append(item)
        self.selection_vlayout.addWidget(item)

    def changeTopicCheckState(self, topic, state):
        for item in self.items_list:
            if item.text() == topic:
                item.setCheckState(state)
                return

    def updateList(self, state, topic=None, force_update_state=False):
        if topic is None:  # The "All" checkbox was checked / unchecked
            if state == Qt.Checked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Unchecked:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Checked:
                        item.setCheckState(Qt.Unchecked)
        else:
            if state == Qt.Checked:
                self.selected_topics.append(topic)
            else:
                self.selected_topics.remove(topic)
                if self.item_all.checkState() == Qt.Checked:
                    self.item_all.setCheckState(Qt.PartiallyChecked)

        if self.selected_topics == []:
            self.ok_button.setEnabled(False)
        else:
            self.ok_button.setEnabled(True)

    def onButtonClicked(self):
        self.close()
        self.recordSettingsSelected.emit(
            self.item_all.checkState() == Qt.Checked, self.selected_topics)

    def onFromNodesButtonClicked(self):
        self.node_selection = NodeSelection(self)
Exemplo n.º 14
0
class FilterDock(QDockWidget):

    def __init__(self, platforms, regions, genres, years):
        super(FilterDock, self).__init__()

        # QDockWidget settings
        self.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.setFeatures(QDockWidget.DockWidgetClosable)
        self.setFixedHeight(150)
        self.setVisible(False)
        self.setWindowTitle("Filter options")

        # The selected items for each widget are saved in a set-dictionary
        self._selections = defaultdict(set)

        #  Widget settings
        # Platform widgets
        self._platformLabel = QLabel("Platform")
        self._platforms = QListWidget()
        self._platforms.addItems(platforms)
        self._platforms.setSelectionMode(QAbstractItemView.MultiSelection)
        self._platforms.setMaximumWidth(200)
        self._platformVBox = QVBoxLayout()
        self._platformVBox.addWidget(self._platformLabel, 0)
        self._platformVBox.addWidget(self._platforms, 1)

        # Region widgets
        self._regionLabel = QLabel("Region")
        self._regions = QListWidget()
        self._regions.addItems(regions)
        self._regions.setSelectionMode(QAbstractItemView.MultiSelection)
        self._regions.setMaximumWidth(200)
        self._regionVBox = QVBoxLayout()
        self._regionVBox.addWidget(self._regionLabel, 0)
        self._regionVBox.addWidget(self._regions, 1)

        # Genre widgets
        self._genreLabel = QLabel("Genre")
        self._genres = QListWidget()
        self._genres.addItems(genres)
        self._genres.setSelectionMode(QAbstractItemView.MultiSelection)
        self._genres.setMaximumWidth(300)
        self._genreVBox = QVBoxLayout()
        self._genreVBox.addWidget(self._genreLabel, 0)
        self._genreVBox.addWidget(self._genres, 1)

        # Year widgets
        self._yearLabel = QLabel("Year")
        self._years = QListWidget()
        self._years.addItems(years)
        self._years.setSelectionMode(QAbstractItemView.MultiSelection)
        self._years.setMaximumWidth(75)
        self._yearsVbox = QVBoxLayout()
        self._yearsVbox.addWidget(self._yearLabel, 0)
        self._yearsVbox.addWidget(self._years, 1)

        # Inventory widgets
        self._itemType = {1: "Game", 2: "Console", 3: "Accessory"}
        self._item = QCheckBox(self._itemType[1])
        self._item.setTristate(True)
        self._item.setCheckState(Qt.PartiallyChecked)
        self._manual = QCheckBox("Manual")
        self._manual.setTristate(True)
        self._manual.setCheckState(Qt.PartiallyChecked)
        self._box = QCheckBox("Box")
        self._box.setTristate(True)
        self._box.setCheckState(Qt.PartiallyChecked)
        self._inventoryLabelsVBox = QVBoxLayout()
        self._inventorySelectionsVBox = QVBoxLayout()
        self._inventorySelectionsVBox.addStretch(3)
        self._inventorySelectionsVBox.addWidget(self._item, 0)
        self._inventorySelectionsVBox.addWidget(self._box, 1)
        self._inventorySelectionsVBox.addWidget(self._manual, 2)
        self._inventorySelectionsVBox.setAlignment(Qt.AlignLeft)
        self._haveHBox = QHBoxLayout()
        self._haveHBox.addLayout(self._inventoryLabelsVBox, 0)
        self._haveHBox.addLayout(self._inventorySelectionsVBox, 1)
        self._inventoryGroup = QGroupBox("Inventory")
        self._inventoryGroup.setMaximumWidth(120)
        self._inventoryGroup.setLayout(self._haveHBox)

        # Clear and Apply button widgets
        self._clearBtn = QPushButton("Clear selection")
        self._clearBtn.setMaximumSize(self._clearBtn.sizeHint())
        self._clearBtn.clicked.connect(self._clearFilters)
        self._btnHBox = QHBoxLayout()
        self._btnHBox.setAlignment(Qt.AlignBottom | Qt.AlignRight)
        self._btnHBox.addWidget(self._clearBtn, 0)

        # General layout
        mainHBox = QHBoxLayout()
        mainHBox.setAlignment(Qt.AlignLeft)
        mainHBox.addLayout(self._platformVBox, 0)
        mainHBox.addLayout(self._regionVBox, 0)
        mainHBox.addLayout(self._genreVBox, 0)
        mainHBox.addLayout(self._yearsVbox, 0)
        mainHBox.addWidget(self._inventoryGroup, 0)
        mainHBox.addLayout(self._btnHBox, 0)
        mainWidget = QWidget()
        mainWidget.setLayout(mainHBox)
        self.setWidget(mainWidget)

    def _clearFilters(self):
        self._platforms.clearSelection()
        self._regions.clearSelection()
        self._genres.clearSelection()
        self._years.clearSelection()
        self._item.setCheckState(Qt.PartiallyChecked)
        self._box.setCheckState(Qt.PartiallyChecked)
        self._manual.setCheckState(Qt.PartiallyChecked)
        logger.info("Cleared all filters.")

    def getSelections(self):
        self._selections = defaultdict(set)  # Reset selections
        if len(self._platforms.selectedItems()) > 0:
            platforms = [x.text() for x in self._platforms.selectedItems()]
            for platform in platforms:
                self._selections["Platform"].add(platform)
        if len(self._regions.selectedItems()) > 0:
            regions = [x.text() for x in self._regions.selectedItems()]
            for region in regions:
                self._selections["Region"].add(region)
        if len(self._genres.selectedItems()) > 0:
            genres = [x.text() for x in self._genres.selectedItems()]
            for genre in genres:
                self._selections["Genre"].add(genre)
        if len(self._years.selectedItems()) > 0:
            years = [x.text() for x in self._years.selectedItems()]
            for year in years:
                self._selections["Year"].add(year)
        if self._item.checkState() is not Qt.PartiallyChecked:
            self._selections[self._item.text()].add("Yes" if self._item.isChecked() else "No")
        if self._manual.checkState() is not Qt.PartiallyChecked:
            self._selections["Manual"].add("Yes" if self._manual.isChecked() else "No")
        if self._box.checkState() is not Qt.PartiallyChecked:
            self._selections["Box"].add("Yes" if self._box.isChecked() else "No")

        return self._selections

    def setItemType(self, itemType: int):
        if 0 < itemType < 4:
            if self._item.text() in self._selections:
                # Delete previous item entry so we don't search for the wrong type in the wrong table
                del self._selections[self._item.text()]
            self._item.setText(self._itemType[itemType])

    def toggleVisibility(self):
        self.setVisible(False if self.isVisible() else True)

    def updatePlatforms(self, platforms):
        self._platforms.clear()
        self._platforms.addItems(platforms)
        logger.info("Updated platforms list.")

    def updateRegions(self, regions):
        self._regions.clear()
        self._regions.addItems(regions)
        logger.info("Updated regions list.")

    def updateGenres(self, genres):
        self._genres.clear()
        self._genres.addItems(genres)
        logger.info("Updated genres list.")

    def updateYears(self, years):
        self._years.clear()
        self._years.addItems(years)
        logger.info("Updated years list.")
Exemplo n.º 15
0
class StatsManager:
    GROUP_BY = ['filename', 'lineno', 'traceback']
    # index in the combo box
    GROUP_BY_FILENAME = 0
    GROUP_BY_LINENO = 1
    GROUP_BY_TRACEBACK = 2

    def __init__(self, window, app):
        self.app = app
        self.window = window
        self.snapshots = window.snapshots
        self.source = window.source
        self.filename_parts = 3
        self._auto_refresh = False

        self.filters = []
        self.history = History(self)

        self.model = StatsModel(self)
        self.view = QTableView(window)
        self.view.setModel(self.model)
        self.cumulative_checkbox = QCheckBox(window.tr("Cumulative sizes"),
                                             window)
        self.group_by = QtGui.QComboBox(window)
        self.group_by.addItems([
            window.tr("Filename"),
            window.tr("Line number"),
            window.tr("Traceback"),
        ])

        self.filters_label = QLabel(window)
        self.summary = QLabel(window)
        self.view.verticalHeader().hide()
        self.view.resizeColumnsToContents()
        self.view.setSortingEnabled(True)

        window.connect(self.group_by,
                       QtCore.SIGNAL("currentIndexChanged(int)"),
                       self.group_by_changed)
        window.connect(self.view,
                       QtCore.SIGNAL("doubleClicked(const QModelIndex&)"),
                       self.double_clicked)
        window.connect(self.cumulative_checkbox,
                       QtCore.SIGNAL("stateChanged(int)"),
                       self.change_cumulative)
        window.connect(self.snapshots.load_button,
                       QtCore.SIGNAL("clicked(bool)"), self.load_snapshots)
        window.connect(
            self.view.selectionModel(),
            QtCore.SIGNAL(
                "selectionChanged(const QItemSelection&, const QItemSelection&)"
            ), self.selection_changed)

        self.clear()
        self._auto_refresh = True

    def clear(self):
        del self.filters[:]
        self.cumulative_checkbox.setCheckState(Qt.Unchecked)
        self.group_by.setCurrentIndex(self.GROUP_BY_FILENAME)
        self.history.clear()
        self.append_history()
        self.refresh()

    def load_snapshots(self, checked):
        self.source.clear()
        self.clear()

    def append_history(self):
        group_by = self.group_by.currentIndex()
        filters = self.filters[:]
        cumulative = self.cumulative_checkbox.checkState()
        state = HistoryState(group_by, filters, cumulative)
        self.history.append(state)

    def restore_state(self, state):
        self.filters = state.filters[:]
        self._auto_refresh = False
        self.cumulative_checkbox.setCheckState(state.cumulative)
        self.group_by.setCurrentIndex(state.group_by)
        self._auto_refresh = True
        self.refresh()

    def format_filename(self, filename):
        parts = filename.split(os.path.sep)
        if len(parts) > self.filename_parts:
            parts = [MORE_TEXT] + parts[-self.filename_parts:]
        return os.path.join(*parts)

    def get_group_by(self):
        index = self.group_by.currentIndex()
        return self.GROUP_BY[index]

    def get_cumulative(self):
        return (self.cumulative_checkbox.checkState() == Qt.Checked)

    def refresh(self):
        group_by = self.get_group_by()
        if group_by != 'traceback':
            cumulative = self.get_cumulative()
        else:
            # FIXME: add visual feedback
            cumulative = False
        snapshot1, snapshot2 = self.snapshots.load_snapshots(self.filters)

        self.view.clearSelection()
        group_by = self.get_group_by()
        self.model.set_stats(snapshot1, snapshot2, group_by, cumulative)

        self.view.resizeColumnsToContents()
        self.view.sortByColumn(self.model.get_default_sort_column(),
                               Qt.DescendingOrder)

        if self.filters:
            filters = []
            for filter in self.filters:
                text = self.format_filename(filter.filename_pattern)
                if filter.lineno:
                    text = "%s:%s" % (text, filter.lineno)
                if filter.all_frames:
                    text += self.window.tr(" (any frame)")
                if filter.inclusive:
                    text = fmt(self.window.tr("include %s"), text)
                else:
                    text = fmt(self.window.tr("exclude %s"), text)
                filters.append(text)
            filters_text = ", ".join(filters)
        else:
            filters_text = self.window.tr("(none)")
        filters_text = fmt(self.window.tr("Filters: %s"), filters_text)
        self.filters_label.setText(filters_text)

        total = self.model.total_text
        lines = len(self.model.stats)
        if group_by == 'filename':
            lines = fmt(self.window.tr("Files: %s"), lines)
        elif group_by == 'lineno':
            lines = fmt(self.window.tr("Lines: %s"), lines)
        else:
            lines = fmt(self.window.tr("Tracebacks: %s"), lines)
        total = fmt(self.window.tr("%s - Total: %s"), lines, total)
        self.summary.setText(total)

    def selection_changed(self, selected, unselected):
        indexes = selected.indexes()
        if not indexes:
            return
        stat = self.model.get_stat(indexes[0])
        if stat is None:
            return
        self.source.set_traceback(stat.traceback,
                                  self.get_group_by() != 'filename')
        self.source.show_frame(stat.traceback[0])

    def double_clicked(self, index):
        stat = self.model.get_stat(index)
        if stat is None:
            return
        group_by = self.get_group_by()
        if group_by == 'filename':
            all_frames = self.get_cumulative()
            self.filters.append(
                tracemalloc.Filter(True,
                                   stat.traceback[0].filename,
                                   all_frames=all_frames))
            self._auto_refresh = False
            self.group_by.setCurrentIndex(self.GROUP_BY_LINENO)
            self.append_history()
            self._auto_refresh = True
            self.refresh()
        elif group_by == 'lineno':
            # Replace filter by filename with filter by line
            new_filter = tracemalloc.Filter(True,
                                            stat.traceback[0].filename,
                                            stat.traceback[0].lineno,
                                            all_frames=False)
            if self.filters:
                old_filter = self.filters[-1]
                replace = (old_filter.inclusive == new_filter.inclusive
                           and old_filter.filename_pattern
                           == new_filter.filename_pattern
                           and old_filter.lineno == None)
            else:
                replace = False
            if replace:
                self.filters[-1] = new_filter
            else:
                self.filters.append(new_filter)
            self._auto_refresh = False
            self.group_by.setCurrentIndex(self.GROUP_BY_TRACEBACK)
            self.append_history()
            self._auto_refresh = True
            self.refresh()

    def group_by_changed(self, index):
        if not self._auto_refresh:
            return
        self.append_history()
        self.refresh()

    def change_cumulative(self, state):
        if not self._auto_refresh:
            return
        self.append_history()
        self.refresh()
Exemplo n.º 16
0
class MainWindow(QMainWindow):
    def __init__(self, backlight_sysfs_path: Path) -> None:
        QMainWindow.__init__(self)

        self.backlight = Backlight(backlight_sysfs_path)

        self.screenshot = QPixmap(get_image_path("raspbian.png"))
        self.image_display_on = load_display_image(
            get_image_path("display_on.png"))
        self.image_display_off = load_display_image(
            get_image_path("display_off.png"))

        widget = QWidget()
        checkbox_layout = QBoxLayout(QBoxLayout.LeftToRight)
        main_layout = QBoxLayout(QBoxLayout.TopToBottom)
        brightness_slider_label = QLabel("Brightness", widget)
        self.live_screen_checkbox = QCheckBox("Show live screen", widget)
        self.live_screen_checkbox.stateChanged.connect(self.update_screen)
        self.power_checkbox = QCheckBox("Power", widget)
        self.power_checkbox.stateChanged.connect(self.write_power_change)
        self.brightness_slider = QSlider(Qt.Horizontal, widget)
        self.brightness_slider.valueChanged.connect(
            self.write_brightness_change)
        self.brightness_slider.setSingleStep(1)
        self.brightness_slider.setMinimum(0)
        self.brightness_slider.setMaximum(100)
        self.screen_image = QLabel()
        checkbox_layout.addWidget(self.power_checkbox)
        checkbox_layout.addWidget(self.live_screen_checkbox)
        main_layout.addLayout(checkbox_layout)
        main_layout.addWidget(brightness_slider_label)
        main_layout.addWidget(self.brightness_slider)
        main_layout.addWidget(self.screen_image)
        widget.setLayout(main_layout)

        self.thread = FileWatcherThread(self, backlight_sysfs_path)
        self.thread.file_changed.connect(self.update_widgets)
        self.thread.start()

        self.timer = QTimer(self)
        self.timer.setInterval(100)
        self.timer.timeout.connect(self.update_screen)
        self.timer.start()

        self.update_widgets("bl_power")
        self.update_widgets("brightness")

        self.setCentralWidget(widget)
        self.setWindowTitle('Raspberry Pi 7" display backlight emulator')
        self.setWindowIcon(QIcon(get_image_path("icon.png")))

    def write_power_change(self):
        on = self.power_checkbox.checkState() == Qt.CheckState.Checked
        self.backlight.power = on

    def write_brightness_change(self):
        value = self.brightness_slider.value()
        self.backlight.brightness = value

    def update_widgets(self, filename: str) -> None:
        if filename == "bl_power":
            self.power_checkbox.setChecked(self.backlight.power)

        if filename == "brightness":
            self.brightness_slider.setValue(self.backlight.brightness)

    def update_screen(self) -> None:
        use_live_screen = (
            self.live_screen_checkbox.checkState() == Qt.CheckState.Checked)
        is_powered_on = self.power_checkbox.checkState(
        ) == Qt.CheckState.Checked
        image_display = (self.image_display_on
                         if is_powered_on else self.image_display_off)
        result = QPixmap(image_display.size())
        result.fill(Qt.transparent)
        painter = QPainter(result)
        painter.drawPixmap(QPoint(0, 0), image_display)

        if is_powered_on:
            screenshot = get_screenshot(
            ) if use_live_screen else self.screenshot
            screenshot = screenshot.scaled(800, 800, Qt.KeepAspectRatio,
                                           Qt.SmoothTransformation)
            screenshot = screenshot.copy(QRect(0, 0, 800, 480 * 0.94))
            offset_x = (image_display.size().width() -
                        screenshot.size().width()) / 2
            offset_y = (image_display.size().height() -
                        screenshot.size().height()) / 2
            painter.setOpacity(self.backlight.brightness / 100)
            painter.drawPixmap(QPoint(offset_x, offset_y), screenshot)

        painter.end()
        result = result.scaled(600, 600, Qt.KeepAspectRatio,
                               Qt.SmoothTransformation)
        self.screen_image.setPixmap(result)

    def closeEvent(self, event) -> None:
        self.thread.interrupt()
        self.thread.quit()
        self.thread.wait()
        self.timer.stop()
        super(MainWindow, self).closeEvent(event)
Exemplo n.º 17
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.inputsToSkip = {
            "SceneInput": 0,
            "MaterialInput": 1,
            "Diffuse Color Material": 2,
        }
        self.data_types_to_skip = {
            "Image": 0,
            "ColorCurves": 1,
            "Histogram": 2,
            "Mask": 3,
            "DataType3D": 4,
            "Gradient": 5,
            "MtlGraph3D": 6,
        }
        self.createWidgets()
        self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint
                            | Qt.WindowStaysOnTopHint)

    def createWidgets(self):
        self._tm = TableModel(self)
        self._tm.inputsToSkip = self.inputsToSkip
        self._tm.data_types_to_skip = self.data_types_to_skip
        self._tv = TableView(self)
        self.alwaysOnTop = QCheckBox("Always on top")
        self.alwaysOnTop.setChecked(True)
        self.drawInputInfoColors = QToolButton()
        self.drawInputInfoColors.setCheckable(True)
        self.drawInputInfoColors.setChecked(True)
        self.drawInputInfoColors.setText("Draw Color Info")
        self.pushButton = QPushButton()
        self.pushButton.setText("Refresh")
        self.pushButton.setFixedSize(QSize(128, 20))
        self.lineEdit = QLineEdit(self)
        self.lineEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.statusBar().showMessage("System Status | Normal")
        self.cacheButton = QToolButton()
        self.cacheButton.setCheckable(True)
        self.cacheButton.setChecked(False)
        self.cacheButton.setText("use cache")

        v_box = QVBoxLayout()
        h_box = QHBoxLayout()
        h_box.setAlignment(Qt.AlignRight)
        h_box.addWidget(self.alwaysOnTop)
        h_box.addWidget(self.lineEdit)
        h_box.addWidget(self.pushButton)
        h_box.addWidget(self.drawInputInfoColors)
        h_box.addWidget(self.cacheButton)
        h_box.setContentsMargins(0, 0, 0, 0)
        v_box.addLayout(h_box)
        v_box.addWidget(self._tv)

        sizeGrip = QSizeGrip(self)
        # sizeGrip.setParent(self)
        # v_box.addWidget(sizeGrip)
        # v_box.setAlignment(sizeGrip, Qt.AlignBottom | Qt.AlignRight)
        v_box.setContentsMargins(2, 2, 2, 2)
        # v_box.setSpacing(0)
        sizeGrip.setWindowFlags(Qt.WindowStaysOnTopHint)

        sizeGrip.move(0, 200)

        central_widget = QWidget()
        central_widget.setLayout(v_box)
        self.setCentralWidget(central_widget)
        self.statusBar()

        self.proxyModel = TableSortFilterProxyModel()
        self.proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setDynamicSortFilter(True)
        self.drawInputInfoColors.setChecked(True)

        # self.lineEdit.textChanged.connect(self._tv.updateColumns)

        # self.proxyModel.setSourceModel(self._tm)
        # self.proxyModel.filteredKeys = self._tm.attributeNameKeys
        self._tv.setModel(self.proxyModel)

        self.progressBar = QProgressBar()
        self.statusBar().addPermanentWidget(self.progressBar)
        # This is simply to show the bar
        # self.progressBar.setGeometry(30, 40, 200, 25)
        self.progressBar.setValue(0)

        # Connections
        self.alwaysOnTop.stateChanged.connect(self.changeAlwaysOnTop)
        self.lineEdit.textChanged.connect(self.filterRegExpChanged)
        self.drawInputInfoColors.clicked.connect(
            self.changeTableModelBackgroundRoleMethod)
        self.cacheButton.clicked.connect(self.changeCacheMode)
        self.pushButton.pressed.connect(self.reloadFusionData)
        self._tm.communicate.broadcast.connect(self.communication)

    def changeAlwaysOnTop(self):
        if self.alwaysOnTop.checkState():
            self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint
                                | Qt.WindowStaysOnTopHint)
            self.show()
        else:
            self.setWindowFlags(self.windowFlags()
                                ^ (Qt.CustomizeWindowHint
                                   | Qt.WindowStaysOnTopHint))
            self.show()

    def communication(self, value):
        if not value:
            return
        if isinstance(value, float):
            self.progressBar.setValue(value)
        if isinstance(value, str):
            self.statusBar().showMessage(value)

    def loadFusionData(self):
        self._tm.load_fusion_data()
        self.proxyModel.setSourceModel(self._tm)
        self._tv.setSortingEnabled(True)
        self._tv.updateColumns()

    def reloadFusionData(self):
        self.proxyModel.setSourceModel(None)
        self._tm.load_fusion_data()
        self.proxyModel.setSourceModel(self._tm)
        self._tv.setSortingEnabled(True)
        self._tv.updateColumns()

    def changeCacheMode(self):
        # Not sure where this goes, is it a method for the TableModel? or should we inherit the dict that has all
        # the fusion input caches and have that cycle through all contained fusion inputs?

        # For now we do it here
        c = self.cacheButton.isChecked()
        for input_list in self._tm.toolsInputs:
            for tool_input in list(input_list.values()):
                tool_input.cache = c

    def changeTableModelBackgroundRoleMethod(self):
        if self.drawInputInfoColors.isChecked():
            self._tm.backgroundRoleMethod = self._tm.backgroundRole
        else:
            self._tm.backgroundRoleMethod = self._tm.noRole

    def filterRegExpChanged(self):
        """
        This makes sure that the ItemDelegates for the TableView columns get updated, we have to do this as for some
        reason Qt has TableView column delegates decoupled from the underlying ProxyModel and indices get out of sync
        during sorting and filtering.
        """

        regExp = self.lineEdit.text()

        self.proxyModel.filteredKeys = []
        self.proxyModel.setFilterRegExp(regExp)
        self._tv.updateColumns()
Exemplo n.º 18
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__(flags=Qt.WindowContextHelpButtonHint
                         | Qt.WindowCloseButtonHint | Qt.CustomizeWindowHint)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setUpMainWindow()

    def setUpMainWindow(self):
        self.setWindowTitle(
            "Lab Tools 1.0 (2021 Edition) - Applications of ML in Mechatronics"
        )
        # set icon
        self.setUpIcon()

        #set up the info and start processing button
        self.inputLineEdit = QLineEdit()
        self.outputFolderLineEdit = QLineEdit()
        self.modelLineEdit = QLineEdit()
        self.browseOutputButton = QPushButton()
        self.browseInputButton = QPushButton()
        self.browseModelButton = QPushButton()
        self.startStopButton = QPushButton()
        self.useDefaultModelCheckbox = QCheckBox()

        self.inputLineEdit = self.findChild(QLineEdit, "inputLineEdit")
        self.modelLineEdit = self.findChild(QLineEdit, "modelLineEdit")
        self.outputFolderLineEdit = self.findChild(QLineEdit,
                                                   "outputFolderLineEdit")
        self.browseOutputButton = self.findChild(QPushButton,
                                                 "browseOutputButton")
        self.browseInputButton = self.findChild(QPushButton,
                                                "browseInputButton")
        self.browseModelButton = self.findChild(QPushButton,
                                                "browseModelButton")
        self.startStopButton = self.findChild(QPushButton, "startStopButton")
        self.useDefaultModelCheckbox = self.findChild(
            QCheckBox, "useDefaultModelCheckbox")
        self.chooseModelLabel = self.findChild(QLabel, "chooseModelLabel")

        #disabling model transfer capability if needed
        self._modelRPiPath = False
        if DISABLE_MODEL_TRASFER:
            self.useDefaultModelCheckbox.hide()
            self.modelLineEdit.setEnabled(1)
            self.browseModelButton.hide()
            self.chooseModelLabel.setText(self.chooseModelLabel.text() +
                                          " Name")
            # self.gridLayout = self.findChild(QGridLayout, "gridLayout")
            # self.gridLayout.removeWidget(self.browseModelButton)
            # self.gridLayout.removeWidget(self.useDefaultModelCheckbox)
            self._modelRPiPath = True

        self.startStopButton.clicked.connect(self.handleStartStopButtonClicked)
        self.browseOutputButton.clicked.connect(self.handleBrowseOutputButton)
        self.browseInputButton.clicked.connect(self.handleBrowseInputButton)
        self.browseModelButton.clicked.connect(self.handleBrowseModelButton)
        self.useDefaultModelCheckbox.stateChanged.connect(
            self.handleUseDefaultModelCheckboxStateChanged)
        self.useDefaultModelCheckbox.setChecked(True)

        #set up the log and progress bar
        self.logTextBrowser = QTextBrowser()
        self.lastLogTextLabel = QLabel()
        self.logTextBrowser = self.findChild(QTextBrowser, "logTextBrowser")
        self.progressBar = self.findChild(QProgressBar, "progressBar")
        self.clearLogButton = self.findChild(QPushButton, "clearLogButton")
        self.saveLogButton = self.findChild(QPushButton, "saveLogButton")
        self.lastLogTextLabel = self.findChild(QLabel, "lastLogTextLabel")
        self.clearLogButton.clicked.connect(self.handleClearLogButton)
        self.saveLogButton.clicked.connect(self.handleSaveLogButton)

        #set up menu bar
        self.actionHelp = self.findChild(QAction, "actionHelp")
        self.actionAbout = self.findChild(QAction, "actionAbout")
        self.actionHelp.triggered.connect(self.handleActionHelpClicked)
        self.actionAbout.triggered.connect(self.handleActionAboutClicked)

        # Add additional menu actions
        self.utilitiesMenu = self.menuBar().addMenu("Utilities")
        self.actionGetRPiIP = QAction("Get RPi IP")
        self.utilitiesMenu.addAction(self.actionGetRPiIP)
        self.actionGetRPiIP.triggered.connect(self.handleActionGetRPiIPClicked)
        self.actionUpdateRPiScript = QAction("Updare RPi Script")
        self.utilitiesMenu.addAction(self.actionUpdateRPiScript)
        self.actionUpdateRPiScript.triggered.connect(
            self.handleActionUpdateRPiScript)

        #create objects from the other classes
        self.logger = Logger(self.logTextBrowser, self.lastLogTextLabel)

        #initialize member variables
        self._b_processRunning = False

        # set up lab names
        self.setUpLabNames()

        #set up serial comms
        self.setupSerial()
        self.refreshSerialPorts()

        self.logger.log("The application is ready!", type="INFO")

    def setUpIcon(self):
        self.appIcon = QIcon("images/favicon.png")
        self.setWindowIcon(self.appIcon)

    def setUpLabNames(self):
        self.labNameComboBox = QComboBox()

        self.labNameComboBox = self.findChild(QComboBox, "labNameComboBox")
        self.labNameComboBox.currentIndexChanged.connect(
            self.handleLabNameComboboxCurrentIndexChanged)
        for code, name in utils.lab_names.items():
            self.labNameComboBox.addItem(code + ": " + name)
        self.labNameComboBox.setCurrentIndex(1)

    def setupSerial(self):
        self.refreshSerialPortsButton = QPushButton()
        self.connectDisconnectSerialButton = QPushButton()
        self.serialPortComboBox = QComboBox()

        self.refreshSerialPortsButton = self.findChild(
            QPushButton, "refreshSerialPortsButton")
        self.connectDisconnectSerialButton = self.findChild(
            QPushButton, "connectDisconnectSerialButton")
        self.serialPortComboBox = self.findChild(QComboBox,
                                                 "serialPortComboBox")
        self.refreshSerialPortsButton.clicked.connect(self.refreshSerialPorts)
        self.connectDisconnectSerialButton.clicked.connect(
            self.handleSerialConnectDisconnect)
        self._b_serialConnected = False

    def refreshSerialPorts(self):
        availablePorts = utils.find_serial_ports()
        self.serialPortComboBox.clear()
        for portName in availablePorts:
            self.serialPortComboBox.addItem(portName)

    def handleSerialConnectDisconnect(self):
        if not self.b_serialConnected:
            try:
                currentPortName = self.serialPortComboBox.currentText()
                self.port = serial.Serial(currentPortName,
                                          115200,
                                          timeout=1,
                                          write_timeout=240,
                                          bytesize=8,
                                          parity='N',
                                          stopbits=1)
                self.port.set_buffer_size(rx_size=10**3, tx_size=10**8)
                self.serialPortComboBox.setItemText(
                    self.serialPortComboBox.currentIndex(),
                    currentPortName + " (CONNECTED)")
                self.connectDisconnectSerialButton.setText("Disconnect")
                self.b_serialConnected = True
                self.refreshSerialPortsButton.setDisabled(1)
            except (OSError, serial.SerialException):
                print("Problem with Serial Connection!")
                self.logger.log(
                    "Problem with Serial Connection, Make sure you chose the right port",
                    type="ERROR")
        else:
            try:
                self.port.close()
                self.refreshSerialPorts()
                self.connectDisconnectSerialButton.setText("Connect")
                self.b_serialConnected = False
                self.refreshSerialPortsButton.setEnabled(1)
            except (OSError, serial.SerialException):
                print("Problem with Serial Connection!")
                self.logger.log("Problem with Serial Connection", type="ERROR")

    def _startButtonClicked(self):
        self.logger.log("Attempting to start the processing", type="INFO")
        if not self.b_serialConnected:
            self.logger.log(
                "Serial is not connected, Please connect serial first",
                type="ERROR")
            return
        if self.inputLineEdit.text()[-4:].lower() != ".csv":
            self.logger.log("Please select a valid input csv file",
                            type="ERROR")
            return
        if self.outputFolderLineEdit.text() == "":
            self.logger.log("Please select an output directory", type="ERROR")
            return
        self.executer = Executer(serialObj=self.port, loggerObj=self.logger)

        if self.modelLineEdit.text() != "":
            modelPath = self.modelLineEdit.text()
        else:
            modelPath = None
            if self._modelRPiPath:
                self.logger.log(
                    "Please select a valid model that is already available in the folder saved_models on the RPi",
                    type="ERROR")
                return

        #Read the Input File
        try:
            inputDataFrame = pd.read_csv(self.inputLineEdit.text())
        except:
            self.logger.log("CSV File Reading Failed, select a valid csv file",
                            type="ERROR")

        possibleInputs = list(inputDataFrame.columns)

        #Display a dialog to ask the user to choose what inputs they want
        dialog = QDialog(self)

        dialog.setWindowTitle("Select the Input Fields")
        dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok
                                         | QDialogButtonBox.Cancel)
        dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0)
        dialogButtons.accepted.connect(dialog.accept)
        dialogButtons.rejected.connect(dialog.reject)

        mainLayout = QVBoxLayout(dialog)
        scroll = QScrollArea(dialog)
        scroll.setWidgetResizable(True)
        layoutWidget = QWidget()
        layout = QVBoxLayout(layoutWidget)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setWidget(layoutWidget)

        chosenInputs = []
        checkboxes = []

        def handleCheckboxClicked():
            dialogButtons.button(QDialogButtonBox.Ok).setDisabled(1)
            for checkbox in checkboxes:
                if checkbox.isChecked():
                    dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0)

        for input in possibleInputs:
            checkbox = QCheckBox(text=input)
            checkbox.clicked.connect(handleCheckboxClicked)
            checkbox.setChecked(True)
            checkboxes.append(checkbox)
            layout.addWidget(checkbox)

        mainLayout.addWidget(
            QLabel(text="Please select the input fields from the following:"))
        mainLayout.addWidget(scroll)
        mainLayout.addWidget(dialogButtons)
        dialog.setLayout(mainLayout)
        # dialog.setFixedHeight(400)
        if dialog.exec_() == QDialog.Accepted:
            for checkbox in checkboxes:
                if checkbox.isChecked():
                    chosenInputs.append(checkbox.text())
            self.logger.log("The chosen input fields are: " +
                            ', '.join(chosenInputs),
                            type="INFO")
        else:
            return

        self.startStopButton.setText("Stop Processing")
        self.b_processRunning = True
        executionResult = self.executer.execute(self.labNameComboBox.currentText().split(":")[0], inputDataFrame, \
                                self.outputFolderLineEdit.text(), inputFields=chosenInputs, progressBar=self.progressBar, \
                                    model=modelPath if not self._modelRPiPath else "RPI:"+modelPath)
        if executionResult == ExecutionResult.COMPLETED:
            self._stopButtonClicked(finishedProcessing=True)
        elif executionResult == ExecutionResult.INTERRUPTED or executionResult == ExecutionResult.FAILED:
            self._stopButtonClicked()
            if self.executer.reset() == ExecutionResult.FAILED:
                self.logger.log(
                    "Resetting the serial state of RPi Failed, please power cycle the RPi",
                    type="ERROR")
            else:
                self.logger.log("The serial state of RPi has been reset",
                                type="INFO")

    def _stopButtonClicked(self, finishedProcessing=False):
        self.startStopButton.setText("Start Processing")
        if finishedProcessing:
            self.logger.log("", special="ProcessingCompleted")
        else:
            self.logger.log("", special="ProcessingStopped")
        self.b_processRunning = False
        #TODO: Complete Implementing this

    def handleStartStopButtonClicked(self):
        if (self.b_processRunning):
            self.executer.requestStop()
        else:
            self._startButtonClicked()

    def handleActionHelpClicked(self):
        helpBox = QMessageBox()
        helpBox.setIcon(QMessageBox.Information)
        helpBox.setStandardButtons(QMessageBox.Ok)
        helpBox.setWindowTitle("Need Help?")
        helpBox.setText(
            "For Help, please reach out to your Instructor or TA or read the lab manual"
        )
        helpBox.setTextFormat(Qt.RichText)
        helpBox.setInformativeText(
            f"You can access the project <a href=\"{utils.docs_link}\">Manual</a> and source in the <a href=\"{utils.repo_link}\">Github Repo!</a>"
        )
        helpBox.setWindowIcon(self.appIcon)
        helpBox.exec_()

    def handleActionAboutClicked(self):
        aboutBox = QMessageBox()
        aboutBox.setIcon(QMessageBox.Information)
        aboutBox.setStandardButtons(QMessageBox.Ok)
        aboutBox.setWindowTitle("About the Software")
        aboutBox.setText(utils.license_text)
        aboutBox.setWindowIcon(self.appIcon)
        aboutBox.exec_()

    def handleBrowseInputButton(self):
        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFile)
        dialog.setNameFilter("*.csv")
        if dialog.exec_():
            filePath = dialog.selectedFiles()
            if len(filePath) == 1:
                self.inputLineEdit.setText(filePath[0])

    def handleBrowseModelButton(self):
        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFile)
        dialog.setNameFilter(utils.lab_model_extensions[
            self.labNameComboBox.currentText().split(":")[0]])
        if dialog.exec_():
            filePath = dialog.selectedFiles()
            if len(filePath) == 1:
                self.modelLineEdit.setText(filePath[0])

    def handleBrowseOutputButton(self):
        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.DirectoryOnly)
        dialog.setOption(QFileDialog.ShowDirsOnly)
        if dialog.exec_():
            folderPath = dialog.selectedFiles()
            if len(folderPath) == 1:
                self.outputFolderLineEdit.setText(folderPath[0])

    def handleSaveLogButton(self):
        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.AcceptMode(QFileDialog.AcceptSave)
        dialog.setNameFilter("*.txt")
        if dialog.exec_():
            filePath = dialog.selectedFiles()
            if len(filePath) == 1:
                if self.logger.saveLog(filePath[0]) != -1:
                    self.logger.log(
                        "The log has been saved, feel free to clear the log now",
                        type="SUCCESS")
                    return
        self.logger.log("Failed to save the log, please select a valid file",
                        type="ERROR")

    def handleClearLogButton(self):
        self.logger.clearLog()

    def handleUseDefaultModelCheckboxStateChanged(self):
        if self._modelRPiPath:
            return
        if not self.useDefaultModelCheckbox.checkState():
            self.modelLineEdit.setDisabled(0)
            self.browseModelButton.setDisabled(0)
        else:
            self.modelLineEdit.clear()
            self.modelLineEdit.setDisabled(1)
            self.browseModelButton.setDisabled(1)

    def handleLabNameComboboxCurrentIndexChanged(self):
        if self._modelRPiPath:
            self.modelLineEdit.setText(utils.lab_default_models[
                self.labNameComboBox.currentText().split(":")[0]])
        # Disable the model options when the lab selected is Communication Test
        if self.labNameComboBox.currentIndex() == 0:
            self.modelLineEdit.setDisabled(1)
            self.browseModelButton.setDisabled(1)
            self.modelLineEdit.setText("Model is not required")
        else:
            self.modelLineEdit.setDisabled(0)
            self.browseModelButton.setDisabled(0)

    def handleActionGetRPiIPClicked(self):
        self.logger.log("Attempting to Get Raspberry Pi IP Address",
                        type="INFO")
        if not self.b_serialConnected:
            replyMessage = "Serial is not connected, Please connect serial first"
        else:
            self.executer = Executer(serialObj=self.port,
                                     loggerObj=self.logger)
            ipaddr = self.executer.executeOther("GET_IP")
            replyMessage = (
                "Raspberry Pi IP is " + ipaddr
            ) if ipaddr != ExecutionResult.FAILED else "Failed to obtain the IP Address"
        self.logger.log(replyMessage)
        ipAddrMessage = QMessageBox()
        ipAddrMessage.setIcon(QMessageBox.Information)
        ipAddrMessage.setStandardButtons(QMessageBox.Ok)
        ipAddrMessage.setWindowTitle("Raspberry Pi IP Address")
        ipAddrMessage.setText(replyMessage)
        ipAddrMessage.setTextFormat(Qt.RichText)
        ipAddrMessage.setWindowIcon(self.appIcon)
        ipAddrMessage.exec_()

    def handleActionUpdateRPiScript(self):
        self.logger.log(
            'Attempting to "git pull" for the Raspberry Pi Python Script',
            type="INFO")
        if not self.b_serialConnected:
            replyMessage = "Serial is not connected, Please connect serial first"
        else:
            self.executer = Executer(serialObj=self.port,
                                     loggerObj=self.logger)
            result = self.executer.executeOther("UPDATE_SCRIPT")
            if result != ExecutionResult.FAILED and "FAIL" not in result:
                replyMessage = "Raspberry Pi Script has been updated. You still need to reboot or power cycle the Raspberry Pi for the updated script to run" \
                                    "\nReceived: " + result
            else:
                replyMessage = "Failed to update the RPi Script"
                if "FAIL" in result:
                    replyMessage = replyMessage + "\nReceived: " + result

        self.logger.log(replyMessage)
        ipAddrMessage = QMessageBox()
        ipAddrMessage.setIcon(QMessageBox.Information)
        ipAddrMessage.setStandardButtons(QMessageBox.Ok)
        ipAddrMessage.setWindowTitle("Raspberry Pi Script Updating Status")
        ipAddrMessage.setText(replyMessage)
        ipAddrMessage.setTextFormat(Qt.RichText)
        ipAddrMessage.setWindowIcon(self.appIcon)
        ipAddrMessage.exec_()

    @property
    def b_processRunning(self):
        return self._b_processRunning

    @property
    def b_serialConnected(self):
        return self._b_serialConnected

    @b_serialConnected.setter
    def b_serialConnected(self, newValue):
        self._b_serialConnected = newValue
        if newValue is True:
            self.logger.log("", special="SerialConnected")
        else:
            self.logger.log("", special="SerialDisconnected")

    @b_processRunning.setter
    def b_processRunning(self, newValue):
        self._b_processRunning = newValue
        if newValue is True:
            self.logger.log("", special="ProcessingStarted")

    def __del__(self):
        if self.b_serialConnected:
            self.port.close()
Exemplo n.º 19
0
class SubtitleInfoDialog(QDialog):
    def __init__(self,
                 subtitle_name="Test",
                 subtitle_delay=0.0,
                 subtitle_language=Default_Subtitle_Language,
                 subtitle_track_name="Test",
                 subtitle_set_default=False,
                 subtitle_set_forced=False,
                 subtitle_default_value_delay=0.0,
                 subtitle_default_value_language=Default_Subtitle_Language,
                 subtitle_default_value_track_name="Test",
                 subtitle_default_value_set_default=False,
                 subtitle_default_value_set_forced=False,
                 subtitle_set_default_disabled=False,
                 subtitle_set_forced_disabled=False,
                 disable_edit=False,
                 parent=None):
        super().__init__(parent)
        self.window_title = "Subtitle Info"
        self.state = "no"
        self.messageIcon = QLabel()

        self.disable_edit = disable_edit

        self.current_subtitle_language = str(subtitle_language)
        self.current_subtitle_delay = str(subtitle_delay)
        self.current_subtitle_track_name = str(subtitle_track_name)
        self.current_subtitle_set_default = subtitle_set_default
        self.current_subtitle_set_forced = subtitle_set_forced

        self.default_subtitle_language = str(subtitle_default_value_language)
        self.default_subtitle_delay = str(subtitle_default_value_delay)
        self.default_subtitle_track_name = str(
            subtitle_default_value_track_name)
        self.default_subtitle_set_default = subtitle_default_value_set_default
        self.default_subtitle_set_forced = subtitle_default_value_set_forced

        self.subtitle_set_default_disabled = subtitle_set_default_disabled
        self.subtitle_set_forced_disabled = subtitle_set_forced_disabled

        self.subtitle_name_label = QLabel("Subtitle Name:")
        self.subtitle_name_value = QLabel(str(subtitle_name))

        self.subtitle_delay_label = QLabel("Subtitle Delay:")
        self.subtitle_delay_spin = QDoubleSpinBox()
        self.setup_subtitle_delay_spin()

        self.subtitle_language_label = QLabel("Subtitle Language:")
        self.subtitle_language_comboBox = QComboBox()
        self.setup_subtitle_language_comboBox()

        self.subtitle_track_name_label = QLabel("Subtitle Track Name:")
        self.subtitle_track_name_lineEdit = QLineEdit()
        self.setup_subtitle_track_name_lineEdit()

        self.subtitle_set_forced_label = QLabel("Subtitle Forced State:")
        self.subtitle_set_forced_checkBox = QCheckBox()
        self.setup_subtitle_set_forced_checkBox()

        self.subtitle_set_default_label = QLabel("Subtitle Default State:")
        self.subtitle_set_default_checkBox = QCheckBox()
        self.setup_subtitle_set_default_checkBox()

        self.yes_button = QPushButton("OK")
        self.no_button = QPushButton("Cancel")
        self.reset_button = QPushButton("Reset To Default")

        self.buttons_layout = QHBoxLayout()
        self.subtitle_delay_layout = QHBoxLayout()
        self.subtitle_language_layout = QHBoxLayout()
        self.subtitle_track_name_layout = QHBoxLayout()
        self.subtitle_set_default_layout = QHBoxLayout()
        self.subtitle_set_forced_layout = QHBoxLayout()
        self.buttons_layout.addWidget(QLabel(""), stretch=3)
        self.buttons_layout.addWidget(self.reset_button, stretch=2)
        self.buttons_layout.addWidget(self.yes_button, stretch=2)
        self.buttons_layout.addWidget(self.no_button, stretch=2)
        self.buttons_layout.addWidget(QLabel(""), stretch=3)
        self.subtitle_setting_layout = QGridLayout()
        self.subtitle_changeble_setting_layout = QFormLayout()
        self.subtitle_changeble_setting_layout.addRow(self.subtitle_name_label,
                                                      self.subtitle_name_value)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_track_name_label, self.subtitle_track_name_lineEdit)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_language_label, self.subtitle_language_comboBox)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_delay_label, self.subtitle_delay_spin)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_set_default_label,
            self.subtitle_set_default_checkBox)
        self.subtitle_changeble_setting_layout.addRow(
            self.subtitle_set_forced_label, self.subtitle_set_forced_checkBox)

        self.subtitle_setting_layout.addLayout(
            self.subtitle_changeble_setting_layout, 0, 0, 5, 2)
        self.subtitle_setting_layout.addWidget(self.messageIcon, 0, 3, 5, -1)

        self.main_layout = QGridLayout()
        self.main_layout.addLayout(self.subtitle_setting_layout, 0, 0, 2, 3)
        self.main_layout.addLayout(self.buttons_layout, 2, 0, 1, -1)
        self.main_layout.setContentsMargins(20, 20, 20, 20)
        self.setLayout(self.main_layout)

        self.setup_ui()
        self.signal_connect()

    def setup_ui(self):
        self.disable_question_mark_window()
        self.messageIcon.setPixmap(
            QtGui.QPixmap(GlobalFiles.SubtitleIconPath).scaledToHeight(100))
        self.set_dialog_values()
        self.set_default_buttons()
        if self.subtitle_set_default_disabled:
            self.subtitle_set_default_disable()
        if self.subtitle_set_forced_disabled:
            self.subtitle_set_forced_disable()
        if self.disable_edit:
            self.subtitle_track_name_lineEdit.setEnabled(False)
            self.subtitle_language_comboBox.setEnabled(False)
            self.subtitle_delay_spin.setEnabled(False)
            self.subtitle_set_default_checkBox.setEnabled(False)
            self.subtitle_set_forced_checkBox.setEnabled(False)
            self.reset_button.setEnabled(False)

        self.setup_tool_tip_hint_subtitle_set_default()
        self.setup_tool_tip_hint_subtitle_set_forced()

    def signal_connect(self):
        self.subtitle_track_name_lineEdit.textEdited.connect(
            self.update_current_subtitle_track_name)
        self.subtitle_delay_spin.editingFinished.connect(
            self.update_current_subtitle_delay)
        self.subtitle_language_comboBox.currentTextChanged.connect(
            self.update_current_subtitle_language)
        self.subtitle_set_default_checkBox.stateChanged.connect(
            self.update_current_subtitle_set_default)
        self.subtitle_set_forced_checkBox.stateChanged.connect(
            self.update_current_subtitle_set_forced)
        self.yes_button.clicked.connect(self.click_yes)
        self.no_button.clicked.connect(self.click_no)
        self.reset_button.clicked.connect(self.reset_subtitle_setting)

    def click_yes(self):
        self.state = "yes"
        self.close()

    def click_no(self):
        self.close()

    def set_dialog_values(self):
        self.setWindowTitle(self.window_title)
        self.setWindowIcon(GlobalFiles.InfoSettingIcon)

    def disable_question_mark_window(self):
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, on=False)

    def increase_message_font_size(self, value):
        message_font = self.message.font()
        message_font.setPointSize(self.message.fontInfo().pointSize() + value)
        self.message.setFont(message_font)

    def set_default_buttons(self):
        self.yes_button.setDefault(True)
        self.yes_button.setFocus()

    def showEvent(self, a0: QtGui.QShowEvent) -> None:
        super().showEvent(a0)
        self.setFixedSize(self.size())

    def setup_subtitle_track_name_lineEdit(self):
        self.subtitle_track_name_lineEdit.setClearButtonEnabled(True)
        self.subtitle_track_name_lineEdit.setText(
            self.current_subtitle_track_name)

    def setup_subtitle_language_comboBox(self):
        self.subtitle_language_comboBox.addItems(AllSubtitlesLanguages)
        self.subtitle_language_comboBox.setCurrentIndex(
            AllSubtitlesLanguages.index(self.current_subtitle_language))
        self.subtitle_language_comboBox.setMaxVisibleItems(8)
        self.subtitle_language_comboBox.setStyleSheet(
            "QComboBox { combobox-popup: 0; }")

    def setup_subtitle_delay_spin(self):
        # self.subtitle_delay_spin.setMaximumWidth(screen_size.width() // 16)
        self.subtitle_delay_spin.setDecimals(3)
        self.subtitle_delay_spin.setMinimum(-9999.0)
        self.subtitle_delay_spin.setMaximum(9999.0)
        self.subtitle_delay_spin.setSingleStep(0.5)
        self.subtitle_delay_spin.setValue(float(self.current_subtitle_delay))

    def setup_subtitle_set_default_checkBox(self):
        self.subtitle_set_default_checkBox.setText("Set Default")
        self.subtitle_set_default_checkBox.setChecked(
            bool(self.current_subtitle_set_default))

    def setup_subtitle_set_forced_checkBox(self):
        self.subtitle_set_forced_checkBox.setText("Set Forced")
        self.subtitle_set_forced_checkBox.setChecked(
            bool(self.current_subtitle_set_forced))

    def update_current_subtitle_track_name(self):
        self.current_subtitle_track_name = str(
            self.subtitle_track_name_lineEdit.text())

    def update_current_subtitle_delay(self):
        self.current_subtitle_delay = round(self.subtitle_delay_spin.value(),
                                            5)

    def update_current_subtitle_language(self):
        self.current_subtitle_language = str(
            self.subtitle_language_comboBox.currentText())

    def update_current_subtitle_set_default(self):
        self.current_subtitle_set_default = (
            self.subtitle_set_default_checkBox.checkState() == Qt.Checked)

    def update_current_subtitle_set_forced(self):
        self.current_subtitle_set_forced = (
            self.subtitle_set_forced_checkBox.checkState() == Qt.Checked)

    def reset_subtitle_setting(self):
        self.current_subtitle_language = self.default_subtitle_language
        self.current_subtitle_delay = self.default_subtitle_delay
        self.current_subtitle_track_name = self.default_subtitle_track_name
        self.current_subtitle_set_default = self.default_subtitle_set_default
        self.current_subtitle_set_forced = self.default_subtitle_set_forced

        self.subtitle_language_comboBox.setCurrentIndex(
            AllSubtitlesLanguages.index(self.current_subtitle_language))
        self.subtitle_delay_spin.setValue(float(self.current_subtitle_delay))
        self.subtitle_track_name_lineEdit.setText(
            self.current_subtitle_track_name)
        self.subtitle_set_default_checkBox.setChecked(
            bool(self.current_subtitle_set_default))
        self.subtitle_set_forced_checkBox.setChecked(
            bool(self.current_subtitle_set_forced))

    def subtitle_set_default_disable(self):
        self.subtitle_set_default_checkBox.setDisabled(True)

    def subtitle_set_forced_disable(self):
        self.subtitle_set_forced_checkBox.setDisabled(True)

    def setup_tool_tip_hint_subtitle_set_default(self):
        if self.subtitle_set_default_checkBox.isEnabled():
            self.subtitle_set_default_checkBox.setToolTip(
                "<nobr>set this subtitle to be the default subtitle track "
                "when play")
            self.subtitle_set_default_checkBox.setToolTipDuration(12000)
        else:
            self.subtitle_set_default_checkBox.setToolTip(
                "<nobr>set this subtitle to be the default subtitle track when play<br><b>Disabled</b> because "
                "option "
                "<b>make this subtitle default</b> is enabled on mux setting tab "
            )
            self.subtitle_set_default_checkBox.setToolTipDuration(12000)

    def setup_tool_tip_hint_subtitle_set_forced(self):
        if self.subtitle_set_forced_checkBox.isEnabled():
            self.subtitle_set_forced_checkBox.setToolTip(
                "<nobr>set this subtitle to be the forced subtitle track when "
                "play")
            self.subtitle_set_forced_checkBox.setToolTipDuration(12000)
        else:
            self.subtitle_set_forced_checkBox.setToolTip(
                "<nobr>set this subtitle to be the forced subtitle track when play<br><b>Disabled</b> because "
                "option "
                "<b>make this subtitle default and forced</b> is enabled on mux setting tab "
            )
            self.subtitle_set_forced_checkBox.setToolTipDuration(12000)

    def execute(self):
        self.exec_()
Exemplo n.º 20
0
class AppearanceTab(QWidget):
    def __init__(self, parent):
        """Initialize the appearance tab
        """

        super(AppearanceTab, self).__init__(parent)

        self.prefs = parent.prefs

        # Default column width code
        col_width_label = QLabel("Default Column Width:")
        self.col_width_edit = QLineEdit(str(self.prefs['default_column_width']))
        self.col_width_edit.setMinimumWidth(40)
        self.col_width_edit.setMaximumWidth(100)
        validator = QIntValidator(10, 200, self)
        self.col_width_edit.setValidator(validator)

        # Visual style code
        style_label = QLabel("Visual Style of Application:")
        self.style_edit = QComboBox(self)
        self.style_edit.addItems(list(QStyleFactory.keys()))
        self.style_edit.setMaximumWidth(200)
        self.style_edit.setCurrentIndex(self.style_edit.findText(self.prefs['style']))

        # Units display code
        units_header_label = QLabel("Units Display:")
        self.header_units_check = QCheckBox('Show Units in Table Headers', self)
        checked_header = Qt.Checked if self.prefs['show_units_in_headers'] == 1 else Qt.Unchecked
        self.header_units_check.setCheckState(checked_header)
        self.cells_units_check = QCheckBox('Show Units in Table Cells', self)
        checked_cells = Qt.Checked if self.prefs['show_units_in_cells'] == 1 else Qt.Unchecked
        self.cells_units_check.setCheckState(checked_cells)

        # Handling of file options code
        default_handling_text = QLabel("Select how options saved directly within an IDF "
                                             "file are treated. See \"Save Options\" tab "
                                             "for the options in question.")
        default_handling_text.setWordWrap(True)
        default_handling_text.setMaximumWidth(450)
        self.button_force = QRadioButton("Force Session Options:", self)
        force_text = QLabel("Options from the current session will be used for all "
                                  "files, ignoring any options saved in the IDF file.")
        force_text.setWordWrap(True)
        force_text.setMaximumWidth(450)
        force_text.setMinimumHeight(30)
        force_text.setIndent(25)
        self.button_obey = QRadioButton("Obey IDF Options if Present:", self)
        obey_text = QLabel("Obey options saved in the IDF file. If none are "
                                 "present, use the current session's options.")
        obey_text.setWordWrap(True)
        obey_text.setMaximumWidth(450)
        obey_text.setMinimumHeight(30)
        obey_text.setIndent(25)

        # Handling of file options group box
        self.behaviour_group_box = QGroupBox("Handling of File-based Options")
        self.behaviour_group_box.setMinimumHeight(220)
        self.behaviour_group_box.setMinimumWidth(450)
        behaviour_box = QVBoxLayout()
        behaviour_box.addWidget(default_handling_text)
        behaviour_box.addWidget(self.button_force)
        behaviour_box.addWidget(force_text)
        behaviour_box.addSpacing(5)
        behaviour_box.addWidget(self.button_obey)
        behaviour_box.addWidget(obey_text)
        behaviour_box.addStretch(1)
        self.behaviour_group_box.setLayout(behaviour_box)

        self.behaviour_button_group = QButtonGroup(self)
        self.behaviour_button_group.addButton(self.button_force)
        self.behaviour_button_group.addButton(self.button_obey)
        self.behaviour_button_group.setId(self.button_force, 0)
        self.behaviour_button_group.setId(self.button_obey, 1)
        self.behaviour_button_group.button(self.prefs['obey_idf_options']).setChecked(True)

        # Main layout code
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(col_width_label)
        mainLayout.addWidget(self.col_width_edit)
        mainLayout.addSpacing(10)
        mainLayout.addWidget(style_label)
        mainLayout.addWidget(self.style_edit)
        mainLayout.addSpacing(10)
        mainLayout.addWidget(self.behaviour_group_box)
        mainLayout.addSpacing(10)
        mainLayout.addWidget(units_header_label)
        mainLayout.addWidget(self.header_units_check)
        mainLayout.addWidget(self.cells_units_check)
        mainLayout.addStretch(1)
        self.setLayout(mainLayout)

        # Update settings
        self.behaviour_button_group.buttonClicked.connect(self.update)
        self.col_width_edit.textChanged.connect(self.update)
        self.style_edit.currentIndexChanged.connect(self.update)
        self.header_units_check.stateChanged.connect(self.update)
        self.cells_units_check.stateChanged.connect(self.update)

    def update(self):
        self.prefs['default_column_width'] = self.col_width_edit.text()
        self.prefs['style'] = self.style_edit.currentText()
        self.prefs['obey_idf_options'] = self.behaviour_button_group.checkedId()
        self.prefs['show_units_in_headers'] = 1 if self.header_units_check.checkState() else 0
        self.prefs['show_units_in_cells'] = 1 if self.cells_units_check.checkState() else 0