Beispiel #1
0
class SignalGrouper(QDialog):
    def __init__(self, chartData, parent=None):
        QDialog.__init__(self, parent)
        self.chartData = chartData
        self._create()

    def _create(self):
        self.mLayout = QVBoxLayout(self)
        
        self.gSelector = QListWidget()
        groups = self.chartData.getDataGroups()
        self.gSelector.addItems(groups)
        self.gSelector.currentTextChanged.connect(self._updateGroupList)
        self.chartData.dataGroupAdded.connect(self.gSelector.addItem)
        self.chartData.dataGroupAdded.connect(self.gSelector.addItem)
        self.mLayout.addWidget(self.gSelector)

        self.sSelector = QListWidget()
        self.mLayout.addWidget(self.sSelector)

        groupBtn = QPushButton('Create group from selected')
        groupBtn.clicked.connect(self.createNewGroup)
        self.mLayout.addWidget(groupBtn)
        

    def _updateGroupList(self):
        newGroup = self.gSelector.currentItem().text()
        sStruct = self.chartData[newGroup].getColStructure()
        self.sSelector.clear()
        for ws in sStruct:
            firstChannel = sStruct[ws][0]
            isOneSignal = self.chartData[newGroup][firstChannel][ws][0]
            if isOneSignal:
                item = QListWidgetItem(ws, self.sSelector)
                item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
                item.setCheckState(Qt.Unchecked)

    def createNewGroup(self):
        checkList = []
        for i in range(self.sSelector.count()):
            sItem = self.sSelector.item(i)
            if sItem.checkState() == Qt.Checked:
                checkList.append(sItem.text())
        if len(checkList) > 0:
            groupName, result = QInputDialog().getText(self, 'Input', 'Enter group name:')
            if result:
                ws = self.gSelector.currentItem().text()
                sStruct = self.chartData[ws].getColStructure(checkList)
                sKeys = list(sStruct.keys())
                for s in range(len(sKeys)):
                    if sStruct[sKeys[s]] != sStruct[sKeys[s-1]]:
                        print('Signals have diffrent channel sets')
                        return
                self.chartData.appendSignalGroup(ws, groupName, sStruct[sKeys[0]], checkList)
            else:
                return
        else:
            return
Beispiel #2
0
class ppDiscoverWidget(QWidget, Discovery):
    DeviceChanged = Signal(ppDevice)

    def __init__(self):
        QWidget.__init__(self)
        Discovery.__init__(self, DeviceID.BEBOP_FAMILY)

        self.button = QPushButton("Refresh Devices")
        self.lst = QListWidget(self)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.lst)
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)
        self.button.clicked.connect(self.discover)
        self.lst.currentItemChanged.connect(self.on_item_changed)
        self.setFixedWidth(140)

    def add_service(self, zeroconf, type, name):
        """ Internal function for zeroconf.ServiceBrowser. """
        info = super().add_service(zeroconf, type, name)
        #        self.devices.append(info)
        item = ppDevice(info)
        self.lst.addItem(item)
        # item2=ppDevice(info)
        # self.lst.addItem(item2)
        print('[' + item.name + '-' + item.ip + ']')
        item.connect()
        item.start_stream()

    def discover(self, wd=2):
        print("searching devices...")
        self.lst.clear()
        #self.devices = []
        super().start()
        super().wait_for_change(2)
        super().stop()
        print("OK")

    def on_item_changed(self, curr, prev):
        print("switch on " + curr.name)
        self.DeviceChanged.emit(curr)

    @property
    def curentDevice(self):
        return self.lst.currentItem()
Beispiel #3
0
class H5Explorer(QDialog):  # pylint: disable=R0903
    """Dialog for selecting a dataset in an H5 file."""
    def __init__(self, items):
        QDialog.__init__(self)
        self.setWindowTitle("Select Dataset")
        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)
        self.setWindowModality(Qt.ApplicationModal)

        self.label = QLabel("Choose the dataset to load:")
        self.label.setStyleSheet("color: #000")
        self.view = QListWidget()

        for i in items:
            self.view.addItem(QListWidgetItem(i))

        self.buttons = QDialogButtonBox(QDialogButtonBox.Ok
                                        | QDialogButtonBox.Cancel)
        self.buttons.accepted.connect(self._button_ok)
        self.buttons.rejected.connect(self._button_cancel)

        layout = QVBoxLayout()
        layout.setSizeConstraint(QLayout.SetFixedSize)
        layout.addWidget(self.label)
        layout.addWidget(self.view)
        layout.addWidget(self.buttons)
        self.setLayout(layout)

    def _button_ok(self):
        self.accept()

    def _button_cancel(self):
        self.reject()

    def result(self):
        """Returns the selected element."""
        return self.view.currentItem().text()
Beispiel #4
0
class Form(QWidget):
    """"""
    def __init__(
        self,
        parent: QApplication = None,
        *,
        title: str = "wooo",
        width: int = 400,
        height: int = 600,
    ) -> None:
        """Constructor"""
        super().__init__(parent)
        mixer.init()  # initializethe pygame mixer

        self.assets_path: str = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'assets')

        if parent is not None:
            self.parent = parent
        """
        self.parent.iconbitmap()
        """
        horiz_pos = 100  # from left of screen
        vertic_pos = 200  # from top of screen
        self.height = height
        self.width = width
        self.title = title

        self.setGeometry(horiz_pos, vertic_pos, self.width,
                         self.height)  # QtCore.QRect(x, y, w, h)
        self.setWindowTitle(self.title)

        self.setWindowIcon(QtGui.QIcon(self.assets_path + '/icons/melody.ico'))
        self.init_vol: int = 70
        self.paused: bool = False
        self.muted: bool = False
        self.playing: bool = False
        self.current_song: Opt[str] = None
        self.selected_song_num: Opt[int] = None
        self.playlist: List[str] = []

        self._init_ui()
        self.show()

    def _init_ui(self) -> None:
        self.layout = QVBoxLayout()
        self._menubar()

        self._create_rightframe()
        self._create_middleframe()
        self._create_leftframe()
        self._create_bottomframe()

        self.edit = QLineEdit("Write my name here")
        self.layout.addWidget(self.edit)

        self.greet_button = QPushButton("Show Greetings")
        self.greet_button.clicked.connect(self.greetings)
        self.layout.addWidget(self.greet_button)

        self._statusbar()
        self.setLayout(self.layout)

    def _menubar(self) -> None:
        menubar = QMenuBar()
        self.layout.addWidget(menubar)

        fileMenu = menubar.addMenu('File')
        fileMenu.addAction('Open', self.browse_file)
        fileMenu.addSeparator()
        fileMenu.addAction('Exit', self.close)

        helpMenu = menubar.addMenu('Help')
        helpMenu.addSeparator()
        helpMenu.addAction('About Us', self.about_us)
        # toolbar = self.addToolBar('Exit')
        # toolbar.addAction(self.play_music)

    def _statusbar(self) -> None:
        self.statusbar = QStatusBar()
        self.layout.addWidget(self.statusbar)
        self.statusbar.showMessage('Welcome', timeout=10_000)
        # status_bar = statusbar_parent.addPermanentWidget(statusbar_parent, stretch=True)

    def _create_rightframe(self) -> None:
        self.rightframe = QVBoxLayout()
        self.layout.addLayout(self.rightframe)

        self.filelabel = QLabel(text='Lets make some noise!')
        self.rightframe.addWidget(self.filelabel)

        self.lengthlabel = QLabel(text='Total Length : --:--')
        self.rightframe.addWidget(self.lengthlabel)

        self.currenttimelabel = QLabel(text='Current Time : --:--')
        self.rightframe.addWidget(self.currenttimelabel)

    def _create_leftframe(self) -> None:
        self.leftframe = QVBoxLayout()
        self.layout.addLayout(self.leftframe)

        self.playlistbox = QListWidget(self)
        self.playlistbox.setToolTip('''PlayListBox:
                                    Select song from list to play.
                                    Use browse or delete buttons to change playlist'''
                                    )
        self.leftframe.addWidget(self.playlistbox)

        self.browse_button = QPushButton("Browse")
        self.browse_button.clicked.connect(self.browse_file)
        self.leftframe.addWidget(self.browse_button)

        self.delete_button = QPushButton("Delete")
        self.delete_button.clicked.connect(self.del_song)
        self.leftframe.addWidget(self.delete_button)

    def _create_middleframe(self) -> None:
        self.middleframe = QVBoxLayout()
        self.layout.addLayout(self.middleframe)

        self.play_button = QPushButton("Play")
        self.play_button.clicked.connect(self.play_music)
        play_icon = QtGui.QIcon(
            QtGui.QPixmap(self.assets_path + '/icons/play.png'))
        # play_icon.addPixmap(QtGui.QPixmap(self.assets_path + '/icons/play.png'))
        self.play_button.setIcon(play_icon)
        # self.play_button.setIconSize(QtCore.QSize(100, 100))
        self.middleframe.addWidget(self.play_button)

        self.stop_button = QPushButton("Stop")
        self.stop_button.clicked.connect(self.stop_music)
        stop_icon = QtGui.QIcon(
            QtGui.QPixmap(self.assets_path + '/icons/stop.png'))
        self.stop_button.setIcon(stop_icon)
        # self.stop_button.setIconSize(QtCore.QSize(100, 100))
        self.middleframe.addWidget(self.stop_button)

        self.pause_button = QPushButton("Pause")
        self.pause_button.clicked.connect(self.pause_music)
        pause_icon = QtGui.QIcon(
            QtGui.QPixmap(self.assets_path + '/icons/pause.png'))
        self.pause_button.setIcon(pause_icon)
        # self.pause_button.setIconSize(QtCore.QSize(100, 100))
        self.middleframe.addWidget(self.pause_button)

    def _create_bottomframe(self) -> None:
        self.bottomframe = QVBoxLayout()
        self.layout.addLayout(self.bottomframe)

        self.volume_button = QPushButton("Mute")
        self.mute_icon = QtGui.QIcon(
            QtGui.QPixmap(self.assets_path + '/icons/mute.png'))
        self.volume_icon = QtGui.QIcon(
            QtGui.QPixmap(self.assets_path + '/icons/volume.png'))
        self.volume_button.setIcon(self.volume_icon)
        # self.volume_button.setIconSize(QtCore.QSize(100, 100))
        self.volume_button.clicked.connect(self.mute_music)
        self.bottomframe.addWidget(self.volume_button)

        self.rewind_button = QPushButton("Rewind")
        rewind_icon = QtGui.QIcon(
            QtGui.QPixmap(self.assets_path + '/icons/rewind.png'))
        self.rewind_button.setIcon(rewind_icon)
        # self.volume_button.setIconSize(QtCore.QSize(100, 100))
        self.play_button.clicked.connect(self.rewind_music)
        self.bottomframe.addWidget(self.rewind_button)

        self.vol_scale = QSlider(QtCore.Qt.Horizontal)
        self.vol_scale.setMinimum(0)
        self.vol_scale.setMaximum(100)
        # self.vol_scale.setTickPosition(QSlider.TicksBelow)
        # self.vol_scale.setTickInterval(5)
        self.vol_scale.setValue(self.init_vol)
        self.vol_scale.valueChanged.connect(self.set_vol)
        self.bottomframe.addWidget(self.vol_scale)
        mixer.music.set_volume(self.vol_scale.value())

        # exitAction = QtGui.QAction('Exit', self)
        # exitAction.setShortcut('Ctrl+Q')
        # exitAction.setStatusTip('Exit application')
        # exitAction.triggered.connect(self.close)

    def set_vol(self) -> None:
        self.vol_from_slider: int = self.vol_scale.value()
        volume_percent: float = self.vol_from_slider / 100
        mixer.music.set_volume(volume_percent)  # from 0 to 1

    def mute_music(self) -> None:
        if self.muted:  # Unmute the music
            mixer.music.set_volume(self.vol_pre_mute / 100)
            self.volume_button.setIcon(self.volume_icon)
            self.vol_scale.setValue(
                self.vol_pre_mute)  # (self.vol_from_slider)
            self.muted = False
        else:  # mute the music
            self.vol_pre_mute: int = self.vol_scale.value()
            mixer.music.set_volume(0)
            self.volume_button.setIcon(self.mute_icon)
            self.vol_scale.setValue(0)
            self.muted = True

    def greetings(self) -> None:
        text = self.edit.text()
        print('Contents of QLineEdit widget: {}'.format(text))
        self.statusbar.showMessage(text, timeout=2_000)

    def about_us(self) -> None:
        text = self.edit.text()
        print('Contents of QLineEdit widget: {}'.format(text))

    def browse_file(self) -> None:
        get_filename_path: Tuple[str, str] = QFileDialog.getOpenFileName(
            self,  # if cancelled, returns ("", "")
            "Open Sound File",
            self.assets_path,
            "Sound Files (*.wav *.mp3 *.ogg)")
        print(get_filename_path)
        filename_path = get_filename_path[0]
        if filename_path:
            self.add_to_playlist(filename_path)
            mixer.music.queue(filename_path)

    def add_to_playlist(self, filepath: str) -> None:
        filename = os.path.basename(filepath)
        index = 0
        # print(self.playlist)
        # QListWidgetItem(self.playlistbox).setText(filename)  # last_added =
        self.playlistbox.insertItem(index, filename)  # .addItems([filenames])
        self.playlist.insert(index, filepath)
        index += 1

    def del_song(self) -> None:
        self.get_selected_song_num()  # update self.selected_song_num
        if self.selected_song_num is not None:  # if a song is selected
            print(self.selected_song_num)
            if self.playlist[
                    self.
                    selected_song_num] == self.current_song:  # if song is currently playing
                self.stop_music()  # stop it
            self.playlistbox.takeItem(
                self.selected_song_num
            )  # remove the song from the box, note returns the song object
            self.playlist.pop(self.selected_song_num)  # and playlist
            # self.selected_song_num remains same, so will play/del next song?
            self.reset_song()
            self.statusbar.showMessage("Song removed from playlist",
                                       timeout=1_000)
            self.selected_song_num = None  # reset self.selected_song_num"""

    def get_selected_song_num(self) -> None:
        if self.playlistbox.count() > 0:
            selected_song_from_box = self.playlistbox.currentItem(
            )  # get current item
            if selected_song_from_box:
                self.selected_song: str = selected_song_from_box.text(
                )  # get items text
                self.selected_song_num = self.playlistbox.currentRow()
            else:
                self.statusbar.showMessage("Choose a file from the playlist",
                                           timeout=2_000)
        else:
            self.statusbar.showMessage("No files loaded to playlist",
                                       timeout=2_000)

    def stop_music(self) -> None:
        if self.playing:
            self.playing = False
            self.current_song = None
            mixer.music.stop()
            self.statusbar.showMessage("Music Stopped", timeout=5_000)

    def pause_music(self) -> None:
        if self.playing:
            self.paused = True
            mixer.music.pause()
            self.statusbar.showMessage("Music paused", timeout=0)

    def rewind_music(self) -> None:
        if self.playing:
            self.stop_music()
            time.sleep(0.5)
            self.play_music()
            self.statusbar.showMessage("Music Rewound to start", timeout=1_000)

    def reset_song(self) -> None:
        self.current_song = None
        self.filelabel.setText("")
        self.lengthlabel.setText('Total Length : --:00')
        self.currenttimelabel.setText("Current Time : --:--")
        # self.statusbar.showMessage("", timeout=0)

    def show_details(self, play_song: str) -> None:
        self.filelabel.setText("Playing" + ' - ' + os.path.basename(play_song))
        file_data = os.path.splitext(play_song)

        if file_data[1] == '.mp3':
            audio = MP3(play_song)
            total_length = audio.info.length
        elif file_data[1] == '.wav':
            a = mixer.Sound(play_song)
            total_length = a.get_length()
        else:
            try:
                a = mixer.Sound(play_song)
                total_length = a.get_length()
            except Exception as e:
                print(e)
        self.current_song_lenth = total_length
        mins, secs = divmod(total_length, 60)  # returns (time//60, remainder)
        mins = round(mins)
        secs = round(secs)
        timeformat = '{:02d}:{:02d}'.format(mins, secs)
        self.lengthlabel.setText("Total Length" + ' - ' + timeformat)

        self.t1 = threading.Thread(target=self.start_count,
                                   args=(total_length, ))
        self.t1.start()

    def start_count(self, total_time: int) -> None:
        """"""
        current_time = 0
        while current_time <= total_time and mixer.music.get_busy(
        ):  # music.get_busy() -> Returns False when stopped
            if self.paused:
                continue  # if paused, infinite loop (don't count)
            else:
                mins, secs = divmod(current_time, 60)
                mins = round(mins)
                secs = round(secs)
                timeformat = '{:02d}:{:02d}'.format(mins, secs)
                self.currenttimelabel.setText("Current Time" + ' - ' +
                                              timeformat)
                time.sleep(1)
                current_time += 1

    def play_music(self) -> None:
        '''if not playing: play, if playing and paused, unpause'''
        self.get_selected_song_num()  # update self.selected_song_num
        if self.selected_song_num is not None and self.playlist:
            play_it: Opt[str] = self.playlist[self.selected_song_num]
        else:
            play_it = None

        if not self.playing and play_it:  # if not yet playing, play selected song
            try:
                self.stop_music()
                time.sleep(0.5)
                mixer.music.load(play_it)
                mixer.music.play()
            except Exception as e:
                # messagebox.showerror('File not found, or unknown file type. Please check again.')
                if DEBUG: print(e)
            else:
                self.playing = True
                self.current_song = play_it
                self.show_details(play_it)
                self.statusbar.showMessage("Playing music" + ' - ' +
                                           os.path.basename(play_it))
        elif self.playing and self.paused:  # if paused, resume
            mixer.music.unpause()
            # self.statusbar.showMessage("Playing music" + ' - ' + os.path.basename(play_it))
            self.statusbar.showMessage("Music Resumed", timeout=1_000)
            self.paused = False
        elif self.playing and not self.paused:
            if play_it == self.current_song and play_it is not None:  # if already playing song, do nothing
                self.statusbar.showMessage(
                    "Playing music" + ' - ' + os.path.basename(play_it),
                    timeout=0)  # TODO timout current song len
            else:  # if different song selected, retry
                self.playing = False
                self.play_music()

    def close(self) -> None:
        try:
            self.stop_music()
            QApplication.closeAllWindows()
        except Exception as e:
            sys.exit(1)
            if DEBUG: print(e)
        else:
            print('App closed')
