Beispiel #1
0
    class PlotMainWindow(QWidget):
        """Base class for plot main windows."""

        def __init__(self, U, plot, length=1, title=None):
            super(PlotMainWindow, self).__init__()

            layout = QVBoxLayout()

            if title:
                title = QLabel('<b>' + title + '</b>')
                title.setAlignment(Qt.AlignHCenter)
                layout.addWidget(title)
            layout.addWidget(plot)

            plot.set(U, 0)

            if length > 1:
                hlayout = QHBoxLayout()

                self.slider = QSlider(Qt.Horizontal)
                self.slider.setMinimum(0)
                self.slider.setMaximum(length - 1)
                self.slider.setTickPosition(QSlider.TicksBelow)
                hlayout.addWidget(self.slider)

                lcd = QLCDNumber(m.ceil(m.log10(length)))
                lcd.setDecMode()
                lcd.setSegmentStyle(QLCDNumber.Flat)
                hlayout.addWidget(lcd)

                layout.addLayout(hlayout)

                hlayout = QHBoxLayout()

                toolbar = QToolBar()
                self.a_play = QAction(self.style().standardIcon(QStyle.SP_MediaPlay), 'Play', self)
                self.a_play.setCheckable(True)
                self.a_rewind = QAction(self.style().standardIcon(QStyle.SP_MediaSeekBackward), 'Rewind', self)
                self.a_toend = QAction(self.style().standardIcon(QStyle.SP_MediaSeekForward), 'End', self)
                self.a_step_backward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipBackward),
                                               'Step Back', self)
                self.a_step_forward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipForward), 'Step', self)
                self.a_loop = QAction(self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop', self)
                self.a_loop.setCheckable(True)
                toolbar.addAction(self.a_play)
                toolbar.addAction(self.a_rewind)
                toolbar.addAction(self.a_toend)
                toolbar.addAction(self.a_step_backward)
                toolbar.addAction(self.a_step_forward)
                toolbar.addAction(self.a_loop)
                if hasattr(self, 'save'):
                    self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self)
                    toolbar.addAction(self.a_save)
                    self.a_save.triggered.connect(self.save)
                hlayout.addWidget(toolbar)

                self.speed = QSlider(Qt.Horizontal)
                self.speed.setMinimum(0)
                self.speed.setMaximum(100)
                hlayout.addWidget(QLabel('Speed:'))
                hlayout.addWidget(self.speed)

                layout.addLayout(hlayout)

                self.timer = QTimer()
                self.timer.timeout.connect(self.update_solution)

                self.slider.valueChanged.connect(self.slider_changed)
                self.slider.valueChanged.connect(lcd.display)
                self.speed.valueChanged.connect(self.speed_changed)
                self.a_play.toggled.connect(self.toggle_play)
                self.a_rewind.triggered.connect(self.rewind)
                self.a_toend.triggered.connect(self.to_end)
                self.a_step_forward.triggered.connect(self.step_forward)
                self.a_step_backward.triggered.connect(self.step_backward)

                self.speed.setValue(50)

            elif hasattr(self, 'save'):
                hlayout = QHBoxLayout()
                toolbar = QToolBar()
                self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self)
                toolbar.addAction(self.a_save)
                hlayout.addWidget(toolbar)
                layout.addLayout(hlayout)
                self.a_save.triggered.connect(self.save)

            self.setLayout(layout)
            self.plot = plot
            self.U = U
            self.length = length

        def slider_changed(self, ind):
            self.plot.set(self.U, ind)

        def speed_changed(self, val):
            self.timer.setInterval(val * 20)

        def update_solution(self):
            ind = self.slider.value() + 1
            if ind >= self.length:
                if self.a_loop.isChecked():
                    ind = 0
                else:
                    self.a_play.setChecked(False)
                    return
            self.slider.setValue(ind)

        def toggle_play(self, checked):
            if checked:
                if self.slider.value() + 1 == self.length:
                    self.slider.setValue(0)
                self.timer.start()
            else:
                self.timer.stop()

        def rewind(self):
            self.slider.setValue(0)

        def to_end(self):
            self.a_play.setChecked(False)
            self.slider.setValue(self.length - 1)

        def step_forward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() + 1
            if ind == self.length and self.a_loop.isChecked():
                ind = 0
            if ind < self.length:
                self.slider.setValue(ind)

        def step_backward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() - 1
            if ind == -1 and self.a_loop.isChecked():
                ind = self.length - 1
            if ind >= 0:
                self.slider.setValue(ind)