class ReportListComponent(QGroupBox):
    currentAnalysisChanged = Signal(object)

    def __init__(self):
        super().__init__()

        self.setTitle("Rapports disponibles")

        main_layout = QVBoxLayout(self)
        self._list = QListWidget()
        self._list.setContextMenuPolicy(Qt.CustomContextMenu)
        self._list.customContextMenuRequested.connect(self._showItemMenu)
        self._list.currentRowChanged.connect(self._currentAnalysisChanged)
        self._list.itemDoubleClicked.connect(lambda item: self._renameItem())

        self._analysis = None

        main_layout.addWidget(self._list)

    def reset(self, analysis: Analysis):
        self._current_analysis_file = None
        self._analysis = analysis

        self._list.clear()
        for analysis in HistoryManager.analysisList():
            item = QListWidgetItem("%s (%s)" % (analysis["name"], analysis["date"]))
            item.setData(Qt.UserRole, analysis["file"])
            item.setData(Qt.UserRole + 1, analysis["name"])
            self._list.addItem(item)
        
        self._list.setCurrentRow(0)

    @Slot(int)
    def _currentAnalysisChanged(self, row: int):
        if row < 0:
            return
        
        new_analysis_file = self._list.item(row).data(Qt.UserRole)

        if self._current_analysis_file == new_analysis_file:
            return

        if self._current_analysis_file is None:
            self._current_analysis_file = new_analysis_file
            return

        self._current_analysis_file = new_analysis_file
        self._analysis = HistoryManager.loadAnalysis(new_analysis_file)
        self.currentAnalysisChanged.emit(self._analysis)

    @Slot(QPoint)
    def _showItemMenu(self, pos: QPoint):
        globalPos = self._list.mapToGlobal(pos)

        actions_menu = QMenu()
        actions_menu.addAction("Renommer", self._renameItem)
        actions_menu.addAction("Supprimer",  self._eraseItem)

        actions_menu.exec_(globalPos)

    @Slot()
    def _renameItem(self):
        item = self._list.currentItem()
        
        input_dialog = QInputDialog(self.parentWidget(), Qt.WindowSystemMenuHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint)
        font = input_dialog.font()
        font.setPixelSize(16)
        input_dialog.setFont(font)
        input_dialog.setMinimumWidth(300)
        input_dialog.setInputMode(QInputDialog.TextInput)
        input_dialog.setWindowTitle("Renommer l'analyse")
        input_dialog.setLabelText("Nouveau nom pour '%s' :" % item.data(Qt.UserRole + 1))
        input_dialog.setTextValue(item.data(Qt.UserRole + 1))
        input_dialog.setOkButtonText("OK")
        input_dialog.setCancelButtonText("Annuler")

        if not input_dialog.exec_():
            return
        
        new_name = input_dialog.textValue()

        if self._analysis is None:
            return

        if new_name == self._analysis.parameters().name():
            return
        
        regexp = QRegExp("^[a-zA-Z0-9_-#éèêëàîï ]{5,30}$")
        
        if not regexp.exactMatch(new_name):
            QMessageBox.warning(self, "Nouveau nom invalide", "Caractères autorisés : alphanumérique, espace, #, - et _ avec une longueur maximale de 30 caractères")
            return


        self._analysis.parameters().setName(new_name)
        HistoryManager.renameAnalysis(item.data(Qt.UserRole), self._analysis)
        
        current_row = self._list.currentRow()
        self.reset(self._analysis)
        self._list.setCurrentRow(current_row)
        self.currentAnalysisChanged.emit(self._analysis)

    @Slot()
    def _eraseItem(self):
        item = self._list.currentItem()

        message_box = QMessageBox()
        message_box.setIcon(QMessageBox.Warning)
        message_box.setWindowTitle("Supprimer une analyse ?")
        message_box.setText("Voulez vous vraiment supprimer l'analyse '%s' de façon définitive ?" % item.data(Qt.UserRole + 1))
        message_box.setInformativeText("Assurez vous d'avoir exportez toutes les données dont vous avez besoin.")
        message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)

        ret = message_box.exec_()
        if ret == QMessageBox.Yes:
            HistoryManager.deleteAnalysis(item.data(Qt.UserRole))
            self._list.takeItem(self._list.currentRow())

        if self._list.currentRow() == -1:
            self.currentAnalysisChanged.emit(None)
Beispiel #6
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]
Beispiel #7
0
class SpecifySearchConditionsDialog(BaseDialog):
    def __init__(self, parent, entity):
        super().__init__(parent, _("Search criteria"), _("&Start search"),
                         _("&Cancel"))
        self._entity = entity
        self._value_widget = None
        self._value_label = None
        self._search_expression_parts = []
        self._added_condition = False
        self._populate_fields_tree(self._entity)

    def create_ui(self):
        fields_label = QLabel(_("Class fields"), self)
        self.layout.addWidget(fields_label, 0, 0)
        self._fields_tree = QTreeWidget(self)
        fields_label.setBuddy(self._fields_tree)
        self._fields_tree.currentItemChanged.connect(
            self.on_fields_tree_sel_changed)
        self.layout.addWidget(self._fields_tree, 1, 0)
        operator_label = QLabel(_("Operator"), self)
        self.layout.addWidget(operator_label, 0, 1)
        self._operator = QListWidget(self)
        operator_label.setBuddy(self._operator)
        self.layout.addWidget(self._operator, 1, 1)
        self._operator.currentRowChanged.connect(self.on_operator_choice)
        self._operator.setCurrentRow(0)
        add_button = QPushButton(_("&Add condition"), self)
        add_button.clicked.connect(self.on_add_clicked)
        self.layout.addWidget(add_button, 2, 0, 1, 3)
        criteria_label = QLabel(_("Current search criteria"), self)
        self.layout.addWidget(criteria_label, 3, 0, 1, 3)
        self._criteria_list = QListWidget(self)
        criteria_label.setBuddy(self._criteria_list)
        self.layout.addWidget(self._criteria_list, 4, 0, 1, 3)
        remove_button = QPushButton(_("&Remove condition"), self)
        remove_button.clicked.connect(self.on_remove_clicked)
        self.layout.addWidget(remove_button, 5, 0, 1, 3)
        distance_label = QLabel(_("Search objects to distance"), self)
        self.layout.addWidget(distance_label, 6, 0)
        self._distance_field = QSpinBox(self)
        self._distance_field.setMaximum(100000)
        self._distance_field.setSuffix(" " + _("meters"))
        self._distance_field.setSpecialValueText(_("No limit"))
        distance_label.setBuddy(self._distance_field)
        self.layout.addWidget(self._distance_field, 6, 1)

    def _populate_fields_tree(self, entity, parent=None):
        if parent is None:
            parent = self._fields_tree.invisibleRootItem()
        metadata = EntityMetadata.for_discriminator(entity)
        for field_name, field in sorted(
                metadata.all_fields.items(),
                key=lambda i: underscored_to_words(i[0])):
            child_metadata = None
            try:
                child_metadata = EntityMetadata.for_discriminator(
                    field.type_name)
            except KeyError:
                pass
            if child_metadata:
                name = get_class_display_name(field.type_name)
                subparent = QTreeWidgetItem([name])
                subparent.setData(0, Qt.UserRole, field_name)
                parent.addChild(subparent)
                self._populate_fields_tree(field.type_name, subparent)
            else:
                item = QTreeWidgetItem([underscored_to_words(field_name)])
                item.setData(0, Qt.UserRole, (field_name, field))
                parent.addChild(item)

    def on_fields_tree_sel_changed(self, item):
        data = item.data(0, Qt.UserRole)
        if data is not None and not isinstance(data, str):
            self._field_name = data[0]
            self._field = data[1]
            self._operators = operators_for_column_class(self._field.type_name)
            self._operator.clear()
            self._operator.addItems([o.label for o in self._operators])
            self._added_condition = False

    def on_operator_choice(self, index):
        self._added_condition = False
        if self._value_widget:
            self.layout.removeWidget(self._value_widget)
            self._value_widget.deleteLater()
        if self._value_label:
            self.layout.removeWidget(self._value_label)
            self._value_label.deleteLater()
            self._value_label = None
        operator = self._operators[self._operator.currentRow()]
        value_label = self._create_value_label(
            operator.get_value_label(self._field))
        self._value_widget = operator.get_value_widget(self, self._field)
        if not self._value_widget:
            return
        QWidget.setTabOrder(self._operator, self._value_widget)
        self._value_label = value_label
        if self._value_label:
            self._value_label.setBuddy(self._value_widget)
            self.layout.addWidget(self._value_label, 0, 2)
        self.layout.addWidget(self._value_widget, 1, 2)

    def _create_value_label(self, label):
        if not label:
            return
        label = QLabel(label, self)
        return label

    def on_add_clicked(self, evt):
        if not hasattr(self, "_field_name"):
            return
        self._added_condition = True
        json_path = []
        parent_item = self._fields_tree.currentItem().parent()
        parent_data = parent_item.data(0, Qt.UserRole) if parent_item else None
        if isinstance(parent_data, str):
            json_path.append(parent_data)
        json_path.append(self._field_name)
        json_path = ".".join(json_path)
        operator_obj = self._operators[self._operator.currentRow()]
        expression = operator_obj.get_comparison_expression(
            self._field, FieldNamed(json_path), self._value_widget)
        self._search_expression_parts.append(expression)
        self._criteria_list.addItem(
            f"{underscored_to_words(self._field_name)} {operator_obj.label} {operator_obj.get_value_as_string(self._field, self._value_widget)}"
        )

    @property
    def distance(self):
        return self._distance_field.value()

    def create_conditions(self):
        conditions = []
        if self._search_expression_parts:
            for part in self._search_expression_parts:
                conditions.append(part)
        return conditions

    def on_remove_clicked(self, evt):
        selection = self._criteria_list.currentRow()
        if selection < 0:
            return
        del self._search_expression_parts[selection]
        self._criteria_list.removeItemWidget(self._criteria_list.currentItem())

    def ok_clicked(self):
        if not self._added_condition:
            if QMessageBox.question(
                    self, _("Question"),
                    _("It appears that you forgot to add the current condition to the conditions list. Do you want to add it before starting the search?"
                      )):
                self.on_add_clicked(None)
        super().ok_clicked()
Beispiel #8
0
class EditCommentBankWindow(QMainWindow):
    def __init__(self, subject_name):
        QMainWindow.__init__(self)
        self.setWindowTitle("Edit Comment Bank: {} - {} {}".format(
            subject_name, config.APP_NAME, config.APP_VERSION))
        self.setMinimumWidth(1200)
        self.setStyleSheet(config.STYLESHEET)

        self.subject = could_try_harder.load(subject_name)
        self.saved_list = could_try_harder.get_saved_list()

        # Widgets
        self.intro_comment_label = QLabel("Introductory Comment:")
        self.intro_comment_label.setProperty("styleClass", "heading")
        self.intro_comment_textedit = QTextEdit()
        self.comment_bank_label = QLabel("Comment Bank")
        self.comment_bank_label.setProperty("styleClass", "heading")
        self.comment_bank_listwidget = QListWidget()
        self.placeholder_instructions_label = QLabel(
            config.PLACEHOLDER_INSTRUCTIONS)
        self.add_comment_label = QLabel("Add Comment:")
        self.add_comment_entry = QLineEdit()
        self.add_comment_button = QPushButton("Add")
        self.update_comment_label = QLabel("Update Comment:")
        self.update_comment_entry = QLineEdit()
        self.update_comment_button = QPushButton("Update")
        self.delete_comment_button = QPushButton("Delete Comment")
        self.import_comments_combo = QComboBox()
        self.import_comments_button = QPushButton("Import...")
        self.cancel_button = QPushButton("Cancel")
        self.save_button = QPushButton("Save")

        # Layout
        self.layout = QVBoxLayout()
        self.top_layout = QHBoxLayout()
        self.intro_comment_layout = QVBoxLayout()
        self.intro_comment_layout.addWidget(self.intro_comment_label)
        self.intro_comment_layout.addWidget(self.intro_comment_textedit)
        self.top_layout.addLayout(self.intro_comment_layout)
        self.top_layout.addWidget(self.placeholder_instructions_label)
        self.layout.addLayout(self.top_layout)
        self.middle_layout = QVBoxLayout()
        self.middle_layout.addWidget(self.comment_bank_label)
        self.middle_layout.addWidget(self.comment_bank_listwidget)
        self.comment_actions_layout = QHBoxLayout()
        self.comment_actions_layout.addWidget(self.delete_comment_button, 0,
                                              Qt.AlignLeft)
        self.comment_actions_layout.addWidget(self.import_comments_combo, 1,
                                              Qt.AlignRight)
        self.comment_actions_layout.addWidget(self.import_comments_button, 0,
                                              Qt.AlignRight)
        self.middle_layout.addLayout(self.comment_actions_layout)
        self.update_comment_layout = QGridLayout()
        self.update_comment_layout.addWidget(self.update_comment_label, 0, 0)
        self.update_comment_layout.addWidget(self.update_comment_entry, 0, 1)
        self.update_comment_layout.addWidget(self.update_comment_button, 0, 2)
        self.update_comment_layout.addWidget(self.add_comment_label, 1, 0)
        self.update_comment_layout.addWidget(self.add_comment_entry, 1, 1)
        self.update_comment_layout.addWidget(self.add_comment_button, 1, 2)
        self.middle_layout.addLayout(self.update_comment_layout)
        self.layout.addLayout(self.middle_layout)
        self.bottom_layout = QHBoxLayout()
        self.bottom_layout.addWidget(self.cancel_button, 0, Qt.AlignLeft)
        self.bottom_layout.addWidget(self.save_button, 0, Qt.AlignRight)
        self.layout.addLayout(self.bottom_layout)

        # Slot connections
        self.comment_bank_listwidget.itemSelectionChanged.connect(
            self.do_update_comment_bank_selection)
        self.import_comments_button.clicked.connect(self.do_import_comments)
        self.update_comment_button.clicked.connect(self.do_update_comment)
        self.update_comment_entry.returnPressed.connect(self.do_update_comment)
        self.add_comment_button.clicked.connect(self.do_add_comment)
        self.add_comment_entry.returnPressed.connect(self.do_add_comment)
        self.delete_comment_button.clicked.connect(self.do_delete_comment)
        self.cancel_button.clicked.connect(self.do_cancel)
        self.save_button.clicked.connect(self.do_save)

        # Initial UI update
        self.update_ui()

        self.widget = QWidget()
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

    def update_ui(self):
        self.update_import_comments_list()
        self.update_intro_comment()
        self.update_comment_bank()

    def update_import_comments_list(self):
        self.import_comments_combo.clear()
        self.import_comments_combo.insertItems(0, self.saved_list)

    def update_intro_comment(self):
        self.intro_comment_textedit.clear()
        self.intro_comment_textedit.insertPlainText(
            self.subject['intro_comment'])

    def update_comment_bank(self):
        self.comment_bank_listwidget.clear()
        self.comment_bank_listwidget.addItems(self.subject['comment_bank'])
        self.do_update_comment_bank_selection()

    @Slot()
    def do_import_comments(self):
        # TODO confirm dialog first
        confirm_msg = QMessageBox(self)
        confirm_msg.setWindowTitle("Confirm")
        confirm_msg.setText("This will override current comments.")
        confirm_msg.setInformativeText("Do you want to continue?")
        confirm_msg.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
        confirm_msg.setDefaultButton(QMessageBox.Yes)
        confirm = confirm_msg.exec()
        if confirm == QMessageBox.Yes:
            if self.import_comments_combo.count() > 0:
                new_subject = could_try_harder.load(
                    self.import_comments_combo.currentText())
                if new_subject:
                    self.subject['intro_comment'] = new_subject[
                        'intro_comment']
                    self.subject['comment_bank'] = new_subject['comment_bank']
                    self.update_ui()
                else:
                    # TODO better error handling here
                    print('Tried to import empty subject.')
                    return
        return

    @Slot()
    def do_update_comment_bank_selection(self):
        if self.comment_bank_listwidget.selectedItems():
            state = True
        else:
            state = False
        self.delete_comment_button.setEnabled(state)
        self.update_comment_button.setEnabled(state)
        # Update the text in the update comment line edit
        self.update_comment_entry.clear()
        if self.comment_bank_listwidget.currentItem():
            self.update_comment_entry.insert(
                self.comment_bank_listwidget.currentItem().text())

    @Slot()
    def do_update_comment(self):
        if self.update_comment_entry.text():
            self.comment_bank_listwidget.currentItem().setText(
                could_try_harder.do_style(
                    self.update_comment_entry.text().strip()))
            self.do_update_comment_bank_selection()

    @Slot()
    def do_add_comment(self):
        if self.add_comment_entry.text():
            self.comment_bank_listwidget.addItem(
                could_try_harder.do_style(
                    self.add_comment_entry.text().strip()))
            self.add_comment_entry.clear()
            self.do_update_comment_bank_selection()

    @Slot()
    def do_delete_comment(self):
        self.comment_bank_listwidget.takeItem(
            self.comment_bank_listwidget.currentRow())
        self.do_update_comment_bank_selection()

    @Slot()
    def do_cancel(self):
        self.close()

    @Slot()
    def do_save(self):
        self.subject['intro_comment'] = could_try_harder.do_style(
            self.intro_comment_textedit.toPlainText().strip())
        self.subject['comment_bank'] = []
        for i in range(self.comment_bank_listwidget.count()):
            self.subject['comment_bank'].append(
                self.comment_bank_listwidget.item(i).text())
        if could_try_harder.save(self.subject):
            self.close()
        else:
            # TODO better error handling here
            print("Save failed.")
Beispiel #9
0
class EditReportsWindow(QMainWindow):
    def __init__(self, subject_name):
        QMainWindow.__init__(self)
        self.setWindowTitle("Edit Reports: {} - {} {}".format(
            subject_name, config.APP_NAME, config.APP_VERSION))
        self.setMinimumWidth(1200)
        self.setStyleSheet(config.STYLESHEET)

        self.subject = could_try_harder.load(subject_name)
        self.student = {}

        # Used to keep track of current student
        self.s_index = 0
        self.load_student()

        # Widgets
        self.previous_student_button = QPushButton("Previous Student")
        self.student_name_label = QLabel()
        self.student_name_label.setProperty("styleClass", "title")
        self.next_student_button = QPushButton("Next Student")
        self.intro_comment_label = QLabel("Introductory Comment")
        self.intro_comment_label.setProperty("styleClass", "heading")
        self.intro_comment = QLabel()
        self.comment_bank_label = QLabel("Comment Bank")
        self.comment_bank_label.setProperty("styleClass", "heading")
        self.comment_bank_listwidget = QListWidget()
        self.add_comment_button = QPushButton("Add Selected Comment")
        self.comment_label = QLabel("Student Comment")
        self.comment_label.setProperty("styleClass", "heading")
        self.comment_textedit = QTextEdit()
        self.cancel_button = QPushButton("Cancel")
        self.save_button = QPushButton("Save")

        # Layout
        self.layout = QVBoxLayout()
        self.top_layout = QHBoxLayout()
        self.top_layout.addWidget(self.previous_student_button, 0,
                                  Qt.AlignLeft)
        self.top_layout.addWidget(self.student_name_label, 1, Qt.AlignCenter)
        self.top_layout.addWidget(self.next_student_button, 0, Qt.AlignRight)
        self.layout.addLayout(self.top_layout)
        self.middle_layout = QVBoxLayout()
        self.middle_layout.addWidget(self.intro_comment_label)
        self.middle_layout.addWidget(self.intro_comment)
        self.middle_layout.addWidget(self.comment_bank_label)
        self.middle_layout.addWidget(self.comment_bank_listwidget)
        self.middle_layout.addWidget(self.add_comment_button)
        self.middle_layout.addWidget(self.comment_label)
        self.middle_layout.addWidget(self.comment_textedit)
        self.layout.addLayout(self.middle_layout)
        self.bottom_layout = QHBoxLayout()
        self.bottom_layout.addWidget(self.cancel_button, 0, Qt.AlignLeft)
        self.bottom_layout.addWidget(self.save_button, 0, Qt.AlignRight)
        self.layout.addLayout(self.bottom_layout)

        # Slots
        self.previous_student_button.clicked.connect(self.do_previous_student)
        self.next_student_button.clicked.connect(self.do_next_student)
        self.comment_bank_listwidget.itemSelectionChanged.connect(
            self.do_update_comment_bank_selection)
        self.add_comment_button.clicked.connect(self.do_add_comment)
        self.cancel_button.clicked.connect(self.do_cancel)
        self.save_button.clicked.connect(self.do_save)

        # Initial UI Update
        self.update_ui()

        self.widget = QWidget()
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

    def update_ui(self):
        # Page title
        self.student_name_label.setText(self.student['first_name'] + " " +
                                        self.student['last_name'])

        # Enable/Disabled Next/Previous Buttons
        if self.s_index <= 0:
            self.previous_student_button.setEnabled(False)
        else:
            self.previous_student_button.setEnabled(True)
        if self.s_index < len(self.subject['students']) - 1:
            self.next_student_button.setEnabled(True)
        else:
            self.next_student_button.setEnabled(False)

        self.do_update_comment_bank_selection()

        # Intro comment
        self.intro_comment.setText(
            could_try_harder.do_placeholders(self.subject['intro_comment'],
                                             self.student['first_name'],
                                             self.student['pronouns']))

        # Comment Bank
        self.comment_bank_listwidget.clear()
        for comment in self.subject['comment_bank']:
            self.comment_bank_listwidget.addItem(
                could_try_harder.do_placeholders(comment,
                                                 self.student['first_name'],
                                                 self.student['pronouns']))

        # Student Comment
        self.comment_textedit.clear()
        self.comment_textedit.insertPlainText(self.student['comment'])

    def load_student(self):
        """
        Loads student into the self.student dict temporarily
        """
        self.student = self.subject['students'][self.s_index]

    def save_comment(self):
        """
        Saves student comment into the self.subject dict temporarily. Not saved into the save file.
        """
        comment = self.comment_textedit.toPlainText()
        comment = could_try_harder.do_placeholders(comment,
                                                   self.student['first_name'],
                                                   self.student['pronouns'])
        comment = could_try_harder.do_style(comment)

        self.subject['students'][self.s_index]['comment'] = comment

    @Slot()
    def do_next_student(self):
        if self.s_index < len(self.subject['students']) - 1:
            self.save_comment()
            self.s_index += 1
            self.load_student()
            self.update_ui()

    @Slot()
    def do_previous_student(self):
        if self.s_index > 0:
            self.save_comment()
            self.s_index -= 1
            self.load_student()
            self.update_ui()

    @Slot()
    def do_update_comment_bank_selection(self):
        # Enable/Disable the Add Comment button
        if self.comment_bank_listwidget.selectedItems():
            self.add_comment_button.setEnabled(True)
        else:
            self.add_comment_button.setEnabled(False)

    @Slot()
    def do_add_comment(self):
        # Add a space if we need to.
        if not self.comment_textedit.textCursor().atStart(
        ) and not self.comment_textedit.textCursor().block().text().endswith(
                " "):
            self.comment_textedit.insertPlainText(" ")
        self.comment_textedit.insertPlainText(
            self.comment_bank_listwidget.currentItem().text())

    @Slot()
    def do_save(self):
        self.save_comment()
        if could_try_harder.save(self.subject):
            self.close()
        else:
            # TODO better error handling here
            print("Save failed")

    @Slot()
    def do_cancel(self):
        self.close()
Beispiel #10
0
class ProjectSwitcher(QDialog):
    def __init__(self, configurationManager: ConfigurationManager,
                 projectComboBox):
        super(ProjectSwitcher, self).__init__()
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Window)
        self.configurationManager = configurationManager
        self.projectComboBox = projectComboBox
        self.latestProjectIndex = -1
        self.setStyleSheet("background-color: #232323; color: white;")
        self.projectList = QListWidget()
        self.vbox = QVBoxLayout()
        self.pathLabel = QLabel()
        self.pathLabel.setStyleSheet("font-size: 10px; color: grey;")
        self.vbox.addWidget(QLabel("<center>Project switcher</center>"), 1)
        self.vbox.addWidget(self.projectList, 10)
        self.vbox.addWidget(self.pathLabel, 1)
        self.setLayout(self.vbox)

    def showSwitcher(self):
        self.latestProjectIndex = self.getCurrentProjectIndex()
        self.updateProjectList()
        self.updateProjectListCurrentItem(self.latestProjectIndex)
        self.setFixedSize(self.sizeHint())
        self.setFixedWidth(500)
        self.show()

    def getCurrentProjectIndex(self):
        for i in range(len(self.configurationManager.allProjects)):
            if self.configurationManager.allProjects[i].proxy.getProjectPath(
            ) == self.configurationManager.currentProject.proxy.getProjectPath(
            ):
                return i
        return -1  # should never execute

    def updateProjectList(self):
        self.projectList.clear()
        for project in self.configurationManager.allProjects:
            self.projectList.addItem(ProjectSwitcherListItem(project.proxy))

    def updateProjectListCurrentItem(self, index):
        self.projectList.setCurrentRow(index)
        projectProxy = self.projectList.currentItem().projectProxy
        self.pathLabel.setText(projectProxy.getProjectPath())

    def hideSwitcher(self):
        if self.latestProjectIndex >= -1:
            self.projectComboBox.setCurrentText(
                self.projectList.currentItem().projectProxy.path)
        self.hide()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Tab or event.key(
        ) == Qt.Key_Down or event.key() == Qt.Key_E:
            self.latestProjectIndex = (self.latestProjectIndex + 1) % len(
                self.configurationManager.allProjects)
        elif event.key() == Qt.Key_Up or event.key() == Qt.Key_Backtab:
            self.latestProjectIndex -= 1
            if self.latestProjectIndex < 0:
                self.latestProjectIndex = len(
                    self.configurationManager.allProjects) - 1
        self.updateProjectListCurrentItem(self.latestProjectIndex)

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_Backtab:
            return
        if event.modifiers() != Qt.ControlModifier:
            if self.latestProjectIndex != -1:
                self.projectComboBox.setCurrentText(
                    self.projectList.currentItem().projectProxy.path)
            self.latestProjectIndex = -1
            self.hideSwitcher()

    def focusOutEvent(self, event):
        super(ProjectSwitcher, self).focusOutEvent(event)
        self.hide()
Beispiel #11
0
class WordSetWidget(PluginWidget):
    """Plugin to show handle word sets from user and gather matching variants
    as a new selection.
    """

    ENABLE = True

    def __init__(self, parent=None):
        super().__init__(parent)
        self.conn = None
        self.set_names = list()
        self.setWindowTitle(self.tr("Word Sets"))
        self.toolbar = QToolBar()
        self.view = QListWidget()
        self.view.setIconSize(QSize(20, 20))
        self.view.itemDoubleClicked.connect(self.open_wordset)
        self.view.setSelectionMode(QAbstractItemView.ExtendedSelection)

        # setup tool bar
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.addAction(FIcon(0xF0415), self.tr("Add Word set"),
                               self.add_wordset)
        self.edit_action = self.toolbar.addAction(FIcon(0xF0DC9),
                                                  self.tr("Edit Word set"),
                                                  self.open_wordset)
        self.remove_action = self.toolbar.addAction(FIcon(0xF0A7A),
                                                    self.tr("Remove Word set"),
                                                    self.remove_wordset)
        self.edit_action.setEnabled(False)
        self.remove_action.setEnabled(False)

        v_layout = QVBoxLayout()
        v_layout.setContentsMargins(0, 0, 0, 0)
        v_layout.setSpacing(0)

        v_layout.addWidget(self.view)
        v_layout.addWidget(self.toolbar)

        self.setLayout(v_layout)

        # Item selected in view
        self.view.selectionModel().selectionChanged.connect(
            self.on_item_selected)

    def on_item_selected(self, *args):
        """Enable the remove button when an item is selected"""
        # Get list of all selected model item indexes
        if self.view.selectionModel().selectedIndexes():
            self.edit_action.setEnabled(True)
            self.remove_action.setEnabled(True)
        else:
            self.edit_action.setEnabled(False)
            self.remove_action.setEnabled(False)

    def import_wordset(self, words, wordset_name):
        """Import given words into a new wordset in database

        Warnings:
            There is NO CHECK on manual user's inputs! Except during DB insertion.

        Args:
            words(list): List of words to be inserted
            wordset_name(str): Name of the word set

        Returns:
            (boolean): Status of the wordset creation
        """
        # Dump the list in a temporary file
        _, filename = tempfile.mkstemp()
        with open(filename, "w") as file:
            [file.write(word + "\n") for word in words]

        # Import the content of the temp file in DB
        result = import_cmd(self.conn, "wordsets", wordset_name, filename)

        if not result["success"]:
            LOGGER.error(result)
            QMessageBox.critical(
                self,
                self.tr("Error while importing set"),
                self.tr("Error while importing set '%s'") % wordset_name,
            )

        os.remove(filename)
        return result["success"]

    def add_wordset(self):
        """Display a window to allow to add/edit/remove word sets

        The set is then imported in database.
        """
        dialog = WordListDialog()

        if dialog.exec_() != QDialog.Accepted:
            return

        wordset_name = None
        while not wordset_name:
            wordset_name, _ = QInputDialog.getText(
                self, self.tr("Create a new set"),
                self.tr("Name of the new set:"))
            if not wordset_name:
                return

            if wordset_name in self.set_names:
                # Name already used
                QMessageBox.critical(
                    self,
                    self.tr("Error while creating set"),
                    self.
                    tr("Error while creating set '%s'; Name is already used") %
                    wordset_name,
                )
                wordset_name = None

        # Import & update view
        self.import_wordset(dialog.model.stringList(), wordset_name)
        self.populate()

    def remove_wordset(self):
        """Delete word set from database"""
        if len(self.view.selectedItems()) == 0:
            # if selection is empty
            return

        reply = QMessageBox.question(
            self,
            self.tr("Drop word set"),
            self.tr("Are you sure you want to remove the selected set(s)?"),
            QMessageBox.Yes | QMessageBox.No,
        )
        if reply != QMessageBox.Yes:
            return

        # Delete all selected sets
        for i in self.view.selectedItems():
            result = drop_cmd(self.conn, "wordsets", i.text())

            if not result["success"]:
                LOGGER.error(result)
                QMessageBox.critical(
                    self,
                    self.tr("Error while deleting set"),
                    self.tr("Error while deleting set '%s'") % i.text(),
                )

        self.populate()

    def open_wordset(self):
        """Display a window to allow to edit the selected word set

        The previous set is dropped and the new is then imported in database.
        """
        wordset_name = self.view.currentItem().text()
        dialog = WordListDialog()

        # populate dialog
        dialog.model.setStringList(
            list(get_words_in_set(self.conn, wordset_name)))

        if dialog.exec_() == QDialog.Accepted:
            # Drop previous
            drop_cmd(self.conn, "wordsets", wordset_name)
            # Import new
            self.import_wordset(dialog.model.stringList(), wordset_name)
            self.populate()

    def on_open_project(self, conn):
        """ override """
        self.conn = conn
        self.on_refresh()

    def on_refresh(self):
        """ override """
        if self.conn:
            self.populate()

    def populate(self):
        """Actualize the list of word sets"""
        self.view.clear()
        self.set_names = list()
        for data in get_wordsets(self.conn):
            set_name = data["name"]
            item = QListWidgetItem()
            item.setText(set_name)
            item.setIcon(FIcon(0xF0A38))
            self.view.addItem(item)
            self.set_names.append(set_name)