Beispiel #2
0
    class MainWindow(QWidget):
        def __init__(self, grid, U):
            assert isinstance(U, Communicable)
            super(MainWindow, self).__init__()

            U = U.data

            layout = QVBoxLayout()

            plotBox = QHBoxLayout()
            plot = GlumpyPatchWidget(self, grid, vmin=np.min(U), vmax=np.max(U), bounding_box=bounding_box, codim=codim)
            bar = ColorBarWidget(self, vmin=np.min(U), vmax=np.max(U))
            plotBox.addWidget(plot)
            plotBox.addWidget(bar)
            layout.addLayout(plotBox)

            if len(U) == 1:
                plot.set(U.ravel())
            else:
                plot.set(U[0])

                hlayout = QHBoxLayout()

                self.slider = QSlider(Qt.Horizontal)
                self.slider.setMinimum(0)
                self.slider.setMaximum(len(U) - 1)
                self.slider.setTickPosition(QSlider.TicksBelow)
                hlayout.addWidget(self.slider)

                lcd = QLCDNumber(m.ceil(m.log10(len(U))))
                lcd.setDecMode()
                lcd.setSegmentStyle(QLCDNumber.Flat)
                hlayout.addWidget(lcd)

                layout.addLayout(hlayout)

                hlayout = QHBoxLayout()

                toolbar = QToolBar()
                self.a_play = QAction(self.style().standardIcon(QStyle.SP_MediaPlay), 'Play', self)
                self.a_play.setCheckable(True)
                self.a_rewind = QAction(self.style().standardIcon(QStyle.SP_MediaSeekBackward), 'Rewind', self)
                self.a_toend = QAction(self.style().standardIcon(QStyle.SP_MediaSeekForward), 'End', self)
                self.a_step_backward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipBackward), 'Step Back', self)
                self.a_step_forward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipForward), 'Step', self)
                self.a_loop = QAction(self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop', self)
                self.a_loop.setCheckable(True)
                toolbar.addAction(self.a_play)
                toolbar.addAction(self.a_rewind)
                toolbar.addAction(self.a_toend)
                toolbar.addAction(self.a_step_backward)
                toolbar.addAction(self.a_step_forward)
                toolbar.addAction(self.a_loop)
                hlayout.addWidget(toolbar)

                self.speed = QSlider(Qt.Horizontal)
                self.speed.setMinimum(0)
                self.speed.setMaximum(100)
                hlayout.addWidget(QLabel('Speed:'))
                hlayout.addWidget(self.speed)

                layout.addLayout(hlayout)

                self.timer = QTimer()
                self.timer.timeout.connect(self.update_solution)

                self.slider.valueChanged.connect(self.slider_changed)
                self.slider.valueChanged.connect(lcd.display)
                self.speed.valueChanged.connect(self.speed_changed)
                self.a_play.toggled.connect(self.toggle_play)
                self.a_rewind.triggered.connect(self.rewind)
                self.a_toend.triggered.connect(self.to_end)
                self.a_step_forward.triggered.connect(self.step_forward)
                self.a_step_backward.triggered.connect(self.step_backward)

                self.speed.setValue(50)

            self.setLayout(layout)
            self.plot = plot
            self.U = U

        def slider_changed(self, ind):
            self.plot.set(self.U[ind])

        def speed_changed(self, val):
            self.timer.setInterval(val * 20)

        def update_solution(self):
            ind = self.slider.value() + 1
            if ind >= len(self.U):
                if self.a_loop.isChecked():
                    ind = 0
                else:
                    self.a_play.setChecked(False)
                    return
            self.slider.setValue(ind)

        def toggle_play(self, checked):
            if checked:
                if self.slider.value() + 1 == len(self.U):
                    self.slider.setValue(0)
                self.timer.start()
            else:
                self.timer.stop()

        def rewind(self):
            self.slider.setValue(0)

        def to_end(self):
            self.a_play.setChecked(False)
            self.slider.setValue(len(self.U) - 1)

        def step_forward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() + 1
            if ind == len(self.U) and self.a_loop.isChecked():
                ind = 0
            if ind < len(self.U):
                self.slider.setValue(ind)

        def step_backward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() - 1
            if ind == -1 and self.a_loop.isChecked():
                ind = len(self.U) - 1
            if ind >= 0:
                self.slider.setValue(ind)
Beispiel #3
0
class MainWindow(QMainWindow):
    start_acq = Signal(str)
    start_rec = Signal(str)
    collect_frame = Signal(object)
    collect_threshed = Signal(object)

    def __init__(self, parent=None):
        ''' sets up the whole main window '''

        #standard init
        super(MainWindow, self).__init__(parent)

        #set the window title
        self.setWindowTitle('Open Ephys Control GUI')

        self.window_height = 700
        self.window_width = 1100

        self.screen2 = QDesktopWidget().screenGeometry(0)
        self.move(
            self.screen2.left() +
            (self.screen2.width() - self.window_width) / 2.,
            self.screen2.top() +
            (self.screen2.height() - self.window_height) / 2.)

        self.get_info()
        self.noinfo = True

        while self.noinfo:
            loop = QEventLoop()
            QTimer.singleShot(500., loop.quit)
            loop.exec_()

        subprocess.Popen('start %s' % open_ephys_path, shell=True)

        self.collect_frame.connect(self.update_frame)
        self.collect_threshed.connect(self.update_threshed)
        self.acquiring = False
        self.recording = False

        self.video_height = self.window_height * .52
        self.video_width = self.window_width * .48

        self.resize(self.window_width, self.window_height)

        #create QTextEdit window 'terminal' for receiving stdout and stderr
        self.terminal = QTextEdit(self)
        #set the geometry
        self.terminal.setGeometry(
            QRect(self.window_width * .02,
                  self.window_height * .15 + self.video_height,
                  self.video_width * .96, 150))

        #make widgets
        self.setup_video_frames()
        self.setup_thresh_buttons()

        self.overlay = True

        #create thread and worker for video processing
        self.videoThread = QThread(self)
        self.videoThread.start()
        self.videoproc_worker = VideoWorker(self)
        self.videoproc_worker.moveToThread(self.videoThread)

        self.vt_file = None
        """""" """""" """""" """""" """""" """""" """""" """
        set up menus
        """ """""" """""" """""" """""" """""" """""" """"""

        #create a QMenuBar and set geometry
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(
            QRect(0, 0, self.window_width * .5, self.window_height * .03))
        #set the QMenuBar as menu bar for main window
        self.setMenuBar(self.menubar)

        #create a QStatusBar
        statusbar = QStatusBar(self)
        #set it as status bar for main window
        self.setStatusBar(statusbar)

        #create icon toolbar with default image
        iconToolBar = self.addToolBar("iconBar.png")

        #create a QAction for the acquire button
        self.action_Acq = QAction(self)
        #make it checkable
        self.action_Acq.setCheckable(True)
        #grab an icon for the button
        acq_icon = self.style().standardIcon(QStyle.SP_MediaPlay)
        #set the icon for the action
        self.action_Acq.setIcon(acq_icon)
        #when the button is pressed, call the Acquire function
        self.action_Acq.triggered.connect(self.Acquire)

        #create a QAction for the record button
        self.action_Record = QAction(self)
        #make it checkable
        self.action_Record.setCheckable(True)
        #grab an icon for the button
        record_icon = self.style().standardIcon(QStyle.SP_DialogYesButton)
        #set the icon for the action
        self.action_Record.setIcon(record_icon)
        #when the button is pressed, call advanced_settings function
        self.action_Record.triggered.connect(self.Record)

        #create QAction for stop button
        action_Stop = QAction(self)
        #grab close icon
        stop_icon = self.style().standardIcon(QStyle.SP_MediaStop)
        #set icon for action
        action_Stop.setIcon(stop_icon)
        #when button pressed, close window
        action_Stop.triggered.connect(self.Stop)

        #show tips for each action in the status bar
        self.action_Acq.setStatusTip("Start acquiring")
        self.action_Record.setStatusTip("Start recording")
        action_Stop.setStatusTip("Stop acquiring/recording")

        #add actions to icon toolbar
        iconToolBar.addAction(self.action_Acq)
        iconToolBar.addAction(self.action_Record)
        iconToolBar.addAction(action_Stop)

        #        self.sort_button = QPushButton('Sort Now',self)
        #        self.sort_button.setGeometry(QRect(self.window_width*.85,0,self.window_width*.15,self.window_height*.05))
        #        self.sort_button.clicked.connect(self.sort_now)

        #show the window if minimized by windows
        self.showMinimized()
        self.showNormal()
        """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""
        """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""

    #this function acts as a slot to accept 'message' signal
    @Slot(str)
    def print_message(self, message):
        ''' print stdout and stderr to terminal window '''

        #move terminal cursor to end
        self.terminal.moveCursor(QTextCursor.End)
        #write message to terminal
        self.terminal.insertPlainText(message)

    def setup_thresh_buttons(self):
        ''' set up buttons for overlay/clearing thresh view '''

        self.button_frame = QFrame(self)
        self.button_frame.setGeometry(
            QRect(self.window_width * .52,
                  self.window_height * .13 + self.video_height,
                  self.video_width * .98, 50))
        button_layout = QHBoxLayout()
        self.button_frame.setLayout(button_layout)
        self.clear_button = QPushButton('Clear')
        self.overlay_button = QPushButton('Overlay')
        button_layout.addWidget(self.clear_button)
        button_layout.addWidget(self.overlay_button)

        self.clear_button.setEnabled(False)
        self.clear_button.clicked.connect(self.clear_threshed)
        self.overlay_button.setEnabled(False)
        self.overlay_button.clicked.connect(self.overlay_threshed)

    def setup_video_frames(self):
        ''' set up spots for playing video frames '''

        filler_frame = np.zeros((360, 540, 3))
        filler_frame = qimage2ndarray.array2qimage(filler_frame)

        self.raw_frame = QFrame(self)
        self.raw_label = QLabel()
        self.raw_label.setText('raw')
        self.raw_frame.setGeometry(
            QRect(self.window_width * .01, self.window_height * .15,
                  self.video_width, self.video_height))
        self.raw_frame
        raw_layout = QVBoxLayout()
        self.raw_frame.setLayout(raw_layout)
        raw_layout.addWidget(self.raw_label)

        self.threshed_frame = QFrame(self)
        self.threshed_label = QLabel()
        self.threshed_label.setText('Threshed')
        self.threshed_frame.setGeometry(
            QRect(self.window_width * .51, self.window_height * .15,
                  self.video_width, self.video_height))
        threshed_layout = QVBoxLayout()
        self.threshed_frame.setLayout(threshed_layout)
        threshed_layout.addWidget(self.threshed_label)

        self.label_frame = QFrame(self)
        self.label_frame.setGeometry(
            QRect(self.window_width * .01, self.window_height * .11,
                  self.video_width * 2, 50))
        self.label_rawlabel = QLabel()
        self.label_rawlabel.setText('Raw Video')
        self.label_threshedlabel = QLabel()
        self.label_threshedlabel.setText('Threshold View')
        label_layout = QHBoxLayout()
        self.label_frame.setLayout(label_layout)
        label_layout.addWidget(self.label_rawlabel)
        label_layout.addWidget(self.label_threshedlabel)

        self.raw_label.setPixmap(QPixmap.fromImage(filler_frame))
        self.threshed_label.setPixmap(QPixmap.fromImage(filler_frame))

    def Acquire(self):

        if self.action_Acq.isChecked():

            self.vidbuffer = []

            if self.recording:

                while 1:
                    try:
                        self.sock.send('StopRecord')
                        self.sock.recv()
                    except:
                        continue
                    break

                self.recording = False

            else:
                #create and start a thread to transport a worker to later
                self.workerThread = QThread(self)
                self.workerThread.start()
                #create a worker object based on Worker class and move it to our
                #worker thread
                self.worker = Worker(self)
                self.worker.moveToThread(self.workerThread)

                try:
                    self.start_acq.disconnect()
                except:
                    pass

                while 1:
                    try:
                        self.sock.send('StartAcquisition')
                        self.sock.recv()
                    except:
                        continue
                    break

                self.acquiring = True
                self.start_acq.connect(self.worker.acquire)
                self.start_acq.emit('start!')

            self.action_Acq.setEnabled(False)
            self.action_Record.setChecked(False)
            self.action_Record.setEnabled(True)

            record_icon = self.style().standardIcon(QStyle.SP_DialogYesButton)
            #set the icon for the action
            self.action_Record.setIcon(record_icon)

    def Record(self):

        if self.action_Record.isChecked():

            if not self.acquiring:
                self.workerThread = QThread(self)
                self.workerThread.start()

                self.worker = Worker(self)
                self.worker.moveToThread(self.workerThread)

                try:
                    self.start_rec.disconnect()
                except:
                    pass

                while 1:
                    try:
                        self.sock.send('StartAcquisition')
                        self.sock.recv()
                    except:
                        continue
                    break

                while 1:
                    try:
                        self.sock.send('StartRecord')
                        self.sock.recv()
                    except:
                        continue
                    break

                self.vidbuffer = []
                self.start_rec.connect(self.worker.acquire)
                self.recording = True
                self.start_rec.emit('start!')

            else:

                while 1:
                    try:
                        self.sock.send('StartRecord')
                        self.sock.recv()
                    except:
                        continue
                    break

                self.vidbuffer = []
                self.recording = True

            record_icon = self.style().standardIcon(QStyle.SP_DialogNoButton)
            #set the icon for the action
            self.action_Record.setIcon(record_icon)
            self.action_Record.setEnabled(False)

            self.action_Acq.setChecked(False)
            self.action_Acq.setEnabled(True)

    def Stop(self):

        self.acquiring = False
        self.recording = False

        while 1:
            try:
                self.sock.send('isRecording')
                rec = self.sock.recv()
            except:
                continue
            break

        if rec == '1':
            while 1:
                try:
                    self.sock.send('StopRecord')
                    self.sock.recv()
                except:
                    continue
                break

            self.action_Record.setEnabled(True)
            self.action_Record.setChecked(False)

        while 1:
            try:
                self.sock.send('isAcquiring')
                acq = self.sock.recv_string()
            except:
                continue
            break

        if acq == '1':
            while 1:
                try:
                    self.sock.send('StopAcquisition')
                    self.sock.recv()
                except:
                    continue
                break

        self.action_Acq.setEnabled(True)
        self.action_Acq.setChecked(False)

        try:
            #open a csv file for saving tracking data
            with open(self.vt_file, 'a') as csvfile:
                #create a writer
                vidwriter = csv.writer(csvfile, dialect='excel-tab')
                #check if it's an empty file
                for row in self.vidbuffer:
                    vidwriter.writerow(row)

        except:
            pass

        record_icon = self.style().standardIcon(QStyle.SP_DialogYesButton)
        #set the icon for the action
        self.action_Record.setIcon(record_icon)

    def update_frame(self, image):
        self.raw_label.setPixmap(QPixmap.fromImage(image))

    def update_threshed(self, threshed_image):
        self.threshed_label.setPixmap(QPixmap.fromImage(threshed_image))

    def clear_threshed(self):
        self.green_frame = np.zeros_like(self.green_frame)
        self.red_frame = np.zeros_like(self.red_frame)

    def overlay_threshed(self):
        if self.overlay:
            self.overlay = False
        elif not self.overlay:
            self.overlay = True


#    def sort_now(self):
#
#        if self.recdir is not None:
#            os.chdir('./kilosort_control')
#            #create and show the main window
#            self.sort_frame = kilosort_control.sort_gui.MainWindow()
#            self.sort_frame.show()
#
#            #set up stream for stdout and stderr based on outputStream class
#            self.outputStream = kilosort_control.sort_gui.outputStream()
#            #when outputStream sends messages, connect to appropriate function for
#            #writing to terminal window
#            self.outputStream.message.connect(self.sort_frame.print_message)
#
#            #connect stdout and stderr to outputStream
#            sys.stdout = self.outputStream
#            sys.stderr = self.outputStream
#
#            self.sort_frame.run_now(self.recdir)
#
#            self.close()

    def get_info(self):

        self.info_window = QWidget()
        self.info_window.resize(400, 350)
        #set title
        self.info_window.setWindowTitle('Session Info')
        #give layout
        info_layout = QVBoxLayout(self.info_window)

        with open('info_fields.pickle', 'rb') as f:
            default_fields = pickle.load(f)
            f.close()

        #set label for pic_resolution setting
        experimenter_label = QLabel('Experimenter:')
        #make a QLineEdit box for displaying/editing settings
        experimenter = QComboBox(self.info_window)
        experimenter.setEditable(True)
        experimenter.addItems(default_fields['experimenter'])
        #add label and box to current window
        info_layout.addWidget(experimenter_label)
        info_layout.addWidget(experimenter)

        #set label for pic_resolution setting
        whose_animal_label = QLabel('Whose animal?')
        #make a QLineEdit box for displaying/editing settings
        whose_animal = QComboBox(self.info_window)
        whose_animal.setEditable(True)
        whose_animal.addItems(default_fields['whose_animal'])
        #add label and box to current window
        info_layout.addWidget(whose_animal_label)
        info_layout.addWidget(whose_animal)

        animal_number_label = QLabel('Animal number:')
        animal_number = QComboBox(self.info_window)
        animal_number.setEditable(True)
        animal_number.addItems(default_fields['animal_number'])
        info_layout.addWidget(animal_number_label)
        info_layout.addWidget(animal_number)

        session_number_label = QLabel('Session number:')
        session_number = QTextEdit(self.info_window)
        session_number.setText('1')
        info_layout.addWidget(session_number_label)
        info_layout.addWidget(session_number)

        session_type_label = QLabel('Session type:')
        session_type = QComboBox(self.info_window)
        session_type.setEditable(True)
        session_type.addItems(default_fields['session_type'])
        info_layout.addWidget(session_type_label)
        info_layout.addWidget(session_type)

        def save_info(self):

            info_fields = {}
            info_fields['experimenter'] = [
                experimenter.itemText(i) for i in range(experimenter.count())
            ]
            info_fields['whose_animal'] = [
                whose_animal.itemText(i) for i in range(whose_animal.count())
            ]
            info_fields['animal_number'] = [
                animal_number.itemText(i) for i in range(animal_number.count())
            ]
            info_fields['session_type'] = [
                session_type.itemText(i) for i in range(session_type.count())
            ]

            with open('info_fields.pickle', 'wb') as f:
                pickle.dump(info_fields, f, protocol=2)
                f.close()

            current_experimenter = str(experimenter.currentText())
            current_whose_animal = str(whose_animal.currentText())
            current_animal_number = str(animal_number.currentText())
            current_session_number = str(session_number.toPlainText())
            current_session_type = str(session_type.currentText())

            recdir = data_save_dir + current_whose_animal + '/' + current_animal_number

            if not os.path.exists(recdir):
                os.makedirs(recdir)

            self.experiment_info = '###### Experiment Info ######\r\n'
            self.experiment_info += 'Experimenter: %s\r\n' % current_experimenter
            self.experiment_info += 'Whose animal? %s\r\n' % current_whose_animal
            self.experiment_info += 'Animal number: %s\r\n' % current_animal_number
            self.experiment_info += 'Session number: %s\r\n' % current_session_number
            self.experiment_info += 'Session type: %s\r\n' % current_session_type

            self.experiment_info = self.experiment_info.encode()

            config_file = config_path + '/' + current_animal_number + '.xml'

            if not os.path.exists(config_file):
                shutil.copy(default_config, config_file)

            tree = et.parse(config_file)
            root = tree.getroot()
            for child in root:
                if child.tag == 'CONTROLPANEL':
                    child.attrib['recordPath'] = recdir.replace('/', '\\')
            tree.write(config_file)
            tree.write(default_config)

            self.info_window.close()
            self.noinfo = False

        ready_button = QPushButton('Ready!')
        ready_button.clicked.connect(lambda: save_info(self))
        info_layout.addWidget(ready_button)

        self.info_window.show()
Beispiel #4
0
    class PlotMainWindow(QWidget):
        """Base class for plot main windows."""
        def __init__(self, U, plot, length=1, title=None):
            super().__init__()

            layout = QVBoxLayout()

            if title:
                title = QLabel('<b>' + title + '</b>')
                title.setAlignment(Qt.AlignHCenter)
                layout.addWidget(title)
            layout.addWidget(plot)

            plot.set(U, 0)

            if length > 1:
                hlayout = QHBoxLayout()

                self.slider = QSlider(Qt.Horizontal)
                self.slider.setMinimum(0)
                self.slider.setMaximum(length - 1)
                self.slider.setTickPosition(QSlider.TicksBelow)
                hlayout.addWidget(self.slider)

                lcd = QLCDNumber(m.ceil(m.log10(length)))
                lcd.setDecMode()
                lcd.setSegmentStyle(QLCDNumber.Flat)
                hlayout.addWidget(lcd)

                layout.addLayout(hlayout)

                hlayout = QHBoxLayout()

                toolbar = QToolBar()
                self.a_play = QAction(
                    self.style().standardIcon(QStyle.SP_MediaPlay), 'Play',
                    self)
                self.a_play.setCheckable(True)
                self.a_rewind = QAction(
                    self.style().standardIcon(QStyle.SP_MediaSeekBackward),
                    'Rewind', self)
                self.a_toend = QAction(
                    self.style().standardIcon(QStyle.SP_MediaSeekForward),
                    'End', self)
                self.a_step_backward = QAction(
                    self.style().standardIcon(QStyle.SP_MediaSkipBackward),
                    'Step Back', self)
                self.a_step_forward = QAction(
                    self.style().standardIcon(QStyle.SP_MediaSkipForward),
                    'Step', self)
                self.a_loop = QAction(
                    self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop',
                    self)
                self.a_loop.setCheckable(True)
                toolbar.addAction(self.a_play)
                toolbar.addAction(self.a_rewind)
                toolbar.addAction(self.a_toend)
                toolbar.addAction(self.a_step_backward)
                toolbar.addAction(self.a_step_forward)
                toolbar.addAction(self.a_loop)
                if hasattr(self, 'save'):
                    self.a_save = QAction(
                        self.style().standardIcon(QStyle.SP_DialogSaveButton),
                        'Save', self)
                    toolbar.addAction(self.a_save)
                    self.a_save.triggered.connect(self.save)
                hlayout.addWidget(toolbar)

                self.speed = QSlider(Qt.Horizontal)
                self.speed.setMinimum(0)
                self.speed.setMaximum(100)
                hlayout.addWidget(QLabel('Speed:'))
                hlayout.addWidget(self.speed)

                layout.addLayout(hlayout)

                self.timer = QTimer()
                self.timer.timeout.connect(self.update_solution)

                self.slider.valueChanged.connect(self.slider_changed)
                self.slider.valueChanged.connect(lcd.display)
                self.speed.valueChanged.connect(self.speed_changed)
                self.a_play.toggled.connect(self.toggle_play)
                self.a_rewind.triggered.connect(self.rewind)
                self.a_toend.triggered.connect(self.to_end)
                self.a_step_forward.triggered.connect(self.step_forward)
                self.a_step_backward.triggered.connect(self.step_backward)

                self.speed.setValue(50)

            elif hasattr(self, 'save'):
                hlayout = QHBoxLayout()
                toolbar = QToolBar()
                self.a_save = QAction(
                    self.style().standardIcon(QStyle.SP_DialogSaveButton),
                    'Save', self)
                toolbar.addAction(self.a_save)
                hlayout.addWidget(toolbar)
                layout.addLayout(hlayout)
                self.a_save.triggered.connect(self.save)

            self.setLayout(layout)
            self.plot = plot
            self.U = U
            self.length = length

        def slider_changed(self, ind):
            self.plot.set(self.U, ind)

        def speed_changed(self, val):
            self.timer.setInterval(val * 20)

        def update_solution(self):
            ind = self.slider.value() + 1
            if ind >= self.length:
                if self.a_loop.isChecked():
                    ind = 0
                else:
                    self.a_play.setChecked(False)
                    return
            self.slider.setValue(ind)

        def toggle_play(self, checked):
            if checked:
                if self.slider.value() + 1 == self.length:
                    self.slider.setValue(0)
                self.timer.start()
            else:
                self.timer.stop()

        def rewind(self):
            self.slider.setValue(0)

        def to_end(self):
            self.a_play.setChecked(False)
            self.slider.setValue(self.length - 1)

        def step_forward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() + 1
            if ind == self.length and self.a_loop.isChecked():
                ind = 0
            if ind < self.length:
                self.slider.setValue(ind)

        def step_backward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() - 1
            if ind == -1 and self.a_loop.isChecked():
                ind = self.length - 1
            if ind >= 0:
                self.slider.setValue(ind)
Beispiel #5
0
class MainWindow(QMainWindow):
	def __init__(self):
		super(MainWindow, self).__init__()		
		self.debug = debug

		self.progset = QSettings("ADLMIDI-pyGUI", "ADLMIDI-pyGUI")
		
		self.about_window = None
		self.settings_window = None
		self.paused = False

		self.MaxRecentFiles = int(self.progset.value("file/MaxRecentFiles", 5))

		self.recentList = self.progset.value("file/recent", [])
		if type(self.recentList) is unicode: self.recentList = [self.recentList]

		self.banks = [	" 0 = AIL (Star Control 3, Albion, Empire 2, Sensible Soccer, Settlers 2, many others)",
						"01 = Bisqwit (selection of 4op and 2op)",
						"02 = HMI (Descent, Asterix)",
						"03 = HMI (Descent:: Int)",
						"04 = HMI (Descent:: Ham)",
						"05 = HMI (Descent:: Rick)",
						"06 = HMI (Descent 2)",
						"07 = HMI (Normality)",
						"08 = HMI (Shattered Steel)",
						"09 = HMI (Theme Park)",
						"10 = HMI (3d Table Sports, Battle Arena Toshinden)",
						"11 = HMI (Aces of the Deep)",
						"12 = HMI (Earthsiege)",
						"13 = HMI (Anvil of Dawn)",
						"14 = DMX (Doom           :: partially pseudo 4op)",
						"15 = DMX (Hexen, Heretic :: partially pseudo 4op)",
						"16 = DMX (MUS Play       :: partially pseudo 4op)",
						"17 = AIL (Discworld, Grandest Fleet, Pocahontas, Slob Zone 3d, Ultima 4, Zorro)",
						"18 = AIL (Warcraft 2)",
						"19 = AIL (Syndicate)",
						"20 = AIL (Guilty, Orion Conspiracy, Terra Nova Strike Force Centauri :: 4op)",
						"21 = AIL (Magic Carpet 2)",
						"22 = AIL (Nemesis)",
						"23 = AIL (Jagged Alliance)",
						"24 = AIL (When Two Worlds War :: 4op, MISSING INSTRUMENTS)",
						"25 = AIL (Bards Tale Construction :: MISSING INSTRUMENTS)",
						"26 = AIL (Return to Zork)",
						"27 = AIL (Theme Hospital)",
						"28 = AIL (National Hockey League PA)",
						"29 = AIL (Inherit The Earth)",
						"30 = AIL (Inherit The Earth, file two)",
						"31 = AIL (Little Big Adventure :: 4op)",
						"32 = AIL (Wreckin Crew)",
						"33 = AIL (Death Gate)",
						"34 = AIL (FIFA International Soccer)",
						"35 = AIL (Starship Invasion)",
						"36 = AIL (Super Street Fighter 2 :: 4op)",
						"37 = AIL (Lords of the Realm :: MISSING INSTRUMENTS)",
						"38 = AIL (SimFarm, SimHealth :: 4op)",
						"39 = AIL (SimFarm, Settlers, Serf City)",
						"40 = AIL (Caesar 2 :: partially 4op, MISSING INSTRUMENTS)",
						"41 = AIL (Syndicate Wars)",
						"42 = AIL (Bubble Bobble Feat. Rainbow Islands, Z)",
						"43 = AIL (Warcraft)",
						"44 = AIL (Terra Nova Strike Force Centuri :: partially 4op)",
						"45 = AIL (System Shock :: partially 4op)",
						"46 = AIL (Advanced Civilization)",
						"47 = AIL (Battle Chess 4000 :: partially 4op, melodic only)",
						"48 = AIL (Ultimate Soccer Manager :: partially 4op)",
						"49 = AIL (Air Bucks, Blue And The Gray, America Invades, Terminator 2029)",
						"50 = AIL (Ultima Underworld 2)",
						"51 = AIL (Kasparov's Gambit)",
						"52 = AIL (High Seas Trader :: MISSING INSTRUMENTS)",
						"53 = AIL (Master of Magic, Master of Orion 2 :: 4op, std percussion)",
						"54 = AIL (Master of Magic, Master of Orion 2 :: 4op, orchestral percussion)",
						"55 = SB  (Action Soccer)",
						"56 = SB  (3d Cyberpuck :: melodic only)",
						"57 = SB  (Simon the Sorcerer :: melodic only)",
						"58 = OP3 (The Fat Man 2op set)",
						"59 = OP3 (The Fat Man 4op set)",
						"60 = OP3 (JungleVision 2op set :: melodic only)",
						"61 = OP3 (Wallace 2op set, Nitemare 3D :: melodic only)",
						"62 = TMB (Duke Nukem 3D)",
						"63 = TMB (Shadow Warrior)",
						"64 = DMX (Raptor)"
					]
					
		self.openicon  = QIcon.fromTheme('document-open', QIcon('img/load.png'))
		self.saveicon  = QIcon.fromTheme('document-save', QIcon('img/save.png'))
		self.playicon  = QIcon.fromTheme('media-playback-start', QIcon('img/play.png'))
		self.pauseicon = QIcon.fromTheme('media-playback-pause', QIcon('img/pause.png'))
		self.stopicon  = QIcon.fromTheme('media-playback-stop', QIcon('img/stop.png'))
		self.quiticon  = QIcon.fromTheme('application-exit', QIcon('img/quit.png'))
		self.abouticon = QIcon.fromTheme('help-about', QIcon('img/about.png'))
		self.setticon  = QIcon.fromTheme('preferences-desktop', QIcon('img/settings.png'))

		self.winsetup()

	def addWorker(self, worker):
		worker.message.connect(self.update)
		worker.finished.connect(self.workerFinished)
		self.threads.append(worker)

	def workerFinished(self):
		pass
		#barf('MSG', 'Thread completed the task!')

	def killWorkers(self):
		pass
		#for worker in self.threads:
		#	worker.terminate()
		
	def winsetup(self):
		self.setWindowIcon(QIcon('img/note.png'))
		
		openFile = QAction(self.openicon, 'Open', self)
		openFile.setShortcut('Ctrl+O')
		openFile.triggered.connect(self.load)
		
		saveFile = QAction(self.saveicon, 'Save', self)
		saveFile.setShortcut('Ctrl+S')
		saveFile.triggered.connect(self.save)
		
		playFile = QAction(self.playicon, 'Play', self)
		playFile.setShortcut('Ctrl+P')
		playFile.triggered.connect(self.play)
		
		pausePlayb = QAction(self.pauseicon, 'Pause', self)
		pausePlayb.setShortcut('Ctrl+R')
		pausePlayb.triggered.connect(self.pause)
		
		stopPlay = QAction(self.stopicon, 'Stop', self)
		stopPlay.setShortcut('Ctrl+Z')
		stopPlay.triggered.connect(self.stop)
		
		exitAction = QAction(self.quiticon, 'Quit', self)
		exitAction.setShortcut('Ctrl+X')
		exitAction.triggered.connect(self.quit)
		
		aboutdlg = QAction(self.abouticon, 'About', self)
		aboutdlg.setShortcut('Ctrl+A')
		aboutdlg.triggered.connect(self.about)
		
		showSett = QAction(self.setticon, 'Settings', self)
		showSett.triggered.connect(self.settings)

		menubar = self.menuBar()

		fileMenu = menubar.addMenu('&File')
		configMenu = menubar.addMenu('&Options')
		configMenu.setStyleSheet("border: 1px solid black;")
		
		self.setLooped = QAction('Loop', configMenu, checkable=True)
		if self.progset.value("sound/Looped") == 'true': self.setLooped.setChecked(True)
		else: self.setLooped.setChecked(False)
		self.setLooped.setShortcut('Ctrl+L')
		
		self.setAutoplay = QAction('Autoplay', configMenu, checkable=True)
		if self.progset.value("sound/Autoplay") == 'true': self.setAutoplay.setChecked(True)
		else: self.setAutoplay.setChecked(False)
		self.setAutoplay.setShortcut('Ctrl+K')
		
		configMenu.addAction(self.setAutoplay)
		configMenu.addAction(self.setLooped)

		fileMenu.setStyleSheet("border: 1px solid black;")
		fileMenu.addAction(openFile)
		fileMenu.addAction(saveFile)
		fileMenu.addSeparator()

		self.recentMenu = fileMenu.addMenu('Recent')
		self.rfUpdate()

		fileMenu.addSeparator()
		fileMenu.addAction(showSett)
		fileMenu.addSeparator()
		fileMenu.addAction(exitAction)

		helpMenu = menubar.addMenu('&Help')
		helpMenu.setStyleSheet("border: 1px solid black;")
		helpMenu.addAction(aboutdlg)
		
		self.numCards = QSpinBox()
		numCards_text = QLabel(" OPL : ")
		self.numCards.setRange(1, 100)
		self.numCards.setValue(int(self.progset.value("sound/numCards", 3)))
		self.numCards.valueChanged.connect(self.updateMax4ops)
		
		self.fourOps = QSpinBox()
		fourOps_text = QLabel(" 4op Ch : ")
		self.fourOps.setRange(0, self.numCards.value()*6)
		self.fourOps.setValue(int(self.progset.value("sound/fourOps", self.numCards.value()*6)))
		
		self.twoOps = QSpinBox()
		twoOps_text = QLabel(" 2op Ch : ")
		self.twoOps.setValue((self.numCards.value()*12 - self.fourOps.value()))
		self.twoOps.setRange(self.twoOps.value(), self.twoOps.value())
		
		toolbar = self.addToolBar('Media')
		toolbar.addAction(playFile)
		toolbar.addAction(pausePlayb)
		toolbar.addAction(stopPlay)
		toolbar.setMovable(False)
		toolbar.addSeparator()
		toolbar.addWidget(numCards_text)
		toolbar.addWidget(self.numCards)
		toolbar.addSeparator()
		toolbar.addWidget(fourOps_text)
		toolbar.addWidget(self.fourOps)
		#toolbar.addSeparator()
		#toolbar.addWidget(twoOps_text)
		#toolbar.addWidget(self.twoOps)
		
		self.statusBar()
		
		self.setFixedSize(380, 90)
		self.center()
		self.setWindowTitle('ADLMIDI pyGUI')
		self.show()
		
		if self.debug: barf("MSG", "Loaded Main Window", True, False)
		self.update("ready")

		self.threads = []
		self.addWorker(AdlMidi(1))
		self.addWorker(AdlMidiSave(2))

	def rfUpdate(self):
		self.recentMenu.clear()
		def recentfile(f2l):
			return lambda: self.load2(f2l)
		self.recentFileActs = []
		recentLength = len(self.recentList)
		for i in range(self.MaxRecentFiles):
			try:
				if i >= recentLength: break
				rev = (recentLength-1)-i
				filetoload = self.recentList[rev]
				filename = path.split(filetoload)[1]
				self.fileact = QAction(filename, self.recentMenu)
				self.fileact.triggered.connect(recentfile(filetoload))
				self.recentFileActs.append(self.fileact)
			except Exception: pass
		for i in range(self.MaxRecentFiles):
			try: self.recentMenu.addAction(self.recentFileActs[i])
			except Exception: pass

	def get_bank(self):
		try:
			selection = self.settings_window.combo.currentText()
			selection = str(selection[0])+str(selection[1])
			return int(selection)
		except Exception: return 1
		
	def center(self):
		qr = self.frameGeometry()
		cp = QDesktopWidget().availableGeometry().center()
		qr.moveCenter(cp)
		self.move(qr.topLeft())

	def about(self):
		if self.about_window is None:
			window = QMessageBox(self)
			self.about_window = window
		else: window = self.about_window
		window = self.about_window
		window.setWindowIcon(QIcon(self.abouticon))
		window.setWindowTitle('About ADLMIDI pyGUI')
		
		credits = "<center><b>ADLMIDI pyGUI v%s (%s)</b><br>Developed by Tristy H. \"KittyTristy\"<br>[<a href=\"https://github.com/KittyTristy/ADLMIDI-pyGUI\">Website</a>] [<a href=\"mailto:[email protected]\">Email</a>] <br><br><br>" % (__version__, system())
		title = "<b>ADLMIDI pyGUI</b> is a GUI wrapper<br>written in Python for use with..<br><br><b>ADLMIDI: MIDI Player<br>for Linux and Windows with OPL3 emulation</b><br>"
		cw = "(C) -- <a href=\"http://iki.fi/bisqwit/source/adlmidi.html\">http://iki.fi/bisqwit/source/adlmidi.html</a></center>"
		credits = credits + title + cw
		window.setText(credits)
			
		window.show()
		window.activateWindow()
		window.raise_()
		
	def settings(self):
		if self.settings_window is None:
			window = QDialog(self)
			self.settings_window = window
		else: window = self.settings_window
		window = self.settings_window
		window.setWindowTitle('Settings')
		
		window.notelabel = QLabel("Currently these settings are only guaranteed to work prior to loading the first MIDI!\nYou'll have to restart ADLMIDI pyGui to change them again if they stop working. \n\nSorry! This will be fixed soon!")
		window.notelabel.setWordWrap(True)
		window.notelabel.setStyleSheet("font-size: 8pt; border-style: dotted; border-width: 1px; padding: 12px;")
		window.banklabel = QLabel("<B>Choose Instrument Bank</B>")
		window.space     = QLabel("")
		window.optlabel  = QLabel("<B>Options</B>")
		
		window.combo = QComboBox()
		window.combo.addItems(self.banks)
		#window.combo.setMaximumWidth(350)
		window.combo.setMaxVisibleItems(12)
		window.combo.setStyleSheet("combobox-popup: 0;")
		window.combo.setCurrentIndex(int(self.progset.value("sound/bank", 1)))
		window.combo.currentIndexChanged.connect(self.saveSettings)
		
		window.perc		= QCheckBox("Adlib Percussion Instrument Mode")
		#window.perc.stateChanged.connect(self.checkOpts)
		window.tremamp  = QCheckBox("Tremolo Amplification Mode")
		#window.tremamp.stateChanged.connect(self.checkOpts)
		window.vibamp   = QCheckBox("Vibrato Amplification Mode")
		#window.vibamp.stateChanged.connect(self.checkOpts)
		window.modscale = QCheckBox("Scaling of Modulator Volume")
		#window.modscale.stateChanged.connect(self.checkOpts)
		
		window.okButton = QPushButton('OK')
		window.okButton.clicked.connect(window.hide)
		
		vbox = QVBoxLayout()
		vbox.addWidget(window.space)
		vbox.addWidget(window.banklabel)
		vbox.addWidget(window.combo)
		vbox.addWidget(window.space)
		vbox.addWidget(window.optlabel)
		vbox.addWidget(window.perc)
		vbox.addWidget(window.tremamp)
		vbox.addWidget(window.vibamp)
		vbox.addWidget(window.modscale)
		vbox.addWidget(window.notelabel)
		
		hbox = QHBoxLayout()
		hbox.addStretch(1)
		hbox.addWidget(window.okButton)
		
		vbox.addLayout(hbox)
		window.setLayout(vbox) 
		
		window.setFixedSize(530, 369)
		window.show()
		window.activateWindow()
		window.raise_()
		
	def updateMax4ops(self):
		self.fourOps.setMaximum(self.numCards.value()*6)
		self.fourOps.setValue(self.numCards.value()*6)
		barf("DBG", "Updating Maximum of 4ops Chs to %s" % (self.numCards.value()*6), True, False)
		#self.twoOps.setValue(self.numCards.value()*12 - self.fourOps.value())
		#self.twoOps.setRange(self.twoOps.value(), self.twoOps.value())
		
	def checkOpts(self):
		global arglist
		#barf("ACT", "Checking if Options have changed..", True, False)
		arglist = []
		try:
			if QAbstractButton.isChecked(self.settings_window.perc) and not ('-p' in arglist): arglist.append('-p')
			elif not QAbstractButton.isChecked(self.settings_window.perc) and ('-p' in arglist): arglist.remove('-p')
		except Exception: pass
		try:
			if QAbstractButton.isChecked(self.settings_window.tremamp) and not ('-t' in arglist): arglist.append('-t')
			elif not QAbstractButton.isChecked(self.settings_window.tremamp) and ('-t' in arglist): arglist.remove('-t')
		except Exception: pass
		try:
			if QAbstractButton.isChecked(self.settings_window.vibamp) and not ('-v' in arglist): arglist.append('-v')
			elif not QAbstractButton.isChecked(self.settings_window.vibamp) and ('-v' in arglist): arglist.remove('-v')
		except Exception: pass
		try:
			if QAbstractButton.isChecked(self.settings_window.modscale) and not ('-s' in arglist): arglist.append('-s')
			elif not QAbstractButton.isChecked(self.settings_window.modscale) and ('-s' in arglist): arglist.remove('-s')
		except Exception: pass

		self.sel_bank = self.get_bank()

	def saveSettings(self):
		self.progset.setValue("sound/Autoplay", self.setAutoplay.isChecked())
		self.progset.setValue("sound/Looped", self.setLooped.isChecked())
		self.progset.setValue("sound/numCards", self.numCards.value())
		self.progset.setValue("sound/fourOps", self.fourOps.value())
		try: self.progset.setValue("sound/bank", self.settings_window.combo.currentIndex())
		except Exception: pass
		if len(self.recentList) >= 1: self.progset.setValue("file/recent", self.recentList[-self.MaxRecentFiles:])
		self.progset.setValue("file/MaxRecentFiles", self.MaxRecentFiles)
		#allkeys = self.progset.allKeys()
		#for key in allkeys:
		#	barf('DBG', str(key) + " " + str(self.progset.value(key)))
		
	def closeEvent(self, event):
		self.stop()
		#self.pkill()
		self.saveSettings()
		barf("DBG", "Quitting", True, False)
		
	def quit(self):
		self.stop()
		#self.pkill()
		self.saveSettings()
		barf("DBG", "Quitting", True, False)
		exit(0)

	def pkill(self):
		try: p.kill()
		except Exception: pass
		
	##############################################################
	##### Statusbar Functions ####################################
	##############################################################
	
	def clear(self):
		try: self.statusBar().removeWidget(self.playStatus)
		except Exception: pass
	
	@Slot(str)
	def update(self, status=''):
		self.clear()
		if status == "ready": text = "&nbsp;<B>Ready</b>"
		elif status == "play": text = "&nbsp;<B>Now Playing: </B>" + path.split(f.name)[1]
		elif status == "loop": text = "&nbsp;<B>Looping: </B>" + path.split(f.name)[1]
		elif status == "stop": text = "&nbsp;<B>Stopped: </B>" + path.split(f.name)[1]
		elif status == "pause": text = "&nbsp;<B>Paused: </B>" + path.split(f.name)[1]
		elif status == "loading": text = "&nbsp;<B>Loading.. </B>"
		elif status == "load": text = "&nbsp;<B>Loaded: </B>" + path.split(f.name)[1]
		elif status == "saving": text = "&nbsp;<B>Saving.. </B>"
		elif status == "saved": text = "&nbsp;<B>Saved as: </B>" + "saved/" + path.splitext(path.split(f.name)[1])[0] + ".wav"
		self.playStatus = QLabel(text)
		self.statusBar().addPermanentWidget(self.playStatus, 1)
		
	##############################################################
	####### Sound Functions ######################################
	##############################################################

	def play(self):
		global Paused, arglist
		if f != None and Paused == False:
			Paused = False
			self.stop()
			self.checkOpts()
			if not self.setLooped.isChecked(): arglist.append('-nl')
			arglist.append(str(self.progset.value("sound/bank", 1)))
			arglist.append(str(self.numCards.value()))
			arglist.append(str(self.fourOps.value()))
			for worker in self.threads:
				if worker.id == 1:
					worker.start()
		elif f != None and Paused == True:
			os.kill(p.pid, signal.SIGCONT)
			self.update("play")
			Paused = False

	def pause(self):
		global p, Paused
		if f != None:
			try:
				if Paused == False:
					os.kill(p.pid, signal.SIGSTOP)
					self.update("pause")
					Paused = True
				elif Paused == True:
					os.kill(p.pid, signal.SIGCONT)
					self.update("play")
					Paused = False
			except Exception: pass

	def stop(self):
		global Paused
		if f != None:
			Paused = False 
			self.pkill()
			self.killWorkers()
			self.update("stop")
				
	##############################################################
	##### Load/Save Functions ####################################
	##############################################################

	def load(self):
		global f
		lastdir = str(self.progset.value("file/lastdir", ""))
		fname, _ = QFileDialog.getOpenFileName(None, 'Open File', lastdir, "MIDI Audio File (*.mid *.MID)")
		if fname != "":
			f = file(fname, 'r')
			if not f.name in self.recentList: self.recentList.append(f.name)
			else:
				self.recentList.remove(f.name)
				self.recentList.append(f.name)
			self.progset.setValue("file/lastdir", path.split(f.name)[0])
			self.rfUpdate()
			self.update("load")
			self.pkill()
			if self.debug: barf("SAV", "Loaded %s" % path.split(f.name)[1], True, False)
			if self.setAutoplay.isChecked(): self.play()
			else: self.update("load")

	def load2(self, r_file=None):
		global f
		f = file(r_file, 'r')
		self.recentList.remove(f.name)
		self.recentList.append(f.name)
		self.rfUpdate()
		self.update("load")
		self.pkill()
		if self.debug: barf("SAV", "Loaded %s" % path.split(f.name)[1], True, False)
		if self.setAutoplay.isChecked(): self.play()
		else: self.update("load")
			
	def save(self):
		if f != None:
			self.stop()
			for worker in self.threads:
				if worker.id == 2:
					worker.start()