Beispiel #12
0
class EventViewer(QDialog):
    def __init__(self, alid=0, db=0, mode=0):
        super().__init__()
        self.font = mainfont
        self.resize(1000, 600)
        layout = QGridLayout()
        self.layout = layout
        self.buttext = []
        self.dictViewer = QWidget()

        self.linedits = {}
        self.last_eid = 0
        self.photo_ids = 0
        self.QLABELM_TYPE = type(QLabelM())

        self.listWidget = QListWidget()
        self.listWidget.itemDoubleClicked.connect(self.doubleClick)
        self.listWidget.itemSelectionChanged.connect(self.itemChanged)

        self.setFont(mainfont)
        self.db = db
        self.alid = alid
        self.event_ids = db.get_all_event_ids(self.alid)
        self.photo_gallery = QLabel()
        #self.photo_gallery.setAlignment(Qt.AlignCenter)
        #self.photo_gallery.setPixmap(QPixmap('f.png').scaled(400,400,Qt.KeepAspectRatio))
        print(self.event_ids)
        if self.event_ids:
            for eid in self.event_ids:
                event = db.get_event_data(self.alid, eid)
                print(event)
                if event:
                    text = ''
                    text = event['event_head'] if type(event) == type(
                        {}) and 'event_head' in event.keys(
                        ) and event['event_head'] != '' else text
                    item = QListWidgetItem(text)
                    if type(event) == type({}) and 'eid' in event.keys():
                        item.setWhatsThis(str(event['eid']))
                    self.listWidget.addItem(item)
            if self.listWidget.count():
                self.listWidget.setCurrentRow(0)

        self.mode = mode

        def openMenu(position):
            # Создание PopupMenu
            menu = QMenu()
            if mode > 0:
                addAction = menu.addAction('Добавить событие')
                #menu.addSeparator()
                editAction = menu.addAction('Переименовать событие')
                #menu.addSeparator()
                delAction = menu.addAction('Удалить событие')
                delAllAction = menu.addAction('Удалить все события')
                menu.addSeparator()
            else:
                addAction, editAction, delAction, delAllAction = QAction(
                ), QAction(), QAction(), QAction()
            quitAction = menu.addAction('Выход')
            action = menu.exec_(self.mapToGlobal(position))

            # Привязка событий к Actions
            if action == addAction:
                text, ok = QInputDialog().getText(self, "Название события",
                                                  "Ввкдите название события:",
                                                  QLineEdit.Normal, '')
                if ok:
                    text = 'Новое событие' if text == '' else text
                    res = self.db.add_event({
                        'alid': self.alid,
                        'event_head': text
                    })
                    if len(res) == 1:
                        event = res[0]
                        text = event['event_head'] if type(event) == type(
                            {}
                        ) and 'event_head' in event.keys(
                        ) and event['event_head'] != '' else 'Новое событие'
                        item = QListWidgetItem(text)
                        item.setWhatsThis(str(event['eid']))
                        self.listWidget.addItem(item)
                        db.events.save()
                        #self.changed = True
                self.event_ids = db.get_all_event_ids(self.alid)

            if action == editAction:
                eid = self.listWidget.currentItem()
                if eid is not None:
                    eid = self.listWidget.currentItem().whatsThis()
                    last_name = self.db.get_event_data(self.alid,
                                                       eid)['event_head']
                    text, ok = QInputDialog().getText(
                        self, "Название события",
                        "Ввкдите новое название события:", QLineEdit.Normal,
                        str(last_name))
                    if ok:
                        event = self.db.edit_event({
                            'alid': self.alid,
                            'eid': eid,
                            'event_head': text
                        })
                        self.listWidget.currentItem().setText(text)
                        self.db.events.save()
                        if event:
                            event = self.db.get_event_data(alid, eid)
                            #b = layout.takeAt(1)
                            self.dictViewer.close()
                            #b.widget().deleteLater()
                            self.dictViewer = DictViewer(
                                event, 1, self.db.events.invizible_fields,
                                self.db.events.editable_fields)
                            self.layout.addWidget(self.dictViewer, 0, 2)
                    self.event_ids = db.get_all_event_ids(self.alid)

            if action == delAction:
                res = QMessageBox.question(
                    self, 'ВНИМАНИЕ!!!',
                    "Вы действительно хотите удалить событие?",
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if res == QMessageBox.Yes:
                    eid = self.listWidget.currentItem()
                    if eid is not None:
                        eid = self.listWidget.currentItem().whatsThis()
                        self.db.del_event({'alid': self.alid, 'eid': eid})
                        self.listWidget.takeItem(self.listWidget.currentRow())
                        self.db.events.save()
                        #self.changed = True
                    self.event_ids = db.get_all_event_ids(self.alid)

            if action == delAllAction:
                res = QMessageBox.question(
                    self, 'ВНИМАНИЕ!!!',
                    "Вы действительно хотите удалить все события?",
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if res == QMessageBox.Yes:
                    if self.db.del_all_events(int(self.alid)):
                        self.listWidget.clear()
                        self.db.events.save()
                        #self.changed = True
                    self.event_ids = db.get_all_event_ids(self.alid)

                    #db.photos.save()

            if action == quitAction:
                self.accept()

        self.listWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.listWidget.customContextMenuRequested.connect(openMenu)

        layout.addWidget(self.listWidget, 0, 0, 1, 1)
        layout.addWidget(self.photo_gallery, 0, 1, 1, 1)

        self.setLayout(layout)

    def doubleClick(self, item):
        if item is not None:
            eid = item.whatsThis()
            text = self.db.get_event_path(self.alid, eid)
            print(eid)

    def closeEvent(self, event):
        if self.last_eid:
            self.check_and_save(self.last_eid)

    def itemChanged(self):
        if self.last_eid:
            self.check_and_save(self.last_eid)

        eid = self.listWidget.currentItem()
        if eid is not None:
            eid = self.listWidget.currentItem().whatsThis()
            event = self.db.get_event_data(self.alid, eid)

            if self.photo_gallery:
                self.photo_gallery.close()

            # Работаем с фотками
            self.photo_gallery = QLabelM(self.alid, self.db, 1, eid)
            self.layout.addWidget(self.photo_gallery, 0, 1,
                                  int(self.db.events.nkeys / 2), 1)

            # Заполняем данными
            self.fill_event_data(event)

            print(event)
            self.last_eid = eid
        self.setFocus()
        #print('item changed = ' + str(eid))

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Left:
            #print('left pressed')
            if type(self.photo_gallery) == self.QLABELM_TYPE:
                self.photo_gallery.prev_show()
        if event.key() == Qt.Key_Right:
            #print('right pressed')
            if type(self.photo_gallery) == self.QLABELM_TYPE:
                self.photo_gallery.next_show()
        #super().keyPressEvent(event)

    def fill_event_data(self, event):
        if type(event) != type({}):
            return

        self.dictViewer.close()
        self.dictViewer = DictViewer(event, 1, self.db.events.invizible_fields,
                                     self.db.events.editable_fields)
        self.layout.addWidget(self.dictViewer, 0, 2, 1, 1)

    def check_and_save(self, eid):
        print('check_and_save' + str(eid))
        changes = self.dictViewer.get_changes()
        event = self.db.get_event_data(self.alid, eid)

        if self.photo_gallery.changed:
            changes['photo_ids'] = self.photo_gallery.photo_ids
        print(changes)
        if len(changes) > 0 and type(event) == type({}):
            print('event changes saved')
            event.update(changes)
            self.db.edit_event(event)
            self.db.events.save()
Beispiel #13
0
class ClientWindow(QDialog):

    def __init__(self):
        super(ClientWindow, self).__init__()

        self.resize(823,511)
        self.setWindowTitle('用户客户端')
        self.friendList = QListWidget()
        self.friendList.doubleClicked.connect(self.changeFriendText)
        self.friendList.clicked.connect(self.changeFriendText)
        self.portLine = QLineEdit()
        self.portLine.setText('12345')
        self.connectBtn = QPushButton('连接')
        self.connectBtn.clicked.connect(self.setupFun)
        self.messageText = QTextEdit()
        self.messageLine = QLineEdit()
        self.sendBtn = QPushButton('发送')
        self.sendBtn.clicked.connect(self.sendFun)

        self.text = ''
        self.userText = {}

        self.initUI()
        self.palette = QPalette()
        self.palette.setBrush(QPalette.Background, QBrush(QPixmap('./image/background.jpg')))
        self.setPalette(self.palette)
        self.client = Client()
        self.client.trigger.connect(self.updateTextFun)
        self.ininData()

    def changeFriendText(self):
        currentItem = self.friendList.currentItem().text()
        self.text = self.userText[currentItem]
        self.messageText.setText(self.text)

    def ininData(self):
        self.friendList.addItem('broadcast')
        self.userText['broadcast'] = ''
        self.friendList.setCurrentItem(self.friendList.item(0))

    def initUI(self):

        mainLayout = QVBoxLayout()
        mainWidget = QWidget()

        widget1 = QWidget()
        layout1 = QHBoxLayout()
        layout1.addWidget(self.portLine)
        layout1.addWidget(self.connectBtn)
        widget1.setLayout(layout1)
        mainLayout.addWidget(widget1)

        widget2 = QWidget()
        layout2 = QHBoxLayout()
        layout2.addWidget(self.messageText)
        layout2.addWidget(self.friendList)
        layout2.setStretch(0,2)
        layout2.setStretch(0,1)
        widget2.setLayout(layout2)
        mainLayout.addWidget(widget2)

        # mainLayout.addStretch(1)
        widget3 = QWidget()
        layout3 = QHBoxLayout()
        layout3.addWidget(self.messageLine)
        layout3.addWidget(self.sendBtn)
        widget3.setLayout(layout3)
        mainLayout.addWidget(widget3)

        self.setLayout(mainLayout)

    def setupFun(self):
        port = int(self.portLine.text())
        self.client.setupFun(port)
        self.client.start()

    def sendFun(self):
        addr = self.friendList.currentItem().text()
        message = self.messageLine.text()
        if message != 'add' and message != 'del':
            self.userText[addr] += '我:' + message + '\n'
        self.changeFriendText()
        if addr != 'broadcast':
            addr = ('localhost',int(addr))
        self.client.sendFun(message,addr)
        self.messageLine.setText('')


    def updateTextFun(self,data):

        currentItem = self.friendList.currentItem().text()
        data = json.loads(data)
        if 'cmd' in data.keys():
            if data['cmd'] == 'add':
                fromUser = str(data['from'])
                addr = ('127.0.0.1',int(fromUser))
                item = self.friendList.findItems(fromUser,Qt.MatchExactly)
                if fromUser not in self.userText.keys():
                    self.userText[fromUser] = ''
                if len(item) == 0:
                    self.friendList.addItem(fromUser)
                    self.client.sendFun('add',addr)  # 已添加
            elif data['cmd'] == 'del':
                fromUser = str(data['from'])
                rows = self.friendList.count()
                for row in range(rows):
                    if fromUser == self.friendList.item(row).text():
                        self.friendList.takeItem(row)
        else:
            message = data['message']
            fromUser = str(data['from'])
            if fromUser != 'broadcast':
                addr = ('127.0.0.1', int(fromUser))
                item = self.friendList.findItems(fromUser, Qt.MatchExactly)
                if fromUser not in self.userText.keys():
                    self.userText[fromUser] = ''
                if len(item) == 0:
                    self.friendList.addItem(fromUser)
                    self.client.sendFun('add', addr)  # 已添加
            if message != 'add' and message != 'del':
                self.userText[fromUser] += fromUser + ':' + message + '\n'
                if fromUser == currentItem:
                    self.text = self.userText[fromUser]
                    self.messageText.setText(self.text)


    def closeEvent(self, event:PySide2.QtGui.QCloseEvent):
        self.client.closeFun()
Beispiel #14
0
class SnippetEditor(QDialog):
    
    def __init__(self, snippetManager: SnippetManager):
        super(SnippetEditor, self).__init__()
        self.snippetManager = snippetManager
        self.snippetDict = deepcopy(self.snippetManager.codeSnippets)
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)
        self.setWindowTitle("Edit code snippets")
        self.setStyleSheet("background-color: #3E3E42; color: white;")
        self.setFixedSize(700, 400)
        self.setWindowIcon(QIcon(main.resource_path("resources/app_icon")))
        self.listView = QListWidget()
        self.nameEdit = QLineEdit()
        self.nameEdit.setStyleSheet(
            "font-size: 14px; background-color: #1E1E1E; color: white; font-family: comic-sans; border: none;")
        self.editor = TextEditor()
        self.editor.setStyleSheet(
            "font-size: 14px; background-color: #1E1E1E; color: white; font-family: comic-sans; border: none;")
        self.editor.setTabStopWidth(4 * QFontMetrics(self.font()).width(' '))
        self.listView.setStyleSheet("background-color: #2D2D30; color: white;")
        for snippet in self.snippetManager.getSnippetsAbbs():
            self.listView.addItem(SnippetListWidgetItem(snippet))
        self.hbox = QHBoxLayout()
        self.hbox2 = QHBoxLayout()
        self.hbox3 = QHBoxLayout()
        self.vbox = QVBoxLayout()
        self.vbox2 = QVBoxLayout()
        self.addButton = QPushButton("Add")
        self.addButton.setStyleSheet("background-color: #2D2D30; color: white;")
        self.removeButton = QPushButton("Remove")
        self.removeButton.setStyleSheet("background-color: #2D2D30; color: white;")
        self.applyButton = QPushButton("Apply")
        self.applyButton.setStyleSheet("background-color: #2D2D30; color: white;")
        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.setStyleSheet("background-color: #2D2D30; color: white;")
        self.okButton = QPushButton("OK")
        self.okButton.setStyleSheet("background-color: #2D2D30; color: white;")
        self.resetButton = QPushButton("Reset to default")
        self.resetButton.setStyleSheet("background-color: #2D2D30; color: white;")
        self.vbox.addWidget(self.listView)
        self.hbox2.addWidget(self.addButton)
        self.hbox2.addWidget(self.removeButton)
        self.hbox2.addWidget(self.applyButton)
        self.vbox.addLayout(self.hbox2)
        self.vbox2.addWidget(self.nameEdit)
        self.vbox2.addWidget(self.editor)
        self.hbox3.addWidget(self.cancelButton)
        self.hbox3.addWidget(self.resetButton)
        self.hbox3.addWidget(self.okButton)
        self.vbox2.addLayout(self.hbox3)
        self.hbox.addLayout(self.vbox)
        self.hbox.addLayout(self.vbox2)
        self.setLayout(self.hbox)

        self.listView.currentItemChanged.connect(self.updateEditor)
        self.okButton.clicked.connect(self.okButtonClicked)
        self.removeButton.clicked.connect(self.removeButtonClicked)
        self.addButton.clicked.connect(self.addButtonClicked)
        self.applyButton.clicked.connect(self.appyButtonClicked)
        self.cancelButton.clicked.connect(self.cancelButtonClicked)
        self.resetButton.clicked.connect(self.resetButtonClicked)

    def resetingSnippetsWarning(self):
        msg = QMessageBox()
        msg.setStyleSheet("background-color: #2D2D30; color: white;")
        msg.setParent(None)
        msg.setModal(True)
        msg.setWindowTitle("Confirm reset to default")
        msg.setText("This will delete all snippets that were created by the user!")
        msg.setInformativeText("Do you want to continue?")
        msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        msg.setDefaultButton(QMessageBox.Yes)
        retValue = msg.exec_()
        if retValue == QMessageBox.Yes:
            return True

    def resetButtonClicked(self):
        if not self.resetingSnippetsWarning():
            return
        self.snippetDict.clear()
        for key in SnippetManager.DEFAULT_SNIPPETS:
            self.snippetDict[key] = SnippetManager.DEFAULT_SNIPPETS[key]
        self.updateList()

    def removeButtonClicked(self):
        snippet = self.listView.currentItem()
        if snippet:
            answer = QMessageBox.question(None, "Delete snippet",
                                          "Are you sure you want to delete snippet '{}'?".format(
                                              str(snippet)),
                                          QMessageBox.Yes | QMessageBox.No)
            if not answer == QMessageBox.Yes:
                return
            del self.snippetDict[str(snippet)]
            self.updateList()

    def checkSnippetName(self, name, checkSelected=False):
        if checkSelected:
            isSelected = name == str(self.listView.currentItem())
        else:
            isSelected = False
        if not isSelected and name in self.snippetDict:
            msg = QMessageBox()
            msg.setStyleSheet("background-color: #2D2D30; color: white;")
            msg.setModal(True)
            msg.setIcon(QMessageBox.Critical)
            msg.setText("Snippet abbreviation already exists.")
            msg.setWindowTitle("Wrong snippet abbreviation")
            msg.exec_()
            return False
        if ' ' in name:
            msg = QMessageBox()
            msg.setStyleSheet("background-color: #2D2D30; color: white;")
            msg.setModal(True)
            msg.setIcon(QMessageBox.Critical)
            msg.setText("Snippet abbreviation cannot contain whitespace characters.")
            msg.setWindowTitle("Wrong snippet abbreviation")
            msg.exec_()
            return False
        if name.strip() == '':
            msg = QMessageBox()
            msg.setStyleSheet("background-color: #2D2D30; color: white;")
            msg.setModal(True)
            msg.setIcon(QMessageBox.Critical)
            msg.setText("Snippet abbreviation cannot be an empty string.")
            msg.setWindowTitle("Wrong snippet abbreviation")
            msg.exec_()
            return False
        if name.strip() in AsemblerSintaksa.keywords or name.strip() in AsemblerSintaksa.declarations or name.strip() \
            in AsemblerSintaksa.registers or name.strip() in CSyntax.functions or name.strip() in CSyntax.keywords_c:
            if not self.nameOvershadowedMsg(name.strip()):
                return False
        return True

    def nameOvershadowedMsg(self, name):
        msg = QMessageBox()
        msg.setStyleSheet("background-color: #2D2D30; color: white;")
        msg.setParent(None)
        msg.setModal(True)
        msg.setWindowTitle("Name overshadowed")
        msg.setText("Shippet name '{}' overshadows a built in name."
                    "\n\nThis may interfere with auto completion of the overshadowed name.".format(name))
        msg.setInformativeText("Do you want to use '{}' for the snippet name regardlessly?".format(name))
        msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        msg.setDefaultButton(QMessageBox.Yes)
        retValue = msg.exec_()
        if retValue == QMessageBox.Yes:
            return True

    def addButtonClicked(self):
        name, entered = QInputDialog.getText(None, "Add code snippet", "Enter snippet abbreviation ", QLineEdit.Normal, "")
        if entered:
            if not self.checkSnippetName(name):
                return
            self.snippetDict[name] = ""
            item = SnippetListWidgetItem(name)
            self.listView.addItem(item)
            self.listView.setCurrentItem(item)

    def updateList(self, selectedName=""):
        self.listView.clear()
        for snippet in self.snippetDict:
            self.listView.addItem(SnippetListWidgetItem(snippet))
        if selectedName:
            items = self.listView.findItems(selectedName, Qt.MatchExactly)
            if len(items) > 0:
                for item in items:
                    self.listView.setItemSelected(item, True)

    def appyButtonClicked(self):
        snippet = self.listView.currentItem()
        if snippet:
            name = self.nameEdit.text()
            if not self.checkSnippetName(name, checkSelected=True):
                return
            del self.snippetDict[str(snippet)]
            self.snippetDict[name] = self.editor.toPlainText()
            self.updateList(selectedName=name)
            self.snippetManager.updateSnippets(self.snippetDict)
        return True


    def okButtonClicked(self):
        self.snippetManager.updateSnippets(self.snippetDict)
        if self.appyButtonClicked():
            self.accept()

    def updateEditor(self, snippet, previous):
        if snippet and str(snippet) in self.snippetDict:
            self.nameEdit.setText(str(snippet))
            self.editor.setText(self.snippetDict[str(snippet)])

    def cancelButtonClicked(self):
        self.reject()

    def closeEvent(self, arg__1):
        self.reject()
class AddElementWindow(QDialog):
    def __init__(self, parent):
        super(AddElementWindow, self).__init__()
        self.parent = parent
        self.setWindowTitle("PyEngine - Element")

        self.grid = QGridLayout()

        ltitle = Label("Elements", 15)
        ltitle.setAlignment(Qt.AlignHCenter)
        lname = Label("Nom", 12)
        lname.setAlignment(Qt.AlignHCenter)
        self.nameInput = QLineEdit()
        ltype = Label("Type", 12)
        ltype.setAlignment(Qt.AlignHCenter)
        self.typelist = QListWidget()
        self.typelist.addItems([i for i in types])
        lparent = Label("Parent", 12)
        lparent.setAlignment(Qt.AlignHCenter)
        self.parentlist = QListWidget()
        self.go = QPushButton("Entrer")
        self.cancel = QPushButton("Annuler")
        spacer = QSpacerItem(20, 25)

        self.go.clicked.connect(self.enter)
        self.cancel.clicked.connect(self.close)
        self.typelist.currentItemChanged.connect(self.item_changed)

        self.grid.addWidget(ltitle, 0, 0, 1, 2)
        self.grid.addItem(spacer, 1, 0)
        self.grid.addWidget(lname, 2, 0, 1, 2)
        self.grid.addWidget(self.nameInput, 3, 0, 1, 2)
        self.grid.addItem(spacer, 4, 0)
        self.grid.addWidget(ltype, 5, 0, 1, 2)
        self.grid.addWidget(self.typelist, 6, 0, 1, 2)
        self.grid.addItem(spacer, 7, 0)
        self.grid.addWidget(lparent, 8, 0, 1, 2)
        self.grid.addWidget(self.parentlist, 9, 0, 1, 2)
        self.grid.addWidget(self.go, 10, 0)
        self.grid.addWidget(self.cancel, 10, 1)

        self.grid.setContentsMargins(10, 10, 10, 10)

        self.setLayout(self.grid)
        self.setFixedSize(400, 500)

        self.setWindowFlags(Qt.CustomizeWindowHint)
        self.setWindowFlags(Qt.WindowTitleHint)
        self.setWindowFlags(Qt.WindowCloseButtonHint)

    def enter(self):
        if self.nameInput.text() == "":
            QMessageBox.warning(self, "Erreur",
                                "Le nom de l'élément n'a pas été fourni")
        elif self.typelist.currentItem() is None:
            QMessageBox.warning(self, "Erreur",
                                "Le type de l'élément n'a pas été fourni")
        elif self.parentlist.currentItem() is None:
            QMessageBox.warning(self, "Erreur",
                                "Le parent de l'élément n'a pas été fourni")
        else:
            for v in self.parent.project.all_objects():
                if v.name == self.parentlist.currentItem().text():
                    obj = Object(self.nameInput.text(),
                                 self.typelist.currentItem().text())
                    obj.parent = v
                    obj.set_property("Nom", self.nameInput.text())
                    v.childs.append(obj)
                    break
            self.parent.elements.update_items()
            self.close()

    def item_changed(self, current, previous):
        item = current.text()
        self.parentlist.clear()
        self.parentlist.addItems([
            v.name for v in self.parent.project.all_objects()
            if v.type_ in get_parent_types(item)
        ])
Beispiel #16
0
class AlbumViewer(QDialog):
    def __init__(self, pid=0, db=0, mode=0):
        super().__init__()
        self.font = mainfont
        self.resize(500, self.height())
        layout = QGridLayout()
        self.layout = layout
        self.buttext = []
        self.last_alid = 0

        self.listWidget = QListWidget()
        self.listWidget.itemDoubleClicked.connect(self.doubleClick)
        self.listWidget.itemSelectionChanged.connect(self.itemChanged)

        self.dictAlbum = QWidget()
        self.DICTVIEWERTYPE = type(DictViewer())
        self.setFont(mainfont)
        self.db = db
        self.pid = pid
        self.album_ids = db.get_all_albums_ids()
        print(self.album_ids)
        if self.album_ids:
            for alid in self.album_ids:
                album = db.get_album_data(alid)
                print(album)
                self.dictAlbum = DictViewer(album, 1,
                                            self.db.albums.invizible_fields,
                                            self.db.albums.editable_fields)

                if album:
                    text = ''
                    text = album['title'] if type(album) == type(
                        {}) and 'title' in album.keys(
                        ) and album['title'] != '' else text
                    item = QListWidgetItem(text)
                    if type(album) == type({}) and 'alid' in album.keys():
                        item.setWhatsThis(str(album['alid']))
                    self.listWidget.addItem(item)
            self.listWidget.setCurrentRow(0)
        self.mode = mode

        def openMenu(position):
            # Создание PopupMenu
            menu = QMenu()
            openAction = menu.addAction('Открыть альбом')
            openEAction = menu.addAction('Открыть события')
            menu.addSeparator()
            if mode > 0:
                #importAction = menu.addAction('Выгрузить альбом')
                exportAction = menu.addAction('Добавить альбом')
                renameAction = menu.addAction('Переименовать альбом')
                #menu.addSeparator()
                #editAction = menu.addAction('Заменить')
                menu.addSeparator()
                delAction = menu.addAction('Удалить альбом')
                delAllAction = menu.addAction('Удалить все альбомы')
                menu.addSeparator()
            else:
                exportAction, delAction, delAllAction = QAction(), QAction(
                ), QAction()
            quitAction = menu.addAction('Выход')
            action = menu.exec_(self.mapToGlobal(position))

            # Привязка событий к Actions
            if action == openAction:
                self.doubleClick(self.listWidget.currentItem())

            if action == openEAction:
                item = self.listWidget.currentItem()
                if item is not None:
                    alid = item.whatsThis()
                    self.events = EventViewer(int(alid), db, 1)
                    self.events.show()

            if action == exportAction:
                text, ok = QInputDialog().getText(self, "Название альбома",
                                                  "Ввкдите название альбома:",
                                                  QLineEdit.Normal, 'Альбом')
                if ok:
                    res = self.db.add_album({'imid': -1, 'title': text})
                    if len(res) == 1:
                        album = res[0]
                        item = QListWidgetItem(text)
                        item.setWhatsThis(str(album['alid']))
                        self.listWidget.addItem(item)
                self.album_ids = db.get_all_albums_ids()

            if action == renameAction:
                item = self.listWidget.currentItem()
                if item is not None:
                    alid = item.whatsThis()
                    album = db.get_album_data(alid)
                    text, ok = QInputDialog().getText(
                        self, "Название альбома", "Ввкдите название альбома:",
                        QLineEdit.Normal, album['title'])
                    if ok:
                        album = db.edit_album({
                            'alid': int(alid),
                            'imid': -1,
                            'title': text
                        })
                        item.setText(text)
                        if album:
                            album = self.db.get_album_data(alid)
                            # b = layout.takeAt(1)
                            # self.dictAlbum.close()
                            # b.widget().deleteLater()
                            self.dictAlbum = DictViewer(
                                album, 1, self.db.albums.invizible_fields,
                                self.db.albums.editable_fields)
                            self.layout.addWidget(self.dictAlbum, 0, 1)
                        self.album_ids = db.get_all_albums_ids()

            if action == delAction:
                res = QMessageBox.question(
                    self, 'ВНИМАНИЕ!!!',
                    "Вы действительно хотите удалить альбом?",
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if res == QMessageBox.Yes:
                    self.delete_item()

            if action == delAllAction:
                res = QMessageBox.question(
                    self, 'ВНИМАНИЕ!!!',
                    "Вы действительно хотите удалить все альбомы?",
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if res == QMessageBox.Yes:
                    item = self.listWidget.currentItem()
                    while item is not None:
                        self.delete_item()
                        item = self.listWidget.currentItem()

                    self.album_ids = db.get_all_albums_ids()

            if action == quitAction:
                self.accept()

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(openMenu)

        layout.addWidget(self.listWidget, 0, 0)
        layout.addWidget(self.dictAlbum, 0, 1)

        self.setLayout(layout)

    def delete_item(self):
        item = self.listWidget.currentItem()
        if item is not None:

            alid = item.whatsThis()
            self.db.del_album(int(alid))
            self.listWidget.takeItem(self.listWidget.currentRow())
            self.album_ids = self.db.get_all_albums_ids()

    def itemChanged(self):
        if self.last_alid:
            self.check_and_save(self.last_alid)

        item = self.listWidget.currentItem()
        if item is not None:
            alid = item.whatsThis()

            album = self.db.get_album_data(alid)
            self.dictAlbum = DictViewer(album, 1,
                                        self.db.albums.invizible_fields,
                                        self.db.albums.editable_fields)
            self.layout.addWidget(self.dictAlbum, 0, 1)
            self.last_alid = alid
        self.setFocus()

    def doubleClick(self, item):
        if item is not None:
            alid = item.whatsThis()
            print(alid)
            self.viewer = QLabelMA(alid, self.db, 1)
            self.viewer.show()

    def check_and_save(self, alid):
        changes = self.dictAlbum.get_changes()
        album = self.db.get_album_data(alid)

        print(changes)
        if len(changes) > 0 and type(album) == type({}):
            print('album changes saved')
            album.update(changes)
            self.db.edit_album(album)
Beispiel #17
0
class MatchStatWindow(QDialog):
    def __init__(self, parent=None):
        super(MatchStatWindow, self).__init__(parent)
        self.setModal(True)
        self.setWindowTitle("Mérkőzés választása")
        self.resize(740, 600)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.merkozesek = QListWidget()
        self.merkozesek.setFixedHeight(200)
        self.merkozesek.setFixedWidth(730)
        self.merkozesek.itemDoubleClicked.connect(self.stat_game)
        self.layout.addWidget(self.merkozesek)
        self.szumma = MatchSumWidget(self)
        self.layout.addWidget(self.szumma)
        self.history = QWidget()
        self.history.setFixedWidth(690)
        self.history_layout = QGridLayout()
        self.history.setLayout(self.history_layout)
        scroll = QScrollArea()
        scroll.setWidget(self.history)
        scroll.setWidgetResizable(True)
        self.layout.addWidget(scroll)

        self.match_valasztas()

    def match_valasztas(self):
        matches = QSqlRelationalTableModel(db=db)
        matches.setTable("match_settings")
        matches.setSort(8, Qt.DescendingOrder)
        matches.select()
        self.merkozesek.clear()
        for i in  range(matches.rowCount()):
            self.merkozesek.addItem(str(matches.record(i).value(1)) + "\t" +
                                    str(matches.record(i).value(2)) + "\t" +
                                    str(int(matches.record(i).value(3)) + matches.record(i).value(6)) + "\t" +
                                    str(int(matches.record(i).value(3)) + matches.record(i).value(7)) + "\t" +
                                    str(matches.record(i).value(4)) + "\t" +
                                    str(matches.record(i).value(5)) + "\t" +
                                    str(matches.record(i).value(8))[:16] + "\t" +
                                    str(matches.record(i).value(0))
            )

    def stat_game(self):
        # Az átvett adatok:
        para = self.merkozesek.currentItem().text().rsplit("\t")
        # Összegyűjtjük egy listába a szükséges infókat
        self.get_adatok(para)
        self.szumma.change_data(self.adatok)
        for x in reversed(range(self.history_layout.count())):
            self.history_layout.itemAt(x).widget().deleteLater()
        # kiszedjük az adott meccs összes set és leg esetére a dobásokat
        sor = 0
        for s in range(1, self.adatok[8] + 1):
            # s: a set-ek száma
            if self.adatok[8] != 1:
                self.history_layout.addWidget(QLabel("Set: " + str(s)), sor, 0, 1, 2)
                sor += 1
            for l in range(1, self.adatok[7][s-1] + 1):
                sl1_model = QSqlQueryModel()
                p1_data_list = []
                p1_data_list.append(self.adatok[4])   # start_score1
                sl1_query = QSqlQuery(f"select * from dobas where match_id ={self.adatok[6]} and set_id={s} and leg_id={l} and player_id='{self.adatok[0]}'", db=db)
                sl1_model.setQuery(sl1_query)
                for i in range(sl1_model.rowCount()):
                    # Itt a model már tartalmazza a p1 összes dobását az adott leg-ben.
                    p1_data_row = []
                    p1_data_row.append(sl1_model.record(i).value(1))
                    p1_data_row.append(sl1_model.record(i).value(2))
                    p1_data_list.append(p1_data_row)
                self.history_layout.addWidget(PlayerLegWidget(self, p1_data_list), sor, 0, Qt.AlignTop)

                sl2_model = QSqlQueryModel()
                p2_data_list = []
                p2_data_list.append(self.adatok[5])  # start_score2
                sl2_query = QSqlQuery(f"select * from dobas where match_id ={self.adatok[6]} and set_id={s} and leg_id={l} and player_id='{self.adatok[2]}'", db=db)
                sl2_model.setQuery(sl2_query)
                for j in range(sl2_model.rowCount()):
                    p2_data_row = []
                    p2_data_row.append(sl2_model.record(j).value(1))
                    p2_data_row.append(sl2_model.record(j).value(2))
                    p2_data_list.append(p2_data_row)
                self.history_layout.addWidget(PlayerLegWidget(self, p2_data_list), sor, 1, Qt.AlignTop)
                sor += 1

    def get_adatok(self, para):
        print(para)
        # self.adatok[0]  : p1_id
        # self.adatok[1]  : name1
        # self.adatok[2]  : p2_id
        # self.adatok[3]  : name2
        # self.adatok[4]  : start_score1
        # self.adatok[5]  : start_score2
        # self.adatok[6]  : match
        # self.adatok[7]  : legs
        # self.adatok[8]  : sets
        # self.adatok[9]  : dátum

        self.adatok = []
        name1_id = int(para[0])
        self.adatok.append(name1_id)
        query_name1 = QSqlQuery(f"select player_name from players where player_id={name1_id}", db=db)
        query_name1.exec_()
        while query_name1.next():
            name1 = query_name1.value(0)
        self.adatok.append(name1)
        name2_id = int(para[1])
        self.adatok.append(name2_id)
        query_name2 = QSqlQuery(f"select player_name from players where player_id={name2_id}", db=db)
        query_name2.exec_()
        while query_name2.next():
            name2 = query_name2.value(0)
        self.adatok.append(name2)

        start_score1 = int(para[2])
        start_score2 = int(para[3])
        match = int(para[7])
        setek = int(para[5])
        self.adatok.append(start_score1)
        self.adatok.append(start_score2)
        self.adatok.append(match)
        # Kell a max set-number, ezt beállítani a sets változóba
        # Ciklussal minden set-ben megnézni a max leg-numbert, és ezeket append-elni a legs[]-hez
        # Végül leg, set sorrendben append-elni az adatokhoz
        legs = []
        sets = 0
        query2 = QSqlQuery(
            f"select max(set_id) as max_set from matches where match_id={match}", db=db)
        query2.exec_()
        while query2.next():
            sets = int(query2.value(0))

        for i in range(1, sets + 1):
            query = QSqlQuery(f"select max(leg_id) as max_leg from matches where match_id={match} and set_id={i}", db=db)
            query.exec_()
            while query.next():
                legs.append(int(query.value(0)))
                # sets.append(int(query.value(1)))

        self.adatok.append(legs)
        self.adatok.append(sets)

        datum = para[6][:16]
        self.adatok.append(datum)
        print(self.adatok)
Beispiel #18
0
class ScriptEditor(QWidget):
    """Main object of script tab"""
    def __init__(self, config, resource):
        QWidget.__init__(self)
        self.channels = resource["tabs"].widget(0).channels
        self.scripts = resource["scripts"]
        self.threadpool = resource["threadpool"]
        self.config = config

        # Create overall layout
        columns = QHBoxLayout(self)
        self.setup_file_list()
        columns.addWidget(self.file_list)
        edit_rows = QVBoxLayout()
        columns.addLayout(edit_rows)
        columns.setStretch(0, 1)
        columns.setStretch(1, 5)

        # Create edit_rows
        self.title_bar = func.label("Select or open file to edit.")
        edit_rows.addWidget(self.title_bar)

        self.editor = QPlainTextEdit()
        self.editor.textChanged.connect(self.text_modified)
        edit_rows.addWidget(self.editor)

        controls = QHBoxLayout()
        edit_rows.addLayout(controls)

        buttons = [
            ["Open", self.open],
            ["New", self.new],
            ["Save", self.save],
            ["Check", self.check],
        ]
        for button in buttons:
            controls.addWidget(func.button(text=button[0], connect=button[1]))

    def setup_file_list(self):
        """Create list of script files"""
        self.file_list = QListWidget()
        self.file_list.itemClicked.connect(self.list_clicked)
        for script in self.scripts.script_list:
            self.file_list.addItem(script)

    def list_clicked(self):
        """Display contents of script when clicked"""
        self.title_bar.setText(self.file_list.currentItem().path)
        self.editor.setPlainText(self.file_list.currentItem().content)

    def text_modified(self):
        """Update content of script and update status to show if edited"""
        if self.file_list.currentItem() is not None:
            self.file_list.currentItem().content = self.editor.toPlainText()
            self.file_list.currentItem().update_status()

    def open(self, text):
        """Open new file and add as script"""
        script_file = QFileDialog.getOpenFileName(
            QWidget(), "Open Script File"
        )[0].rsplit("/", 1)
        if script_file[0]:
            self.add(script_file)

    def new(self, text):
        """Create new file and add to list as script"""
        script_file = QFileDialog.getSaveFileName(QWidget(),
                                                  "Select Directory")[0]
        if script_file:
            open(script_file, "a")
            self.add(script_file.rsplit("/", 1))

    def save(self, text):
        """Save script"""
        try:
            self.file_list.currentItem().save()
        except AttributeError:
            pass

    def check(self, text):
        """Run check protocol to verify validity"""
        worker = Check(self.config, self.file_list.currentItem().content)
        self.threadpool.start(worker)
        worker.signals.status.connect(self.alert_check)

    def alert_check(self, result, message):
        if result:
            msg = {
                "text": "Passed!",
                "info": "Script is good to go.",
            }
        else:
            msg = {
                "text": "Failed!",
                "info": "Script did not pass the check.",
                "detail": message,
                "icon": func.Warning
            }
        func.message(**msg)

    def add(self, file):
        """Add new script to list to make available"""
        self.scripts.script_list.append(scripts.Script(file[1], file[0]))
        self.file_list.addItem(self.scripts.script_list[-1])
        for channel in self.channels:
            channel.settings[1].addItem(self.scripts.script_list[-1].title)
Beispiel #19
0
class PersonaUI(QWidget):
    """
    Widget for Persona creation view.

    :param MainFrame mainframe: application mainframe
    :param QWidget op: parent widget
    """
    def __init__(self, mainframe, op):
        QWidget.__init__(self)
        self.mainframe = mainframe
        self.op = op

        self.grid = QGridLayout()
        self.setLayout(self.grid)

        self.listP = None
        self.listLS = None
        self.listEL1 = None
        self.listEL2 = None

        self.nameT = None
        self.levelT = None
        self.textT = None
        self.strT = None
        self.magT = None
        self.endT = None
        self.agiT = None
        self.luckT = None

        self.createFrame = None
        self.buttonFrame = None
        self.bfgrid = None
        # Actual create frame variables.
        self.cfgrid = None
        self.lsdic = None
        self.slashO = None
        self.strikeO = None
        self.pierceO = None
        self.fireO = None
        self.iceO = None
        self.windO = None
        self.elecO = None
        self.darkO = None
        self.lightO = None
        self.arcO = None
        self.iSpellOs = None
        self.lsSpellO = None
        self.lslevel = None


        self.initUI(True)

    def initUI(self, infoDump):
        """
        Initializes the basic UI showing the list of Personas.
        Does a lot of stuff.

        :param dict infoDump: not sure lol
        """
        self.mainframe.setWindowTitle("Persona Creator")

        if not infoDump:
            self.createFrameDraw()

        self.initButtonFrame(infoDump)

        self.listP = QListWidget(self)
        self.grid.addWidget(self.listP, 0, 3, 2, 1)
        temp = json_reader.readPerNames()
        self.listP.addItems(temp)

    def initButtonFrame(self, infoDump):
        """
        Initializes the buttonframes that are present in all Persona creator views.

        :param dict infoDump: not sure lol
        """
        self.buttonFrame = QWidget(self)
        self.bfgrid = QGridLayout()
        self.buttonFrame.setLayout(self.bfgrid)

        self.grid.addWidget(self.buttonFrame, 3, 0, 1, 4)


        new = QPushButton(self.buttonFrame, text="New")
        new.clicked.connect(self.new)
        self.bfgrid.addWidget(new, 4, 0)

        back = QPushButton(self.buttonFrame, text="Back")
        back.clicked.connect(self.back)
        self.bfgrid.addWidget(back, 4, 4)

        remove = QPushButton(self.buttonFrame, text="Remove")
        remove.clicked.connect(self.remove)
        self.bfgrid.addWidget(remove, 4, 3)

        edit = QPushButton(self.buttonFrame, text="Edit")
        edit.clicked.connect(self.edit)
        self.bfgrid.addWidget(edit, 4, 2)

        if not infoDump:
            save = QPushButton(self.buttonFrame, text="Save")
            save.clicked.connect(self.save)
            self.bfgrid.addWidget(save, 4, 1)


    def createFrameDraw(self):
        """
        Initializes the GUI of the actual creation frame view.
        Does a LOT of stuff.
        """
        self.createFrame = QWidget(self)
        self.cfgrid = QGridLayout()
        self.createFrame.setLayout(self.cfgrid)
        self.grid.addWidget(self.createFrame, 0, 0, 2, 2)

        self.lsdic = {}

        nameL = QLabel(self.createFrame, text="Name:")
        self.cfgrid.addWidget(nameL, 0, 0)
        self.nameT = QLineEdit(self.createFrame)
        self.nameT.setFixedSize(100, 20)
        self.cfgrid.addWidget(self.nameT, 0, 1)

        strL = QLabel(self.createFrame, text="Str")
        self.cfgrid.addWidget(strL, 0, 2)
        self.strT = QLineEdit(self.createFrame)
        self.strT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.strT, 0, 3)
        magL = QLabel(self.createFrame, text="Mag")
        self.cfgrid.addWidget(magL, 1, 2)
        self.magT = QLineEdit(self.createFrame)
        self.magT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.magT, 1, 3)
        endL = QLabel(self.createFrame, text="End")
        self.cfgrid.addWidget(endL, 2, 2)
        self.endT = QLineEdit(self.createFrame)
        self.endT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.endT, 2, 3)
        agiL = QLabel(self.createFrame, text="Agi")
        self.cfgrid.addWidget(agiL, 3, 2)
        self.agiT = QLineEdit(self.createFrame)
        self.agiT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.agiT, 3, 3)
        luckL = QLabel(self.createFrame, text="Luck")
        self.cfgrid.addWidget(luckL, 4, 2)
        self.luckT = QLineEdit(self.createFrame)
        self.luckT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.luckT, 4, 3)

        resList = json_reader.data_list("resistances")
        resL = QLabel(self.createFrame, text="Resistance:")
        self.cfgrid.addWidget(resL, 0, 5)
        slashL = QLabel(self.createFrame, text="Slash")
        self.cfgrid.addWidget(slashL, 1, 5)
        self.slashO = QComboBox(self.createFrame)
        self.slashO.addItems(resList)
        self.slashO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.slashO, 1, 6)
        strikeL = QLabel(self.createFrame, text="Strike")
        self.cfgrid.addWidget(strikeL, 2, 5)
        self.strikeO = QComboBox(self.createFrame)
        self.strikeO.addItems(resList)
        self.strikeO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.strikeO, 2, 6)
        pierceL = QLabel(self.createFrame, text="Pierce")
        self.cfgrid.addWidget(pierceL, 3, 5)
        self.pierceO = QComboBox(self.createFrame)
        self.pierceO.addItems(resList)
        self.pierceO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.pierceO, 3, 6)
        fireL = QLabel(self.createFrame, text="Fire")
        self.cfgrid.addWidget(fireL, 4, 5)
        self.fireO = QComboBox(self.createFrame)
        self.fireO.addItems(resList)
        self.fireO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.fireO, 4, 6)
        iceL = QLabel(self.createFrame, text="Ice")
        self.cfgrid.addWidget(iceL, 5, 5)
        self.iceO = QComboBox(self.createFrame)
        self.iceO.addItems(resList)
        self.iceO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.iceO, 5, 6)
        elecL = QLabel(self.createFrame, text="Elec")
        self.cfgrid.addWidget(elecL, 6, 5)
        self.elecO = QComboBox(self.createFrame)
        self.elecO.addItems(resList)
        self.elecO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.elecO, 6, 6)
        windL = QLabel(self.createFrame, text="Wind")
        self.cfgrid.addWidget(windL, 7, 5)
        self.windO = QComboBox(self.createFrame)
        self.windO.addItems(resList)
        self.windO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.windO, 7, 6)
        lightL = QLabel(self.createFrame, text="Light")
        self.cfgrid.addWidget(lightL, 8, 5)
        self.lightO = QComboBox(self.createFrame)
        self.lightO.addItems(resList)
        self.lightO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.lightO, 8, 6)
        darkL = QLabel(self.createFrame, text="Dark")
        self.cfgrid.addWidget(darkL, 9, 5)
        self.darkO = QComboBox(self.createFrame)
        self.darkO.addItems(resList)
        self.darkO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.darkO, 9, 6)

        spellList = json_reader.data_list("spells")
        self.listLS = QListWidget(self.createFrame)
        self.listLS.setFixedSize(200, 300)
        self.cfgrid.addWidget(self.listLS, 3, 7, 8, 2)

        newLS = QPushButton(self.createFrame, text="+")
        newLS.clicked.connect(self.addLS)
        self.cfgrid.addWidget(newLS, 2, 7)
        delLS = QPushButton(self.createFrame, text="DEL")
        delLS.clicked.connect(self.delLS)
        self.cfgrid.addWidget(delLS, 2, 8)

        lsl = QLabel(self.createFrame, text="Learned Spells:")
        self.cfgrid.addWidget(lsl, 0, 7, 1, 2)

        arcanaL = QLabel(self.createFrame, text="Arcana:")
        self.cfgrid.addWidget(arcanaL, 1, 0)
        arc_list = json_reader.data_list("arcanas")
        self.arcO = QComboBox(self.createFrame)
        self.arcO.addItems(arc_list)
        self.arcO.setCurrentIndex(0)
        self.cfgrid.addWidget(self.arcO, 1, 1)

        levelL = QLabel(self.createFrame, text="Level:")
        self.cfgrid.addWidget(levelL, 2, 0)
        self.levelT = QLineEdit(self.createFrame)
        self.levelT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.levelT, 2, 1)

        heritageL = QLabel(self.createFrame, text="Inherits:")
        self.cfgrid.addWidget(heritageL, 3, 0, 1, 2)

        elements = json_reader.data_list("elements")
        elements.append("Support")
        self.listEL1 = QComboBox(self.createFrame)
        self.listEL1.addItems(elements)
        self.cfgrid.addWidget(self.listEL1, 4, 0)
        self.listEL2 = QComboBox(self.createFrame)
        self.listEL2.addItems(elements)
        self.cfgrid.addWidget(self.listEL2, 4, 1)

        iSpellL = QLabel(self.createFrame, text="Initial Spells:")
        self.cfgrid.addWidget(iSpellL, 5, 0, 1, 2)
        self.iSpellOs = []
        for i in range(6, 9):
            temp = QComboBox(self.createFrame)
            temp.addItems(spellList)
            temp2 = QComboBox(self.createFrame)
            temp2.addItems(spellList)
            self.cfgrid.addWidget(temp, i, 0, 1, 2)
            self.cfgrid.addWidget(temp2, i, 2, 1, 2)
            self.iSpellOs.extend([temp, temp2])

        textL = QLabel(self.createFrame, text="Info:")
        self.cfgrid.addWidget(textL, 10, 0)
        self.textT = QTextEdit(self.createFrame)
        self.textT.setFixedSize(300, 100)
        self.cfgrid.addWidget(self.textT, 10, 1, 1, 5)

        self.lslevel = QLineEdit(self.createFrame)
        self.lslevel.setFixedSize(40, 20)
        self.lsSpellO = QComboBox(self.createFrame)
        self.lsSpellO.addItems(spellList)

        self.cfgrid.addWidget(self.lsSpellO, 1, 7)
        self.cfgrid.addWidget(self.lslevel, 1, 8)

    def addLS(self):
        """
        Add a learned spell to the list, based on what was entered.
        """
        print("Adding learned spell")
        chosenSpell = self.lsSpellO.currentText()
        if (int)(self.lslevel.text()) <= (int)(self.levelT.text()):
            popup("You cannot add a spell at an earlier level than the Persona's base level", "Critical")
            return
        if chosenSpell != "":
            print("Ok")
            self.lsdic[chosenSpell] = self.lslevel.text()
            self.listLS.addItem(chosenSpell + " at level " + self.lslevel.text())
            self.lslevel.setText("")
            self.lsSpellO.setCurrentIndex(0)
            return
        popup("You must choose a spell", "Critical")

    def delLS(self):
        """
        Remove the selected learned spell from the list
        """
        print("Deleting learned spell")
        key = ""
        i = 0
        while len(self.listLS.currentItem().text()) > i:
            if self.listLS.currentItem().text()[i] == " " and \
               self.listLS.currentItem().text()[i+1] == "a" and \
               self.listLS.currentItem().text()[i+2] == "t":  # TODO EWWWWWW
                break
            key += self.listLS.currentItem().text()[i]
            i = i + 1
        print(key)
        print(self.lsdic.pop(key))
        self.listLS.takeItem(self.listLS.currentRow())


    def loadPer(self, name):
        """
        Load a certain Persona from file.

        :param str name: name of Persona to load
        """
        data = json_reader.readOne(name, 'pers')
        self.nameT.setText(data["name"])
        self.textT.setText(data["desc"])
        self.strT.setText(data["stats"][0])
        self.magT.setText(data["stats"][1])
        self.endT.setText(data["stats"][2])
        self.agiT.setText(data["stats"][3])
        self.luckT.setText(data["stats"][4])
        self.levelT.setText(data["level"])

        self.arcO.setCurrentIndex(
            [self.arcO.itemText(i) for i in range(self.arcO.count())].index(data["arcana"])
        )

        self.listEL1.setCurrentIndex(
            [self.listEL1.itemText(i) for i in range(self.listEL1.count())].index(data["heritage"][0])
        )
        self.listEL2.setCurrentIndex(
            [self.listEL2.itemText(i) for i in range(self.listEL2.count())].index(data["heritage"][1])
        )

        self.slashO.setCurrentIndex(
            [self.slashO.itemText(i) for i in range(self.slashO.count())].index(data["resistance"][0])
        )
        self.strikeO.setCurrentIndex(
            [self.strikeO.itemText(i) for i in range(self.strikeO.count())].index(data["resistance"][1])
        )
        self.pierceO.setCurrentIndex(
            [self.pierceO.itemText(i) for i in range(self.pierceO.count())].index(data["resistance"][2])
        )
        self.fireO.setCurrentIndex(
            [self.fireO.itemText(i) for i in range(self.fireO.count())].index(data["resistance"][3])
        )
        self.iceO.setCurrentIndex(
            [self.iceO.itemText(i) for i in range(self.iceO.count())].index(data["resistance"][4])
        )
        self.elecO.setCurrentIndex(
            [self.elecO.itemText(i) for i in range(self.elecO.count())].index(data["resistance"][5])
        )
        self.windO.setCurrentIndex(
            [self.windO.itemText(i) for i in range(self.windO.count())].index(data["resistance"][6])
        )
        self.lightO.setCurrentIndex(
            [self.lightO.itemText(i) for i in range(self.lightO.count())].index(data["resistance"][7])
        )
        self.darkO.setCurrentIndex(
            [self.darkO.itemText(i) for i in range(self.darkO.count())].index(data["resistance"][8])
        )

        i = 0
        for combobox in self.iSpellOs:
            combobox.setCurrentIndex(
                [combobox.itemText(j) for j in range(combobox.count()-1)].index(data["spellDeck"][i])
            )
            i += 1

        self.lsdic = data["spellLearn"]
        self.listLS.clear()
        for spell, level in self.lsdic.items():
            self.listLS.addItem(spell + " at level " + level)

        print("Loaded " + data["name"])

    def edit(self):
        """
        Switch to edit view, also loads the selected Persona.
        """
        try:
            if self.listP.currentItem().text() != "":
                if self.createFrame and not popup("Override any unsaved changes?", "Warning"):
                    return
                self.loadPer(self.listP.currentItem().text())
        except AttributeError:  # To initialize createFrame UI before load
            if self.listP.currentItem().text() != "":
                temp = self.listP.currentItem().text()
                self.buttonFrame.close()
                self.initUI(False)
                self.loadPer(temp)
            else:
                return
        self.createFrame.show()
        self.mainframe.center()
        print("Changed to edit frame")

    def save(self):
        """
        Validate all info and save to file on disk.
        """
        if os.path.exists(json_reader.buildPath("data/pers/"+self.nameT.text()+".json")):
            if not popup("Override existing Persona "+self.nameT.text()+"?", "Question"):
                return
        print("Saving")
        spellDeck = []
        for combobox in self.iSpellOs:
            spellDeck.append(combobox.currentText())
        stats = [self.strT.text(), self.magT.text(), self.endT.text(), self.agiT.text(), self.luckT.text()]
        res = [self.slashO.currentText(), self.strikeO.currentText(), self.pierceO.currentText(),
               self.fireO.currentText(), self.iceO.currentText(), self.elecO.currentText(),
               self.windO.currentText(), self.lightO.currentText(), self.darkO.currentText()]
        try:
            (int)(self.levelT.text())
            (int)(self.strT.text())
            (int)(self.magT.text())
            (int)(self.endT.text())
            (int)(self.agiT.text())
            (int)(self.luckT.text())
        except ValueError:
            popup("There is a number entry that isn't valid.\nEntries requiring numbers are:\nLEVEL\nSTR"
                  "\nMAG\nEND\nAGI\nLUCK", "Critical")
            print("Not Saved")
            return
        if not (self.nameT.text() and not self.nameT.text().isspace()):
            popup("No name entered for your Persona. Name is a required field.", "Critical")
            print("No Name, not saved")
            return
        toWrite = Persona(
            self.nameT.text(),
            self.arcO.currentText(),
            self.levelT.text(),
            self.textT.toPlainText(),
            spellDeck,
            self.lsdic,
            stats,
            res,
            [self.listEL1.currentText(), self.listEL2.currentText()]
        )
        json_reader.writeOne(toWrite, 'pers')
        temp = self.nameT.text()
        if (temp not in [self.listP.item(i).text() for i in range(self.listP.count())]):
            self.listP.addItem(temp)
        self.loadPer(temp)
        print("Saved Persona")

    def remove(self):
        """
        Remove a created Persona from the list and delete the file on disk.
        """
        if self.listP.currentItem().text() == "":
            return
        if not popup(
                "Are you certain you want to completely remove this Persona?\n(Cannot be undone)", "Warning"
            ):
            return
        print("Removing Persona " + self.listP.currentItem().text())
        json_reader.deletePer(self.listP.currentItem().text())
        self.listP.takeItem(
            [self.listP.item(i).text() for i in range(self.listP.count())].index(
                self.listP.currentItem().text())
        )

    def new(self):
        """
        Open an empty Persona edit view.
        """
        if self.createFrame and not popup("Override any unsaved changes?", "Warning"):
            return
        if self.createFrame:
            self.createFrame.close()
        self.buttonFrame.close()
        self.initUI(False)
        self.createFrame.show()
        self.mainframe.center()
        print("Created")

    def back(self):
        """
        Return to the parent widget.
        """
        print("Returned to main screen")
        self.mainframe.changeState(self.op)
Beispiel #20
0
class CustomInputDialog(QDialog):
    def __init__(self, parent, title):
        super().__init__(parent)
        self.setWindowTitle(title)
        self._new_item = None
        self._editable_text = ""
        self._accepted_item = None
        self._list_wg = QListWidget()
        self._list_wg.itemDoubleClicked.connect(
            self._handle_item_double_clicked)
        self._list_wg.itemChanged.connect(self._handle_item_changed)

    def accept(self, item=None):
        if item is None:
            item = self._list_wg.currentItem()
        if item is self._new_item and item.text() == self._editable_text:
            self._list_wg.editItem(item)
            return
        self._accepted_item = item
        self.done(QDialog.Accepted)

    def reject(self):
        self.done(QDialog.Rejected)

    @Slot("QListWidgetItem")
    def _handle_item_double_clicked(self, item):
        self.accept(item)

    @Slot("QListWidgetItem")
    def _handle_item_changed(self, item):
        if item is self._new_item and item.text() != self._editable_text:
            item.setForeground(qApp.palette().text())  # pylint: disable=undefined-variable
            self._new_item = None

    @classmethod
    def get_item(cls,
                 parent,
                 title,
                 label,
                 items,
                 icons=None,
                 editable_text=""):
        if icons is None:
            icons = {}
        dialog = cls(parent, title)
        layout = QVBoxLayout(dialog)
        label = QLabel(label)
        label.setWordWrap(True)
        if editable_text:
            dialog._editable_text = editable_text
            items.append(dialog._editable_text)
        dialog._list_wg.addItems(items)
        for item in dialog._list_wg.findItems("*", Qt.MatchWildcard):
            icon = icons.get(item.text())
            if icon is not None:
                item.setData(Qt.DecorationRole, icon)
        if editable_text:
            dialog._new_item = dialog._list_wg.item(dialog._list_wg.count() -
                                                    1)
            dialog._new_item.setFlags(dialog._new_item.flags()
                                      | Qt.ItemIsEditable)
            foreground = qApp.palette().text()  # pylint: disable=undefined-variable
            color = foreground.color()
            color.setAlpha(128)
            foreground.setColor(color)
            dialog._new_item.setForeground(foreground)
        button_box = QDialogButtonBox()
        button_box.setStandardButtons(QDialogButtonBox.Cancel
                                      | QDialogButtonBox.Ok)
        layout.addWidget(label)
        layout.addWidget(dialog._list_wg)
        layout.addWidget(button_box)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.close)
        if dialog.exec_() == QDialog.Rejected:
            return None
        return dialog._accepted_item.text()
Beispiel #21
0
class MyWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.streamfile = ""
        self.streams = {}
        scriptdir = os.path.dirname(os.path.realpath(__file__))
        icon = (scriptdir + os.path.sep + "icon/pyradio.ico")
        self.setWindowIcon(QtGui.QIcon(icon))
        self.setStuff()
        # Tray
        self.tray = QSystemTrayIcon()
        self.tray.setIcon(QtGui.QIcon(icon))
        self.tray.activated.connect(self.call)

        self.icon = QtGui.QIcon()
        self.icon.addFile(icon)
        self.setWindowIcon(self.icon)

        # tray menu
        self.trayIconMenu = QtWidgets.QMenu()
        self.quitAction = QtWidgets.QAction("&Quit", triggered=self.close)
        self.trayIconMenu.addAction(self.quitAction)
        self.tray.setContextMenu(self.trayIconMenu)
        self.trayIconMenu.setStyleSheet(open("css/main.css", "r").read())

        # Media player
        self.radio = vlc.MediaPlayer()
        self.playing = False

        self.pal = QtGui.QPalette(self.palette())

        self.playing_label = QLabel("Stopped")
        self.label = QLabel("Radios:")

        self.label.setAlignment(Qt.AlignCenter)
        self.playing_label.setAlignment(Qt.AlignCenter)
        self.btn = QPushButton("Play/Stop")
        self.btn.clicked.connect(self.control)
        self.list = QListWidget()
        self.list.itemDoubleClicked.connect(self.control)

        self.edit = QPushButton("Edit Radios")
        self.edit.clicked.connect(self.openfile)
        self.refresh = QPushButton("Refresh")
        self.refresh.clicked.connect(self.refreshstreams)

        self.slider = QSlider(QtGui.Qt.Horizontal)
        self.slider.setMaximum(100)
        self.slider.setValue(self.volume)
        self.slider.valueChanged.connect(self.changeVolume)

        self.setStyleSheet(open("css/main.css", "r").read())

        self.refreshstreams()

        self.current = ""
        self.buttons = QHBoxLayout()

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.list)
        self.layout.addWidget(self.playing_label)
        self.layout.addWidget(self.slider)
        self.buttons.addWidget(self.btn)
        self.buttons.addWidget(self.edit)
        self.buttons.addWidget(self.refresh)

        self.layout.addLayout(self.buttons)
        self.setLayout(self.layout)

    def setStuff(self):
        info = self.readInfo()
        print(info)
        if len(info) == 0:
            info = ["", "", "", "", ""]
        if (info[0] == ""):
            self.volume = 80
        else:
            self.volume = int(info[0])
        if info[3].strip() == "false" or info[3] == "":
            if info[1] == "":
                self.resize(800, 600)
            else:
                w, h = info[1].split(" ")
                self.resize(int(w), int(h))
            if info[2] != "":
                x, y = info[2].split(" ")
                self.move(int(x), int(y))
        else:
            self.showMaximized()
        if len(info) < 5:
            # show dialog
            self.chooseStreamfile()
        else:
            self.streamfile = info[4].strip()

    def chooseStreamfile(self):
        self.dialog = QFileDialog(self)
        self.dialog.setFileMode(QFileDialog.AnyFile)
        if self.dialog.exec_():
            filename = self.dialog.selectedFiles()
            self.streamfile = filename[0]

    def changeVolume(self):
        self.volume = self.slider.value()
        self.radio.audio_set_volume(self.volume)

    def getVolume(self):
        try:
            with open("data", "r") as file:
                return int(file.readline())
        except:
            with open("data", "w") as file:
                file.write(str(80))
                return 80

    def control(self):
        if self.playing and self.current == self.streams[
                self.list.currentItem().text()]:
            self.stop()
        else:
            self.radio.stop()
            self.play()

    def stop(self):
        self.radio.stop()
        self.playing_label.setText("Stopped")
        self.playing = False

    def play(self):
        self.current = self.list.currentItem().text()
        for i in self.streams:
            if self.current == i:
                self.current = self.streams[i]
                break
        self.radio = vlc.MediaPlayer(self.current)
        self.radio.play()
        self.radio.audio_set_volume(self.slider.value())
        self.playing_label.setText("Playing")
        self.playing = True
        self.tray.showMessage(self.list.currentItem().text(), "",
                              self.tray.icon(), 1000)

    def next(self):
        isthis = False
        self.current = self.list.currentItem().text()
        for n, i in enumerate(self.streams):
            if isthis:
                self.list.setCurrentRow(n)
                break
            else:
                if self.current == i:
                    isthis = True
                    if n + 1 >= len(self.streams):
                        self.list.setCurrentRow(0)
        self.stop()
        self.play()

    def previous(self):
        isthis = False
        self.current = self.list.currentItem().text()
        for n, i in enumerate(self.streams):
            if isthis:
                self.list.setCurrentRow(n - 2)
                break
            else:
                if self.current == i:
                    isthis = True
                    if n - 1 < 0:
                        self.list.setCurrentRow(len(self.streams) - 1)
                        break
                    elif n == len(self.streams) - 1:
                        self.list.setCurrentRow(n - 1)

        self.stop()
        self.play()

    def openfile(self):
        # Opens radios.txt
        webbrowser.open(self.streamfile)

    def refreshstreams(self):

        # Refreshes the stream list when button pressed
        if self.list.currentItem():
            current = self.list.currentItem().text()
        else:
            current = None
        self.streams = {}
        try:
            with open(self.streamfile, "r") as file:
                lines = file.readlines()
                for line in lines:
                    nline = line.strip().split(":", 1)
                    self.streams[nline[0]] = nline[1].split("#")[0]
        except:
            self.chooseStreamfile()
            self.refreshstreams()
            return

        self.list.clear()

        for i, n in enumerate(self.streams):
            self.list.addItem(n)
            if n == current:
                self.list.setCurrentRow(i)
        if not self.list.currentItem():
            self.list.setCurrentRow(0)

    def changeEvent(self, event):

        # This minimizes the program to tray when Minimize button pressed

        if event.type() == QEvent.WindowStateChange:
            if self.windowState() & Qt.WindowMinimized:
                print(QSystemTrayIcon.isSystemTrayAvailable())
                if QSystemTrayIcon.isSystemTrayAvailable(
                ) and self.isActiveWindow():
                    event.ignore()
                    self.tray.show()
                    self.hide()
                    self.listener = keyboard.Listener(
                        on_release=self.on_release)
                    self.listener.start()

    def closeEvent(self, event):
        file = open("data", "w+")
        info = str(self.volume) + "\n" + str(self.size().width()) + " " + str(self.size().height()) + "\n" +\
               str(self.pos().x()) + " " + str(self.pos().y()) + "\n"
        if (self.isMaximized()):
            info += "true"
        else:
            info += "false"
        info += "\n"
        info += self.streamfile + "\n"
        file.write(info)
        file.close()

    def readInfo(self):
        try:
            with open("data", "r", encoding="utf-8") as file:
                info = file.readlines()
                return info
        except:
            with open("data", "w", encoding="utf-8") as file:
                file.write("")
                return ""

    def keyReleaseEvent(self, event):

        # This is for media controls when radio is opened

        key = event.key()
        if key == Qt.Key_MediaPlay or key == Qt.Key_MediaTogglePlayPause or \
                key == Qt.Key_MediaPause:
            self.control()
        elif key == Qt.Key_MediaNext:
            self.next()
        elif key == Qt.Key_MediaPrevious:
            self.previous()

    def call(self, reason):
        # This is caled when tray icon is pressed
        if reason == QSystemTrayIcon.ActivationReason.Trigger:
            self.show()
            self.setFocus()
            self.listener.stop()
            del self.listener
            self.tray.hide()
            self.setWindowState(Qt.WindowActive)
        elif reason == QSystemTrayIcon.ActivationReason.Context:
            self.tray.contextMenu().show()
        elif reason == QSystemTrayIcon.ActivationReason.MiddleClick:
            print("Middle click on tray icon")
        else:
            print("Unknown reason")

    def on_release(self, key):
        # This is for media controls when program in tray.
        try:
            if key == keyboard.Key.media_play_pause:  # might need a different key
                self.control()
            elif keyboard.Key.media_next == key:  # might need a different key
                self.next()
            elif keyboard.Key.media_previous == key:  # might need a different key
                self.previous()
        except AttributeError as e:
            print(e)
Beispiel #22
0
class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle("{} {}".format(config.APP_NAME,
                                           config.APP_VERSION))
        self.setMinimumWidth(600)
        self.setStyleSheet(config.STYLESHEET)

        # Widgets
        self.import_label = QLabel(
            'Import a CSV class list to add a new class of reports.')
        self.import_button = QPushButton('Import CSV...')
        self.saved_label = QLabel('You have the following saved classes:')
        self.saved_listwidget = QListWidget(self)
        self.edit_comment_bank_button = QPushButton('Edit Comment Bank')
        self.edit_reports_button = QPushButton('Edit Reports')
        self.export_reports_button = QPushButton('Export Reports')
        self.delete_class_button = QPushButton('Delete')

        # Layout
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.import_label)
        self.layout.addWidget(self.import_button)
        self.layout.addWidget(self.saved_label)
        self.layout.addWidget(self.saved_listwidget)
        self.layout.addWidget(self.edit_comment_bank_button)
        self.layout.addWidget(self.edit_reports_button)
        self.layout.addWidget(self.export_reports_button)
        self.layout.addWidget(self.delete_class_button)

        # Initial run of listbox update
        self.update_saved_list()

        # Slot connections
        self.import_button.clicked.connect(self.import_csv)
        self.saved_listwidget.itemSelectionChanged.connect(
            self.do_update_selection)
        self.edit_comment_bank_button.clicked.connect(self.edit_comment_bank)
        self.edit_reports_button.clicked.connect(self.edit_reports)
        self.export_reports_button.clicked.connect(self.export_reports)
        self.delete_class_button.clicked.connect(self.delete_class)

        self.widget = QWidget()
        self.widget.setLayout(self.layout)

        self.setCentralWidget(self.widget)

    @Slot()
    def import_csv(self):
        # TODO proper validation for input will mean building this dialog out
        # properly using QLineEdit
        subject_name, ok = QInputDialog().getText(
            self, "Subject Name", "Enter a name or code for the subject:")
        if subject_name and ok:
            filename, filt = QFileDialog.getOpenFileName(
                self, "Import CSV", os.path.expanduser("~"),
                "Comma Separated (*.csv)")
            if could_try_harder.import_class_list(filename, subject_name):
                self.update_saved_list()
            else:
                # TODO better error handling here
                print("Import Failed")
                return

    def update_saved_list(self):
        self.saved_listwidget.clear()
        self.saved_listwidget.addItems(could_try_harder.get_saved_list())
        self.do_update_selection()

    @Slot()
    def do_update_selection(self):
        if self.saved_listwidget.selectedItems():
            state = True
        else:
            state = False
        self.edit_comment_bank_button.setEnabled(state)
        self.edit_reports_button.setEnabled(state)
        self.export_reports_button.setEnabled(state)
        self.delete_class_button.setEnabled(state)

    @Slot()
    def edit_comment_bank(self):
        subject_name = self.saved_listwidget.currentItem().text()
        self.edit_comment_bank_window = EditCommentBankWindow(subject_name)
        self.edit_comment_bank_window.show()

    @Slot()
    def edit_reports(self):
        subject_name = self.saved_listwidget.currentItem().text()
        self.edit_reports_window = EditReportsWindow(subject_name)
        self.edit_reports_window.show()

    @Slot()
    def export_reports(self):
        subject_name = self.saved_listwidget.currentItem().text()
        filename, filt = QFileDialog.getSaveFileName(self, "Export",
                                                     os.path.expanduser("~"),
                                                     "Text Files (*.txt)")
        if filename:
            if not could_try_harder.export(subject_name, filename):
                # TODO better error handling here
                print("Export failed.")
                return

    @Slot()
    def delete_class(self):
        confirm_msg = QMessageBox(self)
        confirm_msg.setWindowTitle("Confirm")
        confirm_msg.setText(
            "This will delete the class, comment bankd and reports.")
        confirm_msg.setInformativeText("Continue?")
        confirm_msg.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
        confirm_msg.setDefaultButton(QMessageBox.Yes)
        confirm = confirm_msg.exec()
        if confirm == QMessageBox.Yes:
            subject_name = self.saved_listwidget.currentItem().text()
            if not could_try_harder.delete(subject_name):
                # TODO better error handling here
                print("Delete failed.")
            self.update_saved_list()
Beispiel #23
0
class CreationContainer(QWidget):
    """
    Apparently just another level of parent class for social link display.
    Man I was stupid.
    Still am luigi2hands

    :param MainFrame mainframe: application mainframe
    :param QWidget op: parent widget
    :param int load: index to load maybe?
    """
    def __init__(self, mainframe, op, load):
        QWidget.__init__(self)
        self.mainframe = mainframe
        self.op = op
        self.op.cc = self
        self.load = load

        # View initializers...
        self.actions = None
        self.window = None

        self.initUI()
        self.op.grid.addWidget(self, 0, 0, 2, 10)

    def initUI(self):
        """
        Initialize the GUI.
        Does lots of stuff.
        """
        self.grid = QGridLayout()
        self.setLayout(self.grid)

        self.actions = self.op.link.getIDs()
        self.actions.append("New element")
        types = ["Info", "Speak", "Camera Change", "Movement"]

        self.save = QPushButton(self, text="Save")
        self.grid.addWidget(self.save, 3, 0)

        self.existing_connections = QListWidget(self)
        self.populateExistingConnections()
        self.grid.addWidget(self.existing_connections, 1, 5, 2, 1)

        self.next = QComboBox(self)
        self.next.addItems(self.actions)
        self.next.setMaximumWidth(150)
        if self.load != 0:
            self.next.setCurrentIndex(self.op.i)
        self.grid.addWidget(self.next, 3, 2)

        self.window = None

        self.actOM = QComboBox(self)
        self.actOM.addItems(types)
        self.actOM.activated.connect(self.changeFrame)
        self.grid.addWidget(self.actOM, 0, 0, 1, 2)

        self.connect()
        self.next.setCurrentIndex(self.next.count() - 1)

        self.backB = QPushButton(self, text="Back to List Menu")
        self.backB.clicked.connect(self.back)
        self.grid.addWidget(self.backB, 3, 4)

        self.lead = QLabel(self, text="Leads to:")
        self.lead.setAlignment(Qt.AlignRight)
        self.grid.addWidget(self.lead, 3, 1)

        self.connectB = QPushButton(self, text="Connect")
        self.connectB.clicked.connect(self.lightConnect)
        self.grid.addWidget(self.connectB, 3, 3)

        self.follow_path = QPushButton(self, text="Enter linked element")
        self.follow_path.clicked.connect(self.follow)
        self.grid.addWidget(self.follow_path, 0, 6, 2, 1)

        self.rmvRel = QPushButton(self, text="Remove this connection")
        self.rmvRel.clicked.connect(self.removeRelation)
        self.grid.addWidget(self.rmvRel, 1, 6, 2, 1)

        self.conLab = QLabel(self, text="This action connects to:")
        self.grid.addWidget(self.conLab, 0, 5)

    def removeRelation(self):
        """
        Remove a relation, which will also delete the uniquely dependant subtree.
        """
        if not self.existing_connections.currentItem() or \
           not popup("Are you sure you want to remove this relation? Any elements with a unique dependancy "
                     "on this relation will also be deleted.\nIt is highly recommended you take a look at "
                     "the graphical view of the tree in order to see the potential effects of the deletion.",
                     "Warning"):
            return
        self.op.link.delRelation(
            self.op.i,
            self.actions.index(self.existing_connections.currentItem().text()))
        self.populateExistingConnections()
        self.updateElementList()
        self.op.linkstored.save()

    def populateExistingConnections(self):
        """
        Display all the existing connections of the current node.
        """
        self.existing_connections.clear()
        for relation in self.op.link.getRelations(self.op.i):
            self.existing_connections.addItem(
                self.op.link.getOneID(self.op.link.getItem(relation)))

    def back(self):
        """
        Return to the higher-level cutscene container view...
        """
        if not popup("Return to list main menu?\n(Lose any unsaved changes)",
                     "Warning"):
            return
        self.close()
        self.op.cc = None
        self.op.viewF(False)

    def follow(self):
        """
        Move on to the edit view of the selected relationship.
        """
        if not self.existing_connections.currentItem() or \
           self.existing_connections.currentItem().text() == "":
            return
        self.next.setCurrentIndex([
            self.next.itemText(i) for i in range(self.next.count())
        ].index(self.existing_connections.currentItem().text()))
        self.op.i = self.actions.index(self.next.currentText())
        self.connect()
        self.next.setCurrentIndex(self.next.count() - 1)

    def lightConnect(self):
        """
        Create a relationship between the current action and another.
        """
        if not self.checkCached():
            popup("Please save this action before linking it to a new one",
                  "Information")
            return
        if self.next.currentText() == "New element":
            self.op.link.addRelation(self.op.i, self.op.link.size())
            print("Linked to index " + str(self.op.link.size()))
            self.op.i = self.op.link.size()
            self.load = 0
            self.changeFrame(0)
            self.updateElementList()
        else:
            self.op.link.addRelation(
                self.op.i, self.actions.index(self.next.currentText()))
            print("Linked to index " +
                  str(self.actions.index(self.next.currentText())))
        self.populateExistingConnections()

    def connect(self):
        """
        Create a relationship between the current action and another, and enter the edit view of the
        relationship.

        :raises Exception: if the requested new action's type can't be processed (should never happen)
        """
        print(self.next.currentText())
        if self.next.currentText() == "New element":
            self.load = 0
            self.changeFrame(0)
        else:
            if isinstance(
                    self.op.link.getItem(
                        self.actions.index(self.next.currentText())), Info):
                self.actOM.setCurrentIndex(0)
            elif isinstance(
                    self.op.link.getItem(
                        self.actions.index(self.next.currentText())), Speak):
                self.actOM.setCurrentIndex(1)
            elif isinstance(
                    self.op.link.getItem(
                        self.actions.index(self.next.currentText())), Camera):
                self.actOM.setCurrentIndex(2)
            elif isinstance(
                    self.op.link.getItem(
                        self.actions.index(self.next.currentText())),
                    Movement):
                self.actOM.setCurrentIndex(3)
            else:
                raise Exception("Not a type!")
            self.load = self.op.link.getItem(
                self.actions.index(self.next.currentText()))
            self.changeFrame(0)

    def checkCached(self):
        """
        Check if the current element has been saved before.

        :returns: if the element has been saved
        :rtype: bool
        """
        print(len(self.op.link.items) - 1)
        print(self.op.i)
        if self.op.link.getItem(self.op.i) == []:
            return False
        return True

    def updateElementList(self):
        """
        Update the relationships list, I think.
        """
        self.next.clear()
        self.actions = self.op.link.getIDs()
        self.actions.append("New element")
        self.next.addItems(self.actions)
        self.next.setCurrentIndex(len(self.actions) - 1)

    def changeFrame(self, _):
        """
        Change view to edit a certain type of action.

        :param objct _: unused, but required by caller
        """
        print("Changed to " + self.actOM.currentText())
        try:
            self.window.close()
        except AttributeError:
            pass  # No window open
        if self.actOM.currentText() == "Speak":
            self.window = SpeakFrame(self, self.load)
        elif self.actOM.currentText() == "Camera Change":
            self.window = CameraFrame(self, self.load)
        elif self.actOM.currentText() == "Movement":
            self.window = MoveFrame(self, self.load)
        else:  # self.actOM.currentText() == "Info":
            self.window = InfoFrame(self, self.load)
        try:
            self.save.clicked.disconnect()
        except:  #pylint: disable=bare-except
            pass
        self.save.clicked.connect(self.window.save)
        self.populateExistingConnections()
        self.updateElementList()
Beispiel #24
0
class PiecesPlayer(QWidget):
    """ main widget of application (used as widget inside PiecesMainWindow) """
    def __init__(self, parent):
        """ standard constructor: set up class variables, ui elements
            and layout """

        # TODO: split current piece info into separate lineedits for title, album name and length
        # TODO: make time changeable by clicking next to the slider (not only
        #       by dragging the slider)
        # TODO: add "about" action to open info dialog in new "help" menu
        # TODO: add option to loop current piece (?)
        # TODO: more documentation
        # TODO: add some "whole piece time remaining" indicator? (complicated)
        # TODO: implement a playlist of pieces that can be edited and enable
        #       going back to the previous piece (also un- and re-shuffling?)
        # TODO: implement debug dialog as menu action (if needed)

        if not isinstance(parent, PiecesMainWindow):
            raise ValueError('Parent widget must be a PiecesMainWindow')

        super(PiecesPlayer, self).__init__(parent=parent)

        # -- declare and setup variables for storing information --
        # various data
        self._set_str = ''  # string of currently loaded directory sets
        self._pieces = {}  # {<piece1>: [<files piece1 consists of>], ...}
        self._playlist = []  # list of keys of self._pieces (determines order)
        self._shuffled = True  # needed for (maybe) reshuffling when looping
        # doc for self._history:
        # key: timestamp ('HH:MM:SS'),
        # value: info_str of piece that started playing at that time
        self._history = {}
        self._status = 'Paused'
        self._current_piece = {'title': '', 'files': [], 'play_next': 0}
        self._default_volume = 60  # in percent from 0 - 100
        self._volume_before_muted = self._default_volume
        # set to true by self.__event_movement_ended and used by self.__update
        self._skip_to_next = False
        # vlc-related variables
        self._vlc_instance = VLCInstance()
        self._vlc_mediaplayer = self._vlc_instance.media_player_new()
        self._vlc_mediaplayer.audio_set_volume(self._default_volume)
        self._vlc_medium = None
        self._vlc_events = self._vlc_mediaplayer.event_manager()

        # -- create and setup ui elements --
        # buttons
        self._btn_play_pause = QPushButton(QIcon(get_icon_path('play')), '')
        self._btn_previous = QPushButton(QIcon(get_icon_path('previous')), '')
        self._btn_next = QPushButton(QIcon(get_icon_path('next')), '')
        self._btn_volume = QPushButton(QIcon(get_icon_path('volume-high')), '')
        self._btn_loop = QPushButton(QIcon(get_icon_path('loop')), '')
        self._btn_loop.setCheckable(True)
        self._btn_play_pause.clicked.connect(self.__action_play_pause)
        self._btn_previous.clicked.connect(self.__action_previous)
        self._btn_next.clicked.connect(self.__action_next)
        self._btn_volume.clicked.connect(self.__action_volume_clicked)
        # labels
        self._lbl_current_piece = QLabel('Current piece:')
        self._lbl_movements = QLabel('Movements:')
        self._lbl_time_played = QLabel('00:00')
        self._lbl_time_left = QLabel('-00:00')
        self._lbl_volume = QLabel('100%')
        # needed so that everything has the same position
        # independent of the number of digits of volume
        self._lbl_volume.setMinimumWidth(55)
        # sliders
        self._slider_time = QSlider(Qt.Horizontal)
        self._slider_volume = QSlider(Qt.Horizontal)
        self._slider_time.sliderReleased.connect(
            self.__event_time_changed_by_user)
        self._slider_volume.valueChanged.connect(self.__event_volume_changed)
        self._slider_time.setRange(0, 100)
        self._slider_volume.setRange(0, 100)
        self._slider_volume.setValue(self._default_volume)
        self._slider_volume.setMinimumWidth(100)
        # other elements
        self._checkbox_loop_playlist = QCheckBox('Loop playlist')
        self._lineedit_current_piece = QLineEdit()
        self._lineedit_current_piece.setReadOnly(True)
        self._lineedit_current_piece.textChanged.connect(
            self.__event_piece_text_changed)
        self._listwidget_movements = QListWidget()
        self._listwidget_movements.itemClicked.connect(
            self.__event_movement_selected)

        # -- create layout and insert ui elements--
        self._layout = QVBoxLayout(self)
        # row 0 (name of current piece)
        self._layout_piece_name = QHBoxLayout()
        self._layout_piece_name.addWidget(self._lbl_current_piece)
        self._layout_piece_name.addWidget(self._lineedit_current_piece)
        self._layout.addLayout(self._layout_piece_name)
        # rows 1 - 5 (movements of current piece)
        self._layout.addWidget(self._lbl_movements)
        self._layout.addWidget(self._listwidget_movements)
        # row 6 (time)
        self._layout_time = QHBoxLayout()
        self._layout_time.addWidget(self._lbl_time_played)
        self._layout_time.addWidget(self._slider_time)
        self._layout_time.addWidget(self._lbl_time_left)
        self._layout.addLayout(self._layout_time)
        # row 7 (buttons and volume)
        self._layout_buttons_and_volume = QHBoxLayout()
        self._layout_buttons_and_volume.addWidget(self._btn_play_pause)
        self._layout_buttons_and_volume.addWidget(self._btn_previous)
        self._layout_buttons_and_volume.addWidget(self._btn_next)
        self._layout_buttons_and_volume.addWidget(self._btn_loop)
        self._layout_buttons_and_volume.addSpacing(40)
        # distance between loop and volume buttons: min. 40, but stretchable
        self._layout_buttons_and_volume.addStretch()
        self._layout_buttons_and_volume.addWidget(self._btn_volume)
        self._layout_buttons_and_volume.addWidget(self._slider_volume)
        self._layout_buttons_and_volume.addWidget(self._lbl_volume)
        self._layout.addLayout(self._layout_buttons_and_volume)

        # -- setup hotkeys --
        self._KEY_CODES_PLAY_PAUSE = [269025044]
        self._KEY_CODES_NEXT = [269025047]
        self._KEY_CODES_PREVIOUS = [269025046]
        self._keyboard_listener = keyboard.Listener(on_press=self.__on_press)
        self._keyboard_listener.start()
        QShortcut(QKeySequence('Space'), self, self.__action_play_pause)

        # -- various setup --
        self._timer = QTimer(self)
        self._timer.timeout.connect(self.__update)
        self._timer.start(100)  # update every 100ms
        self.setMinimumWidth(900)
        self.setMinimumHeight(400)
        # get directory set(s) input and set up self._pieces
        # (exec_ means we'll wait for the user input before continuing)
        DirectorySetChooseDialog(self, self.set_pieces_and_playlist).exec_()
        # skip to next movement / next piece when current one has ended
        self._vlc_events.event_attach(VLCEventType.MediaPlayerEndReached,
                                      self.__event_movement_ended)

    def __action_next(self):
        """ switches to next file in self._current_piece['files']
            or to the next piece, if the current piece has ended """

        reset_pause_after_current = False

        # current movement is last of the current piece
        if self._current_piece['play_next'] == -1:
            if len(self._playlist) == 0:  # reached end of playlist
                if self._btn_loop.isChecked():
                    self._playlist = list(self._pieces.keys())
                    if self._shuffled:
                        shuffle(self._playlist)
                    return

                if self._status == 'Playing':
                    self.__action_play_pause()
                self._current_piece['title'] = ''
                self._current_piece['files'] = []
                self._current_piece['play_next'] = -1
                self._lineedit_current_piece.setText('')
                self.__update_movement_list()
                self.parentWidget().update_status_bar(
                    self._status, 'End of playlist reached.')
                return
            else:
                if self.parentWidget().get_exit_after_current():
                    self.parentWidget().exit()
                if self.parentWidget().get_pause_after_current():
                    self.__action_play_pause()
                    reset_pause_after_current = True
                    # reset of the menu action will be at the end of this
                    # function, or else we won't stay paused

                self._current_piece['title'] = self._playlist.pop(0)
                self._current_piece['files'] = [
                    p[1:-1] for p in self._pieces[self._current_piece['title']]
                ]
                # some pieces only have one movement
                self._current_piece['play_next'] = \
                    1 if len(self._current_piece['files']) > 1 else -1
                self.__update_vlc_medium(0)
                self._lineedit_current_piece.setText(
                    create_info_str(self._current_piece['title'],
                                    self._current_piece['files']))
                self.__update_movement_list()
                self._history[datetime.now().strftime('%H:%M:%S')] = \
                    self._lineedit_current_piece.text()
        else:
            self.__update_vlc_medium(self._current_piece['play_next'])
            # next is last movement
            if self._current_piece['play_next'] == \
               len(self._current_piece['files']) - 1:
                self._current_piece['play_next'] = -1
            else:  # there are at least two movements of current piece left
                self._current_piece['play_next'] += 1
        if self._status == 'Paused' and not reset_pause_after_current:
            self.__action_play_pause()
        elif reset_pause_after_current:
            self.parentWidget().set_pause_after_current(False)
        else:
            self._vlc_mediaplayer.play()
        self.parentWidget().update_status_bar(
            self._status,
            f'{len(self._pieces) - len(self._playlist)}/{len(self._pieces)}')

    def __action_play_pause(self):
        """ (gets called when self._btn_play_pause is clicked)
            toggles playing/pausing music and updates everything as needed """

        # don't do anything now (maybe end of playlist reached?)
        if self._current_piece['title'] == '':
            return

        if self._status == 'Paused':
            if not self._vlc_medium:
                self.__action_next()
            self._vlc_mediaplayer.play()
            self._btn_play_pause.setIcon(QIcon(get_icon_path('pause')))
            self._status = 'Playing'
        else:
            self._vlc_mediaplayer.pause()
            self._btn_play_pause.setIcon(QIcon(get_icon_path('play')))
            self._status = 'Paused'
        self.parentWidget().update_status_bar(
            self._status,
            f'{len(self._pieces) - len(self._playlist)}/{len(self._pieces)}')

    def __action_previous(self):
        """ (called when self._btn_previous ist clicked)
            goes back one movement of the current piece, if possible
            (cannot go back to previous piece) """

        # can't go back to previous piece, but current one has no or one movement
        if len(self._current_piece['files']) <= 1:
            pass
        # currently playing first movement, so nothing to do as well
        elif self._current_piece['play_next'] == 1:
            pass
        else:  # we can go back one movement
            # currently at last movement
            if self._current_piece['play_next'] == -1:
                # set play_next to last movement
                self._current_piece['play_next'] = \
                    len(self._current_piece['files']) - 1
            else:  # currently before last movement
                # set play_next to current movement
                self._current_piece['play_next'] -= 1
            self._vlc_mediaplayer.stop()
            self.__update_vlc_medium(self._current_piece['play_next'] - 1)
            self._vlc_mediaplayer.play()

    def __action_volume_clicked(self):
        """ (called when self._btn_volume is clicked)
            (un)mutes volume """

        if self._slider_volume.value() == 0:  # unmute volume
            self._slider_volume.setValue(self._volume_before_muted)
        else:  # mute volume
            self._volume_before_muted = self._slider_volume.value()
            self._slider_volume.setValue(0)

    def __event_movement_ended(self, event):
        """ (called when self._vlc_media_player emits a MediaPlayerEndReached
            event)
            sets self._skip_to_next to True so the next self.__update call
            will trigger self.__action_next """

        self._skip_to_next = True

    def __event_movement_selected(self):
        """ (called when self._listwidget_movements emits itemClicked)
            skips to the newly selected movement """

        index = self._listwidget_movements.indexFromItem(
            self._listwidget_movements.currentItem()).row()
        # user selected a movement different from the current one
        if index != self.__get_current_movement_index():
            self._current_piece['play_next'] = index
            self.__action_next()

    def __event_piece_text_changed(self):
        """ (called when self._lineedit_current_piece emits textChanged)
            ensures that the user sees the beginning of the text in
            self._lineedit_current_piece (if text is too long, the end will be
            cut off and the user must scroll manually to see it) """

        self._lineedit_current_piece.setCursorPosition(0)

    def __event_volume_changed(self):
        """ (called when value of self._slider_volume changes)
            updates text of self._lbl_volume to new value of self._slider_value
            and sets icon of self._btn_volume to a fitting one """

        volume = self._slider_volume.value()
        self._lbl_volume.setText(f'{volume}%')
        if volume == 0:
            self._btn_volume.setIcon(QIcon(get_icon_path('volume-muted')))
        elif volume < 34:
            self._btn_volume.setIcon(QIcon(get_icon_path('volume-low')))
        elif volume < 67:
            self._btn_volume.setIcon(QIcon(get_icon_path('volume-medium')))
        else:
            self._btn_volume.setIcon(QIcon(get_icon_path('volume-high')))
        self._vlc_mediaplayer.audio_set_volume(volume)

    def __event_time_changed_by_user(self):
        """ (called when user releases self._slider_time)
            synchronizes self._vlc_mediaplayer's position to the new value
            of self._slider_time """

        self._vlc_mediaplayer.set_position(self._slider_time.value() / 100)

    def __get_current_movement_index(self):
        """ returns the index of the current movement in
            self._current_piece['files'] """

        play_next = self._current_piece['play_next']
        if play_next == -1:
            return len(self._current_piece['files']) - 1
        else:
            return play_next - 1

    def __on_press(self, key):
        """ (called by self._keyboard_listener when a key is pressed)
            looks up key code corresponding to key and calls the appropriate
            action function """

        try:  # key is not always of the same type (why would it be?!)
            key_code = key.vk
        except AttributeError:
            key_code = key.value.vk
        if key_code in self._KEY_CODES_PLAY_PAUSE:
            self.__action_play_pause()
        elif key_code in self._KEY_CODES_NEXT:
            self.__action_next()
        elif key_code in self._KEY_CODES_PREVIOUS:
            self.__action_previous()

    def __update_movement_list(self):
        """ removes all items currently in self._listwidget_movements and adds
            everything in self._current_piece['files] """

        # TODO: use ID3 title instead of filename

        while self._listwidget_movements.count() > 0:
            self._listwidget_movements.takeItem(0)
        files = self._current_piece['files']
        if os_name == 'nt':  # windows paths look different than posix paths
            # remove path to file, title number and .mp3 ending
            files = [i[i.rfind('\\') + 3:-4] for i in files]
        else:
            files = [i[i.rfind('/') + 4:-4] for i in files]
        self._listwidget_movements.addItems(files)

    def __update(self):
        """ (periodically called when self._timer emits timeout signal)
            updates various ui elements"""

        # -- select currently playing movement in self._listwidget_movements --
        if self._listwidget_movements.count() > 0:
            self._listwidget_movements.item(
                self.__get_current_movement_index()).setSelected(True)

        # -- update text of self._lbl_time_played and self._lbl_time_left,
        # if necessary --
        if self._vlc_medium:
            try:
                time_played = self._vlc_mediaplayer.get_time()
                medium_duration = self._vlc_medium.get_duration()
                # other values don't make sense (but do occur)
                if (time_played >= 0) and (time_played <= medium_duration):
                    self._lbl_time_played.setText(
                        get_time_str_from_ms(time_played))
                else:
                    self._lbl_time_played.setText(get_time_str_from_ms(0))
                self._lbl_time_left.setText(
                    f'-{get_time_str_from_ms(medium_duration - time_played)}')
            except OSError:  # don't know why that occurs sometimes
                pass

        # -- update value of self._slider_time --
        # don't reset slider to current position if user is dragging it
        if not self._slider_time.isSliderDown():
            try:
                self._slider_time.setValue(
                    self._vlc_mediaplayer.get_position() * 100)
            except OSError:  # don't know why that occurs sometimes
                pass

        if self._skip_to_next:
            self._skip_to_next = False
            self.__action_next()

    def __update_vlc_medium(self, files_index):
        old_medium = self._vlc_medium
        self._vlc_medium = self._vlc_instance.media_new(
            self._current_piece['files'][files_index])
        self._vlc_medium.parse()
        self._vlc_mediaplayer.set_media(self._vlc_medium)
        if old_medium:  # only release if not None
            old_medium.release()

    def get_history(self):
        """ getter function for parent widget """

        return self._history

    def get_set_str(self):
        """ getter function for parent widget """

        return self._set_str if self._set_str != '' \
            else 'No directory set loaded.'

    def set_pieces_and_playlist(self, pieces, playlist, set_str, shuffled):
        """ needed so that DirectorySetChooseDialog can set our self._pieces
            and self._playlist """

        # just to be sure
        if isinstance(pieces, dict) and isinstance(playlist, list):
            self._vlc_mediaplayer.stop()
            self._set_str = set_str
            self._pieces = pieces
            self._playlist = playlist
            self._shuffled = shuffled
            self._current_piece['title'] = self._playlist.pop(0)
            self._current_piece['files'] = [
                p.replace('"', '')
                for p in self._pieces[self._current_piece['title']]
            ]
            self._current_piece['play_next'] = \
                1 if len(self._current_piece['files']) > 1 else -1
            self._lineedit_current_piece.setText(
                create_info_str(self._current_piece['title'],
                                self._current_piece['files']))
            self.__update_movement_list()
            self.__update_vlc_medium(0)
            self._history[datetime.now().strftime('%H:%M:%S')] = \
                self._lineedit_current_piece.text()

    def exit(self):
        """ exits cleanly """

        try:  # don't know why that occurs sometimes
            self._vlc_mediaplayer.stop()
            self._vlc_mediaplayer.release()
            self._vlc_instance.release()
        except OSError:
            pass

        self._keyboard_listener.stop()
Beispiel #25
0
class BrowserWin(QWidget):
    def __init__(self, *args, **kwargs):

        super(BrowserWin, self).__init__(*args, **kwargs)

        # parent Maya window
        self.setParent(mainWindow)
        self.setWindowFlags(Qt.Window)
        # Window settings
        self.setWindowTitle('AC_AssetBrowser')

        # Build window
        self.mainLayout = QVBoxLayout()
        self.btnLayout = QHBoxLayout()
        self.radioLayout = QHBoxLayout()

        # radio buttons load import
        self.radioLabel = QLabel("Action: ")
        self.importRadioBtn = QRadioButton("Import File")
        self.openRadioBtn = QRadioButton("Open File")
        self.saveRadioBtn = QRadioButton("Save File")

        # Find asset directories to load from and populate the drop down
        self.fileType = QComboBox()
        self.__populate_list(self.fileType)
        self.curr_cat = self.fileType.currentText()

        # list of assets in self.list
        self.fileList = QListWidget()
        self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.__populate_list(self.fileList,
                             directory=os.path.join(DIRECTORY, self.curr_cat))

        self.fileName = QLineEdit()

        self.loadBtn = QPushButton("Load Asset")
        self.publishBtn = QPushButton("Publish")
        self.closeBtn = QPushButton("Close")

        # Add widgets to layouts
        self.radioLayout.addWidget(self.radioLabel)
        self.radioLayout.addWidget(self.importRadioBtn)
        self.radioLayout.addWidget(self.openRadioBtn)
        self.radioLayout.addWidget(self.saveRadioBtn)

        self.mainLayout.addLayout(self.radioLayout)

        self.mainLayout.addWidget(self.fileType)
        self.mainLayout.addWidget(self.fileList)
        self.mainLayout.addWidget(self.fileName)

        self.btnLayout.addWidget(self.loadBtn)
        self.btnLayout.addWidget(self.publishBtn)
        self.btnLayout.addWidget(self.closeBtn)

        self.mainLayout.addLayout(self.btnLayout)
        self.setLayout(self.mainLayout)

        # Set state of widgets
        self.importRadioBtn.toggle()
        self.fileName.setPlaceholderText("file_name")
        self.fileName.setEnabled(False)
        self.publishBtn.setEnabled(False)

        # Signals
        self.fileType.currentIndexChanged.connect(self.selectionChanged)
        self.loadBtn.clicked.connect(self.loadBtnCmd)
        self.publishBtn.clicked.connect(self.publishBtnCmd)
        self.closeBtn.clicked.connect(self.closeBtnCmd)
        self.importRadioBtn.toggled.connect(self.onImportToggled)
        self.openRadioBtn.toggled.connect(self.onOpenToggled)
        self.saveRadioBtn.toggled.connect(self.onSaveToggled)

    def __populate_list(self, destination, directory=DIRECTORY):
        _dirs = os.listdir(directory)
        _items = [_dir for _dir in _dirs]

        return destination.addItems(_items)

    def selectionChanged(self):
        self.curr_cat = self.fileType.currentText()
        self.fileList.clear()
        self.__populate_list(self.fileList,
                             directory=os.path.join(DIRECTORY, self.curr_cat))

    def loadBtnCmd(self):
        if self.importRadioBtn.isChecked():
            selected_files = self.fileList.selectedItems()
            for _file in selected_files:
                asset_file = os.path.join(DIRECTORY, self.curr_cat,
                                          _file.text())
                cmds.file(asset_file, i=True)
        elif self.openRadioBtn.isChecked():
            selected_file = self.fileList.currentItem()
            asset_file = os.path.join(DIRECTORY, self.curr_cat,
                                      selected_file.text())
            cmds.file(asset_file, o=True, force=True)
        else:
            print("Did you mean to publish this asset?")

    def publishBtnCmd(self):
        if self.saveRadioBtn.isChecked() and self.fileName.text() is not None:
            path_to_save = os.path.join(DIRECTORY, self.curr_cat,
                                        self.fileName.text())
            cmds.file(rn="{}.ma".format(path_to_save))
            cmds.file(save=True)
            self.fileList.clear()
            self.__populate_list(self.fileList,
                                 directory=os.path.join(
                                     DIRECTORY, self.curr_cat))

    def closeBtnCmd(self):
        self.close()

    def onSaveToggled(self):
        items = self.fileList.selectedItems()
        for item in items:
            item.setSelected(False)
        self.fileName.setEnabled(not self.fileName.isEnabled())
        self.publishBtn.setEnabled(not self.publishBtn.isEnabled())

    def onImportToggled(self):
        if self.importRadioBtn.isChecked():
            self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def onOpenToggled(self):
        if self.openRadioBtn.isChecked():
            items = self.fileList.selectedItems()
            items.pop()
            for item in items:
                item.setSelected(False)
            self.fileList.setSelectionMode(QAbstractItemView.SingleSelection)
Beispiel #26
0
class SelectMatchWindow(QDialog):
    def __init__(self, parent=None):
        super(SelectMatchWindow, self).__init__(parent)
        self.parent = parent
        self.setModal(True)
        self.setWindowTitle("Mérkőzés választása")
        self.resize(600, 400)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        self.read_config()
        self.tournaments = QComboBox()
        self.tournaments.setModelColumn(0)
        self.tournaments.currentIndexChanged.connect(self.torna_valasztas)
        self.layout.addWidget(self.tournaments)
        self.merkozesek = QListWidget()
        self.merkozesek.setFixedHeight(300)
        self.merkozesek.setFixedWidth(500)
        self.merkozesek.itemDoubleClicked.connect(self.start_game)
        self.merkozesek.itemSelectionChanged.connect(self.start_game)
        self.layout.addWidget(self.merkozesek)

        self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonbox.clicked.connect(self.buttonbox_click)
        self.layout.addWidget(self.buttonbox)

        self.load_torna()

    def load_torna(self):
        torna = QSqlQueryModel()
        query = QSqlQuery("select * from torna_settings where aktiv=1")
        torna.setQuery(query)
        if torna.record(0).value(0):
            for i in range(torna.rowCount()):
                self.tournaments.addItem(
                    torna.record(i).value(1),
                    torna.record(i).value(0))  # a value(0) a torna_id
        else:
            print("Nincs aktív torna")

    def torna_valasztas(self, i):
        print(self.tournaments.itemData(i))
        # matches = QSqlRelationalTableModel()
        # matches.setTable("torna_match")
        # matches.setFilter(f'a.torna_id=8889 and a.player1_id=c.player_id and a.player2_id=d.player_id and c.torna_id=a.torna_id and d.torna_id=a.torna_id and a.torna_id=b.torna_id')
        # matches.setFilter(f'torna_name = "{self.tournaments.currentText()}" and torna_resztvevok.torna_id=torna_settings.torna_id and station_id = "{self.station_id}"')
        # matches.setRelation(0, QSqlRelation("torna_settings", "torna_id", "torna_name"))
        # matches.setRelation(2, QSqlRelation("torna_resztvevok", "player_id", "player_name"))
        # matches.setRelation(3, QSqlRelation("torna_resztvevok", "player_id", "player_name"))
        # matches.setRelation(7, QSqlRelation("reged_station", "id", "station_id"))
        # matches.select()
        # print(matches)
        # self.merkozesek.clear()
        # for i in  range(matches.rowCount()):
        #     self.merkozesek.addItem(matches.record(i).value(0) + "\t" +
        #                             str(matches.record(i).value(1)) + "\t" +
        #                             matches.record(i).value(2) + "\t" +
        #                             matches.record(i).value(3) + "\t" +
        #                             matches.record(i).value(4) + "\t" +
        #                             str(matches.record(i).value(5))+ "\t" +
        #                             str(matches.record(i).value(6)))
        matches = QSqlQueryModel()
        # todo itt még nincs táblához kötve a lekérés
        matches_query = QSqlQuery(
            f'SELECT a.match_id,  b.torna_name, c.player_name as nev1, \
        d.player_name as nev2, a.variant, a.sets, a.legsperset FROM `torna_match` a, torna_settings b, torna_resztvevok c, \
        torna_resztvevok d WHERE a.torna_id={self.tournaments.itemData(i)} and a.player1_id=c.player_id and a.player2_id=d.player_id \
        and c.torna_id=a.torna_id and d.torna_id=a.torna_id and a.torna_id=b.torna_id and a.match_status<2'
        )
        matches.setQuery(matches_query)
        self.merkozesek.clear()
        for i in range(matches.rowCount()):
            self.merkozesek.addItem(
                str(matches.record(i).value(0)) + "\t" +
                matches.record(i).value(1) + "\t" +
                matches.record(i).value(2) + "\t" +
                matches.record(i).value(3) + "\t" +
                matches.record(i).value(4) + "\t" +
                str(matches.record(i).value(5)) + "\t" +
                str(matches.record(i).value(6)))

    def buttonbox_click(self, b):
        if b.text() == "OK":
            self.accept()
        elif b.text() == "Cancel":
            self.reject()

    def read_config(self):
        if os.path.exists('config.ini'):
            # Van config.ini, ki kell értékelni
            config.read('config.ini')
            self.station_id = config['DEFAULT'].get('station id')
            self.secret = config['DEFAULT'].get('secret key')
            # todo módosítani kell a torna_match táblát, hogy tartalmazza a tabla mellett a hozzá tartozó secret-et is
        else:
            # Nincs config.ini, alapértékekkel inicializálni
            msg = QMessageBox(self)
            msg.setStyleSheet("fonz-size: 20px")
            msg.setWindowTitle("Hiányzó beállítás file!")
            msg.setText(
                '<html style="font-size: 14px; color: red">Nem tudtam beolvasni a konfigurációt!<br></html>'
                +
                '<html style="font-size: 16px">Kérem módosítsa a beállításokat!</html>'
            )
            msg.exec_()
            sys.exit(1)

    def start_game(self):
        para = self.merkozesek.currentItem().text().rsplit("\t")
        p1_model = QSqlQueryModel()
        p1_query = QSqlQuery(
            f"select player_id from torna_resztvevok where player_name='{para[2]}'"
        )
        p1_model.setQuery(p1_query)
        p2_model = QSqlQueryModel()
        p2_query = QSqlQuery(
            f"select player_id from torna_resztvevok where player_name='{para[3]}'"
        )
        p2_model.setQuery(p2_query)

        params = []
        params.append(para[2])
        params.append(para[3])
        params.append(int(para[0]))
        self.match_id = int(para[0])
        params.append(int(p1_model.record(0).value(0)))
        params.append(int(p2_model.record(0).value(0)))
        params.append(para[4])
        params.append(int(para[6]))
        params.append(int(para[5]))
        params.append(0)  # hc1
        params.append(0)  # hc2
        params.append(0)  #bets_of...
        self.parent.new_game_window.params = params
        self.parent.new_game_window.refresh()

    def accept(self):
        query = QSqlQuery(
            f"update torna_match set match_status=1 where match_id={self.match_id}"
        )
        query.exec_()
        #self.match_id
        super().accept()

    def reject(self):
        self.parent.new_game_window.close()
        super().reject()